Skip to content
This repository was archived by the owner on Sep 10, 2021. It is now read-only.

Commit 7ac3ef1

Browse files
committed
ENH: refs #873. Improve community invitation methods
-Add ability to invite by email, including for users that do not exist yet -Add ability to invite into groups besides just the member group
1 parent d5fa3dd commit 7ac3ef1

14 files changed

+601
-134
lines changed

core/controllers/CommunityController.php

Lines changed: 193 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -321,6 +321,12 @@ function viewAction()
321321
Zend_Registry::get('notifier')->callback('CALLBACK_CORE_USER_JOINED_COMMUNITY', array('user' => $this->userSession->Dao, 'community' => $communityDao));
322322
if($this->view->isInvited)
323323
{
324+
$invitationDao = $this->CommunityInvitation->isInvited($communityDao, $this->userSession->Dao, true);
325+
if($invitationDao->getGroupId() !== $member_group->getKey())
326+
{
327+
// If user is invited to something besides the member group, we should add them to that group also
328+
$this->Group->addUser($invitationDao->getGroup(), $this->userSession->Dao);
329+
}
324330
$this->CommunityInvitation->removeInvitation($communityDao, $this->userSession->Dao);
325331
}
326332
}
@@ -406,69 +412,171 @@ function deleteAction()
406412
$this->_redirect('/');
407413
}//end delete
408414

409-
/** Invite a user to a community*/
415+
/**
416+
* Dialog for inviting a user to a community
417+
* @param communityId Id of the community to invite into. Write permission required.
418+
*/
410419
function invitationAction()
411420
{
412421
$this->disableLayout();
413422

414-
$communityId = $this->_getParam("communityId");
415-
if(!isset($communityId) || !is_numeric($communityId))
423+
$communityId = $this->_getParam('communityId');
424+
if(!isset($communityId))
416425
{
417-
throw new Zend_Exception("Community ID should be a number");
426+
throw new Zend_Exception('Must pass a communityId parameter');
418427
}
419428
$communityDao = $this->Community->load($communityId);
420-
if($communityDao === false || !$this->Community->policyCheck($communityDao, $this->userSession->Dao, MIDAS_POLICY_WRITE))
429+
if(!$communityDao)
421430
{
422-
throw new Zend_Exception("This community doesn't exist or you don't have the permissions.");
431+
throw new Zend_Exception('Invalid communityId', 404);
432+
}
433+
if(!$this->Community->policyCheck($communityDao, $this->userSession->Dao, MIDAS_POLICY_WRITE))
434+
{
435+
throw new Zend_Exception('Write permission required on the community', 403);
423436
}
437+
}
424438

