We launched new forums in March 2019—join us there. In a hurry for help with your website? Get Help Now!
    • 36760
    • 136 Posts
    This builds on my other thread a little bit: http://forums.modx.com/thread/97119/showing-user-extended-fields-alongside-normal-fields-in-manager, but I thought it was different enough to warrant a new thread.

    After getting ClassExtender working, I decided to take customizing the user update page in the manger a step further. My hope is to organize the user fields to match the same order/groupings as the registration form. For testing purposes, I only worked with the Username field, but I hope to apply this same method to all the fields.


    First, I created a script called user-forms.js to remove the username field:

    jQuery(function($) {
        $(window).bind("load", function() {
            $('#modx-user-username').remove();
        });
    });

    Inside the ExtraUsersFields plugin I have the jQuery library loading OnFormPreRender, and my user-forms script loading OnUserFormRender. Both using $modx->regClientStartupScript. This successfully removes the field.


    Then, I re-add the username field inside the MyExtraUserFields chunk, using code similar to the sample fields. This will be where I do all the field ordering, add headers, etc.

    <div class="x-form-item x-tab-item">
        <label class="x-form-item-label" style="width:auto; font-weight:bold; float:none; font-size:12px">Username Testing</label>
        <div class="x-form-item x-tab-item" id="x-form-el-modx-user-username">
            <input type="text" name="username" value="[[+username]]" class="x-form-text x-form-field" 
                onClick="Ext.getCmp('modx-panel-user').markDirty();" />
        </div>
    </div>

    One question here is do I still need onClick="Ext.getCmp('modx-panel-user').markDirty();" on the fields?


    To make my placeholder work, I setup a new plugin called rePopulateUserFields:

    $uid = 9;
    $user = $modx->getObject('modUser', $uid);
    if ($user) {
       $username = $user->get('username');
       $profile = $user->getOne('Profile');
       if ($profile) {
           $modx->setPlaceholder('username', $username);
       }
    }


    This is where my big problem is. I can't figure out how to get the ID of the user I'm editing. What I have above repopulates the username field correctly, but only for the user with an ID of 9.


    To summarize my questions:
    1. Do I need to include onClick="Ext.getCmp('modx-panel-user').markDirty();" on my fields that aren't extended fields?
    2. How do I get the ID of the user I'm editing in the manager, as opposed to the ID of the user who is logged into the manager?
      --Tentatively using $uid = htmlspecialchars($_GET['id']); as per my first reply below
    3. Finally, is this the best method to accomplish what I want? I feel like using jQuery might not be the best way to remove the fields, but it's all I could come up with.

    Thanks for the help! [ed. note: firebot6 last edited this post 8 years, 10 months ago.]
      • 36760
      • 136 Posts
      Turns out I was thinking too hard with regards to getting the user id for the page, it's right in the URL! I just added $uid = htmlspecialchars($_GET['id']); to my rePopulateUserFields plugin. In place of $uid = 9;

      I read up on using $_GET and it seems there are possibly security concerns as far as someone injecting something malicious into the URL. Is this a concern if I'm only using it in the manager area, assuming someone with manager access isn't up to no good?
      • The problem with any input from any source is the possibility of the input value being crafted to mess with the database - SQL injection. If the input value is going anywhere near the database, it needs to be validated and sanitized. An example might be
        ...SELECT * FROM tablename WHERE 'id' = $_GET['id']...

        http://phpsecurity.readthedocs.org/en/latest/Injection-Attacks.html

        However, even in the case where GET or POST value is used immediately and only in code, or is reflected directly back to the visitor, it is still necessary to validate and sanitize the value. Reflected XSS attacks are accomplished by inserting malicious Javascript into the GET or POST, so that when it is inserted into the page to be viewed in the visitor's browser it will run the code.
        http://phpsecurity.readthedocs.org/en/latest/Cross-Site-Scripting-%28XSS%29.html

        In your case, you are looking for the user ID, which must be an integer. So there are two PHP functions that you can use to validate and sanitize the GET value. Since GET and POST values are of necessity strings, use the is_numeric() function to determine if the value is a representation of a number - 42 is a number, '42' is a string representation of a number. Then to make doubly sure you're getting an integer value, explicitly cast it to integer.

        if (is_int($_GET['id']) {
            $id = intval($_GET['id']);
        }
        
        [ed. note: sottwell last edited this post 8 years, 10 months ago.]
          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
          • 4172
          • 5,888 Posts
          you could try to create your own CMP with MIGXdb.
          Here is an example

          https://github.com/Bruno17/migxclientmanager
            -------------------------------

            you can buy me a beer, if you like MIGX

            http://webcmsolutions.de/migx.html

            Thanks!
            • 3749
            • 24,544 Posts
            Susan, I think you might have meant this:

            $id = null;
            if (isset($_GET['id'])) {
                $id = (int) $_GET['id'];
            }


            Otherwise, the code could throw an E_NOTICE error (also, casting to (int) is a little faster than intval() ).

            BTW, MODX sanitizes the $_POST, $_GET, and $_REQUEST arrays on every request, and xPDO sanitizes every DB request, though extra sanitizing never hurts.

            @firebot6: Another way to go would be to use UpdateProfile (and the ClassExtender helper for it) to create a custom form in the front end. It keeps the users out of the Manager, but creates a front-end page (though presumably, it would only be available to logged-in users).
              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
              • 36760
              • 136 Posts
              Thank you all for the replies and information. I'll be sure to implement the sanitization methods suggested. Security is pretty important with this site (even more so than normal), so I don't want to take any chances.

              @Bruno17
              I'll take a look at MIGX, though I'm not sure if it will work in this instance based on the description. I just moved all my extra data away from the "extended" field.

              @BobRay
              The reason I was hoping to do it in the manager is because the site is being made to collect a bunch of user information for program signups, which may need to be manually edited after signup by admins. It seemed more intuitive for the end-user admins (not me) to be able to do it all without leaving the manager area. Though the Update Profile page was my backup plan if all this really fell through.