/**
  * TODO: Document me
  */
 private function getUpdateOptions($userinfo)
 {
     global $wgRequest;
     // Build an array of attributes to update
     $updateOptions = array();
     foreach (FacebookUser::$availableUserUpdateOptions as $option) {
         // Translate the MW parameter into a FB parameter
         $value = FacebookUser::getOptionFromInfo($option, $userinfo);
         // If no corresponding value was received from Facebook, then continue
         if (!$value) {
             continue;
         }
         // Check to see if the option was checked on a previous page (default to true)
         $checked = $wgRequest->getText("wpUpdateUserInfo{$option}", '0') != '1';
         // Build the list item for the update option
         $item = '<li>';
         $item .= '<input name="wpUpdateUserInfo' . $option . '" type="checkbox" ' . 'value="1" id="wpUpdateUserInfo' . $option . '" ' . ($checked ? 'checked="checked" ' : '') . '/>';
         $item .= '<label for="wpUpdateUserInfo' . $option . '">' . wfMsgHtml("facebook-{$option}") . wfMsgExt('colon-separator', array('escapenoentities')) . " <i>{$value}</i></label></li>";
         $updateOptions[] = $item;
     }
     // Implode the update options into an unordered list
     $updateChoices = '';
     if (count($updateOptions) > 0) {
         $updateChoices .= wfMsgHtml('facebook-updateuserinfo') . "\n";
         $updateChoices .= "<ul>\n" . implode("\n", $updateOptions) . "\n</ul>\n";
     }
     return $updateChoices;
 }
 /**
  * @throws FacebookUserException
  */
 function createUser($username, $domain = '')
 {
     global $wgUser, $wgAuth;
     // Make sure we're not stealing an existing user account (it can't hurt to check twice)
     if (empty($username) || !FacebookUser::userNameOK($username)) {
         wfDebug("Facebook: Name not OK: '{$username}'\n");
         // TODO: Provide an error message that explains that they need to pick a name or the name is taken.
         throw new FacebookUserException('connectNewUserView', 'facebook-invalidname');
     }
     /// START OF TYPICAL VALIDATIONS AND RESTRICTIONS ON ACCOUNT-CREATION. ///
     // Check the restrictions again to make sure that the user can create this account.
     if (wfReadOnly()) {
         // Indicate readOnlyPage error
         throw new FacebookUserException('readonlypage', null);
     }
     global $wgFbDisableLogin;
     if (empty($wgFbDisableLogin)) {
         // These two permissions don't apply in $wgFbDisableLogin mode because
         // then technically no users can create accounts
         if ($wgUser->isBlockedFromCreateAccount()) {
             wfDebug("Facebook: Blocked user was attempting to create account via Facebook Connect.\n");
             throw new FacebookUserException('facebook-error', 'facebook-errortext');
         } else {
             $titleObj = SpecialPage::getTitleFor('Connect');
             $permErrors = $titleObj->getUserPermissionsErrors('createaccount', $wgUser, true);
             if (count($permErrors) > 0) {
                 // Special case for permission errors
                 throw new FacebookUserException($permErrors, 'createaccount');
             }
         }
     }
     // If we are not allowing users to login locally, we should be checking
     // to see if the user is actually able to authenticate to the authenti-
     // cation server before they create an account (otherwise, they can
     // create a local account and login as any domain user). We only need
     // to check this for domains that aren't local.
     if ($domain != '' && $domain != 'local' && !$wgAuth->canCreateAccounts() && !$wgAuth->userExists($username)) {
         throw new FacebookUserException('facebook-error', 'wrongpassword');
     }
     // IP-blocking (and open proxy blocking) protection from SpecialUserLogin
     global $wgEnableSorbs, $wgProxyWhitelist;
     $ip = wfGetIP();
     if ($wgEnableSorbs && !in_array($ip, $wgProxyWhitelist) && $wgUser->inSorbsBlacklist($ip)) {
         throw new FacebookUserException('facebook-error', 'sorbs_create_account_reason');
     }
     // Run a hook to let custom forms make sure that it is okay to proceed with
     // processing the form. This hook should only check preconditions and should
     // not store values.  Values should be stored using the hook at the bottom of
     // this function. Can use 'this' to call
     // sendPage('chooseNameFormView', 'SOME-ERROR-MSG-CODE-HERE') if some of the
     // preconditions are invalid.
     #if (!wfRunHooks( 'SpecialConnect::createUser::validateForm', array( &$this ) )) {
     #	return;
     #}
     $user = User::newFromName($username);
     if (!$user) {
         wfDebug("Facebook: Error creating new user.\n");
         throw new FacebookUserException('facebook-error', 'facebook-error-creating-user');
     }
     // TODO: Make user a Facebook user here: $fbUser = new FacebookUser($user);
     // Let extensions abort the account creation.
     // NOTE: Currently this is commented out because it seems that most wikis might have a
     // handful of restrictions that won't be needed on Facebook Connections. For instance,
     // requiring a CAPTCHA or age-verification, etc. Having a Facebook account as a pre-
     // requisite removes the need for that.
     /*
     $abortError = '';
     if( !wfRunHooks( 'AbortNewAccount', array( $user, &$abortError ) ) ) {
     	// Hook point to add extra creation throttles and blocks
     	wfDebug( "SpecialConnect::createUser: a hook blocked creation\n" );
     	throw new FacebookUserException('facebook-error', 'facebook-error-user-creation-hook-aborted',
     			array( $abortError ));
     }
     */
     // Apply account-creation throttles
     global $wgAccountCreationThrottle, $wgMemc;
     if ($wgAccountCreationThrottle && $wgUser->isPingLimitable()) {
         $key = wfMemcKey('acctcreate', 'ip', $ip);
         $value = $wgMemc->get($key);
         if (!$value) {
             $wgMemc->set($key, 0, 86400);
         }
         if ($value >= $wgAccountCreationThrottle) {
             // 'acct_creation_throttle_hit' should actually use 'parseinline' not 'parse' in $wgOut->showErrorPage()
             throw new FacebookUserException('facebook-error', 'acct_creation_throttle_hit', array($wgAccountCreationThrottle));
         }
         $wgMemc->incr($key);
     }
     /// END OF TYPICAL VALIDATIONS AND RESTRICTIONS ON ACCOUNT-CREATION. ///
     // Fill in the info we know
     $userinfo = $this->getUserInfo();
     $email = FacebookUser::getOptionFromInfo('email', $userinfo);
     $realName = FacebookUser::getOptionFromInfo('fullname', $userinfo);
     $pass = '';
     // Create the account (locally on main cluster or via $wgAuth on other clusters)
     // $wgAuth essentially checks to see if these are valid parameters for new users
     if (!$wgAuth->addUser($user, $pass, $email, $realName)) {
         wfDebug("Facebook: Error adding new user to database.\n");
         throw new FacebookUserException('facebook-error', 'facebook-errortext');
     }
     // Add the user to the local database (regardless of whether $wgAuth was used)
     // This is a custom version of similar code in SpecialUserLogin's LoginForm
     // with differences due to the fact that this code doesn't require a password, etc.
     global $wgExternalAuthType;
     if ($wgExternalAuthType) {
         $user = ExternalUser::addUser($user, $pass, $email, $realName);
         if (is_object($user)) {
             $extUser = ExternalUser::newFromName($username);
             $extUser->linkToLocal($user->getId());
             $extEmail = $extUser->getPref('emailaddress');
             if (!empty($extEmail) && empty($email)) {
                 $user->setEmail($extEmail);
             }
         }
     } else {
         $user->addToDatabase();
     }
     // Attach the user to their Facebook account in the database.
     // This must be done up here, because somewhere after this (I'm not too
     // sure where) the data must be in the database before copy-to-local is
     // done for shared setups.
     FacebookDB::addFacebookID($user, $this->id);
     $this->user = $user;
     $wgAuth->initUser($this->user, true);
     // $autocreate == true
     $wgAuth->updateUser($this->user);
     // No passwords for Facebook accounts.
     /*
     if ( $wgAuth->allowPasswordChange() ) {
     	$this->user->setPassword( $pass );
     }
     */
     // Store which fields should be auto-updated from Facebook when the user logs in.
     global $wgRequest;
     $updateFormPrefix = 'wpUpdateUserInfo';
     foreach (self::$availableUserUpdateOptions as $option) {
         if ($wgRequest->getVal($updateFormPrefix . $option, '') != '') {
             $user->setOption("facebook-update-on-login-{$option}", 1);
         } else {
             $user->setOption("facebook-update-on-login-{$option}", 0);
         }
     }
     // Process the FacebookPushEvent preference checkboxes if Push Events are enabled
     global $wgFbEnablePushToFacebook;
     if (!empty($wgFbEnablePushToFacebook)) {
         global $wgFbPushEventClasses;
         if (!empty($wgFbPushEventClasses)) {
             foreach ($wgFbPushEventClasses as $pushEventClassName) {
                 $pushObj = new $pushEventClassName();
                 $className = get_class();
                 $prefName = $pushObj->getUserPreferenceName();
                 $this->user->setOption($prefName, $wgRequest->getCheck($prefName) ? '1' : '0');
             }
         }
         // Save the preference for letting user select to never send anything to their newsfeed
         $prefName = FacebookPushEvent::$PREF_TO_DISABLE_ALL;
         $this->user->setOption($prefName, $wgRequest->getCheck($prefName) ? '1' : '0');
     }
     // I think this should be done here
     $this->user->setToken();
     // This is done via login()
     #$this->user->saveSettings();
     // Log the user in
     $this->login();
     // Update user count
     $ssUpdate = new SiteStatsUpdate(0, 0, 0, 0, 1);
     $ssUpdate->doUpdate();
     wfRunHooks('AddNewAccount', array($this->user));
     // Allow custom form processing to store values since this form submission was successful.
     // This hook should not fail on invalid input, instead check the input using the SpecialConnect::createUser::validateForm hook above.
     #wfRunHooks( 'SpecialConnect::createUser::postProcessForm', array( &$this ) );
     $wgUser->addNewUserLogEntryAutoCreate();
 }