425-
if($this->_request->isPost())
439+
/**
440+
* Ajax method for sending an invitation email to a user
441+
* @param communityId Id of the community to invite into
442+
* @param [groupId] Id of the group to invite into. If none is passed, uses the members group
443+
* @param [userId] Id of the user to invite. If not passed, must pass email parameter
444+
* @param [email] Email of the user to invite. If not passed, must pass userId parameter.
445+
If no such user exists, sends an email inviting the user to register and join the group.
446+
*/
447+
function sendinvitationAction()
448+
{
449+
$this->disableLayout();
450+
$this->disableView();
451+
452+
$communityId = $this->_getParam('communityId');
453+
$userId = $this->_getParam('userId');
454+
$email = $this->_getParam('email');
455+
456+
$community = $this->Community->load($communityId);
457+
if(!$community)
426458
{
427-
$this->disableView();
428-
$sendInvitation = $this->_getParam('sendInvitation');
429-
if(isset($sendInvitation))
459+
throw new Zend_Exception('Invalid communityId', 404);
460+
}
461+
if(!$this->Community->policyCheck($community, $this->userSession->Dao, MIDAS_POLICY_WRITE))
462+
{
463+
throw new Zend_Exception('Write permission required on the community', 403);
464+
}
465+
$isAdmin = $this->Community->policyCheck($community, $this->userSession->Dao, MIDAS_POLICY_ADMIN);
466+
467+
$groupId = $this->_getParam('groupId');
468+
if(isset($groupId))
469+
{
470+
$group = $this->Group->load($groupId);
471+
if($group->getCommunityId() !== $community->getKey())
430472
{
431-
$userId = $this->_getParam('userId');
432-
$userDao = $this->User->load($userId);
433-
if($userDao == false)
434-
{
435-
throw new Zend_Exception("Unable to find user.");
436-
}
437-
if($this->Group->userInGroup($userDao, $communityDao->getMemberGroup()))
473+
throw new Zend_Exception('Specified group is not in the specified community');
474+
}
475+
if(!$isAdmin && $groupId == $community->getAdmingroupId())
476+
{
477+
throw new Zend_Exception('Only members of the admin group may invite users to the admin group');
478+
}
479+
}
480+
else
481+
{
482+
$group = $community->getMemberGroup();
483+
}
484+
485+
if(isset($userId)) // invite an existing user by id
486+
{
487+
$user = $this->User->load($userId);
488+
if($user == false)
489+
{
490+
throw new Zend_Exception('Invalid userId');
491+
}
492+
$this->_sendUserInvitation($user, $group);
493+
}
494+
else if(isset($email)) // invite an existing or non-existing user by email
495+
{
496+
$existingUser = $this->User->getByEmail($email);
497+
if($existingUser)
498+
{
499+
$this->_sendUserInvitation($existingUser, $group);
500+
}
501+
else
502+
{
503+
$validator = new Zend_Validate_EmailAddress();
504+
if(!$validator->isValid($email))
438505
{
439-
echo JsonComponent::encode(array(false, $userDao->getFullName().' is already a member of this community'));
440-
return;
506+
throw new Zend_Exception('Invalid email syntax: '.$email);
441507
}
442-
$invitation = $this->CommunityInvitation->createInvitation($communityDao, $this->userSession->Dao, $userDao);
443-
// Check if there is already a pending invitation
444-
if($invitation == false)
508+
$newuserModel = MidasLoader::loadModel('NewUserInvitation');
509+
$newuserinvite = $newuserModel->createInvitation($email, $group, $this->userSession->Dao);
510+
511+
$url = $this->getServerURL().$this->view->webroot;
512+
$subject = 'Midas invitation';
513+
$text = $this->userSession->Dao->getFullName().
514+
' has invited you to join the <b>'.$community->getName().
515+
'</b> community on Midas.<br/><br/>'.
516+
'<a href="'.$url.'/user/acceptinvite?email='.$email.
517+
'&authKey='.$newuserinvite->getAuthKey().
518+
'">Click here</a> to complete your user registration '.
519+
'if you wish to join.<br/><br/>Generated by Midas';
520+
$headers = "From: Midas\nReply-To: no-reply\nX-Mailer: PHP/".phpversion().
521+
"\nMIME-Version: 1.0\nContent-type: text/html; charset = UTF-8";
522+
if($this->isTestingEnv() || mail($email, $subject, $text, $headers))
445523
{
446-
echo JsonComponent::encode(array(false, $userDao->getFullName().
447-
$this->t(' is already invited to this community.')));
524+
$this->getLogger()->info('User '.$this->userSession->Dao->getEmail().' emailed '.$email.' to join '
525+
.$community->getName().' ('.$group->getName().' group)');
448526
}
449527
else
450528
{
451-
if(!$this->isTestingEnv())
452-
{
453-
$url = $this->getServerURL().$this->view->webroot;
454-
$email = $userDao->getEmail();
455-
$subject = 'Midas community invitation';
456-
$text = 'You have been invited to join the <b>'.$communityDao->getName().
457-
'</b> community at '.$url.'.<br/><br/>'.
458-
'<a href="'.$url.'/community/'.$communityDao->getKey().'">'.
459-
'Click here</a> to see the community, and click the "Join the community" button '.
460-
'if you wish to join.<br/><br/>Generated by Midas';
461-
$headers = "From: Midas\nReply-To: no-reply\nX-Mailer: PHP/".phpversion()."\nMIME-Version: 1.0\nContent-type: text/html; charset = UTF-8";
462-
if(!mail($email, $subject, $text, $headers))
463-
{
464-
$this->getLogger()->warn('Failed sending community invitation email to '.$email.' for community '.$communityDao->getName());
465-
}
466-
}
467-
echo JsonComponent::encode(array(true, $userDao->getFullName().' '.$this->t('has been invited')));
529+
$this->getLogger()->warn('Failed sending register/community invitation email to '.$email.' for community '.$community->getName());
468530
}
531+
532+
echo JsonComponent::encode(array(true, 'Invitation sent to '.$email));
533+
}
534+
}
535+
else
536+
{
537+
throw new Zend_Exception('Must pass userId or email parameter');
538+
}
539+
}
540+
541+
/**
542+
* Helper method to create an invitaton record to the group and send an email to the existing user
543+
*/
544+
private function _sendUserInvitation($userDao, $groupDao)
545+
{
546+
if($this->Group->userInGroup($userDao, $groupDao))
547+
{
548+
echo JsonComponent::encode(array(false, $userDao->getFullName().' is already a member of this community'));
549+
return;
550+
}
551+
$community = $groupDao->getCommunity();
552+
$invitation = $this->CommunityInvitation->createInvitation($groupDao, $this->userSession->Dao, $userDao);
553+
// Check if there is already a pending invitation
554+
if(!$invitation)
555+
{
556+
echo JsonComponent::encode(array(false, $userDao->getFullName().$this->t(' is already invited to this community.')));
557+
}
558+
else
559+
{
560+
$url = $this->getServerURL().$this->view->webroot;
561+
$subject = 'Midas community invitation';
562+
$text = 'You have been invited to join the <b>'.$community->getName().
563+
'</b> community at '.$url.'.<br/><br/>'.
564+
'<a href="'.$url.'/community/'.$community->getKey().'">'.
565+
'Click here</a> to see the community, and click the "Join the community" button '.
566+
'if you wish to join.<br/><br/>Generated by Midas';
567+
$headers = "From: Midas\nReply-To: no-reply\nX-Mailer: PHP/".phpversion()."\nMIME-Version: 1.0\nContent-type: text/html; charset = UTF-8";
568+
if($this->isTestingEnv() || mail($userDao->getEmail(), $subject, $text, $headers))
569+
{
570+
$this->getLogger()->info('User '.$this->userSession->Dao->getEmail().' invited user '.$userDao->getEmail().' to '
571+
.$community->getName().' ('.$groupDao->getName().' group)');
572+
}
573+
else
574+
{
575+
$this->getLogger()->warn('Failed sending community invitation email to '.$email.' for community '.$community->getName());
469576
}
577+
echo JsonComponent::encode(array(true, $userDao->getFullName().' '.$this->t('has been invited')));
470578
}
471-
}//end invite
579+
}
472580

