001    /**
002     * Copyright (c) 2000-present Liferay, Inc. All rights reserved.
003     *
004     * This library is free software; you can redistribute it and/or modify it under
005     * the terms of the GNU Lesser General Public License as published by the Free
006     * Software Foundation; either version 2.1 of the License, or (at your option)
007     * any later version.
008     *
009     * This library is distributed in the hope that it will be useful, but WITHOUT
010     * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
011     * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
012     * details.
013     */
014    
015    package com.liferay.portal.service.impl;
016    
017    import com.liferay.portal.kernel.exception.MembershipRequestCommentsException;
018    import com.liferay.portal.kernel.exception.PortalException;
019    import com.liferay.portal.kernel.language.LanguageUtil;
020    import com.liferay.portal.kernel.model.Group;
021    import com.liferay.portal.kernel.model.MembershipRequest;
022    import com.liferay.portal.kernel.model.MembershipRequestConstants;
023    import com.liferay.portal.kernel.model.Resource;
024    import com.liferay.portal.kernel.model.ResourceConstants;
025    import com.liferay.portal.kernel.model.Role;
026    import com.liferay.portal.kernel.model.RoleConstants;
027    import com.liferay.portal.kernel.model.User;
028    import com.liferay.portal.kernel.model.UserGroupRole;
029    import com.liferay.portal.kernel.security.permission.ActionKeys;
030    import com.liferay.portal.kernel.security.permission.ResourceActionsUtil;
031    import com.liferay.portal.kernel.service.ServiceContext;
032    import com.liferay.portal.kernel.util.ListUtil;
033    import com.liferay.portal.kernel.util.OrderByComparator;
034    import com.liferay.portal.kernel.util.PropsKeys;
035    import com.liferay.portal.kernel.util.SubscriptionSender;
036    import com.liferay.portal.kernel.util.Validator;
037    import com.liferay.portal.service.base.MembershipRequestLocalServiceBaseImpl;
038    import com.liferay.portal.util.PrefsPropsUtil;
039    import com.liferay.portal.util.ResourcePermissionUtil;
040    
041    import java.util.ArrayList;
042    import java.util.Date;
043    import java.util.LinkedHashSet;
044    import java.util.List;
045    import java.util.Set;
046    
047    /**
048     * @author Jorge Ferrer
049     */
050    public class MembershipRequestLocalServiceImpl
051            extends MembershipRequestLocalServiceBaseImpl {
052    
053            @Override
054            public MembershipRequest addMembershipRequest(
055                            long userId, long groupId, String comments,
056                            ServiceContext serviceContext)
057                    throws PortalException {
058    
059                    User user = userPersistence.findByPrimaryKey(userId);
060    
061                    validate(comments);
062    
063                    long membershipRequestId = counterLocalService.increment();
064    
065                    MembershipRequest membershipRequest =
066                            membershipRequestPersistence.create(membershipRequestId);
067    
068                    membershipRequest.setCompanyId(user.getCompanyId());
069                    membershipRequest.setUserId(userId);
070                    membershipRequest.setCreateDate(new Date());
071                    membershipRequest.setGroupId(groupId);
072                    membershipRequest.setComments(comments);
073                    membershipRequest.setStatusId(
074                            MembershipRequestConstants.STATUS_PENDING);
075    
076                    membershipRequestPersistence.update(membershipRequest);
077    
078                    notifyGroupAdministrators(membershipRequest, serviceContext);
079    
080                    return membershipRequest;
081            }
082    
083            @Override
084            public void deleteMembershipRequests(long groupId) {
085                    List<MembershipRequest> membershipRequests =
086                            membershipRequestPersistence.findByGroupId(groupId);
087    
088                    for (MembershipRequest membershipRequest : membershipRequests) {
089                            deleteMembershipRequest(membershipRequest);
090                    }
091            }
092    
093            @Override
094            public void deleteMembershipRequests(long groupId, long statusId) {
095                    List<MembershipRequest> membershipRequests =
096                            membershipRequestPersistence.findByG_S(groupId, statusId);
097    
098                    for (MembershipRequest membershipRequest : membershipRequests) {
099                            deleteMembershipRequest(membershipRequest);
100                    }
101            }
102    
103            @Override
104            public void deleteMembershipRequestsByUserId(long userId) {
105                    List<MembershipRequest> membershipRequests =
106                            membershipRequestPersistence.findByUserId(userId);
107    
108                    for (MembershipRequest membershipRequest : membershipRequests) {
109                            deleteMembershipRequest(membershipRequest);
110                    }
111            }
112    
113            @Override
114            public List<MembershipRequest> getMembershipRequests(
115                    long userId, long groupId, long statusId) {
116    
117                    return membershipRequestPersistence.findByG_U_S(
118                            groupId, userId, statusId);
119            }
120    
121            @Override
122            public boolean hasMembershipRequest(
123                    long userId, long groupId, long statusId) {
124    
125                    List<MembershipRequest> membershipRequests = getMembershipRequests(
126                            userId, groupId, statusId);
127    
128                    if (membershipRequests.isEmpty()) {
129                            return false;
130                    }
131                    else {
132                            return true;
133                    }
134            }
135    
136            @Override
137            public List<MembershipRequest> search(
138                    long groupId, int status, int start, int end) {
139    
140                    return membershipRequestPersistence.findByG_S(
141                            groupId, status, start, end);
142            }
143    
144            @Override
145            public List<MembershipRequest> search(
146                    long groupId, int status, int start, int end,
147                    OrderByComparator<MembershipRequest> obc) {
148    
149                    return membershipRequestPersistence.findByG_S(
150                            groupId, status, start, end, obc);
151            }
152    
153            @Override
154            public int searchCount(long groupId, int status) {
155                    return membershipRequestPersistence.countByG_S(groupId, status);
156            }
157    
158            @Override
159            public void updateStatus(
160                            long replierUserId, long membershipRequestId, String replyComments,
161                            long statusId, boolean addUserToGroup,
162                            ServiceContext serviceContext)
163                    throws PortalException {
164    
165                    validate(replyComments);
166    
167                    MembershipRequest membershipRequest =
168                            membershipRequestPersistence.findByPrimaryKey(membershipRequestId);
169    
170                    membershipRequest.setReplyComments(replyComments);
171                    membershipRequest.setReplyDate(new Date());
172    
173                    if (replierUserId != 0) {
174                            membershipRequest.setReplierUserId(replierUserId);
175                    }
176                    else {
177                            long defaultUserId = userLocalService.getDefaultUserId(
178                                    membershipRequest.getCompanyId());
179    
180                            membershipRequest.setReplierUserId(defaultUserId);
181                    }
182    
183                    membershipRequest.setStatusId(statusId);
184    
185                    membershipRequestPersistence.update(membershipRequest);
186    
187                    if ((statusId == MembershipRequestConstants.STATUS_APPROVED) &&
188                            addUserToGroup) {
189    
190                            long[] addUserIds = new long[] {membershipRequest.getUserId()};
191    
192                            userLocalService.addGroupUsers(
193                                    membershipRequest.getGroupId(), addUserIds);
194                    }
195    
196                    if (replierUserId != 0) {
197                            notify(
198                                    membershipRequest.getUserId(), membershipRequest,
199                                    PropsKeys.SITES_EMAIL_MEMBERSHIP_REPLY_SUBJECT,
200                                    PropsKeys.SITES_EMAIL_MEMBERSHIP_REPLY_BODY, serviceContext);
201                    }
202            }
203    
204            protected List<Long> getGroupAdministratorUserIds(long groupId)
205                    throws PortalException {
206    
207                    Set<Long> userIds = new LinkedHashSet<>();
208    
209                    Group group = groupLocalService.getGroup(groupId);
210                    String modelResource = Group.class.getName();
211    
212                    List<Role> roles = ListUtil.copy(
213                            ResourceActionsUtil.getRoles(
214                                    group.getCompanyId(), group, modelResource, null));
215    
216                    List<Role> teamRoles = roleLocalService.getTeamRoles(groupId);
217    
218                    roles.addAll(teamRoles);
219    
220                    Resource resource = resourceLocalService.getResource(
221                            group.getCompanyId(), modelResource,
222                            ResourceConstants.SCOPE_INDIVIDUAL, String.valueOf(groupId));
223    
224                    List<String> actions = ResourceActionsUtil.getResourceActions(
225                            Group.class.getName());
226    
227                    for (Role role : roles) {
228                            String roleName = role.getName();
229    
230                            if (roleName.equals(RoleConstants.OWNER)) {
231                                    continue;
232                            }
233    
234                            if ((roleName.equals(RoleConstants.ORGANIZATION_ADMINISTRATOR) ||
235                                     roleName.equals(RoleConstants.ORGANIZATION_OWNER)) &&
236                                    !group.isOrganization()) {
237    
238                                    continue;
239                            }
240    
241                            if (roleName.equals(RoleConstants.SITE_ADMINISTRATOR) ||
242                                    roleName.equals(RoleConstants.SITE_OWNER) ||
243                                    roleName.equals(RoleConstants.ORGANIZATION_ADMINISTRATOR) ||
244                                    roleName.equals(RoleConstants.ORGANIZATION_OWNER)) {
245    
246                                    Role curRole = roleLocalService.getRole(
247                                            group.getCompanyId(), roleName);
248    
249                                    List<UserGroupRole> userGroupRoles =
250                                            userGroupRoleLocalService.getUserGroupRolesByGroupAndRole(
251                                                    groupId, curRole.getRoleId());
252    
253                                    for (UserGroupRole userGroupRole : userGroupRoles) {
254                                            userIds.add(userGroupRole.getUserId());
255                                    }
256                            }
257    
258                            List<String> currentIndividualActions = new ArrayList<>();
259                            List<String> currentGroupActions = new ArrayList<>();
260                            List<String> currentGroupTemplateActions = new ArrayList<>();
261                            List<String> currentCompanyActions = new ArrayList<>();
262    
263                            ResourcePermissionUtil.populateResourcePermissionActionIds(
264                                    groupId, role, resource, actions, currentIndividualActions,
265                                    currentGroupActions, currentGroupTemplateActions,
266                                    currentCompanyActions);
267    
268                            if (currentIndividualActions.contains(ActionKeys.ASSIGN_MEMBERS) ||
269                                    currentGroupActions.contains(ActionKeys.ASSIGN_MEMBERS) ||
270                                    currentGroupTemplateActions.contains(
271                                            ActionKeys.ASSIGN_MEMBERS) ||
272                                    currentCompanyActions.contains(ActionKeys.ASSIGN_MEMBERS)) {
273    
274                                    List<UserGroupRole> currentUserGroupRoles =
275                                            userGroupRoleLocalService.getUserGroupRolesByGroupAndRole(
276                                                    groupId, role.getRoleId());
277    
278                                    for (UserGroupRole userGroupRole : currentUserGroupRoles) {
279                                            userIds.add(userGroupRole.getUserId());
280                                    }
281                            }
282                    }
283    
284                    return new ArrayList<>(userIds);
285            }
286    
287            protected void notify(
288                            long userId, MembershipRequest membershipRequest,
289                            String subjectProperty, String bodyProperty,
290                            ServiceContext serviceContext)
291                    throws PortalException {
292    
293                    User user = userPersistence.findByPrimaryKey(userId);
294                    User requestUser = userPersistence.findByPrimaryKey(
295                            membershipRequest.getUserId());
296    
297                    String fromName = PrefsPropsUtil.getStringFromNames(
298                            membershipRequest.getCompanyId(), PropsKeys.SITES_EMAIL_FROM_NAME,
299                            PropsKeys.ADMIN_EMAIL_FROM_NAME);
300    
301                    String fromAddress = PrefsPropsUtil.getStringFromNames(
302                            membershipRequest.getCompanyId(),
303                            PropsKeys.SITES_EMAIL_FROM_ADDRESS,
304                            PropsKeys.ADMIN_EMAIL_FROM_ADDRESS);
305    
306                    String toName = user.getFullName();
307                    String toAddress = user.getEmailAddress();
308    
309                    String subject = PrefsPropsUtil.getContent(
310                            membershipRequest.getCompanyId(), subjectProperty);
311    
312                    String body = PrefsPropsUtil.getContent(
313                            membershipRequest.getCompanyId(), bodyProperty);
314    
315                    String statusKey = null;
316    
317                    if (membershipRequest.getStatusId() ==
318                                    MembershipRequestConstants.STATUS_APPROVED) {
319    
320                            statusKey = "approved";
321                    }
322                    else if (membershipRequest.getStatusId() ==
323                                            MembershipRequestConstants.STATUS_DENIED) {
324    
325                            statusKey = "denied";
326                    }
327                    else {
328                            statusKey = "pending";
329                    }
330    
331                    SubscriptionSender subscriptionSender = new SubscriptionSender();
332    
333                    subscriptionSender.setBody(body);
334                    subscriptionSender.setCompanyId(membershipRequest.getCompanyId());
335                    subscriptionSender.setContextAttributes(
336                            "[$COMMENTS$]", membershipRequest.getComments(),
337                            "[$REPLY_COMMENTS$]", membershipRequest.getReplyComments(),
338                            "[$REQUEST_USER_ADDRESS$]", requestUser.getEmailAddress(),
339                            "[$REQUEST_USER_NAME$]", requestUser.getFullName(), "[$STATUS$]",
340                            LanguageUtil.get(user.getLocale(), statusKey), "[$USER_ADDRESS$]",
341                            user.getEmailAddress(), "[$USER_NAME$]", user.getFullName());
342                    subscriptionSender.setFrom(fromAddress, fromName);
343                    subscriptionSender.setHtmlFormat(true);
344                    subscriptionSender.setMailId(
345                            "membership_request", membershipRequest.getMembershipRequestId());
346                    subscriptionSender.setScopeGroupId(membershipRequest.getGroupId());
347                    subscriptionSender.setServiceContext(serviceContext);
348                    subscriptionSender.setSubject(subject);
349    
350                    subscriptionSender.addRuntimeSubscribers(toAddress, toName);
351    
352                    subscriptionSender.flushNotificationsAsync();
353            }
354    
355            protected void notifyGroupAdministrators(
356                            MembershipRequest membershipRequest, ServiceContext serviceContext)
357                    throws PortalException {
358    
359                    List<Long> userIds = getGroupAdministratorUserIds(
360                            membershipRequest.getGroupId());
361    
362                    for (Long userId : userIds) {
363                            notify(
364                                    userId, membershipRequest,
365                                    PropsKeys.SITES_EMAIL_MEMBERSHIP_REQUEST_SUBJECT,
366                                    PropsKeys.SITES_EMAIL_MEMBERSHIP_REQUEST_BODY, serviceContext);
367                    }
368            }
369    
370            protected void validate(String comments) throws PortalException {
371                    if (Validator.isNull(comments) || Validator.isNumber(comments)) {
372                            throw new MembershipRequestCommentsException();
373                    }
374            }
375    
376    }