Permalink
Browse files

Merge from upstream - https://github.com/ajshort/silverstripe-memberp…

  • Loading branch information...
alexhayes committed Sep 7, 2011
2 parents 9e07cbd + 789e8ec commit 83134dffedf15a29ed1eab7aa80ba7223d0ef29a
View
@@ -7,4 +7,8 @@
throw new Exception('The Member Profiles module requires the Orderable module.');
}
+Director::addRules(20, array(
+ 'member-approval' => 'MemberApprovalController'
+));
+
Object::add_extension('Member', 'MemberProfileExtension');
View
@@ -26,14 +26,14 @@ class MemberProfilePage extends Page implements PermissionProvider {
'AllowProfileViewing' => 'Boolean',
'AllowProfileEditing' => 'Boolean',
'AllowAdding' => 'Boolean',
- 'RegistrationRedirect' => 'Boolean',
-
- 'EmailType' => 'Enum("Validation, Confirmation, None", "None")',
- 'EmailFrom' => 'Varchar(255)',
- 'EmailSubject' => 'Varchar(255)',
- 'EmailTemplate' => 'Text',
- 'ConfirmationTitle' => 'Varchar(255)',
- 'ConfirmationContent' => 'HTMLText'
+ 'RegistrationRedirect' => 'Boolean',
+ 'RequireApproval' => 'Boolean',
+ 'EmailType' => 'Enum("Validation, Confirmation, None", "None")',
+ 'EmailFrom' => 'Varchar(255)',
+ 'EmailSubject' => 'Varchar(255)',
+ 'EmailTemplate' => 'Text',
+ 'ConfirmationTitle' => 'Varchar(255)',
+ 'ConfirmationContent' => 'HTMLText'
);
public static $has_one = array(
@@ -46,8 +46,9 @@ class MemberProfilePage extends Page implements PermissionProvider {
);
public static $many_many = array (
- 'Groups' => 'Group',
- 'SelectableGroups' => 'Group',
+ 'Groups' => 'Group',
+ 'SelectableGroups' => 'Group',
+ 'ApprovalGroups' => 'Group',
'RegistrationGroups' => 'Group'
);
@@ -127,6 +128,10 @@ public function providePermissions() {
public function getCMSFields() {
$fields = parent::getCMSFields();
+ Requirements::javascript(THIRDPARTY_DIR . '/jquery/jquery.js');
+ Requirements::javascript(THIRDPARTY_DIR . '/jquery-livequery/jquery.livequery.js');
+ Requirements::javascript('memberprofiles/javascript/MemberProfilePageCms.js');
+
// Setup tabs
$fields->addFieldToTab('Root', $profile = new TabSet('Profile'), 'Content');
$fields->addFieldToTab('Root', $email = new Tab('Email'), 'Behaviour');
@@ -275,10 +280,18 @@ public function getCMSFields() {
_t('MemberProfiles.ALLOWADD',
'Allow members with member creation permissions to add members via this page')),
'ClassName');
- $fields->addFieldToTab('Root.Behaviour',
- new HeaderField('PageSettingsHeader',
- _t('MemberProfiles.PAGEBEHAVIOUR', 'Page Behaviour')),
- 'ClassName');
+
+ $requireApproval = new CheckboxField('RequireApproval', _t(
+ 'MemberProfiles.REQUIREREGAPPROVAL', 'Require registration approval by an administrator?'
+ ));
+ $fields->addFieldToTab('Root.Behaviour', $requireApproval, 'ClassName');
+
+ $approvalGroups = _t('MemberProfiles.NOTIFYTHESEGROUPS', 'Notify these groups to approve new registrations');
+ $approvalGroups = new TreeMultiselectField('ApprovalGroups', $approvalGroups, 'Group');
+ $fields->addFieldToTab('Root.Behaviour', $approvalGroups, 'ClassName');
+
+ $pageSettings = new HeaderField('PageSettingsHeader', _t('MemberProfiles.PAGEBEHAVIOUR', 'Page Behaviour'));
+ $fields->addFieldToTab('Root.Behaviour', $pageSettings, 'ClassName');
return $fields;
}
@@ -473,7 +486,7 @@ public function RegisterForm() {
*/
public function register($data, Form $form) {
if($member = $this->addMember($form)) {
- if($this->EmailType != 'Validation' && !$this->AllowAdding) {
+ if(!$this->RequireApproval && $this->EmailType != 'Validation' && !$this->AllowAdding) {
$member->logIn();
}
@@ -718,7 +731,10 @@ protected function addMember($form) {
$groupIds = $this->getSettableGroupIdsFrom($form);
$form->saveInto($member);
- $member->ProfilePageID = $this->ID;
+
+ $member->ProfilePageID = $this->ID;
+ $member->NeedsValidation = ($this->EmailType == 'Validation');
+ $member->NeedsApproval = $this->RequireApproval;
try {
$member->write();
@@ -730,17 +746,42 @@ protected function addMember($form) {
// set after member is created otherwise the member object does not exist
$member->Groups()->setByIDList($groupIds);
- if($this->EmailType == 'Validation') {
- $email = new MemberConfirmationEmail($this, $member);
- $email->send();
+ // If we require admin approval, send an email to the admin and delay
+ // sending an email to the member.
+ if ($this->RequireApproval) {
+ $groups = $this->ApprovalGroups();
+ $emails = array();
- $member->NeedsValidation = true;
- $member->write();
- } elseif($this->EmailType == 'Confirmation') {
+ if ($groups) foreach ($groups as $group) {
+ foreach ($group->Members() as $_member) {
+ if ($member->Email) $emails[] = $_member->Email;
+ }
+ }
+
+ if ($emails) {
+ $email = new Email();
+ $config = SiteConfig::current_site_config();
+ $approve = Controller::join_links(
+ Director::baseURL(), 'member-approval', $member->ID, '?token=' . $member->ValidationKey
+ );
+
+ $email->setSubject("Registration Approval Requested for $config->Title");
+ $email->setBcc(implode(',', array_unique($emails)));
+ $email->setTemplate('MemberRequiresApprovalEmail');
+ $email->populateTemplate(array(
+ 'SiteConfig' => $config,
+ 'Member' => $member,
+ 'ApproveLink' => Director::absoluteURL($approve)
+ ));
+
+ $email->send();
+ }
+ } elseif($this->EmailType != 'None') {
$email = new MemberConfirmationEmail($this, $member);
$email->send();
}
+ $this->extend('onAddMember', $member);
return $member;
}
@@ -753,7 +794,7 @@ protected function getProfileFields($context) {
$fields = new FieldSet();
// depending on the context, load fields from the current member
- if(Member::currentUserID() && $context != 'Add') {
+ if(Member::currentUser() && $context != 'Add') {
$memberFields = Member::currentUser()->getMemberFormFields();
} else {
$memberFields = singleton('Member')->getMemberFormFields();
@@ -0,0 +1,64 @@
+<?php
+/**
+ * @package silverstripe-memberprofiles
+ */
+class MemberApprovalController extends Page_Controller {
+
+ public static $url_handlers = array(
+ '$ID' => 'index'
+ );
+
+ public static $allowed_actions = array(
+ 'index'
+ );
+
+ public function index($request) {
+ $id = $request->param('ID');
+ $token = $request->getVar('token');
+
+ if (!$id || !ctype_digit($id)) {
+ $this->httpError(404, 'A member ID was not specified.');
+ }
+
+ $member = DataObject::get_by_id('Member', $id);
+
+ if (!$member) {
+ $this->httpError(404, 'The specified member could not be found.');
+ }
+
+ if (!$member->canEdit()) {
+ return Security::permissionFailure();
+ }
+
+ if ($token != $member->ValidationKey) {
+ $this->httpError(400, 'An invalid token was specified.');
+ }
+
+ if (!$member->NeedsApproval) {
+ $title = _t('MemberProfiles.ALREADYAPPROVED', 'Already Approved');
+ $content = _t('MemberProfiles.ALREADYAPPROVEDNOTE', 'This member has already been approved');
+
+ return $this->render(array(
+ 'Title' => $title,
+ 'Content' => "<p>$content</p>"
+ ));
+ }
+
+ $member->NeedsApproval = false;
+ $member->write();
+
+ $title = _t('MemberProfiles.MEMBERAPPROVED', 'Member Approved');
+ $content = _t('MemberProfiles.MEMBERAPPROVED', 'The member "%s" has been approved and can now log in.');
+ $content = sprintf($content, Convert::raw2xml("$member->Name <$member->Email>"));
+
+ return $this->render(array(
+ 'Title' => $title,
+ 'Content' => $content
+ ));
+ }
+
+ public function Link($action = null) {
+ return Controller::join_links(Director::baseURL(), 'member-approval', $action);
+ }
+
+}
@@ -12,7 +12,8 @@ public function extraStatics() {
'db' => array (
'ValidationKey' => 'Varchar(40)',
'NeedsValidation' => 'Boolean',
- 'PublicFieldsRaw' => 'Text'
+ 'NeedsApproval' => 'Boolean',
+ 'PublicFieldsRaw' => 'Text'
),
'has_one' => array (
'ProfilePage' => 'MemberProfilePage'
@@ -29,6 +30,11 @@ public function setPublicFields($fields) {
}
public function canLogIn($result) {
+ if($this->owner->NeedsApproval) $result->error(_t (
+ 'MemberProfiles.NEEDSAPPROVALTOLOGIN',
+ 'An administrator must confirm your account before you can log in.'
+ ));
+
if($this->owner->NeedsValidation) $result->error(_t (
'MemberProfiles.NEEDSVALIDATIONTOLOGIN',
'You must validate your account before you can log in.'
@@ -51,11 +57,28 @@ public function populateDefaults() {
$this->owner->ValidationKey = sha1(mt_rand() . mt_rand());
}
+ public function onAfterWrite() {
+ $changed = $this->owner->getChangedFields();
+
+ if (array_key_exists('NeedsApproval', $changed)) {
+ $before = $changed['NeedsApproval']['before'];
+ $after = $changed['NeedsApproval']['after'];
+ $page = $this->owner->ProfilePage();
+ $email = $page->EmailType;
+
+ if ($before == true && $after == false && $email != 'None') {
+ $email = new MemberConfirmationEmail($page, $this->owner);
+ $email->send();
+ }
+ }
+ }
+
public function updateMemberFormFields($fields) {
$fields->removeByName('ValidationKey');
$fields->removeByName('NeedsValidation');
+ $fields->removeByName('NeedsApproval');
$fields->removeByName('ProfilePageID');
- $fields->removeByName('PublicFields');
+ $fields->removeByName('PublicFieldsRaw');
// For now we just pass an empty array as the list of selectable groups -
// it's up to anything that uses this to populate it appropriately
@@ -64,12 +87,31 @@ public function updateMemberFormFields($fields) {
}
public function updateCMSFields($fields) {
+ $mainFields = $fields->fieldByName("Root")->fieldByName("Main")->Children;
+
$fields->removeByName('ValidationKey');
$fields->removeByName('NeedsValidation');
+ $fields->removeByName('NeedsApproval');
$fields->removeByName('ProfilePageID');
- $fields->removeByName('PublicFields');
+ $fields->removeByName('PublicFieldsRaw');
+
+ if ($this->owner->NeedsApproval) {
+ $note = _t(
+ 'MemberProfiles.NOLOGINUNTILAPPROVED',
+ 'This user has not yet been approved. They cannot log in until their account is approved.'
+ );
+
+ $mainFields->merge(array(
+ new HeaderField('ApprovalHheader', _t('MemberProfiles.REGAPPROVAL', 'Registration Approval')),
+ new LiteralField('ApprovalNote', "<p>$note</p>"),
+ new DropdownField('NeedsApproval', '', array(
+ true => _t('MemberProfiles.DONOTCHANGE', 'Do not change'),
+ false => _t('MemberProfiles.APPROVETHISMEMBER', 'Approve this member')
+ ))
+ ));
+ }
- if($this->owner->NeedsValidation) $fields->addFieldsToTab('Root.Main', array (
+ if($this->owner->NeedsValidation) $mainFields->merge(array(
new HeaderField(_t('MemberProfiles.EMAILCONFIRMATION', 'Email Confirmation')),
new LiteralField('ConfirmationNote', '<p>' . _t (
'MemberProfiles.NOLOGINTILLCONFIRMED',
@@ -0,0 +1,7 @@
+;(function($) {
+ $("#Form_EditForm_RequireApproval").livequery(function() {
+ $(this)
+ .change(function() { $("#ApprovalGroups").toggle(this.checked); })
+ .trigger("change");
+ });
+})(jQuery);
@@ -0,0 +1,25 @@
+<p>
+ A new member has registered for $SiteConfig.Title, and requires approval
+ before they can log in:
+</p>
+
+<% control Member %>
+ <dl>
+ <dt>Name:</dt>
+ <dd>$Name</dd>
+ <dt>Email:</dt>
+ <dd>$Email</dd>
+ <dt>Registered:</dt>
+ <dd>$Created.Date</dd>
+ </dl>
+<% end_control %>
+
+<p>
+ Please visit the link below to confirm this member. Once approved they will
+ be sent a confirmation email if configured. If you do not approve this member
+ then they will not be able to log in.
+</p>
+
+<p>
+ <a href="$ApproveLink">$ApproveLink</a>
+</p>

0 comments on commit 83134df

Please sign in to comment.