473581
/** Create a community (ajax)*/
474582
function createAction()
@@ -669,4 +777,47 @@ public function removeuserfromgroupAction()
669777
$this->Group->removeUser($group, $user);
670778
echo JsonComponent::encode(array(true, 'Removed user '.$user->getFullName().' from group '.$group->getName()));
671779
}
780+
781+
/**
782+
* Show dialog for selecting a group from the community.
783+
* Requires moderator or admin permission on the community
784+
* @param communityId The id of the community
785+
*/
786+
public function selectgroupAction()
787+
{
788+
$this->disableLayout();
789+
790+
$communityId = $this->_getParam('communityId');
791+
792+
if(!isset($communityId))
793+
{
794+
throw new Zend_Exception('Community id parameter required');
795+
}
796+
$community = $this->Community->load($communityId);
797+
if(!$community)
798+
{
799+
throw new Zend_Exception('Community '.$communityId.' does not exist', 404);
800+
}
801+
if(!$this->Community->policyCheck($community, $this->userSession->Dao, MIDAS_POLICY_WRITE))
802+
{
803+
throw new Zend_Exception('Moderator or admin privileges required', 403);
804+
}
805+
$isAdmin = $this->Community->policyCheck($community, $this->userSession->Dao, MIDAS_POLICY_ADMIN);
806+
807+
$this->view->groups = array($community->getMemberGroup(), $community->getModeratorGroup());
808+
if($isAdmin)
809+
{
810+
$this->view->groups[] = $community->getAdminGroup();
811+
}
812+
$allGroups = $community->getGroups();
813+
foreach($allGroups as $group)
814+
{
815+
if($group->getKey() != $community->getMembergroupId() &&
816+
$group->getKey() != $community->getModeratorgroupId() &&
817+
$group->getKey() != $community->getAdmingroupId())
818+
{
819+
$this->view->groups[] = $group;
820+
}
821+
}
822+
}
672823
}//end class

