added Subscribable AssetAspect to Wiki
This commit is contained in:
parent
b838102df5
commit
0697673846
15 changed files with 936 additions and 56 deletions
|
|
@ -25,6 +25,7 @@
|
|||
- fixed #10925: Wrong message in i18n
|
||||
- relabel Help in the Admin Console to Template Help
|
||||
- fixed #10928: EMS Print Ticket -- Time not processed for timezone
|
||||
- added Subscribable AssetAspect to Wiki
|
||||
|
||||
7.7.19
|
||||
- fixed #10838: Forwarded forum post email to new CS adds reply to original thread
|
||||
|
|
|
|||
BIN
docs/upgrades/packages-7.8.0/default-wiki-front-page.wgpkg
Normal file
BIN
docs/upgrades/packages-7.8.0/default-wiki-front-page.wgpkg
Normal file
Binary file not shown.
BIN
docs/upgrades/packages-7.8.0/default-wiki-page.wgpkg
Normal file
BIN
docs/upgrades/packages-7.8.0/default-wiki-page.wgpkg
Normal file
Binary file not shown.
Binary file not shown.
|
|
@ -33,6 +33,7 @@ my $session = start(); # this line required
|
|||
# upgrade functions go here
|
||||
reorganizeAdSpaceProperties($session);
|
||||
fixTemplateSettingsFromShunt($session);
|
||||
addSubscribableAspect( $session );
|
||||
|
||||
finish($session); # this line required
|
||||
|
||||
|
|
@ -46,6 +47,26 @@ finish($session); # this line required
|
|||
# print "DONE!\n" unless $quiet;
|
||||
#}
|
||||
|
||||
#----------------------------------------------------------------------------
|
||||
# Add tables for the subscribable aspect
|
||||
sub addSubscribableAspect {
|
||||
my $session = shift;
|
||||
print "\tAdding Subscribable aspect..." unless $quiet;
|
||||
|
||||
$session->db->write( <<'ESQL' );
|
||||
CREATE TABLE assetAspect_Subscribable (
|
||||
assetId CHAR(22) BINARY NOT NULL,
|
||||
revisionDate BIGINT NOT NULL,
|
||||
subscriptionGroupId CHAR(22) BINARY,
|
||||
subscriptionTemplateId CHAR(22) BINARY,
|
||||
skipNotification INT,
|
||||
PRIMARY KEY ( assetId, revisionDate )
|
||||
)
|
||||
ESQL
|
||||
|
||||
print "DONE!\n" unless $quiet;
|
||||
}
|
||||
|
||||
#----------------------------------------------------------------------------
|
||||
# Describe what our function does
|
||||
sub reorganizeAdSpaceProperties {
|
||||
|
|
|
|||
|
|
@ -12,7 +12,11 @@ package WebGUI::Asset::WikiPage;
|
|||
|
||||
use strict;
|
||||
use Class::C3;
|
||||
use base qw(WebGUI::AssetAspect::Comments WebGUI::Asset);
|
||||
use base qw(
|
||||
WebGUI::AssetAspect::Subscribable
|
||||
WebGUI::AssetAspect::Comments
|
||||
WebGUI::Asset
|
||||
);
|
||||
use Tie::IxHash;
|
||||
use WebGUI::International;
|
||||
use WebGUI::Utility;
|
||||
|
|
@ -236,6 +240,73 @@ sub getEditForm {
|
|||
|
||||
#-------------------------------------------------------------------
|
||||
|
||||
=head2 getSubscriptionTemplate ( )
|
||||
|
||||
=cut
|
||||
|
||||
sub getSubscriptionTemplate {
|
||||
my ( $self ) = @_;
|
||||
return $self->getParent->getSubscriptionTemplate;
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------
|
||||
|
||||
=head2 getTemplateVars ( )
|
||||
|
||||
Get the common template vars for this asset
|
||||
|
||||
=cut
|
||||
|
||||
sub getTemplateVars {
|
||||
my ( $self ) = @_;
|
||||
my $i18n = WebGUI::International->new($self->session, "Asset_WikiPage");
|
||||
my $wiki = $self->getWiki;
|
||||
my $owner = WebGUI::User->new( $self->session, $self->get('ownerUserId') );
|
||||
my $keywords = WebGUI::Keyword->new($self->session)->getKeywordsForAsset({
|
||||
asset => $self,
|
||||
asArrayRef => 1,
|
||||
});
|
||||
my @keywordsLoop = ();
|
||||
foreach my $word (@{$keywords}) {
|
||||
push @keywordsLoop, {
|
||||
keyword => $word,
|
||||
url => $wiki->getUrl("func=byKeyword;keyword=".$word),
|
||||
};
|
||||
}
|
||||
my $var = {
|
||||
%{ $self->get },
|
||||
url => $self->getUrl,
|
||||
keywordsLoop => \@keywordsLoop,
|
||||
viewLabel => $i18n->get("viewLabel"),
|
||||
editLabel => $i18n->get("editLabel"),
|
||||
historyLabel => $i18n->get("historyLabel"),
|
||||
wikiHomeLabel => $i18n->get("wikiHomeLabel", "Asset_WikiMaster"),
|
||||
searchLabel => $i18n->get("searchLabel", "Asset_WikiMaster"),
|
||||
searchUrl => $wiki->getUrl("func=search"),
|
||||
recentChangesUrl => $wiki->getUrl("func=recentChanges"),
|
||||
recentChangesLabel => $i18n->get("recentChangesLabel", "Asset_WikiMaster"),
|
||||
mostPopularUrl => $wiki->getUrl("func=mostPopular"),
|
||||
mostPopularLabel => $i18n->get("mostPopularLabel", "Asset_WikiMaster"),
|
||||
wikiHomeUrl => $wiki->getUrl,
|
||||
historyUrl => $self->getUrl("func=getHistory"),
|
||||
editContent => $self->getEditForm,
|
||||
allowsAttachments => $wiki->get("allowAttachments"),
|
||||
comments => $self->getFormattedComments(),
|
||||
canEdit => $self->canEdit,
|
||||
content => $wiki->autolinkHtml(
|
||||
$self->scrubContent,
|
||||
{skipTitles => [$self->get('title')]},
|
||||
),
|
||||
isSubscribed => $self->isSubscribed,
|
||||
subscribeUrl => $self->getSubscribeUrl,
|
||||
unsubscribeUrl => $self->getUnsubscribeUrl,
|
||||
owner => $owner->get('alias'),
|
||||
};
|
||||
return $var;
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------
|
||||
|
||||
=head2 getWiki
|
||||
|
||||
Returns an object referring to the wiki that contains this page. If it is not a WikiMaster,
|
||||
|
|
@ -438,43 +509,7 @@ Renders this asset.
|
|||
|
||||
sub view {
|
||||
my $self = shift;
|
||||
my $i18n = WebGUI::International->new($self->session, "Asset_WikiPage");
|
||||
my $keywords = WebGUI::Keyword->new($self->session)->getKeywordsForAsset({
|
||||
asset=>$self,
|
||||
asArrayRef=>1,
|
||||
});
|
||||
my $wiki = $self->getWiki;
|
||||
my @keywordsLoop = ();
|
||||
foreach my $word (@{$keywords}) {
|
||||
push(@keywordsLoop, {
|
||||
keyword=>$word,
|
||||
url=>$wiki->getUrl("func=byKeyword;keyword=".$word),
|
||||
});
|
||||
}
|
||||
my $var = {
|
||||
keywordsLoop => \@keywordsLoop,
|
||||
viewLabel => $i18n->get("viewLabel"),
|
||||
editLabel => $i18n->get("editLabel"),
|
||||
historyLabel => $i18n->get("historyLabel"),
|
||||
wikiHomeLabel => $i18n->get("wikiHomeLabel", "Asset_WikiMaster"),
|
||||
searchLabel => $i18n->get("searchLabel", "Asset_WikiMaster"),
|
||||
searchUrl => $self->getParent->getUrl("func=search"),
|
||||
recentChangesUrl => $self->getParent->getUrl("func=recentChanges"),
|
||||
recentChangesLabel => $i18n->get("recentChangesLabel", "Asset_WikiMaster"),
|
||||
mostPopularUrl => $self->getParent->getUrl("func=mostPopular"),
|
||||
mostPopularLabel => $i18n->get("mostPopularLabel", "Asset_WikiMaster"),
|
||||
wikiHomeUrl => $self->getParent->getUrl,
|
||||
historyUrl => $self->getUrl("func=getHistory"),
|
||||
editContent => $self->getEditForm,
|
||||
allowsAttachments => $self->getWiki->get("allowAttachments"),
|
||||
comments => $self->getFormattedComments(),
|
||||
canEdit => $self->canEdit,
|
||||
content => $self->getWiki->autolinkHtml(
|
||||
$self->scrubContent,
|
||||
{skipTitles => [$self->get('title')]},
|
||||
),
|
||||
};
|
||||
return $self->processTemplate($var, $self->getWiki->get("pageTemplateId"));
|
||||
return $self->processTemplate($self->getTemplateVars, $self->getWiki->get("pageTemplateId"));
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------
|
||||
|
|
|
|||
|
|
@ -11,7 +11,11 @@ package WebGUI::Asset::Wobject::WikiMaster;
|
|||
#-------------------------------------------------------------------
|
||||
|
||||
use Class::C3;
|
||||
use base qw(WebGUI::AssetAspect::RssFeed WebGUI::Asset::Wobject);
|
||||
use base qw(
|
||||
WebGUI::AssetAspect::Subscribable
|
||||
WebGUI::AssetAspect::RssFeed
|
||||
WebGUI::Asset::Wobject
|
||||
);
|
||||
use strict;
|
||||
use Tie::IxHash;
|
||||
use WebGUI::International;
|
||||
|
|
@ -444,6 +448,36 @@ sub getRssFeedItems {
|
|||
return $var;
|
||||
}
|
||||
|
||||
#----------------------------------------------------------------------------
|
||||
|
||||
=head2 getTemplateVars ( )
|
||||
|
||||
Get the common template variables for all views of the wiki.
|
||||
|
||||
=cut
|
||||
|
||||
sub getTemplateVars {
|
||||
my ( $self ) = @_;
|
||||
my $i18n = WebGUI::International->new($self->session, "Asset_WikiMaster");
|
||||
my $var = { %{$self->get},
|
||||
url => $self->getUrl,
|
||||
searchLabel => $i18n->get("searchLabel"),
|
||||
mostPopularUrl => $self->getUrl("func=mostPopular"),
|
||||
mostPopularLabel => $i18n->get("mostPopularLabel"),
|
||||
addPageLabel => $i18n->get("addPageLabel"),
|
||||
addPageUrl => $self->getUrl("func=add;class=WebGUI::Asset::WikiPage"),
|
||||
recentChangesUrl => $self->getUrl("func=recentChanges"),
|
||||
recentChangesLabel => $i18n->get("recentChangesLabel"),
|
||||
restoreLabel => $i18n->get("restoreLabel"),
|
||||
canAdminister => $self->canAdminister,
|
||||
isSubscribed => $self->isSubscribed,
|
||||
subscribeUrl => $self->getSubscribeUrl,
|
||||
unsubscribeUrl => $self->getUnsubscribeUrl,
|
||||
};
|
||||
|
||||
return $var;
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------
|
||||
|
||||
=head2 prepareView
|
||||
|
|
@ -492,6 +526,19 @@ sub processPropertiesFromFormPost {
|
|||
|
||||
#-------------------------------------------------------------------
|
||||
|
||||
=head2 shouldSkipNotification ( )
|
||||
|
||||
WikiMasters do not send notification
|
||||
|
||||
=cut
|
||||
|
||||
sub shouldSkipNotification {
|
||||
my ( $self ) = @_;
|
||||
return 1;
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------
|
||||
|
||||
=head2 view
|
||||
|
||||
Render the front page of the wiki.
|
||||
|
|
@ -500,23 +547,13 @@ Render the front page of the wiki.
|
|||
|
||||
sub view {
|
||||
my $self = shift;
|
||||
my $i18n = WebGUI::International->new($self->session, "Asset_WikiMaster");
|
||||
my $var = {
|
||||
description => $self->autolinkHtml($self->get('description')),
|
||||
searchLabel=>$i18n->get("searchLabel"),
|
||||
mostPopularUrl=>$self->getUrl("func=mostPopular"),
|
||||
mostPopularLabel=>$i18n->get("mostPopularLabel"),
|
||||
addPageLabel=>$i18n->get("addPageLabel"),
|
||||
addPageUrl=>$self->getUrl("func=add;class=WebGUI::Asset::WikiPage"),
|
||||
recentChangesUrl=>$self->getUrl("func=recentChanges"),
|
||||
recentChangesLabel=>$i18n->get("recentChangesLabel"),
|
||||
restoreLabel => $i18n->get("restoreLabel"),
|
||||
canAdminister => $self->canAdminister,
|
||||
keywordCloud => WebGUI::Keyword->new($self->session)->generateCloud({
|
||||
startAsset=>$self,
|
||||
displayFunc=>"byKeyword",
|
||||
}),
|
||||
};
|
||||
my $var = $self->getTemplateVars;
|
||||
$var->{ description } = $self->autolinkHtml( $var->{ description } );
|
||||
$var->{ keywordCloud }
|
||||
= WebGUI::Keyword->new($self->session)->generateCloud({
|
||||
startAsset=>$self,
|
||||
displayFunc=>"byKeyword",
|
||||
});
|
||||
my $template = $self->{_frontPageTemplate};
|
||||
$self->appendSearchBoxVars($var);
|
||||
$self->appendRecentChanges($var, $self->get('recentChangesCountFront'));
|
||||
|
|
|
|||
514
lib/WebGUI/AssetAspect/Subscribable.pm
Normal file
514
lib/WebGUI/AssetAspect/Subscribable.pm
Normal file
|
|
@ -0,0 +1,514 @@
|
|||
package WebGUI::AssetAspect::Subscribable;
|
||||
|
||||
use strict;
|
||||
use Class::C3;
|
||||
|
||||
=head1 NAME
|
||||
|
||||
WebGUI::AssetAspect::Subscribable - Let users subscribe to your asset
|
||||
|
||||
=head1 SYNOPSIS
|
||||
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
|
||||
=head1 METHODS
|
||||
|
||||
#----------------------------------------------------------------------------
|
||||
|
||||
=head2 definition ( session [, definition ] )
|
||||
|
||||
=cut
|
||||
|
||||
sub definition {
|
||||
my $class = shift;
|
||||
my $session = shift;
|
||||
my $definition = shift;
|
||||
my $i18n = __PACKAGE__->i18n($session);
|
||||
|
||||
tie my %properties, 'Tie::IxHash', (
|
||||
subscriptionGroupId => {
|
||||
tab => "security",
|
||||
fieldType => "subscriptionGroup",
|
||||
label => $i18n->echo("Subscription Group"),
|
||||
hoverHelp => $i18n->echo("The users who are subscribed to recieve e-mail alerts for this asset"),
|
||||
defaultValue => undef,
|
||||
noFormPost => 1,
|
||||
},
|
||||
subscriptionTemplateId => {
|
||||
tab => "display",
|
||||
fieldType => "template",
|
||||
namespace => $class->getSubscriptionTemplateNamespace,
|
||||
label => $i18n->echo("Subscription Template"),
|
||||
hoverHelp => $i18n->echo("The template to use to send out e-mail notifications"),
|
||||
},
|
||||
skipNotification => {
|
||||
autoGenerate => 0,
|
||||
noFormPost => 1,
|
||||
fieldType => 'yesNo',
|
||||
},
|
||||
);
|
||||
|
||||
push @{ $definition }, {
|
||||
autoGenerateForms => 1,
|
||||
tableName => "assetAspect_Subscribable",
|
||||
properties => \%properties,
|
||||
};
|
||||
|
||||
return $class->maybe::next::method( $session, $definition );
|
||||
}
|
||||
|
||||
#----------------------------------------------------------------------------
|
||||
|
||||
=head2 addRevision ( properties [, revisionDate, options ] )
|
||||
|
||||
Override addRevision to set skipNotification to 0 for each new revision.
|
||||
|
||||
=cut
|
||||
|
||||
sub addRevision {
|
||||
my $self = shift;
|
||||
my $properties = shift;
|
||||
|
||||
$properties->{ skipNotification } = 0;
|
||||
|
||||
return $self->maybe::next::method( $properties, @_ );
|
||||
}
|
||||
|
||||
#----------------------------------------------------------------------------
|
||||
|
||||
=head2 canSubscribe ( [userId ] )
|
||||
|
||||
Returns true if the user is allowed to subscribe to this asset. C<userId> is
|
||||
a userId to check, defaults to the current user.
|
||||
|
||||
By default, Visitors are not allowed to subscribe. Anyone else who canView,
|
||||
canSubscribe.
|
||||
|
||||
=cut
|
||||
|
||||
sub canSubscribe {
|
||||
my $self = shift;
|
||||
my $userId = shift || $self->session->user->userId;
|
||||
|
||||
return 0 if $userId eq "1";
|
||||
return $self->canView( $userId );
|
||||
}
|
||||
|
||||
#----------------------------------------------------------------------------
|
||||
|
||||
=head2 commit ( )
|
||||
|
||||
By default, send the notification out when the asset is committed. Override
|
||||
this if you don't want this asset to send out notifications (but you still
|
||||
want to be able to subscribe to children)
|
||||
|
||||
=cut
|
||||
|
||||
sub commit {
|
||||
my ( $self, @args ) = @_;
|
||||
$self->maybe::next::method( @args );
|
||||
if ( !$self->shouldSkipNotification ) {
|
||||
$self->notifySubscribers;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
#----------------------------------------------------------------------------
|
||||
|
||||
=head2 createSubscriptionGroup ( )
|
||||
|
||||
Create a group to hold subscribers to this asset, if there is not one already.
|
||||
|
||||
=cut
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
#----------------------------------------------------------------------------
|
||||
|
||||
=head2 DOES ( role )
|
||||
|
||||
Returns true if the asset does the specified role. This mixin does the
|
||||
"Subscribable" role.
|
||||
|
||||
=cut
|
||||
|
||||
sub DOES {
|
||||
my $self = shift;
|
||||
my $role = shift;
|
||||
|
||||
return 1 if ( lc $role eq "subscribable" );
|
||||
return $self->maybe::next::method( $role );
|
||||
}
|
||||
|
||||
#----------------------------------------------------------------------------
|
||||
|
||||
=head2 getSubscriptionContent ( )
|
||||
|
||||
Get the content to send to subscribers. By default, will process the template
|
||||
from C<getSubscriptionTemplate> with the variables from C<getTemplateVars> or
|
||||
C<get>.
|
||||
|
||||
=cut
|
||||
|
||||
sub getSubscriptionContent {
|
||||
my $self = shift;
|
||||
my $template = $self->getSubscriptionTemplate;
|
||||
my $var;
|
||||
if ( $self->can("getTemplateVars") ) {
|
||||
# Rely on getTemplateVars sub judgement
|
||||
$var = $self->getTemplateVars;
|
||||
}
|
||||
else {
|
||||
# Try to make sense of the asset properties
|
||||
$var = {
|
||||
%{ $self->get },
|
||||
url => $self->session->url->getSiteURL . $self->getUrl,
|
||||
}
|
||||
}
|
||||
|
||||
return $template->process( $var );
|
||||
}
|
||||
|
||||
#----------------------------------------------------------------------------
|
||||
|
||||
=head2 getSubscriptionGroup ( )
|
||||
|
||||
Gets the WebGUI::Group for the subscribers group.
|
||||
|
||||
=cut
|
||||
|
||||
sub getSubscriptionGroup {
|
||||
my $self = shift;
|
||||
my $groupId = $self->get( "subscriptionGroupId" );
|
||||
my $group = $groupId ? WebGUI::Group->new( $self->session, $groupId ) : $self->createSubscriptionGroup;
|
||||
return $group;
|
||||
}
|
||||
|
||||
#----------------------------------------------------------------------------
|
||||
|
||||
=head2 getSubscriptionTemplate ( )
|
||||
|
||||
Get a WebGUI::Asset::Template object for the subscription template.
|
||||
|
||||
=cut
|
||||
|
||||
sub getSubscriptionTemplate {
|
||||
my $self = shift;
|
||||
my $templateId = $self->get( "subscriptionTemplateId" );
|
||||
my $template = WebGUI::Asset::Template->new( $self->session, $templateId ); # This should throw if we don't
|
||||
return $template;
|
||||
}
|
||||
|
||||
#----------------------------------------------------------------------------
|
||||
|
||||
=head2 getSubscriptionTemplateNamespace ( )
|
||||
|
||||
Get the namespace for the subscription template.
|
||||
|
||||
=cut
|
||||
|
||||
sub getSubscriptionTemplateNamespace {
|
||||
return "AssetAspect/Subscribable";
|
||||
}
|
||||
|
||||
#----------------------------------------------------------------------------
|
||||
|
||||
=head2 getSubscribeUrl ( )
|
||||
|
||||
Get the URL to subscribe to this asset.
|
||||
|
||||
=cut
|
||||
|
||||
sub getSubscribeUrl {
|
||||
my $self = shift;
|
||||
return $self->getUrl( 'func=subscribe' );
|
||||
}
|
||||
|
||||
#----------------------------------------------------------------------------
|
||||
|
||||
=head2 getUnsubscribeUrl ( )
|
||||
|
||||
Get the URL to unsubscribe from this asset.
|
||||
|
||||
=cut
|
||||
|
||||
sub getUnsubscribeUrl {
|
||||
my $self = shift;
|
||||
return $self->getUrl( 'func=unsubscribe' );
|
||||
}
|
||||
|
||||
#----------------------------------------------------------------------------
|
||||
|
||||
=head2 i18n ( )
|
||||
|
||||
Get the i18n for RSSCapable
|
||||
|
||||
=cut
|
||||
|
||||
sub i18n {
|
||||
my $class = shift;
|
||||
my $session = shift;
|
||||
|
||||
return WebGUI::International->new( $session );
|
||||
}
|
||||
|
||||
#----------------------------------------------------------------------------
|
||||
|
||||
=head2 isSubscribed ( [userId] )
|
||||
|
||||
Returns true if the user is subscribed to the asset. C<userId> is a userId to
|
||||
check, defaults to the current user.
|
||||
|
||||
=cut
|
||||
|
||||
sub isSubscribed {
|
||||
my $self = shift;
|
||||
my $userId = shift;
|
||||
my $user = $userId
|
||||
? WebGUI::User->new( $self->session, $userId )
|
||||
: $self->session->user
|
||||
;
|
||||
my $group = $self->getSubscriptionGroup;
|
||||
# TODO: Make WebGUI::Group throw error if group not found
|
||||
if ( !$group ) {
|
||||
return 0;
|
||||
}
|
||||
else {
|
||||
return $user->isInGroup( $group->getId );
|
||||
}
|
||||
}
|
||||
|
||||
#----------------------------------------------------------------------------
|
||||
|
||||
=head2 _makeMessageId ( string )
|
||||
|
||||
Make the message ID following proper RFC2822. C<string> is a unique identifier
|
||||
for the message.
|
||||
|
||||
=cut
|
||||
|
||||
sub _makeMessageId {
|
||||
my $self = shift;
|
||||
my $string = shift;
|
||||
my $domain = $self->session->config->get( "sitename" )->[ 0 ];
|
||||
return "wg-" . $string . "@" . $domain;
|
||||
}
|
||||
|
||||
#----------------------------------------------------------------------------
|
||||
|
||||
=head2 notifySubscribers ( [options] )
|
||||
|
||||
Notify all the subscribers of this asset. C<options> is a hash reference of
|
||||
options with the following keys:
|
||||
|
||||
content -> Content to send to the subscribers. Defaults to getSubscriptionContent
|
||||
subject -> E-mail subject. Defaults to the asset title.
|
||||
from -> E-mail address this message is from. Defaults to the e-mail address of
|
||||
the owner of this asset, or the Company E-Mail from settings
|
||||
replyTo -> E-mail address to reply to. Defaults to the listAddress, the Mail
|
||||
Return Path from settings, or the Company E-Mail from settings
|
||||
inReplyTo -> Asset ID of the asset this subscription message is replying to
|
||||
listAddress -> The address of the mailing list this is being sent from, if necessary
|
||||
|
||||
=cut
|
||||
|
||||
sub notifySubscribers {
|
||||
my $self = shift;
|
||||
my $opt = shift;
|
||||
my $session = $self->session;
|
||||
my $setting = $self->session->setting;
|
||||
my $companyEmail = $setting->get( "companyEmail" );
|
||||
my $mailReturnPath = $setting->get( "mailReturnPath" );
|
||||
|
||||
$opt->{ subject } ||= $self->getTitle;
|
||||
$opt->{ content } ||= $self->getSubscriptionContent;
|
||||
WebGUI::Macro::process( $self->session, \$opt->{content} );
|
||||
|
||||
if ( !$opt->{ from } ) {
|
||||
my $owner = WebGUI::User->new( $self->session, $self->get( "ownerUserId" ) );
|
||||
$opt->{ from } = $owner->profileField( "email" ) || $opt->{ listAddress } || $companyEmail;
|
||||
}
|
||||
|
||||
if ( !$opt->{ replyTo } ) {
|
||||
$opt->{ replyTo } = $opt->{listAddress} || $mailReturnPath || $companyEmail;
|
||||
}
|
||||
|
||||
$opt->{ returnPath } = $mailReturnPath || $opt->{listAddress} || $companyEmail || $opt->{ from };
|
||||
|
||||
my $messageId = $self->_makeMessageId( $self->getId );
|
||||
|
||||
### Get all the people we need to send to
|
||||
# Any parent asset that does subscribable
|
||||
# First asset in this list is the topmost parent, and is the list ID
|
||||
my @assets = ( $self );
|
||||
my $parentAsset = $self->getParent;
|
||||
while ( $parentAsset ) {
|
||||
last if !$parentAsset->DOES( "subscribable" );
|
||||
unshift @assets, $parentAsset;
|
||||
$parentAsset = $parentAsset->getParent;
|
||||
}
|
||||
|
||||
### Prepare the actual sender address (the address of the process sending,
|
||||
# not the address of the user who initiated the sending)
|
||||
my $sender = $opt->{listAddress} || $companyEmail || $opt->{from};
|
||||
my $siteurl = $session->url->getSiteURL;
|
||||
# XXX This doesnt seem right...
|
||||
my $listId = $sender;
|
||||
$listId =~ s/\@/\./;
|
||||
|
||||
for my $asset ( @assets ) {
|
||||
my $group = $asset->getSubscriptionGroup;
|
||||
my $mail
|
||||
= WebGUI::Mail::Send->create( $self->session, {
|
||||
from => '<' . $opt->{ from } . '>',
|
||||
returnPath => '<' . $opt->{ returnPath } . '>',
|
||||
replyTo => '<' . $opt->{ replyTo } . '>',
|
||||
toGroup => $group->getId,
|
||||
subject => $opt->{ subject },
|
||||
messageId => '<' . $messageId . '>',
|
||||
} );
|
||||
|
||||
# Add threading headers
|
||||
if ( $opt->{ inReplyTo } ) {
|
||||
$mail->addHeaderField( "In-Reply-To", '<' . $opt->{inReplyTo} . '>' );
|
||||
$mail->addHeaderField( "References", '<' . $opt->{inReplyTo} . '>' );
|
||||
}
|
||||
|
||||
$mail->addHeaderField("List-ID", $assets[0]->getTitle." <".$listId.">");
|
||||
$mail->addHeaderField("List-Help", "<mailto:".$companyEmail.">, <".$setting->get("companyURL").">");
|
||||
$mail->addHeaderField("List-Owner", "<mailto:".$companyEmail.">, <".$setting->get("companyURL")."> (".$setting->get("companyName").")");
|
||||
$mail->addHeaderField("Sender", "<".$sender.">");
|
||||
$mail->addHeaderField("List-Unsubscribe", "<".$siteurl.$asset->getUnsubscribeUrl.">");
|
||||
$mail->addHeaderField("X-Unsubscribe-Web", "<".$siteurl.$asset->getUnsubscribeUrl.">");
|
||||
$mail->addHeaderField("List-Subscribe", "<".$siteurl.$asset->getSubscribeUrl.">");
|
||||
$mail->addHeaderField("X-Subscribe-Web", "<".$siteurl.$asset->getSubscribeUrl.">");
|
||||
$mail->addHeaderField("List-Archive", "<".$siteurl.$assets[0]->getUrl.">");
|
||||
$mail->addHeaderField("X-Archives", "<".$siteurl.$assets[0]->getUrl.">");
|
||||
if ( $opt->{listAddress} ) {
|
||||
$mail->addHeaderField("List-Post", "<mailto:".$opt->{listAddress}.">");
|
||||
}
|
||||
else {
|
||||
$mail->addHeaderField("List-Post", "No");
|
||||
}
|
||||
$mail->addHtml($opt->{content});
|
||||
$mail->addFooter;
|
||||
$mail->queue;
|
||||
}
|
||||
}
|
||||
|
||||
#----------------------------------------------------------------------------
|
||||
|
||||
=head2 setSkipNotification ( )
|
||||
|
||||
Set a flag so that this asset does not send out notifications for this
|
||||
revision.
|
||||
|
||||
=cut
|
||||
|
||||
sub setSkipNotification {
|
||||
my $self = shift;
|
||||
my $value = shift;
|
||||
$value = defined $value ? $value : 1;
|
||||
|
||||
$self->update( {
|
||||
skipNotification => $value,
|
||||
} );
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
#----------------------------------------------------------------------------
|
||||
|
||||
=head2 shouldSkipNotification ( )
|
||||
|
||||
Returns true if the asset should skip notifications.
|
||||
|
||||
=cut
|
||||
|
||||
sub shouldSkipNotification {
|
||||
my $self = shift;
|
||||
return $self->get( "skipNotification" ) ? 1 : 0;
|
||||
}
|
||||
|
||||
#----------------------------------------------------------------------------
|
||||
|
||||
=head2 subscribe ( [userId] )
|
||||
|
||||
Subscribe a user to this asset. C<userId> is a userId to subscribe, defaults
|
||||
to the current user.
|
||||
|
||||
=cut
|
||||
|
||||
sub subscribe {
|
||||
my $self = shift;
|
||||
my $userId = shift || $self->session->user->userId;
|
||||
$self->getSubscriptionGroup->addUsers( [$userId] );
|
||||
return;
|
||||
}
|
||||
|
||||
#----------------------------------------------------------------------------
|
||||
|
||||
=head2 unsubscribe ( [userId] )
|
||||
|
||||
Unsubscribe a user from this asset. C<userId> is a userId to unsubscribe,
|
||||
defaults to the current user.
|
||||
|
||||
=cut
|
||||
|
||||
sub unsubscribe {
|
||||
my $self = shift;
|
||||
my $userId = shift || $self->session->user->userId;
|
||||
$self->getSubscriptionGroup->deleteUsers( [$userId] );
|
||||
return;
|
||||
}
|
||||
|
||||
#----------------------------------------------------------------------------
|
||||
|
||||
=head2 www_subscribe ( )
|
||||
|
||||
Subscribe the current user to this asset.
|
||||
|
||||
=cut
|
||||
|
||||
sub www_subscribe {
|
||||
my $self = shift;
|
||||
$self->subscribe if $self->canSubscribe;
|
||||
return $self->www_view;
|
||||
}
|
||||
|
||||
#----------------------------------------------------------------------------
|
||||
|
||||
=head2 www_unsubscribe ( )
|
||||
|
||||
Unsubscribe the current user from this asset.
|
||||
|
||||
=cut
|
||||
|
||||
sub www_unsubscribe {
|
||||
my $self = shift;
|
||||
$self->unsubscribe;
|
||||
return $self->www_view;
|
||||
}
|
||||
|
||||
1; # You can't handle the truth
|
||||
|
|
@ -146,6 +146,18 @@ our $HELP = {
|
|||
{ 'name' => 'useContentFilter', },
|
||||
{ 'name' => 'filterCode', },
|
||||
{ 'name' => 'maxImageSize', },
|
||||
{
|
||||
name => 'isSubscribed',
|
||||
description => 'help isSubscribed',
|
||||
},
|
||||
{
|
||||
name => 'subscribeUrl',
|
||||
description => 'help subscribeUrl',
|
||||
},
|
||||
{
|
||||
name => 'unsubscribeUrl',
|
||||
description => 'help unsubscribeUrl',
|
||||
},
|
||||
],
|
||||
fields => [],
|
||||
related => [],
|
||||
|
|
|
|||
|
|
@ -76,6 +76,22 @@ our $HELP = {
|
|||
},
|
||||
{ 'name' => 'editContent', },
|
||||
{ 'name' => 'content', },
|
||||
{
|
||||
name => 'isSubscribed',
|
||||
description => 'help isSubscribed',
|
||||
},
|
||||
{
|
||||
name => 'subscribeUrl',
|
||||
description => 'help subscribeUrl',
|
||||
},
|
||||
{
|
||||
name => 'unsubscribeUrl',
|
||||
description => 'help unsubscribeUrl',
|
||||
},
|
||||
{
|
||||
name => 'owner',
|
||||
description => 'help owner',
|
||||
},
|
||||
],
|
||||
related => [],
|
||||
},
|
||||
|
|
@ -110,6 +126,17 @@ our $HELP = {
|
|||
related => [],
|
||||
},
|
||||
|
||||
|
||||
'subscription template' => {
|
||||
title => 'help subscription title',
|
||||
body => 'help subscription body',
|
||||
isa => [
|
||||
{
|
||||
tag => 'view template',
|
||||
namespace => 'Asset_WikiPage',
|
||||
},
|
||||
],
|
||||
},
|
||||
};
|
||||
|
||||
1;
|
||||
|
|
|
|||
14
lib/WebGUI/i18n/English/AssetAspect_Subscribable.pm
Normal file
14
lib/WebGUI/i18n/English/AssetAspect_Subscribable.pm
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
package WebGUI::i18n::English::AssetAspect_Subscribable;
|
||||
|
||||
use strict;
|
||||
|
||||
our $I18N = {
|
||||
"new post" => {
|
||||
message => 'has posted to one of your subscriptions',
|
||||
lastUpdated => 0,
|
||||
context => 'Title of the e-mail that is sent for subscriptions',
|
||||
},
|
||||
};
|
||||
|
||||
1;
|
||||
#vim:ft=perl
|
||||
|
|
@ -494,6 +494,35 @@ listing of pages that are related to a specific keyword?| },
|
|||
lastUpdated => 1166848379,
|
||||
},
|
||||
|
||||
'help isSubscribed' => {
|
||||
message => q{This variable is true if the user is subscribed to the entire wiki},
|
||||
lastUpdated => 0,
|
||||
context => q{Help for template variable},
|
||||
},
|
||||
|
||||
'help subscribeUrl' => {
|
||||
message => q{The URL to subscribe to the entire wiki},
|
||||
lastUpdated => 0,
|
||||
context => q{Help for template variable},
|
||||
},
|
||||
|
||||
'help unsubscribeUrl' => {
|
||||
message => q{The URL to unsubscribe from the entire wiki},
|
||||
lastUpdated => 0,
|
||||
context => q{Help for template variable},
|
||||
},
|
||||
|
||||
'subscribe' => {
|
||||
message => q{Subscribe},
|
||||
lastUpdated => 0,
|
||||
context => q{Label for link to subscribe to e-mail notifications},
|
||||
},
|
||||
|
||||
'unsubscribe' => {
|
||||
message => q{Unsubscribe},
|
||||
lastUpdated => 0,
|
||||
context => q{Label for link to unsubscribe from e-mail notifications},
|
||||
},
|
||||
};
|
||||
|
||||
1;
|
||||
|
|
|
|||
|
|
@ -268,6 +268,41 @@ our $I18N =
|
|||
lastUpdated => 1169141075,
|
||||
},
|
||||
|
||||
'help isSubscribed' => {
|
||||
message => q{This variable is true if the user is subscribed to this wiki page},
|
||||
lastUpdated => 0,
|
||||
context => q{Help for template variable},
|
||||
},
|
||||
|
||||
'help subscribeUrl' => {
|
||||
message => q{The URL to subscribe to this wiki page},
|
||||
lastUpdated => 0,
|
||||
context => q{Help for template variable},
|
||||
},
|
||||
|
||||
'help unsubscribeUrl' => {
|
||||
message => q{The URL to unsubscribe from this wiki page},
|
||||
lastUpdated => 0,
|
||||
context => q{Help for template variable},
|
||||
},
|
||||
|
||||
'help owner' => {
|
||||
message => q{The username of the owner of the page},
|
||||
lastUpdated => 0,
|
||||
context => q{Help for template variable},
|
||||
},
|
||||
|
||||
'help subscription title' => {
|
||||
message => q{Wiki Page Subscription E-mail},
|
||||
lastUpdated => 0,
|
||||
context => 'Title for help page',
|
||||
},
|
||||
|
||||
'help subscription body' => {
|
||||
message => q{The template to send via e-mail to the people subscribed to the wiki},
|
||||
lastUpdated => 0,
|
||||
context => 'Body text for help page',
|
||||
},
|
||||
};
|
||||
|
||||
1;
|
||||
|
|
|
|||
57
t/Asset/WikiPage/subscribable.t
Normal file
57
t/Asset/WikiPage/subscribable.t
Normal file
|
|
@ -0,0 +1,57 @@
|
|||
# vim:syntax=perl
|
||||
#-------------------------------------------------------------------
|
||||
# WebGUI is Copyright 2001-2009 Plain Black Corporation.
|
||||
#-------------------------------------------------------------------
|
||||
# Please read the legal notices (docs/legal.txt) and the license
|
||||
# (docs/license.txt) that came with this distribution before using
|
||||
# this software.
|
||||
#------------------------------------------------------------------
|
||||
# http://www.plainblack.com info@plainblack.com
|
||||
#------------------------------------------------------------------
|
||||
|
||||
# Test the subscribable features of the Wiki
|
||||
#
|
||||
#
|
||||
|
||||
use FindBin;
|
||||
use strict;
|
||||
use lib "$FindBin::Bin/../../lib";
|
||||
use Test::More;
|
||||
use WebGUI::Test; # Must use this before any other WebGUI modules
|
||||
use WebGUI::Session;
|
||||
|
||||
#----------------------------------------------------------------------------
|
||||
# Init
|
||||
my $session = WebGUI::Test->session;
|
||||
my $import = WebGUI::Asset->getImportNode( $session );
|
||||
my $wiki
|
||||
= $import->addChild( {
|
||||
className => 'WebGUI::Asset::Wobject::WikiMaster',
|
||||
subscriptionTemplateId => 'limMkk80fMB3fqNZVf162w',
|
||||
groupIdView => '7', # Everyone
|
||||
} );
|
||||
|
||||
my $page
|
||||
= $wiki->addChild( {
|
||||
className => 'WebGUI::Asset::WikiPage',
|
||||
}, undef, undef, { skipAutoCommitWorkflows => 1 } );
|
||||
|
||||
WebGUI::Test->tagsToRollback( WebGUI::VersionTag->getWorking( $session ) );
|
||||
|
||||
#----------------------------------------------------------------------------
|
||||
# Tests
|
||||
|
||||
plan tests => 4; # Increment this number for each test you create
|
||||
|
||||
#----------------------------------------------------------------------------
|
||||
# Test subscribable methods
|
||||
ok( $page->DOES('subscribable'), 'WikiMaster is subscribable' );
|
||||
|
||||
ok( my $template = $page->getSubscriptionTemplate, 'getSubscriptionTemplate returns something' );
|
||||
isa_ok( $template, 'WebGUI::Asset::Template', 'getSubscriptionTemplate' );
|
||||
is( $template->getId, 'limMkk80fMB3fqNZVf162w', 'getSubscriptionTemplate gets wikimaster template' );
|
||||
|
||||
#----------------------------------------------------------------------------
|
||||
# Cleanup
|
||||
|
||||
#vim:ft=perl
|
||||
98
t/Asset/Wobject/WikiMaster/subscribable.t
Normal file
98
t/Asset/Wobject/WikiMaster/subscribable.t
Normal file
|
|
@ -0,0 +1,98 @@
|
|||
# vim:syntax=perl
|
||||
#-------------------------------------------------------------------
|
||||
# WebGUI is Copyright 2001-2009 Plain Black Corporation.
|
||||
#-------------------------------------------------------------------
|
||||
# Please read the legal notices (docs/legal.txt) and the license
|
||||
# (docs/license.txt) that came with this distribution before using
|
||||
# this software.
|
||||
#------------------------------------------------------------------
|
||||
# http://www.plainblack.com info@plainblack.com
|
||||
#------------------------------------------------------------------
|
||||
|
||||
# Test the subscribable features of the Wiki
|
||||
#
|
||||
#
|
||||
|
||||
use FindBin;
|
||||
use strict;
|
||||
use lib "$FindBin::Bin/../../../lib";
|
||||
use Test::More;
|
||||
use WebGUI::Test; # Must use this before any other WebGUI modules
|
||||
use WebGUI::Session;
|
||||
|
||||
#----------------------------------------------------------------------------
|
||||
# Init
|
||||
my $session = WebGUI::Test->session;
|
||||
my $import = WebGUI::Asset->getImportNode( $session );
|
||||
my $wiki
|
||||
= $import->addChild( {
|
||||
className => 'WebGUI::Asset::Wobject::WikiMaster',
|
||||
subscriptionTemplateId => 'limMkk80fMB3fqNZVf162w',
|
||||
groupIdView => '7', # Everyone
|
||||
} );
|
||||
|
||||
WebGUI::Test->tagsToRollback( WebGUI::VersionTag->getWorking( $session ) );
|
||||
|
||||
#----------------------------------------------------------------------------
|
||||
# Tests
|
||||
|
||||
plan tests => 17; # Increment this number for each test you create
|
||||
|
||||
#----------------------------------------------------------------------------
|
||||
# Test subscribable methods
|
||||
ok( $wiki->DOES('subscribable'), 'WikiMaster is subscribable' );
|
||||
ok( $wiki->shouldSkipNotification, "WikiMaster never notifies" );
|
||||
|
||||
ok( my $template = $wiki->getSubscriptionTemplate, 'getSubscriptionTemplate returns something' );
|
||||
isa_ok( $template, 'WebGUI::Asset::Template', 'getSubscriptionTemplate' );
|
||||
|
||||
is( $wiki->getSubscriptionTemplateNamespace, 'AssetAspect/Subscribable', 'getSubscriptionNamespace' );
|
||||
|
||||
ok( my $subgroup = $wiki->getSubscriptionGroup, 'getSubscriptionGroup returns something' );
|
||||
isa_ok( $subgroup, 'WebGUI::Group', 'getSubscriptionGroup' );
|
||||
|
||||
is( $wiki->getSubscribeUrl, $wiki->getUrl('func=subscribe'), 'getSubscribeUrl' );
|
||||
is( $wiki->getUnsubscribeUrl, $wiki->getUrl('func=unsubscribe'), 'getUnsubscribeUrl' );
|
||||
|
||||
|
||||
#----------------------------------------------------------------------------
|
||||
# canSubscribe permissions
|
||||
$session->user({ userId => '1' });
|
||||
ok( !$wiki->canSubscribe, 'Visitor cannot subscribe' );
|
||||
ok( $wiki->canSubscribe( '3' ), 'Admin can subscribe' );
|
||||
|
||||
# subscribe
|
||||
$wiki->subscribe('3');
|
||||
ok(
|
||||
WebGUI::User->new( $session, '3' )->isInGroup( $wiki->getSubscriptionGroup->getId ),
|
||||
'subscribe'
|
||||
);
|
||||
|
||||
# isSubscribed
|
||||
ok( $wiki->isSubscribed( '3' ), 'isSubscribed' );
|
||||
|
||||
# unsubscribe
|
||||
$wiki->unsubscribe('3');
|
||||
ok(
|
||||
!WebGUI::User->new( $session, '3' )->isInGroup( $wiki->getSubscriptionGroup->getId ),
|
||||
'unsubscribe'
|
||||
);
|
||||
|
||||
|
||||
#----------------------------------------------------------------------------
|
||||
# skip notification
|
||||
ok( !$wiki->get('skipNotification'), 'skipNotification defaults to false' );
|
||||
$wiki->setSkipNotification(1);
|
||||
ok( $wiki->get('skipNotification'), 'setSkipNotification sets skipNotification' );
|
||||
|
||||
# add revision
|
||||
my $new_rev = $wiki->addRevision({},time+1);
|
||||
ok( !$new_rev->get('skipNotification'), 'addRevision resets skipNotification to false' );
|
||||
|
||||
# notify subscribers
|
||||
# subscription content
|
||||
|
||||
#----------------------------------------------------------------------------
|
||||
# Cleanup
|
||||
|
||||
#vim:ft=perl
|
||||
Loading…
Add table
Add a link
Reference in a new issue