Moving users out of one Group, and into Another Group
Permalink
Is a /jobs/ script going to be the best way to accomplish this? Does the concrete5 API allow it? I'm working on a project that must automatically move users from one group to another, once a year, at a specific date and time. Example:
Greg is in the group Freshman
Sonia is in Sophomores
Fred is in Juniors
Dan is in Seniors
Every year, on June 1st at midnight:
Greg is removed from Freshman and placed in Sophomores
Sonia moves into Juniors
Fred moves into Seniors
Dan stays where he is, since we don't need anything to happen to Seniors.
Also, once a month, I'd like to adjust page permissions automatically per these groups. Seems like the API shoudl make that pretty easy, eh? Can anyone share their experience with creating a /jobs/ script like this?
Greg is in the group Freshman
Sonia is in Sophomores
Fred is in Juniors
Dan is in Seniors
Every year, on June 1st at midnight:
Greg is removed from Freshman and placed in Sophomores
Sonia moves into Juniors
Fred moves into Seniors
Dan stays where he is, since we don't need anything to happen to Seniors.
Also, once a month, I'd like to adjust page permissions automatically per these groups. Seems like the API shoudl make that pretty easy, eh? Can anyone share their experience with creating a /jobs/ script like this?
Hey, thanks. It looks like a great start.
I'm not in production on this project yet, so it will be a little while yet before I can use this, but I'll let you know the results when I'm finished.
I'm not in production on this project yet, so it will be a little while yet before I can use this, but I'll let you know the results when I'm finished.
Thanks for the help earlier. I'm finally getting around to testing this code. It's not working right off the bat. The "job running" gif runs for a long time, continues to when I reload the page. Since the feedback on the jobs dashboard page is pretty minimal, I can't figure out how to tell WHAT it's doing.
How can I test this incrementally line-by-line to find out where its breaking down? I tried breaking the instructions out of the run() function and putting them in a separate php file at the webroot, but it fails at the Group loader (for obvious reasons).
Any advice or ideas on how to test this?
How can I test this incrementally line-by-line to find out where its breaking down? I tried breaking the instructions out of the run() function and putting them in a separate php file at the webroot, but it fails at the Group loader (for obvious reasons).
Any advice or ideas on how to test this?
I wasn't intending it to be just a drop in code block. I'm pretty sure that's what they pay you for not me. ;) That said you can run job through the browser while testing it and you will see any errors.
You can run a job by copying and pasting that long URI string at the bottom of the "Jobs" page and appending &jHandle=job_handle (change job handle to your jobs handle)
I can see by checking that code I posted that
should have been
I've edited to above code block so that it is now correct.
I didn't run that code or anything and I don't know if it actually works even. It was simply to illustrate what the process would look like to get you started.
There is an API browser here
http://www.concrete5.org/api/
This will help you when looking at some of those calls as well.
Don't take this the wrong way. I'll be more than happy to give a fellow developer a hand, but I wasn't intending to simply do it for you, just send you in the right direction. Sorry if there was confusion.
You can run a job by copying and pasting that long URI string at the bottom of the "Jobs" page and appending &jHandle=job_handle (change job handle to your jobs handle)
I can see by checking that code I posted that
$enter = Group::getByName($classes[index + 1]);
should have been
$enter = Group::getByName($classes[$index + 1]);
I've edited to above code block so that it is now correct.
I didn't run that code or anything and I don't know if it actually works even. It was simply to illustrate what the process would look like to get you started.
There is an API browser here
http://www.concrete5.org/api/
This will help you when looking at some of those calls as well.
Don't take this the wrong way. I'll be more than happy to give a fellow developer a hand, but I wasn't intending to simply do it for you, just send you in the right direction. Sorry if there was confusion.
Oh, of course, i totally understand your intentions, and really appreciate your help here. :)
I was more interested in finding how to get some "on-page" php errors to help me track down the problem. The job just keeps running forever, and thus doesn't throw any errors in the dashboard.
I didn't realize that I can use that URL to actually visit a specific job. This should make it a lot easier to track things down!
Thanks again for sharing your thoughts.
I was more interested in finding how to get some "on-page" php errors to help me track down the problem. The job just keeps running forever, and thus doesn't throw any errors in the dashboard.
I didn't realize that I can use that URL to actually visit a specific job. This should make it a lot easier to track things down!
Thanks again for sharing your thoughts.
No problem. I was just worried because I really didn't test it at all and you should definitely test it out first because it might have an error that will mess things up for your data.
Thank you so much for your time so far. No worries on the data side. The project is still in its early development stages and so we only have dummy data in there anyway. :)
The API is pretty new to me, since I haven't had to write any specialized programs for our projects until now. After digging into the API, I am finding it extremely useful.
I seems that we don't need to load the Group model, but DO need to load the UserList model. But now that I've done that, and the script has no run time errors, I'm still not seeing users enter and exit groups when the job runs. I'm getting a success message, but nothing appears to happen. It's acts as though it's just ignoring the exitGroup() and enterGroup() statements completely. You figure if they didn't work they would throw an error.
It looks good on paper... any ideas? Maybe there's some sort of quirk with the User class or something?
The API is pretty new to me, since I haven't had to write any specialized programs for our projects until now. After digging into the API, I am finding it extremely useful.
I seems that we don't need to load the Group model, but DO need to load the UserList model. But now that I've done that, and the script has no run time errors, I'm still not seeing users enter and exit groups when the job runs. I'm getting a success message, but nothing appears to happen. It's acts as though it's just ignoring the exitGroup() and enterGroup() statements completely. You figure if they didn't work they would throw an error.
It looks good on paper... any ideas? Maybe there's some sort of quirk with the User class or something?
hmm...
maybe check to see if we are getting any $users from the UserList.
Maybe
after the
Are you classes named the same as the array above?
If we don't get any $users than the foreach loop never runs to add and remove $users, so that could be a problem spot?
maybe check to see if we are getting any $users from the UserList.
Maybe
var_dump($users);
after the
$user = $ul->get();
Are you classes named the same as the array above?
If we don't get any $users than the foreach loop never runs to add and remove $users, so that could be a problem spot?
[EDIT] I realize that I could be experiencing a conflict within the system, since I'm also using the simple subscriptions add-on. This plugin can make user profiles can be a little higher-maintenance than usual, so that may explain things. I'll get back in touch about that soon.
[/EDIT]
I made sure to synch up the group names, so that's not the issue.
The var_dump shows that I'm getting User objects placed into the $users array. Thus, the second foreach loop must be running...
For clarity, here's the code, with the var_dump statement in, and the results of the var_dump. Sorry in advance for all the code.
and here is the result of the var dump:
[/EDIT]
I made sure to synch up the group names, so that's not the issue.
The var_dump shows that I'm getting User objects placed into the $users array. Thus, the second foreach loop must be running...
For clarity, here's the code, with the var_dump statement in, and the results of the var_dump. Sorry in advance for all the code.
function run() { $classes = array('Freshman', 'Sophomore', 'Junior', 'Senior'); // Load the user_list model Loader::model('user_list'); // ...Graduate the Users foreach($classes as $index => $class) { // This gets us a list of users that we can filter $ul = new UserList(); // This takes a group name $ul->filterByGroup($class); // This returns the results $users = $ul->get(); var_dump($users); die(); //
Viewing 15 lines of 42 lines. View entire code block.
and here is the result of the var dump:
array(2) { [0]=> object(UserInfo)#92 (15) { ["error"]=> string(0) "" ["uID"]=> string(1) "4" ["uLastLogin"]=> string(1) "0" ["uIsValidated"]=> string(2) "-1" ["uPreviousLogin"]=> string(1) "0" ["uIsFullRecord"]=> string(1) "1" ["uNumLogins"]=> string(1) "0" ["uDateAdded"]=> string(19) "2011-12-19 18:48:23" ["uIsActive"]=> string(1) "1" ["uLastOnline"]=> string(1) "0" ["uHasAvatar"]=> string(1) "0" ["uName"]=> string(8) "freshman" ["uEmail"]=> string(21) "freshman@freshman.fre" ["uPassword"]=> string(32) "1b586a5860c871d4cbde6ef87cc1d091" ["uTimezone"]=> NULL } [1]=> object(UserInfo)#90 (15) { ["error"]=> string(0) "" ["uID"]=> string(1) "5" ["uLastLogin"]=> string(1) "0" ["uIsValidated"]=> string(2) "-1" ["uPreviousLogin"]=> string(1) "0" ["uIsFullRecord"]=> string(1) "1" ["uNumLogins"]=> string(1) "0" ["uDateAdded"]=> string(19) "2011-12-19 18:48:48" ["uIsActive"]=> string(1) "1" ["uLastOnline"]=> string(1) "0" ["uHasAvatar"]=> string(1) "0" ["uName"]=> string(9) "sophomore" ["uEmail"]=> string(23) "sophomore@sophomore.sop" ["uPassword"]=> string(32) "0ee384301128b843c84b2496cdad64e8" ["uTimezone"]=> string(19) "America/Los_Angeles" } }
Got it! I identified the problem thanks to this thread, and a post by Benji.
http://www.concrete5.org/community/forums/customizing_c5/how-to-add...
The UserList model only returns a list of UserInfo objects. UserInfo objects dont' have the enterGroup() method. Only User Objects do. So after we pull up the UserInfo object from the list, we then have to extract the UserObject by using:
Also, reversed the order of the Group names in the $classes array -- the original code graduated freshmen directly to the seniors group. Going backwards prevents this and still accomplishes the end result. :)
So the run() function winds up looking like this:
http://www.concrete5.org/community/forums/customizing_c5/how-to-add...
The UserList model only returns a list of UserInfo objects. UserInfo objects dont' have the enterGroup() method. Only User Objects do. So after we pull up the UserInfo object from the list, we then have to extract the UserObject by using:
$user = $userInfo->getUserObject();
Also, reversed the order of the Group names in the $classes array -- the original code graduated freshmen directly to the seniors group. Going backwards prevents this and still accomplishes the end result. :)
So the run() function winds up looking like this:
function run() { $classes = array( 'Graduates', 'Senior', 'Junior', 'Sophomore', 'Freshman' ); // Load the user_list model Loader::model('user_list'); // ...Graduate the Users foreach($classes as $index => $class) { // This gets us a list of users that we can filter $ul = new UserList(); // This takes a group name $ul->filterByGroup($class); // This returns the results $users = $ul->get(); // // Now we'll go through the class and move them up //
Viewing 15 lines of 43 lines. View entire code block.
Oops, looks like I was giving those freshman too much credit. haha.
Glad you got it sorted out. Thanks for posting back the solution. I learned something too.
Best Regards
Glad you got it sorted out. Thanks for posting back the solution. I learned something too.
Best Regards
Happy to oblige. Teamwork makes the dreamwork. ;)
I want to revive this thread to add to it. I'm doing something similar and want to notify users of their group change.
I was looking at the documentation to send an email when a user is activated and thinking of adding to the site_events.php:
Then the on_change.php file would look like:
I just wonder if the onActivation is something built into C5 and if I can change it to onChange and have it function. I'm going to test this today and hopefully have my answer.
I was looking at the documentation to send an email when a user is activated and thinking of adding to the site_events.php:
Events::extend('on_user_change', 'OnChange', 'sendChangeMail', 'models/on_change.php');
Then the on_change.php file would look like:
class OnChange { public function sendChangeMail($ui) { $mh = Loader::helper('mail'); $userEmailAddress = $ui->uEmail; $userName = $ui->uName; $userFname = $ui->getAttribute('firstname'); $mh->addParameter('memEmail',$userEmailAddress); $mh->addParameter('memName',$userName); $mh->addParameter('memFname',$userFname); $mh->to($userEmailAddress); $mh->load('notify_user_change'); $mh->sendMail(); } }
I just wonder if the onActivation is something built into C5 and if I can change it to onChange and have it function. I'm going to test this today and hopefully have my answer.
I didn't test that. But hey, might work. You use the jobs run() method and cron job it to run once a year on that date.