mirror of
https://github.com/Alfresco/alfresco-community-repo.git
synced 2025-08-07 17:49:17 +00:00
Added "following email"
Added activities email templates patch git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@28883 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
@@ -472,6 +472,7 @@
|
|||||||
<value>alfresco.messages.jbpm-engine-messages</value>
|
<value>alfresco.messages.jbpm-engine-messages</value>
|
||||||
<value>alfresco.messages.activiti-engine-messages</value>
|
<value>alfresco.messages.activiti-engine-messages</value>
|
||||||
<value>alfresco.messages.wdr-messages</value>
|
<value>alfresco.messages.wdr-messages</value>
|
||||||
|
<value>alfresco.messages.subscription-service</value>
|
||||||
</list>
|
</list>
|
||||||
</property>
|
</property>
|
||||||
</bean>
|
</bean>
|
||||||
|
@@ -525,6 +525,11 @@
|
|||||||
<prop key="location">alfresco/templates/activities-email-templates.acp</prop>
|
<prop key="location">alfresco/templates/activities-email-templates.acp</prop>
|
||||||
<prop key="messages">alfresco/messages/bootstrap-spaces</prop>
|
<prop key="messages">alfresco/messages/bootstrap-spaces</prop>
|
||||||
</props>
|
</props>
|
||||||
|
<props>
|
||||||
|
<prop key="path">/${spaces.company_home.childname}/${spaces.dictionary.childname}/${spaces.templates.email.childname}</prop>
|
||||||
|
<prop key="location">alfresco/templates/following-email-templates.acp</prop>
|
||||||
|
<prop key="messages">alfresco/messages/bootstrap-spaces</prop>
|
||||||
|
</props>
|
||||||
<props>
|
<props>
|
||||||
<prop key="path">/${spaces.company_home.childname}/${spaces.dictionary.childname}/${spaces.templates.rss.childname}</prop>
|
<prop key="path">/${spaces.company_home.childname}/${spaces.dictionary.childname}/${spaces.templates.rss.childname}</prop>
|
||||||
<prop key="location">alfresco/templates/rss_templates.acp</prop>
|
<prop key="location">alfresco/templates/rss_templates.acp</prop>
|
||||||
|
@@ -97,6 +97,11 @@ email.template.email_template_for_notifying_users_of_an_Invite=Email template fo
|
|||||||
|
|
||||||
email.templates.email_template_for_notifying_new_users=Email template used to inform new users of their accounts
|
email.templates.email_template_for_notifying_new_users=Email template used to inform new users of their accounts
|
||||||
|
|
||||||
|
spaces.templates.email.following.name=Following Email Templates
|
||||||
|
spaces.templates.email.following.description=Following Email Templates
|
||||||
|
|
||||||
|
email.templates.email_template_for_following_notifications=Email template used to generate following notification emails
|
||||||
|
|
||||||
version.default=Default version
|
version.default=Default version
|
||||||
version.french=French version
|
version.french=French version
|
||||||
version.german=German version
|
version.german=German version
|
||||||
|
@@ -409,5 +409,13 @@ patch.exampleJavaScript.description=Loads sample Javascript file into datadictio
|
|||||||
patch.fixAclInheritance.description=Fixes any ACL inheritance issues.
|
patch.fixAclInheritance.description=Fixes any ACL inheritance issues.
|
||||||
patch.fixAclInheritance.result=Fixed {0} ACLs.
|
patch.fixAclInheritance.result=Fixed {0} ACLs.
|
||||||
|
|
||||||
|
patch.followingMailTemplates.description=Adds email templates for following notifications
|
||||||
|
|
||||||
|
patch.activitiesTemplatesUpdate.description=Updates activities email templates.
|
||||||
|
patch.activitiesTemplatesUpdate.err.template_folder_not_found=Activities email template folder could not be found.
|
||||||
|
patch.activitiesTemplatesUpdate.err.source_not_found=New activities email template ACP could not be found.
|
||||||
|
patch.activitiesTemplatesUpdate.err.update_failed=Could not update activities email template: {0}
|
||||||
|
patch.activitiesTemplatesUpdate.result=Updated {0} activities email templates.
|
||||||
|
|
||||||
patch.avmToAdmRemoteStore.description=Migrates Share Surf config from AVM sitestore to DM Sites folder.
|
patch.avmToAdmRemoteStore.description=Migrates Share Surf config from AVM sitestore to DM Sites folder.
|
||||||
patch.avmToAdmRemoteStore.complete=Completed Share Surf config migration.
|
patch.avmToAdmRemoteStore.complete=Completed Share Surf config migration.
|
||||||
|
7
config/alfresco/messages/subscription-service.properties
Normal file
7
config/alfresco/messages/subscription-service.properties
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
# Subscription service messages
|
||||||
|
|
||||||
|
subscription.notification.email.subject={0} is now following you
|
||||||
|
|
||||||
|
subscription_service.err.disabled=The subscription is disabled
|
||||||
|
subscription_service.err.write-denied=No permissions to update
|
||||||
|
subscription_service.err.private-list=This list is marked as private
|
@@ -2600,6 +2600,50 @@
|
|||||||
</props>
|
</props>
|
||||||
</property>
|
</property>
|
||||||
</bean>
|
</bean>
|
||||||
|
|
||||||
|
<bean id="patch.activitiesEmailTemplateUpdate" class="org.alfresco.repo.admin.patch.impl.ActivitiesTemplatesUpdatePatch" parent="basePatch">
|
||||||
|
<property name="id">
|
||||||
|
<value>patch.activitiesTemplatesUpdate</value>
|
||||||
|
</property>
|
||||||
|
<property name="description">
|
||||||
|
<value>patch.activitiesTemplatesUpdate.description</value>
|
||||||
|
</property>
|
||||||
|
<property name="fixesFromSchema" value="0" />
|
||||||
|
<property name="fixesToSchema" value="5010" />
|
||||||
|
<property name="targetSchema" value="5011" />
|
||||||
|
<property name="dependsOn">
|
||||||
|
<list>
|
||||||
|
<ref bean="patch.activitiesEmailTemplate" />
|
||||||
|
</list>
|
||||||
|
</property>
|
||||||
|
<property name="fileFolderService">
|
||||||
|
<ref bean="fileFolderService" />
|
||||||
|
</property>
|
||||||
|
<property name="versionService">
|
||||||
|
<ref bean="versionService" />
|
||||||
|
</property>
|
||||||
|
<property name="newTemplatesFile">
|
||||||
|
<value>alfresco/templates/activities-email-templates.acp</value>
|
||||||
|
</property>
|
||||||
|
</bean>
|
||||||
|
|
||||||
|
<bean id="patch.followingMailTemplates" class="org.alfresco.repo.admin.patch.impl.GenericBootstrapPatch" parent="basePatch" >
|
||||||
|
<property name="id"><value>patch.followingMailTemplates</value></property>
|
||||||
|
<property name="description"><value>patch.followingMailTemplates.description</value></property>
|
||||||
|
<property name="fixesFromSchema"><value>0</value></property>
|
||||||
|
<property name="fixesToSchema"><value>5010</value></property>
|
||||||
|
<property name="targetSchema"><value>5011</value></property>
|
||||||
|
<property name="importerBootstrap">
|
||||||
|
<ref bean="spacesBootstrap" />
|
||||||
|
</property>
|
||||||
|
<property name="bootstrapView">
|
||||||
|
<props>
|
||||||
|
<prop key="path">/${spaces.company_home.childname}/${spaces.dictionary.childname}/${spaces.templates.email.childname}</prop>
|
||||||
|
<prop key="location">alfresco/templates/following-email-templates.acp</prop>
|
||||||
|
<prop key="messages">alfresco/messages/bootstrap-spaces</prop>
|
||||||
|
</props>
|
||||||
|
</property>
|
||||||
|
</bean>
|
||||||
|
|
||||||
<bean id="patch.newUserEmailTemplates" class="org.alfresco.repo.admin.patch.impl.GenericBootstrapPatch" parent="basePatch" >
|
<bean id="patch.newUserEmailTemplates" class="org.alfresco.repo.admin.patch.impl.GenericBootstrapPatch" parent="basePatch" >
|
||||||
<property name="id"><value>patch.newUserEmailTemplates</value></property>
|
<property name="id"><value>patch.newUserEmailTemplates</value></property>
|
||||||
|
@@ -376,6 +376,7 @@ spaces.templates.content.childname=app:content_templates
|
|||||||
spaces.templates.email.childname=app:email_templates
|
spaces.templates.email.childname=app:email_templates
|
||||||
spaces.templates.email.invite1.childname=app:invite_email_templates
|
spaces.templates.email.invite1.childname=app:invite_email_templates
|
||||||
spaces.templates.email.notify.childname=app:notify_email_templates
|
spaces.templates.email.notify.childname=app:notify_email_templates
|
||||||
|
spaces.templates.email.following.childname=app:following
|
||||||
spaces.templates.rss.childname=app:rss_templates
|
spaces.templates.rss.childname=app:rss_templates
|
||||||
spaces.savedsearches.childname=app:saved_searches
|
spaces.savedsearches.childname=app:saved_searches
|
||||||
spaces.scripts.childname=app:scripts
|
spaces.scripts.childname=app:scripts
|
||||||
|
@@ -25,6 +25,10 @@
|
|||||||
<property name="personService" ref="PersonService" />
|
<property name="personService" ref="PersonService" />
|
||||||
<property name="activityService" ref="activityService" />
|
<property name="activityService" ref="activityService" />
|
||||||
<property name="authorityService" ref="AuthorityService" />
|
<property name="authorityService" ref="AuthorityService" />
|
||||||
|
<property name="actionService" ref="ActionService" />
|
||||||
|
<property name="searchService" ref="SearchService" />
|
||||||
|
<property name="namespaceService" ref="NamespaceService" />
|
||||||
|
<property name="fileFolderService" ref="FileFolderService" />
|
||||||
</bean>
|
</bean>
|
||||||
|
|
||||||
</beans>
|
</beans>
|
Binary file not shown.
BIN
config/alfresco/templates/following-email-templates.acp
Normal file
BIN
config/alfresco/templates/following-email-templates.acp
Normal file
Binary file not shown.
@@ -0,0 +1,210 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2005-2011 Alfresco Software Limited.
|
||||||
|
*
|
||||||
|
* This file is part of Alfresco
|
||||||
|
*
|
||||||
|
* Alfresco is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Lesser General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* Alfresco is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public License
|
||||||
|
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
package org.alfresco.repo.admin.patch.impl;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.FileOutputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.util.Enumeration;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import org.alfresco.model.ContentModel;
|
||||||
|
import org.alfresco.repo.admin.patch.AbstractPatch;
|
||||||
|
import org.alfresco.repo.version.VersionModel;
|
||||||
|
import org.alfresco.service.cmr.admin.PatchException;
|
||||||
|
import org.alfresco.service.cmr.model.FileFolderService;
|
||||||
|
import org.alfresco.service.cmr.repository.ContentWriter;
|
||||||
|
import org.alfresco.service.cmr.repository.NodeRef;
|
||||||
|
import org.alfresco.service.cmr.repository.StoreRef;
|
||||||
|
import org.alfresco.service.cmr.version.VersionService;
|
||||||
|
import org.alfresco.service.cmr.version.VersionType;
|
||||||
|
import org.alfresco.service.namespace.QName;
|
||||||
|
import org.alfresco.util.TempFileProvider;
|
||||||
|
import org.apache.commons.compress.archivers.zip.ZipArchiveEntry;
|
||||||
|
import org.apache.commons.compress.archivers.zip.ZipFile;
|
||||||
|
import org.springframework.extensions.surf.util.I18NUtil;
|
||||||
|
import org.springframework.util.FileCopyUtils;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Patch to update the activities email templates. Current templates become
|
||||||
|
* versions of the new templates.
|
||||||
|
*
|
||||||
|
* @author Florian Mueller
|
||||||
|
*/
|
||||||
|
public class ActivitiesTemplatesUpdatePatch extends AbstractPatch
|
||||||
|
{
|
||||||
|
private static final String MSG_SUCCESS = "patch.activitiesTemplatesUpdate.result";
|
||||||
|
|
||||||
|
protected FileFolderService fileFolderService;
|
||||||
|
protected VersionService versionService;
|
||||||
|
|
||||||
|
protected String newTemplatesFile;
|
||||||
|
protected String newTemplatesName;
|
||||||
|
|
||||||
|
protected ZipFile zipFile;
|
||||||
|
|
||||||
|
public void setFileFolderService(FileFolderService fileFolderService)
|
||||||
|
{
|
||||||
|
this.fileFolderService = fileFolderService;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setVersionService(VersionService versionService)
|
||||||
|
{
|
||||||
|
this.versionService = versionService;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setNewTemplatesFile(String newTemplatesFile)
|
||||||
|
{
|
||||||
|
this.newTemplatesFile = newTemplatesFile;
|
||||||
|
|
||||||
|
int x = newTemplatesFile.lastIndexOf("/");
|
||||||
|
if (x < 0)
|
||||||
|
{
|
||||||
|
newTemplatesName = newTemplatesFile;
|
||||||
|
} else
|
||||||
|
{
|
||||||
|
newTemplatesName = newTemplatesFile.substring(x + 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
x = newTemplatesName.lastIndexOf(".");
|
||||||
|
if (x > 0)
|
||||||
|
{
|
||||||
|
newTemplatesName = newTemplatesName.substring(0, x);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected String applyInternal() throws Exception
|
||||||
|
{
|
||||||
|
// get templates folder
|
||||||
|
NodeRef templateFolder = getTemplateFolder();
|
||||||
|
|
||||||
|
// get ACP file
|
||||||
|
ZipFile zipFile = getZipFile();
|
||||||
|
|
||||||
|
// iterate over all templates in the ACP file and apply version
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
Enumeration<ZipArchiveEntry> zae = (Enumeration<ZipArchiveEntry>) zipFile.getEntries();
|
||||||
|
int count = 0;
|
||||||
|
while (zae.hasMoreElements())
|
||||||
|
{
|
||||||
|
ZipArchiveEntry entry = zae.nextElement();
|
||||||
|
if (!(entry.getName().startsWith(newTemplatesName + "/") && entry.getName().endsWith(".ftl")))
|
||||||
|
{
|
||||||
|
// ignore non-template files
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// find matching node and add version
|
||||||
|
NodeRef nodeRef = findMatchingNode(templateFolder, entry);
|
||||||
|
if (nodeRef != null)
|
||||||
|
{
|
||||||
|
addNewVersion(nodeRef, zipFile, entry);
|
||||||
|
count++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return I18NUtil.getMessage(MSG_SUCCESS, count);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected NodeRef getTemplateFolder()
|
||||||
|
{
|
||||||
|
String xpath = "app:company_home/app:dictionary/app:email_templates/cm:activities";
|
||||||
|
try
|
||||||
|
{
|
||||||
|
NodeRef rootNodeRef = nodeService.getRootNode(StoreRef.STORE_REF_WORKSPACE_SPACESSTORE);
|
||||||
|
List<NodeRef> nodeRefs = searchService.selectNodes(rootNodeRef, xpath, null, namespaceService, false);
|
||||||
|
|
||||||
|
if (nodeRefs.size() < 1)
|
||||||
|
{
|
||||||
|
throw new PatchException("patch.activitiesTemplatesUpdate.err.template_folder_not_found");
|
||||||
|
}
|
||||||
|
|
||||||
|
return nodeRefs.get(0);
|
||||||
|
} catch (Exception e)
|
||||||
|
{
|
||||||
|
throw new PatchException("patch.activitiesTemplatesUpdate.err.template_folder_not_found", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected ZipFile getZipFile()
|
||||||
|
{
|
||||||
|
InputStream templateFileStream = ActivitiesTemplatesUpdatePatch.class.getClassLoader().getResourceAsStream(
|
||||||
|
newTemplatesFile);
|
||||||
|
if (templateFileStream == null)
|
||||||
|
{
|
||||||
|
throw new PatchException("patch.activitiesTemplatesUpdate.err.source_not_found");
|
||||||
|
}
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
File tempFile = TempFileProvider.createTempFile("templateFile", ".tmp");
|
||||||
|
FileOutputStream os = new FileOutputStream(tempFile);
|
||||||
|
FileCopyUtils.copy(templateFileStream, os);
|
||||||
|
|
||||||
|
return new ZipFile(tempFile, "Cp437");
|
||||||
|
} catch (IOException e)
|
||||||
|
{
|
||||||
|
throw new PatchException("patch.activitiesTemplatesUpdate.err.source_not_found", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected NodeRef findMatchingNode(NodeRef parentNodeRef, ZipArchiveEntry entry)
|
||||||
|
{
|
||||||
|
String name = entry.getName();
|
||||||
|
int x = name.lastIndexOf("/");
|
||||||
|
if (x > 0)
|
||||||
|
{
|
||||||
|
name = name.substring(x + 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
return nodeService.getChildByName(parentNodeRef, ContentModel.ASSOC_CONTAINS, name);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void addNewVersion(NodeRef nodeRef, ZipFile zipFile, ZipArchiveEntry entry)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if (nodeService.hasAspect(nodeRef, ContentModel.ASPECT_VERSIONABLE) == false)
|
||||||
|
{
|
||||||
|
Map<QName, Serializable> props = new HashMap<QName, Serializable>();
|
||||||
|
props.put(ContentModel.PROP_INITIAL_VERSION, true);
|
||||||
|
props.put(ContentModel.PROP_AUTO_VERSION, false);
|
||||||
|
nodeService.addAspect(nodeRef, ContentModel.ASPECT_VERSIONABLE, props);
|
||||||
|
}
|
||||||
|
|
||||||
|
Map<String, Serializable> versionProperties = new HashMap<String, Serializable>();
|
||||||
|
versionProperties.put(VersionModel.PROP_VERSION_TYPE, VersionType.MAJOR);
|
||||||
|
|
||||||
|
versionService.createVersion(nodeRef, versionProperties);
|
||||||
|
|
||||||
|
ContentWriter writer = fileFolderService.getWriter(nodeRef);
|
||||||
|
writer.setMimetype("text/plain");
|
||||||
|
writer.setEncoding("UTF-8");
|
||||||
|
writer.putContent(zipFile.getInputStream(entry));
|
||||||
|
} catch (Exception e)
|
||||||
|
{
|
||||||
|
throw new PatchException("patch.activitiesTemplatesUpdate.err.update_failed", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@@ -19,16 +19,27 @@
|
|||||||
package org.alfresco.repo.subscriptions;
|
package org.alfresco.repo.subscriptions;
|
||||||
|
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
import org.alfresco.model.ContentModel;
|
import org.alfresco.model.ContentModel;
|
||||||
import org.alfresco.query.PagingRequest;
|
import org.alfresco.query.PagingRequest;
|
||||||
|
import org.alfresco.repo.action.executer.MailActionExecuter;
|
||||||
import org.alfresco.repo.activities.ActivityType;
|
import org.alfresco.repo.activities.ActivityType;
|
||||||
import org.alfresco.repo.domain.subscriptions.SubscriptionsDAO;
|
import org.alfresco.repo.domain.subscriptions.SubscriptionsDAO;
|
||||||
|
import org.alfresco.repo.search.SearcherException;
|
||||||
import org.alfresco.repo.security.authentication.AuthenticationUtil;
|
import org.alfresco.repo.security.authentication.AuthenticationUtil;
|
||||||
import org.alfresco.repo.security.permissions.AccessDeniedException;
|
import org.alfresco.repo.security.permissions.AccessDeniedException;
|
||||||
|
import org.alfresco.service.cmr.action.Action;
|
||||||
|
import org.alfresco.service.cmr.action.ActionService;
|
||||||
import org.alfresco.service.cmr.activities.ActivityService;
|
import org.alfresco.service.cmr.activities.ActivityService;
|
||||||
|
import org.alfresco.service.cmr.model.FileFolderService;
|
||||||
import org.alfresco.service.cmr.repository.NodeRef;
|
import org.alfresco.service.cmr.repository.NodeRef;
|
||||||
import org.alfresco.service.cmr.repository.NodeService;
|
import org.alfresco.service.cmr.repository.NodeService;
|
||||||
|
import org.alfresco.service.cmr.repository.StoreRef;
|
||||||
|
import org.alfresco.service.cmr.search.SearchService;
|
||||||
import org.alfresco.service.cmr.security.AuthorityService;
|
import org.alfresco.service.cmr.security.AuthorityService;
|
||||||
import org.alfresco.service.cmr.security.PersonService;
|
import org.alfresco.service.cmr.security.PersonService;
|
||||||
import org.alfresco.service.cmr.subscriptions.PagingFollowingResults;
|
import org.alfresco.service.cmr.subscriptions.PagingFollowingResults;
|
||||||
@@ -37,10 +48,12 @@ import org.alfresco.service.cmr.subscriptions.PrivateSubscriptionListException;
|
|||||||
import org.alfresco.service.cmr.subscriptions.SubscriptionItemTypeEnum;
|
import org.alfresco.service.cmr.subscriptions.SubscriptionItemTypeEnum;
|
||||||
import org.alfresco.service.cmr.subscriptions.SubscriptionService;
|
import org.alfresco.service.cmr.subscriptions.SubscriptionService;
|
||||||
import org.alfresco.service.cmr.subscriptions.SubscriptionsDisabledException;
|
import org.alfresco.service.cmr.subscriptions.SubscriptionsDisabledException;
|
||||||
|
import org.alfresco.service.namespace.NamespaceService;
|
||||||
import org.apache.commons.logging.Log;
|
import org.apache.commons.logging.Log;
|
||||||
import org.apache.commons.logging.LogFactory;
|
import org.apache.commons.logging.LogFactory;
|
||||||
import org.json.JSONException;
|
import org.json.JSONException;
|
||||||
import org.json.JSONObject;
|
import org.json.JSONObject;
|
||||||
|
import org.springframework.extensions.surf.util.I18NUtil;
|
||||||
|
|
||||||
public class SubscriptionServiceImpl implements SubscriptionService
|
public class SubscriptionServiceImpl implements SubscriptionService
|
||||||
{
|
{
|
||||||
@@ -54,9 +67,12 @@ public class SubscriptionServiceImpl implements SubscriptionService
|
|||||||
private static final String FOLLOWER_FIRSTNAME = "followerFirstName";
|
private static final String FOLLOWER_FIRSTNAME = "followerFirstName";
|
||||||
private static final String FOLLOWER_LASTNAME = "followerLastName";
|
private static final String FOLLOWER_LASTNAME = "followerLastName";
|
||||||
private static final String FOLLOWER_USERNAME = "followerUserName";
|
private static final String FOLLOWER_USERNAME = "followerUserName";
|
||||||
|
private static final String FOLLOWER_JOBTITLE = "followerJobTitle";
|
||||||
private static final String USER_FIRSTNAME = "userFirstName";
|
private static final String USER_FIRSTNAME = "userFirstName";
|
||||||
private static final String USER_LASTNAME = "userLastName";
|
private static final String USER_LASTNAME = "userLastName";
|
||||||
private static final String USER_USERNAME = "userUserName";
|
private static final String USER_USERNAME = "userUserName";
|
||||||
|
private static final String FOLLOWING_COUNT = "followingCount";
|
||||||
|
private static final String FOLLOWER_COUNT = "followerCount";
|
||||||
|
|
||||||
private static final String SUBSCRIBER_FIRSTNAME = "subscriberFirstName";
|
private static final String SUBSCRIBER_FIRSTNAME = "subscriberFirstName";
|
||||||
private static final String SUBSCRIBER_LASTNAME = "subscriberLastName";
|
private static final String SUBSCRIBER_LASTNAME = "subscriberLastName";
|
||||||
@@ -68,6 +84,10 @@ public class SubscriptionServiceImpl implements SubscriptionService
|
|||||||
protected PersonService personService;
|
protected PersonService personService;
|
||||||
protected ActivityService activityService;
|
protected ActivityService activityService;
|
||||||
protected AuthorityService authorityService;
|
protected AuthorityService authorityService;
|
||||||
|
protected ActionService actionService;
|
||||||
|
protected SearchService searchService;
|
||||||
|
protected NamespaceService namespaceService;
|
||||||
|
protected FileFolderService fileFolderService;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the subscriptions DAO.
|
* Sets the subscriptions DAO.
|
||||||
@@ -109,6 +129,38 @@ public class SubscriptionServiceImpl implements SubscriptionService
|
|||||||
this.authorityService = authorityService;
|
this.authorityService = authorityService;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the action service.
|
||||||
|
*/
|
||||||
|
public final void setActionService(ActionService actionService)
|
||||||
|
{
|
||||||
|
this.actionService = actionService;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the search service.
|
||||||
|
*/
|
||||||
|
public final void setSearchService(SearchService searchService)
|
||||||
|
{
|
||||||
|
this.searchService = searchService;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the namespace service.
|
||||||
|
*/
|
||||||
|
public final void setNamespaceService(NamespaceService namespaceService)
|
||||||
|
{
|
||||||
|
this.namespaceService = namespaceService;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the fileFolder service.
|
||||||
|
*/
|
||||||
|
public final void setFileFolderService(FileFolderService fileFolderService)
|
||||||
|
{
|
||||||
|
this.fileFolderService = fileFolderService;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public PagingSubscriptionResults getSubscriptions(String userId, SubscriptionItemTypeEnum type,
|
public PagingSubscriptionResults getSubscriptions(String userId, SubscriptionItemTypeEnum type,
|
||||||
PagingRequest pagingRequest)
|
PagingRequest pagingRequest)
|
||||||
@@ -215,9 +267,10 @@ public class SubscriptionServiceImpl implements SubscriptionService
|
|||||||
|
|
||||||
if (userId.equalsIgnoreCase(AuthenticationUtil.getRunAsUser()))
|
if (userId.equalsIgnoreCase(AuthenticationUtil.getRunAsUser()))
|
||||||
{
|
{
|
||||||
String activityDataJSON = null;
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
String activityDataJSON = null;
|
||||||
|
|
||||||
NodeRef followerNode = personService.getPerson(userId, false);
|
NodeRef followerNode = personService.getPerson(userId, false);
|
||||||
NodeRef userNode = personService.getPerson(userToFollow, false);
|
NodeRef userNode = personService.getPerson(userToFollow, false);
|
||||||
JSONObject activityData = new JSONObject();
|
JSONObject activityData = new JSONObject();
|
||||||
@@ -229,13 +282,23 @@ public class SubscriptionServiceImpl implements SubscriptionService
|
|||||||
activityData.put(USER_FIRSTNAME, nodeService.getProperty(userNode, ContentModel.PROP_FIRSTNAME));
|
activityData.put(USER_FIRSTNAME, nodeService.getProperty(userNode, ContentModel.PROP_FIRSTNAME));
|
||||||
activityData.put(USER_LASTNAME, nodeService.getProperty(userNode, ContentModel.PROP_LASTNAME));
|
activityData.put(USER_LASTNAME, nodeService.getProperty(userNode, ContentModel.PROP_LASTNAME));
|
||||||
activityDataJSON = activityData.toString();
|
activityDataJSON = activityData.toString();
|
||||||
|
|
||||||
|
activityService.postActivity(ActivityType.SUBSCRIPTIONS_FOLLOW, null, ACTIVITY_TOOL, activityDataJSON);
|
||||||
|
|
||||||
} catch (JSONException je)
|
} catch (JSONException je)
|
||||||
{
|
{
|
||||||
// log error, subsume exception
|
// log error, subsume exception
|
||||||
logger.error("Failed to get activity data: " + je);
|
logger.error("Failed to get activity data: " + je);
|
||||||
}
|
}
|
||||||
|
|
||||||
activityService.postActivity(ActivityType.SUBSCRIPTIONS_FOLLOW, null, ACTIVITY_TOOL, activityDataJSON);
|
try
|
||||||
|
{
|
||||||
|
sendFollowingMail(userId, userToFollow);
|
||||||
|
} catch (Exception e)
|
||||||
|
{
|
||||||
|
// log error, subsume exception
|
||||||
|
logger.error("Failed to send following email: " + e);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -379,4 +442,105 @@ public class SubscriptionServiceImpl implements SubscriptionService
|
|||||||
throw new IllegalArgumentException("Only user nodes supported!");
|
throw new IllegalArgumentException("Only user nodes supported!");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sends an email to the person that is followed.
|
||||||
|
*/
|
||||||
|
protected void sendFollowingMail(String userId, String userToFollow)
|
||||||
|
{
|
||||||
|
NodeRef followerNode = personService.getPerson(userId, false);
|
||||||
|
NodeRef userNode = personService.getPerson(userToFollow, false);
|
||||||
|
|
||||||
|
Serializable emailFeedDisabled = nodeService.getProperty(userNode, ContentModel.PROP_EMAIL_FEED_DISABLED);
|
||||||
|
if (emailFeedDisabled instanceof Boolean && ((Boolean) emailFeedDisabled).booleanValue())
|
||||||
|
{
|
||||||
|
// this user doesn't want to be notified
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Serializable emailAddress = nodeService.getProperty(userNode, ContentModel.PROP_EMAIL);
|
||||||
|
if (emailAddress == null)
|
||||||
|
{
|
||||||
|
// we can't send an email without email address
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
NodeRef templateNodeRef = getEmailTemplateRef();
|
||||||
|
if (templateNodeRef == null)
|
||||||
|
{
|
||||||
|
// we can't send an email without template
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// compile the mail subject
|
||||||
|
String followerFullName = (nodeService.getProperty(followerNode, ContentModel.PROP_FIRSTNAME) + " " + nodeService
|
||||||
|
.getProperty(followerNode, ContentModel.PROP_LASTNAME)).trim();
|
||||||
|
String subjectText = I18NUtil.getMessage("subscription.notification.email.subject", followerFullName);
|
||||||
|
|
||||||
|
Map<String, Object> model = new HashMap<String, Object>();
|
||||||
|
|
||||||
|
model.put(FOLLOWER_USERNAME, userId);
|
||||||
|
model.put(FOLLOWER_FIRSTNAME, nodeService.getProperty(followerNode, ContentModel.PROP_FIRSTNAME));
|
||||||
|
model.put(FOLLOWER_LASTNAME, nodeService.getProperty(followerNode, ContentModel.PROP_LASTNAME));
|
||||||
|
model.put(FOLLOWER_JOBTITLE, nodeService.getProperty(followerNode, ContentModel.PROP_JOBTITLE));
|
||||||
|
model.put(USER_USERNAME, userToFollow);
|
||||||
|
model.put(USER_FIRSTNAME, nodeService.getProperty(userNode, ContentModel.PROP_FIRSTNAME));
|
||||||
|
model.put(USER_LASTNAME, nodeService.getProperty(userNode, ContentModel.PROP_LASTNAME));
|
||||||
|
model.put(FOLLOWING_COUNT, -1);
|
||||||
|
try
|
||||||
|
{
|
||||||
|
model.put(FOLLOWING_COUNT, getFollowingCount(userId));
|
||||||
|
} catch (Exception e)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
model.put(FOLLOWER_COUNT, -1);
|
||||||
|
try
|
||||||
|
{
|
||||||
|
model.put(FOLLOWER_COUNT, getFollowersCount(userId));
|
||||||
|
} catch (Exception e)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
Action mail = actionService.createAction(MailActionExecuter.NAME);
|
||||||
|
|
||||||
|
mail.setParameterValue(MailActionExecuter.PARAM_TO, emailAddress);
|
||||||
|
mail.setParameterValue(MailActionExecuter.PARAM_SUBJECT, subjectText);
|
||||||
|
mail.setParameterValue(MailActionExecuter.PARAM_TEMPLATE, templateNodeRef);
|
||||||
|
mail.setParameterValue(MailActionExecuter.PARAM_TEMPLATE_MODEL, (Serializable) model);
|
||||||
|
|
||||||
|
actionService.executeAction(mail, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the NodeRef of the email template or <code>null</code> if the
|
||||||
|
* template coudln't be found.
|
||||||
|
*/
|
||||||
|
protected NodeRef getEmailTemplateRef()
|
||||||
|
{
|
||||||
|
// Find the following email template
|
||||||
|
String xpath = "app:company_home/app:dictionary/app:email_templates/app:following/cm:following-email.html.ftl";
|
||||||
|
try
|
||||||
|
{
|
||||||
|
NodeRef rootNodeRef = nodeService.getRootNode(StoreRef.STORE_REF_WORKSPACE_SPACESSTORE);
|
||||||
|
List<NodeRef> nodeRefs = searchService.selectNodes(rootNodeRef, xpath, null, namespaceService, false);
|
||||||
|
if (nodeRefs.size() > 1)
|
||||||
|
{
|
||||||
|
logger.error("Found too many email templates using: " + xpath);
|
||||||
|
nodeRefs = Collections.singletonList(nodeRefs.get(0));
|
||||||
|
} else if (nodeRefs.size() == 0)
|
||||||
|
{
|
||||||
|
logger.error("Cannot find the email template using " + xpath);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
// Now localise this
|
||||||
|
NodeRef base = nodeRefs.get(0);
|
||||||
|
NodeRef local = fileFolderService.getLocalizedSibling(base);
|
||||||
|
return local;
|
||||||
|
} catch (SearcherException e)
|
||||||
|
{
|
||||||
|
logger.error("Cannot find the email template!", e);
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user