Skip to main content

This site requires you to update your browser. Your browsing experience maybe affected by not having the most up to date version.

Customising the CMS

Critical issues adding/editing/grouping Members making SS unusable?


Reply

7 Posts   1732 Views

Avatar
dizzystuff

5 April 2010 at 10:31pm (Last edited: 5 April 2010 10:36pm), Community Member, 93 Posts

Argh! Blergh! That's not a trolling thread title, I really don't know what to do about this or how to get around it :((

If I've got this right, and I hope I haven't, I've got an epic problem working with Members. Adding, Editing, Adding to SecurityGroups and avoiding duplicate Email Addresses of Members or overwriting Members along the way.

1) If I am in the Security Admin and attempt to add a Member to a Security Group, if the entered Email Address doesn't already exist for a Member then a new Member is created. This is surely a problem, a full Member form has not been completed so the Member is missing much info, and potentially it was just a typo anyway. Is there any way to disable this creation? And return a message to the user?

2) More critically, if I am in a Security Group and I type in an existing Member's Email Address but mistype or accidentally leave First or Last Name fields blank - this actually updates the Member itself, removing First and Last Name in addition to adding the Member to the Security Group. Do you guys trust your users that much?

Is there any way to select a Member to be added to a Security Group based on the Email Address in the form (ie the Unique Member Field field) without updating the associated Member record with the rest of the submitted info? I just can't let users near this screen while it functions like this. Am I the only one this causes major concerns for?

So instead I use ModelAdmin managing my Members to avoid SecurityAdmin. Which comes with critical problems also:

1) If a Member is added with an email address that an existing Member already has, an ajax 500 error is returned but the user is not notified AND an empty/ghost row is added to the Members table.

2) If I edit a Member record and update the Email Address to be that of an existing other Member, the form is allowed to Save successfully and I now have two Members with the same Email Address / Unique Member Field.

This all seems like such a major oversight / issue with Member management that I really must be missing something and will be happy if that's the case. I hope this post doesn't come across snarky, I don't intend it to be, I'm just at the end of many hours/days/weeks trying to implement a Member management solution that will be useable and reliable for crazy CMS Users. Outside of this, Silverstripe is a dream to work with, I'm a genuine fan.

If I need to extend a whole bunch of stuff to get to the above, I'll happily do so. And if it gets complicated, I'll dive right into the docs/forums/book/api/dev-google-group. It's just that so far they haven't done the trick.

Surely with all the production Silverstripe sites out there I'm not the only person to come across this, nor be the only person who would not be happy handing this Member management functionality to a client. If anyone could be of help, I'd be very appreciative. Further, I'm certainly prepared to pay for good help that helps me turn this around rapidly, feel free to get in touch via luke@dizzylabs.com.au.

Regards
dizzy

Avatar
dizzystuff

6 April 2010 at 1:21am Community Member, 93 Posts

One of my core issues is that Email address can sometimes be a poor choice for unique fields among Members. I'd admit that the majority of the time this wouldn't be the case, but when serving a studnet base of families where there may be just one email addy amongst family members but each family member requires a user account... eek.

And given all the issues above with adding/editing/overwriting email addys as it is, the fact that users should also be able to update the field adds an extra level of stuff I don't want to deal with. I know (I think) on the front end there is a Member_Validator field that prevents duplicate email addresses, but with emails often updated I can just see a CMS User going into the admin to update an email addy on behalf of a family and fiddling with a tenuous StudentAdmin more often than otherwise needed.

So. My solution so far is to replace Email Address with Username as the Unique Identifier Field for Members. I figure that I will make this Username field unavailable for editing once the Member is created, so in the ModelAdmin implementation I remove my worries of CMS Users overwriting the Unique Identifier Field but still allow them to update email addresses to their hearts' content.

This still leaves me with the problem though of Adding a new Member via ModelAdmin and duplicating the Username -> I get an empty/ghost row in the Members table and the user does not get an error returned to the screen.

For the SecurityAdmin, I have added Username to the Summary_Fields for Member so it appears in the MemberTableField columns, but I don't think there's any resolution for me here in respect to my concerns above. It's just weird, considering SecurityAdmin is the intended primary manager of Members in Silverstripe, is that right?

