webgui_newsletter/lib/WebGUI/AssetAspect/Subscriber.pm
2010-05-21 18:09:08 +02:00

464 lines
14 KiB
Perl

package WebGUI::AssetAspect::Subscriber;
use strict;
use warnings;
use Class::C3;
use Carp;
use WebGUI::Asset::Template;
use WebGUI::Macro;
use Tie::IxHash;
#----------------------------------------------------------------------------
sub definition {
my $class = shift;
my $session = shift;
my $definition = shift;
# my $i18n = WebGUI::International->new( $session,'AssetAspect_Subscriber' );
tie my %properties, 'Tie::IxHash', (
subscriptionGroupId => {
fieldType => 'subscriptionGroup',
label => 'Subscription group',
tab => 'subscription',
noFormPost => 1,
},
subscriptionEnabled => {
fieldType => 'yesNo',
defaultValue => 1,
label => 'Enable subscription',
tab => 'subscription',
},
alwaysConfirmSubscription => {
fieldType => 'yesNo',
defaultValue => 0,
label => 'Always require subscription confirmation',
tab => 'subscription',
},
allowAnonymousSubscription => {
fieldType => 'yesNo',
defaultValue => 1,
label => 'Allow anonymous subscription',
tab => 'subscription',
},
confirmationRequiredTemplateId => {
fieldType => 'template',
defaultValue => 'd1tQuv-OlPwgz6PnLcq-hA',
label => 'Confirmation required template',
namespace => 'Subscriber/ConfirmationRequired',
tab => 'subscription',
},
confirmationEmailSubject => {
fieldType => 'text',
defaultVale => 'Confirm your subscription mutation',
label => 'Confirmation email subject',
tab => 'subscription',
},
confirmationEmailTemplateId => {
fieldType => 'template',
defaultValue => '4aLemgMrTFhG3eqg57jCpQ',
label => 'Confirmation email template',
namespace => 'Subscriber/ConfirmationEmail',
tab => 'subscription',
},
noMutationEmailSubject => {
fieldType => 'text',
defaultVale => '(Un)subscribe result',
label => 'No mutation email subject',
tab => 'subscription',
},
noMutationEmailTemplateId => {
fieldType => 'template',
defaultValue => 'Q8t7dUqMk05D2m7Jbgg4BQ',
label => 'No mutation email template',
namespace => 'Subscriber/NoMutationEmail',
tab => 'subscription',
},
);
push( @{ $definition }, {
autoGenerateForms => 1,
tableName => 'assetAspectSubscriber',
className => 'WebGUI::AssetAspect::Subscriber',
properties => \%properties
} );
return $class->next::method( $session, $definition );
}
#----------------------------------------------------------------------------
sub duplicate {
my $self = shift;
my $properties = shift;
my $newSelf = $self->next::method( $properties );
$newSelf->update({ subscriptionGroupId => '' });
$newSelf->createSubscriptionGroup;
return $newSelf;
}
#----------------------------------------------------------------------------
sub getEditTabs {
my $self = shift;
return ( $self->next::method, [ 'subscription', 'Subscription', 9 ] );
}
#----------------------------------------------------------------------------
sub canSubscribe {
my $self = shift;
return !$self->session->user->isVisitor && !$self->isSubscribed;
}
#----------------------------------------------------------------------------
sub canUnsubscribe {
my $self = shift;
return !$self->session->user->isVisitor && $self->isSubscribed;
}
#----------------------------------------------------------------------------
sub createSubscriptionGroup {
my $self = shift;
if ( my $groupId = $self->get('subscriptionGroupId') ) {
return WebGUI::Group->new( $self->session, $groupId );
}
else {
my $group = WebGUI::Group->new($self->session, "new");
$group->name( "Subscription " . $self->getTitle );
$group->description( "Subscription Group for " . $self->getTitle . "(" . $self->getId . ")" );
$group->isEditable( 0 );
$group->showInForms( 0 );
$group->deleteGroups( [ "3" ] ); # admins don't want to be auto subscribed to this thing
$self->update({
subscriptionGroupId => $group->getId
});
return $group;
}
}
#----------------------------------------------------------------------------
sub isSubscribed {
my $self = shift;
my $user = shift || $self->session->user;
my $db = $self->session->db;
return $user->isInGroup( $self->getSubscriptionGroup->getId );
}
#----------------------------------------------------------------------------
sub getSubscriptionForm {
my $self = shift;
my $session = $self->session;
my $i18n = WebGUI::International->new( $session, 'Asset_NewsletterCollection' );
my $formHeader =
WebGUI::Form::formHeader( $session, { action => $self->getUrl } )
. WebGUI::Form::hidden( $session, { name => 'func', value => 'processSubscription' } )
;
my $subscribeButton =
sprintf '<button type="submit" name="action" value="subscribe">%s</button>', $i18n->get('subscribe');
my $unsubscribeButton =
sprintf '<button type="submit" name="action" value="unsubscribe">%s</button>', $i18n->get('unsubscribe');
my $emailBox = WebGUI::Form::email( $session, { name => 'email', value => '' } );
my $formFooter = WebGUI::Form::formFooter( $session );
my $output = '';
if ( $session->user->isRegistered ) {
$output .= $subscribeButton if $self->canSubscribe;
$output .= $unsubscribeButton if $self->canUnsubscribe;
return unless $output;
return $formHeader . $output . $formFooter;
}
#### TODO: anonymousAllowed
else {
return $formHeader . $emailBox . $subscribeButton . $unsubscribeButton . $formFooter;
}
return;
}
#----------------------------------------------------------------------------
sub getSubscriptionGroup {
my $self = shift;
my $groupId = $self->get( "subscriptionGroupId" );
my $group = $groupId
? WebGUI::Group->new( $self->session, $groupId )
: $self->createSubscriptionGroup
;
return $group;
}
#----------------------------------------------------------------------------
sub getEmailVars {
my $self = shift;
my $user = shift;
my $var = {};
my $userProperties = $user->get;
while ( my ($key, $value) = each %{ $userProperties } ) {
$var->{ "user_$key" } = $value;
}
$var->{ user_isRegular } = !WebGUI::User::SpecialState->isAdHocUser( $user );
my $assetProperties = $self->get;
while ( my ($key, $value) = each %{ $assetProperties } ) {
$var->{ "asset_$key" } = $value;
}
return $var;
}
#----------------------------------------------------------------------------
sub sendSubscriptionConfirmation {
my $self = shift;
my $user = shift;
my $code = shift;
my $action = shift || 'subscribe';
my $session = $self->session;
my $var = $self->getEmailVars( $user );
my $url = $session->url->getSiteURL . $self->getUrl( "func=confirmSubscription;code=$code" );
$var->{ confirmUrl } = $url;
$var->{ code } = $code;
$var->{ actionIsSubscribe } = $action eq 'subscribe';
my $mail = WebGUI::Mail::Send->create( $self->session, {
to => $user->get('email'),
subject => $self->get('confirmationEmailSubject'),
} );
my $templateId = $self->get('confirmationEmailTemplateId');
my $template = WebGUI::Asset::Template->new( $session, $templateId );
if ( $template ) {
$mail->addHtml( $template->process( $var ) );
}
else {
$session->log->error( "Cannot instanciate confirmation email template with id [$templateId]" );
$mail->addText( "Click here to confirm your (un)subscription: $url" );
}
$mail->send;
return;
}
#----------------------------------------------------------------------------
sub sendNoMutationEmail {
my $self = shift;
my $user = shift;
my $action = shift || 'subscribe';
my $session = $self->session;
my $var = $self->getEmailVars( $user );
$var->{ actionIsSubscribe } = $action eq 'subscribe';
my $mail = WebGUI::Mail::Send->create( $self->session, {
to => $user->get('email'),
subject => $self->get('noMutationEmailSubject'),
} );
my $templateId = $self->get('noMutationEmailTemplateId');
my $template = WebGUI::Asset::Template->new( $session, $templateId );
if ( $template ) {
$mail->addHtml( $template->process( $var ) );
}
else {
$session->log->error( "Cannot instanciate no mutation email template with id [$templateId]" );
if ( $action eq 'subscribe' ) {
$mail->addText( "This email address is already subscribed to " . $self->get('title') );
}
}
$mail->send;
return;
}
sub logConfirmation {
my $self = shift;
my $code = shift || return;
my $session = $self->session;
my $db = $session->db;
$db->write(
' update assetAspectSubscriber_log set '
.' confirmationIp=?, confirmationDate=?, confirmed=? where code=? and assetId=?',
[
$session->env->getIp,
time(),
1,
$code,
$self->getId,
]
);
return;
};
sub logRequest {
my $self = shift;
my $type = shift || croak 'No type passed to logrequest';
my $user = shift || croak 'No user passed to logRequest';
my $code = shift;
my $session = $self->session;
my $db = $session->db;
$db->write(
' insert into assetAspectSubscriber_log set '
.' assetId=?, requestIp=?, requestDate=?, code=?, confirmed=?, anonymous=?, type=?, userId=?, email=?',
[
$self->getId,
$session->env->getIp,
time(),
$code,
0,
$self->session->user->isVisitor,
$type,
$user->getId,
$user->get('email'),
]
);
return;
};
#----------------------------------------------------------------------------
sub subscribe {
my $self = shift;
my $user = shift || $self->session->user;
my $requireConfirm = shift // $self->get('alwaysConfirmSubscription');
my $session = $self->session;
if ( $requireConfirm ) {
if ( $user->isInGroup( $self->getSubscriptionGroup->getId ) ) {
$self->sendNoMutationEmail( $user, 'subscribe' );
$self->logRequest( 'already_subscribed', $user );
}
else {
my $code = $self->session->id->generate;
$self->logRequest( 'subscribe', $user, $code );
$self->sendSubscriptionConfirmation( $user, $code );
}
}
else {
$self->getSubscriptionGroup->addUsers( [ $user->getId ] );
$self->logRequest( 'subscribe', $user );
}
return;
}
#----------------------------------------------------------------------------
sub unsubscribe {
my $self = shift;
my $user = shift || $self->session->user;
$self->getSubscriptionGroup->deleteUsers( [ $user->getId ] );
$self->logRequest( 'unsubscribe', $user );
return;
}
#----------------------------------------------------------------------------
sub www_confirmSubscription {
my $self = shift;
my ($form, $db) = $self->session->quick( 'form', 'db' );
my $code = $form->get('code');
return unless $code;
my $userId = $db->quickScalar( 'select userId from assetAspectSubscriber_log where confirmed=? and code=?', [
0,
$code,
] );
if ( $userId ) {
$self->getSubscriptionGroup->addUsers( [ $userId ] );
$self->logConfirmation( $code );
}
else {
return $self->processStyle( 'Verkeerde code' );
}
return $self->processStyle( 'U bent aangemeld voor deze nieuwsbrief' );
}
#----------------------------------------------------------------------------
sub www_processSubscription {
my $self = shift;
my $session = $self->session;
my $form = $session->form;
my $action = $form->get( 'action' );
return unless $action eq 'subscribe' || $action eq 'unsubscribe';
if ( $session->user->isRegistered ) {
if ( $action eq 'subscribe' && $self->canSubscribe ) {
$self->subscribe;
}
if ( $action eq 'unsubscribe' && $self->canUnsubscribe ) {
$self->unsubscribe;
}
return unless $self->get('alwaysConfirmSubscription');
}
elsif ( $self->get('allowAnonymousSubscription') ) {
my $email = $form->email( 'email' );
return 'Error: no email address passed' unless $email;
my $emailUser = WebGUI::User::SpecialState->newByEmail( $session, $email );
if ( $action eq 'unsubscribe' && defined $emailUser ) {
$self->unsubscribe( $emailUser );
}
if ( $action eq 'subscribe' ) {
if ( !defined $emailUser ) {
$emailUser = WebGUI::User::SpecialState->create( $session );
$emailUser->update( { email => $email } );
}
$emailUser->addSpecialState( 'Subscriber', $self->getId );
$self->subscribe( $emailUser, 1 );
}
}
else {
return $self->processStyle( 'Anonymous subscription is not allowed. Please log in to (un)subscribe' );
}
return $self->processStyle( $self->processTemplate( {}, $self->get('confirmationRequiredTemplateId') ) );
}
#----------------------------------------------------------------------------
sub www_subscribe {
my $self = shift;
if ( $self->canSubscribe ) {
$self->subscribe;
}
return $self->www_view;
}
#----------------------------------------------------------------------------
sub www_unsubscribe {
my $self = shift;
if ( $self->canUnsubscribe ) {
$self->unsubscribe;
}
return $self->www_view;
}
1;