We launched new forums in March 2019—join us there. In a hurry for help with your website? Get Help Now!
    • 38800
    • 35 Posts
    I'm running MODX Revolution 2.2.4 with Login 1.8.0, and appear to have run into what has been logged as a bug here: http://tracker.modx.com/issues/7281 .

    It's perfectly possible to manually create a user account with a purely numerical username in the Manager.

    However, when a user attempts to self-register with a numeric username using Login.Register, the username is created OK, and the confirmation e-mail sent. But when the user clicks on the e-mail link to confirm, although they're taken to the right page - which calls the [[!ConfirmRegister]] snippet - their username isn't activated. Everything works apart from the actual activation of the newly-created numerical username.

    I'm attempting to work around this by writing code to prepend a lower-case "u" to the chosen numerical username. I have a snippet which runs before the "Register" snippet on the page that contains the registration form, which consists of the following code:

    if (isset($_POST['registerbtn'])) {
        $_POST['username:required'] = "u".$_POST['username:required'];
    }


    This works fine, and the whole registration and activation process goes through, so that we end up with a username in the format "u12345" created in the database, where "12345" is the username the user chose.

    The difficulty I'm having is in presenting a login form to the user that requires them only to type the numerical portion of the username. Easy enough in theory - I just need to prepend a "u" to whatever they enter as the username. The "PreHooks" feature of the Login snippet looks like it might be the ticket for this, but what I've done doesn't work - I specified a prehook with the following code:

    $_POST['username'] = "u".$_POST['username'];
    return true;


    However, it's as if the prehook wasn't there - I can log in if I include the "u" at the beginning of the username, but not if I omit it.

    Can anyone suggest what I might do to make this work, please?
      • 3749
      • 24,544 Posts
      I think preHooks (unintuitively) run after the data is saved to the DB.

      You could use JavaScript to add the letter in an OnClick() or OnChange() event. You could have the username field be a dummy field and make the real username field hidden and alter that hidden field when the user fills in the dummy one. I think you could also add an OnClick() event to the submit button and just add it there before submitting the form.

      If you want to avoid JS, you could get the user object in a postHook, change the username, and save it.


      ------------------------------------------------------------------------------------------
      PLEASE, PLEASE specify the version of MODX you are using.
      MODX info for everyone: http://bobsguides.com/modx.html
        Did I help you? Buy me a beer
        Get my Book: MODX:The Official Guide
        MODX info for everyone: http://bobsguides.com/modx.html
        My MODX Extras
        Bob's Guides is now hosted at A2 MODX Hosting
        • 38800
        • 35 Posts
        Thanks Bob! I've read your reply and researched MODX user objects (I do want to avoid JavaScript if I can), and am wondering if we're at cross purposes. Either you've misunderstood me, or I've misunderstood you - but I'm not sure which!!

        The registration and confirmation process works fine, and I end up with a user in the database in the format "u123".

        The problem is where the user tries to log in with their newly-created account. I want them to be able to type "123" into the username field, so I included the following in the login page:

        [[!Login? &loginTpl=`lgnLoginTpl` &logoutTpl=`lgnLogoutTpl` 
        &errTpl=`lgnErrTpl` &loginResourceId=`7` &logoutResourceId=`7` 
        &preHooks=`AlphaAddLogin`]]


        The 'AlphaAddLogin' snippet referred to above contains the following code:

        $_POST['username'] = "u".$_POST['username'];
        return true;


        Since the form generated by the Login snippet posts the form data back to the same page, the idea was that it adds the "u" onto the front of the number typed by the user before the Login snippet gets its hands on it.

        I tried adding an extra test snippet just above the call to the Login snippet with the following code:

        echo "<p>".$_POST['username']."</p>";


        ...and $_POST['username'] did indeed end up being prepended by a "u". But for some reason the Login snippet ended up processing the username as typed by the user - in other words just the number - and so the authentication failed.

        Maybe the snippets on a page aren't processed sequentially as I assumed?
          • 3749
          • 24,544 Posts
          Sorry, I did misunderstand you. I get it now.

          I think this is the problem (from the Login docs):

          preHooks -- A comma-separated list of 'hooks', or Snippets, that will be executed before the user is registered but *after validation.*

          So a preHook is no good.

          I thought that a plugin attached to OnBeforeWebLogin would do it (that event fires just before the user is authenticated and $username is available there). Unfortunately, the params array is not passed by reference so any changes you make would be ignored and if you return anything, the validation fails.

          I don't see any reason why your extra snippet wouldn't work, though, as long as it's above the login snippet and executes only when the form is submitted. Both your snippet and the Login snippet should be called uncached.


          ------------------------------------------------------------------------------------------
          PLEASE, PLEASE specify the version of MODX you are using.
          MODX info for everyone: http://bobsguides.com/modx.html

            Did I help you? Buy me a beer
            Get my Book: MODX:The Official Guide
            MODX info for everyone: http://bobsguides.com/modx.html
            My MODX Extras
            Bob's Guides is now hosted at A2 MODX Hosting
            • 38800
            • 35 Posts
            I'm finding the documentation on prehooks a bit ambiguous - under the "Using Hooks" heading at http://rtfm.modx.com/display/ADDON/Login.Using+Pre+and+Post+Hooks it says "Pre-Hooks in Login are fired before the action occurs, but after field validation" - so slightly different wording.

            Could it be that it means validation of user input (checking that the fields aren't blank etc.), rather than meaning validation of the entered credentials against the user record in the database?
              • 28042 ☆ A M B ☆
              • 24,524 Posts
              Certainly sounds that way to me. Might be worth testing it.
                Studying MODX in the desert - http://sottwell.com
                Tips and Tricks from the MODX Forums and Slack Channels - http://modxcookbook.com
                Join the Slack Community - http://modx.org
                • 3749
                • 24,544 Posts
                It's logical that "validation" would refer to the form rather than authenticating the user, but that wouldn't explain why the OP's code didn't work (though there could be something else wrong with it).

                The code is here: https://github.com/splittingred/Login/tree/develop/core/components/login, but spread around between controllers, processors, and the snippet.


                ------------------------------------------------------------------------------------------
                PLEASE, PLEASE specify the version of MODX you are using.
                MODX info for everyone: http://bobsguides.com/modx.html
                  Did I help you? Buy me a beer
                  Get my Book: MODX:The Official Guide
                  MODX info for everyone: http://bobsguides.com/modx.html
                  My MODX Extras
                  Bob's Guides is now hosted at A2 MODX Hosting
                  • 38800
                  • 35 Posts
                  Thanks Bob. I had a look through the code you linked to, and it seemed to me that the file at https://github.com/splittingred/Login/blob/develop/core/components/login/controllers/web/Login.php might hold the key. But I'm just not understanding enough of it to be able to make any kind of judgement as to What Needs to be Done, unfortunately. I do have experience in object-oriented PHP code and I'm a super-quick learner, but sadly the aforementioned experience doesn't date back further than ...well ... last night actually! smiley
                    • 3749
                    • 24,544 Posts
                    LOL. I would try this, in a plugin called FixUserName -- attached to OnUserSave:


                    <?php
                    if ($mode == modSystemEvent::MODE_NEW) {
                         $userName = $user->get('username');
                        if (is_numeric($userName)) {
                            $user->set('username', 'u' . $userName);
                             $user->save();
                        }   
                    }
                    


                    The only catch being that the username sent in the email will be wrong (unless you prepend the 'u' in the emailTpl chunk).


                    ------------------------------------------------------------------------------------------
                    PLEASE, PLEASE specify the version of MODX you are using.
                    MODX info for everyone: http://bobsguides.com/modx.html
                      Did I help you? Buy me a beer
                      Get my Book: MODX:The Official Guide
                      MODX info for everyone: http://bobsguides.com/modx.html
                      My MODX Extras
                      Bob's Guides is now hosted at A2 MODX Hosting
                      • 38800
                      • 35 Posts
                      Thanks Bob - actually I had got the user registration part working, with the leading "u" being added. Although this is a more elegant way of achieving it!

                      So when a user registers with a number of 123, a user with username of u123 is created in the database. All good there.

                      The trouble is with all of the users who have already registered and had their usernames created in the database. I want them to be able to log in using just the number, and have the system add the leading "u" in to the number they type, so that it matches the username in the database.

                      Harder than it looks, it seems!!