Btw, I've got the Email to Username change up and humming in 2.4 really nicely IMO. I used the existing [url=http://silverstripe.org/auth-username-module/]Auth_Username Module[/url] as a starting-point/head-start, and rejigged it to work with 2.4. Also I removed any need to make changes to core, to allow for updating. I'm still testing and tweaking but I will eventually submit it to the Modules library. If anyone wants/needs the raw stuff as it is now, shout and I'll post as a zip.

Avatar
Aram

8 April 2010 at 12:45am Community Member, 598 Posts

Hi Dizzy

That sounds like a good way to solve it a lot of the issues. When I came across this issue I tried adding some code to the onBeforeWrite() function in my DO, but I couldn't figure out how to prevent a save and return a nice error. If that can be figured out then it shouldn't be much trouble to prevent that ghost row and return a proper error in ModelAdmin......

Your username module also sounds like a great idea, I look forward to seeing it :)

Aram

www.SSBits.com - SilverSripe Tutorials, tips and other bits

Avatar
meganub

30 October 2010 at 4:11am Community Member, 15 Posts

Hi Dizzy/Aram,

I've just hit the exact same issue with Member in ModelAdmin. I managed to get past various issues to do with creating users by extending the CollectionController. however I'm now blocked at this stage.

From what I've seen so far of the CollectionController, a DO is written twice (once to generate ID, once to save data) - and the error occurs on the second write.

I'm investigating the issue now, so I'll post back any findings. I've subscribed to this thread as well if you have any pearls of wisdom picked up since April to share with me :)

Cheers

Avatar
meganub

2 November 2010 at 5:41am Community Member, 15 Posts

Right Guys, I've figured this one out.

Basically you need to extend ModelAdmin_RecordController and ModelAdmin_CollectionController:

In your own ModelAdmin_CollectionController class, override doCreate() like so:

   function doCreate($data, $form, $request) {
      $className = $this->getModelClass();
      $model = new $className();
      $saveError = false; /// new ///
      // We write before saveInto, since this will let us save has-many and many-many relationships :-)

      // if dealing with a Member model, then save and blank email first
      if ($model instanceOf Member) {
         $form->saveInto($model);
         $model->Email = '';
      }

      $model->write();
      $form->saveInto($model);

      // try the last write, catch a failure...
      try {
         $model->write();         
      }
      catch(ValidationException $e) {
         if ($model instanceOf Member)
            $saveError = true;
      }

      if(Director::is_ajax()) {
         $class = $this->parentController->getRecordControllerClass($this->getModelClass());
         $recordController = new $class($this, $request, $model->ID);
         return new SS_HTTPResponse(
            $recordController->EditForm($saveError)->forAjaxTemplate(),
            200,
            sprintf(
               _t('ModelAdmin.LOADEDFOREDITING', "Loaded '%s' for editing."),
               $model->Title
            )
         );
      } else {
         Director::redirect(Controller::join_links($this->Link(), $model->ID , 'edit'));
      }
   }

In your own ModelAdmin_RecordController class, override EditForm() to make use of the $saveError boolean now passed to it:

   public function EditForm($memberError=false) {
   ...

and before the form is returned in same method:

   if ($memberError) {
      $form->sessionMessage("A user with this email address already exists in the system. Please change the email and save again.", 'bad');         
   }

The problem was that the exception thrown by the Member class on encountering the duplicate email was not getting caught. In the overridden ModelAdmin_CollectionController I'm not saving the data first without the email address, so if it errors out there is at least a partial record stored. The second write() is now surrounded by a try...catch, which deals with the error gracefully via the overridden ModelAdmin_RecordController.

Avatar
meganub

11 June 2011 at 8:51pm Community Member, 15 Posts

Hi CHD,

What has your post content got to do with Members in model admin? I think you may have posted to the wrong topic.

Cheers

Meganub

Avatar
CHD

13 June 2011 at 2:38am Community Member, 218 Posts

well i was just searching through the forums for help on using a form anywhere in a site, and also checking the database for existing members before writing, and this was one of the threads that popped up a lot, so i figured anybody in the future looking for the same problem will end up here too!

sorry if its not really relevant to this thread...