core/controllers/SearchController.php

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,8 @@ public function liveAction()
9393
$userSearch = $this->getRequest()->getParam('userSearch');
9494
$itemSearch = $this->getRequest()->getParam('itemSearch');
9595

96+
$OtherOptions = array();
97+
9698
if(isset($shareSearch))
9799
{
98100
$ItemsDao = array();
@@ -128,6 +130,18 @@ public function liveAction()
128130
$GroupsDao = array();
129131
// Search for the users
130132
$UsersDao = $this->User->getUsersFromSearch($search, $this->userSession->Dao);
133+
$allowEmail = $this->_getParam('allowEmail');
134+
if(isset($allowEmail))
135+
{
136+
$validator = new Zend_Validate_EmailAddress();
137+
if($validator->isValid($search))
138+
{
139+
$OtherOptions[] = array('label' => 'Send to '.$search,
140+
'key' => 'email',
141+
'value' => $search,
142+
'category' => 'Email invitation');
143+
}
144+
}
131145
}
132146
elseif(isset($itemSearch))
133147
{
@@ -314,6 +328,11 @@ public function liveAction()
314328
$n++;
315329
$results[] = $result;
316330
}
331+
// Other live search options
332+
foreach($OtherOptions as $option)
333+
{
334+
$results[] = $option;
335+
}
317336

318337
echo JsonComponent::encode($results);
319338
}

core/controllers/UserController.php

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1059,6 +1059,17 @@ public function deletedialogAction()
10591059
$this->view->user = $user;
10601060
}
10611061

1062+
/**
1063+
* Accept a new user invitation (clicked the link sent in the email)
1064+
* @param email The email address of the registering user
1065+
* @param authKey The auth key sent in the email
1066+
*/
1067+
public function acceptinviteAction()
1068+
{
1069+
$email = $this->_getParam('email');
1070+
$authKey = $this->_getParam('authKey');
1071+
}
1072+
10621073
/** Delete a user */
10631074
public function deleteAction()
10641075
{

core/database/upgrade/3.2.10.php

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
<?php
2+
3+
/**
4+
* Upgrade 3.2.10 adds newuserinvite table
5+
*/
6+
class Upgrade_3_2_10 extends MIDASUpgrade
7+
{
8+
9+
public function preUpgrade()
10+
{
11+
}
12+
13+
public function mysql()
14+
{
15+
$this->db->query("CREATE TABLE `newuserinvitation` (
16+
`newuserinvitation_id` bigint(20) NOT NULL AUTO_INCREMENT,
17+
`auth_key` varchar(255) NOT NULL,
18+
`email` varchar(255) NOT NULL,
19+
`inviter_id` bigint(20) NOT NULL,
20+
`community_id` bigint(20) NOT NULL,
21+
`group_id` bigint(20) NOT NULL,
22+
`date_creation` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
23+
PRIMARY KEY (`newuserinvitation_id`)
24+
)");
25+
$this->db->query("ALTER TABLE `communityinvitation` ADD COLUMN `group_id` bigint(20) NULL DEFAULT NULL");
26+
}
27+
28+
public function pgsql()
29+
{
30+
$this->db->query("CREATE TABLE newuserinvitation (
31+
newuserinvitation_id serial PRIMARY KEY,
32+
auth_key character varying(255) NOT NULL,
33+
email character varying(255) NOT NULL,
34+
inviter_id bigint NOT NULL,
35+
community_id bigint NOT NULL,
36+
group_id bigint NOT NULL,
37+
date_creation timestamp without time zone NOT NULL DEFAULT now()
38+
)");
39+
$this->db->query("ALTER TABLE communityinvitation ADD COLUMN group_id bigint NULL DEFAULT NULL");
40+
}
41+
42+
public function postUpgrade()
43+
{
44+
}
45+
46+
}
47+
?>

0 commit comments

Comments
 (0)