001    /**
002     * Copyright (c) 2000-2013 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.portlet.sites.action;
016    
017    import com.liferay.portal.DuplicateGroupException;
018    import com.liferay.portal.GroupFriendlyURLException;
019    import com.liferay.portal.GroupNameException;
020    import com.liferay.portal.LayoutSetVirtualHostException;
021    import com.liferay.portal.LocaleException;
022    import com.liferay.portal.NoSuchGroupException;
023    import com.liferay.portal.NoSuchLayoutException;
024    import com.liferay.portal.RemoteExportException;
025    import com.liferay.portal.RemoteOptionsException;
026    import com.liferay.portal.RequiredGroupException;
027    import com.liferay.portal.kernel.dao.orm.QueryUtil;
028    import com.liferay.portal.kernel.exception.PortalException;
029    import com.liferay.portal.kernel.exception.SystemException;
030    import com.liferay.portal.kernel.servlet.SessionErrors;
031    import com.liferay.portal.kernel.staging.StagingUtil;
032    import com.liferay.portal.kernel.util.Constants;
033    import com.liferay.portal.kernel.util.GetterUtil;
034    import com.liferay.portal.kernel.util.HttpUtil;
035    import com.liferay.portal.kernel.util.ParamUtil;
036    import com.liferay.portal.kernel.util.UnicodeProperties;
037    import com.liferay.portal.kernel.util.Validator;
038    import com.liferay.portal.liveusers.LiveUsers;
039    import com.liferay.portal.model.Group;
040    import com.liferay.portal.model.GroupConstants;
041    import com.liferay.portal.model.Layout;
042    import com.liferay.portal.model.LayoutConstants;
043    import com.liferay.portal.model.LayoutSet;
044    import com.liferay.portal.model.MembershipRequest;
045    import com.liferay.portal.model.MembershipRequestConstants;
046    import com.liferay.portal.security.auth.PrincipalException;
047    import com.liferay.portal.service.GroupLocalServiceUtil;
048    import com.liferay.portal.service.GroupServiceUtil;
049    import com.liferay.portal.service.LayoutLocalServiceUtil;
050    import com.liferay.portal.service.LayoutSetServiceUtil;
051    import com.liferay.portal.service.MembershipRequestLocalServiceUtil;
052    import com.liferay.portal.service.MembershipRequestServiceUtil;
053    import com.liferay.portal.service.ServiceContext;
054    import com.liferay.portal.service.ServiceContextFactory;
055    import com.liferay.portal.struts.PortletAction;
056    import com.liferay.portal.theme.ThemeDisplay;
057    import com.liferay.portal.util.PortalUtil;
058    import com.liferay.portal.util.WebKeys;
059    import com.liferay.portlet.asset.AssetCategoryException;
060    import com.liferay.portlet.asset.AssetTagException;
061    import com.liferay.portlet.sites.util.SitesUtil;
062    
063    import java.util.List;
064    
065    import javax.portlet.ActionRequest;
066    import javax.portlet.ActionResponse;
067    import javax.portlet.PortletConfig;
068    import javax.portlet.RenderRequest;
069    import javax.portlet.RenderResponse;
070    
071    import org.apache.struts.action.ActionForm;
072    import org.apache.struts.action.ActionForward;
073    import org.apache.struts.action.ActionMapping;
074    
075    /**
076     * @author Brian Wing Shun Chan
077     * @author Zsolt Berentey
078     */
079    public class EditGroupAction extends PortletAction {
080    
081            @Override
082            public void processAction(
083                            ActionMapping actionMapping, ActionForm actionForm,
084                            PortletConfig portletConfig, ActionRequest actionRequest,
085                            ActionResponse actionResponse)
086                    throws Exception {
087    
088                    ThemeDisplay themeDisplay = (ThemeDisplay)actionRequest.getAttribute(
089                            WebKeys.THEME_DISPLAY);
090    
091                    String cmd = ParamUtil.getString(actionRequest, Constants.CMD);
092    
093                    String redirect = ParamUtil.getString(actionRequest, "redirect");
094                    String closeRedirect = ParamUtil.getString(
095                            actionRequest, "closeRedirect");
096    
097                    try {
098                            if (cmd.equals(Constants.ADD) || cmd.equals(Constants.UPDATE)) {
099                                    Object[] returnValue = updateGroup(actionRequest);
100    
101                                    Group group = (Group)returnValue[0];
102                                    String oldFriendlyURL = (String)returnValue[1];
103                                    String oldStagingFriendlyURL = (String)returnValue[2];
104                                    long newRefererPlid = (Long)returnValue[3];
105    
106                                    redirect = HttpUtil.setParameter(
107                                            redirect, "doAsGroupId", group.getGroupId());
108                                    redirect = HttpUtil.setParameter(
109                                            redirect, "refererPlid", newRefererPlid);
110    
111                                    closeRedirect = updateCloseRedirect(
112                                            closeRedirect, group, themeDisplay, oldFriendlyURL,
113                                            oldStagingFriendlyURL);
114                            }
115                            else if (cmd.equals(Constants.DEACTIVATE) ||
116                                             cmd.equals(Constants.RESTORE)) {
117    
118                                    updateActive(actionRequest, cmd);
119                            }
120                            else if (cmd.equals(Constants.DELETE)) {
121                                    deleteGroup(actionRequest);
122                            }
123    
124                            sendRedirect(
125                                    portletConfig, actionRequest, actionResponse, redirect,
126                                    closeRedirect);
127                    }
128                    catch (Exception e) {
129                            if (e instanceof NoSuchGroupException ||
130                                    e instanceof PrincipalException) {
131    
132                                    SessionErrors.add(actionRequest, e.getClass());
133    
134                                    setForward(actionRequest, "portlet.sites_admin.error");
135                            }
136                            else if (e instanceof AssetCategoryException ||
137                                             e instanceof AssetTagException ||
138                                             e instanceof DuplicateGroupException ||
139                                             e instanceof GroupFriendlyURLException ||
140                                             e instanceof GroupNameException ||
141                                             e instanceof LayoutSetVirtualHostException ||
142                                             e instanceof LocaleException ||
143                                             e instanceof RemoteExportException ||
144                                             e instanceof RemoteOptionsException ||
145                                             e instanceof RequiredGroupException ||
146                                             e instanceof SystemException) {
147    
148                                    SessionErrors.add(actionRequest, e.getClass(), e);
149    
150                                    sendRedirect(
151                                            portletConfig, actionRequest, actionResponse, redirect,
152                                            closeRedirect);
153                            }
154                            else {
155                                    throw e;
156                            }
157                    }
158            }
159    
160            @Override
161            public ActionForward render(
162                            ActionMapping actionMapping, ActionForm actionForm,
163                            PortletConfig portletConfig, RenderRequest renderRequest,
164                            RenderResponse renderResponse)
165                    throws Exception {
166    
167                    try {
168                            ActionUtil.getGroup(renderRequest);
169                    }
170                    catch (Exception e) {
171                            if (e instanceof NoSuchGroupException ||
172                                    e instanceof PrincipalException) {
173    
174                                    SessionErrors.add(renderRequest, e.getClass());
175    
176                                    return actionMapping.findForward("portlet.sites_admin.error");
177                            }
178                            else {
179                                    throw e;
180                            }
181                    }
182    
183                    return actionMapping.findForward(
184                            getForward(renderRequest, "portlet.sites_admin.edit_site"));
185            }
186    
187            protected void deleteGroup(ActionRequest actionRequest) throws Exception {
188                    ThemeDisplay themeDisplay = (ThemeDisplay)actionRequest.getAttribute(
189                            WebKeys.THEME_DISPLAY);
190    
191                    long groupId = ParamUtil.getLong(actionRequest, "groupId");
192    
193                    GroupServiceUtil.deleteGroup(groupId);
194    
195                    LiveUsers.deleteGroup(themeDisplay.getCompanyId(), groupId);
196            }
197    
198            protected long getRefererGroupId(ThemeDisplay themeDisplay)
199                    throws Exception {
200    
201                    long refererGroupId = 0;
202    
203                    try {
204                            Layout refererLayout = LayoutLocalServiceUtil.getLayout(
205                                    themeDisplay.getRefererPlid());
206    
207                            refererGroupId = refererLayout.getGroupId();
208                    }
209                    catch (NoSuchLayoutException nsle) {
210                    }
211    
212                    return refererGroupId;
213            }
214    
215            protected void updateActive(ActionRequest actionRequest, String cmd)
216                    throws Exception {
217    
218                    ThemeDisplay themeDisplay = (ThemeDisplay)actionRequest.getAttribute(
219                            WebKeys.THEME_DISPLAY);
220    
221                    long groupId = ParamUtil.getLong(actionRequest, "groupId");
222    
223                    if ((groupId == themeDisplay.getDoAsGroupId()) ||
224                            (groupId == themeDisplay.getScopeGroupId()) ||
225                            (groupId == getRefererGroupId(themeDisplay))) {
226    
227                            throw new RequiredGroupException(String.valueOf(groupId));
228                    }
229    
230                    Group group = GroupServiceUtil.getGroup(groupId);
231    
232                    boolean active = false;
233    
234                    if (cmd.equals(Constants.RESTORE)) {
235                            active = true;
236                    }
237    
238                    ServiceContext serviceContext = ServiceContextFactory.getInstance(
239                            Group.class.getName(), actionRequest);
240    
241                    GroupServiceUtil.updateGroup(
242                            groupId, group.getName(), group.getDescription(), group.getType(),
243                            group.getFriendlyURL(), active, serviceContext);
244            }
245    
246            protected String updateCloseRedirect(
247                            String closeRedirect, Group group, ThemeDisplay themeDisplay,
248                            String oldFriendlyURL, String oldStagingFriendlyURL)
249                    throws PortalException, SystemException {
250    
251                    if (Validator.isNull(closeRedirect) || (group == null)) {
252                            return closeRedirect;
253                    }
254    
255                    String oldPath = null;
256                    String newPath = null;
257    
258                    if (Validator.isNotNull(oldFriendlyURL)) {
259                            oldPath = oldFriendlyURL;
260                            newPath = group.getFriendlyURL();
261    
262                            if (closeRedirect.contains(oldPath)) {
263                                    closeRedirect = PortalUtil.updateRedirect(
264                                            closeRedirect, oldPath, newPath);
265                            }
266                            else {
267                                    closeRedirect = PortalUtil.getGroupFriendlyURL(
268                                            group, false, themeDisplay);
269                            }
270                    }
271    
272                    if (Validator.isNotNull(oldStagingFriendlyURL)) {
273                            Group stagingGroup = group.getStagingGroup();
274    
275                            if (GroupLocalServiceUtil.fetchGroup(
276                                            stagingGroup.getGroupId()) == null) {
277    
278                                    oldPath = oldStagingFriendlyURL;
279                                    newPath = group.getFriendlyURL();
280                            }
281                            else {
282                                    oldPath = oldStagingFriendlyURL;
283                                    newPath = stagingGroup.getFriendlyURL();
284                            }
285    
286                            if (closeRedirect.contains(oldPath)) {
287                                    closeRedirect = PortalUtil.updateRedirect(
288                                            closeRedirect, oldPath, newPath);
289                            }
290                            else {
291                                    closeRedirect = PortalUtil.getGroupFriendlyURL(
292                                            group, false, themeDisplay);
293                            }
294                    }
295    
296                    return closeRedirect;
297            }
298    
299            protected Object[] updateGroup(ActionRequest actionRequest)
300                    throws Exception {
301    
302                    ThemeDisplay themeDisplay = (ThemeDisplay)actionRequest.getAttribute(
303                            WebKeys.THEME_DISPLAY);
304    
305                    long userId = PortalUtil.getUserId(actionRequest);
306    
307                    long liveGroupId = ParamUtil.getLong(actionRequest, "liveGroupId");
308    
309                    boolean active;
310                    String description = null;
311                    String friendlyURL = null;
312                    String name = null;
313                    int type;
314    
315                    ServiceContext serviceContext = ServiceContextFactory.getInstance(
316                            Group.class.getName(), actionRequest);
317    
318                    Group liveGroup = null;
319                    String oldFriendlyURL = null;
320                    String oldStagingFriendlyURL = null;
321    
322                    if (liveGroupId <= 0) {
323    
324                            // Add group
325    
326                            name = ParamUtil.getString(actionRequest, "name");
327                            description = ParamUtil.getString(actionRequest, "description");
328                            type = ParamUtil.getInteger(actionRequest, "type");
329                            friendlyURL = ParamUtil.getString(actionRequest, "friendlyURL");
330                            active = ParamUtil.getBoolean(actionRequest, "active");
331    
332                            liveGroup = GroupServiceUtil.addGroup(
333                                    name, description, type, friendlyURL, true, active,
334                                    serviceContext);
335    
336                            LiveUsers.joinGroup(
337                                    themeDisplay.getCompanyId(), liveGroup.getGroupId(), userId);
338                    }
339                    else {
340    
341                            // Update group
342    
343                            liveGroup = GroupLocalServiceUtil.getGroup(liveGroupId);
344    
345                            oldFriendlyURL = liveGroup.getFriendlyURL();
346    
347                            name = ParamUtil.getString(
348                                    actionRequest, "name", liveGroup.getName());
349                            description = ParamUtil.getString(
350                                    actionRequest, "description", liveGroup.getDescription());
351                            type = ParamUtil.getInteger(
352                                    actionRequest, "type", liveGroup.getType());
353                            friendlyURL = ParamUtil.getString(
354                                    actionRequest, "friendlyURL", liveGroup.getFriendlyURL());
355                            active = ParamUtil.getBoolean(
356                                    actionRequest, "active", liveGroup.getActive());
357    
358                            liveGroup = GroupServiceUtil.updateGroup(
359                                    liveGroupId, name, description, type, friendlyURL, active,
360                                    serviceContext);
361    
362                            if (type == GroupConstants.TYPE_SITE_OPEN) {
363                                    List<MembershipRequest> membershipRequests =
364                                            MembershipRequestLocalServiceUtil.search(
365                                                    liveGroupId, MembershipRequestConstants.STATUS_PENDING,
366                                                    QueryUtil.ALL_POS, QueryUtil.ALL_POS);
367    
368                                    for (MembershipRequest membershipRequest : membershipRequests) {
369                                            MembershipRequestServiceUtil.updateStatus(
370                                                    membershipRequest.getMembershipRequestId(),
371                                                    themeDisplay.translate(
372                                                            "your-membership-has-been-approved"),
373                                                    MembershipRequestConstants.STATUS_APPROVED,
374                                                    serviceContext);
375    
376                                            LiveUsers.joinGroup(
377                                                    themeDisplay.getCompanyId(),
378                                                    membershipRequest.getGroupId(),
379                                                    new long[] {membershipRequest.getUserId()});
380                                    }
381                            }
382                    }
383    
384                    // Settings
385    
386                    UnicodeProperties typeSettingsProperties =
387                            liveGroup.getTypeSettingsProperties();
388    
389                    String customJspServletContextName = ParamUtil.getString(
390                            actionRequest, "customJspServletContextName",
391                            typeSettingsProperties.getProperty("customJspServletContextName"));
392    
393                    typeSettingsProperties.setProperty(
394                            "customJspServletContextName", customJspServletContextName);
395    
396                    String googleAnalyticsId = ParamUtil.getString(
397                            actionRequest, "googleAnalyticsId",
398                            typeSettingsProperties.getProperty("googleAnalyticsId"));
399    
400                    typeSettingsProperties.setProperty(
401                            "googleAnalyticsId", googleAnalyticsId);
402    
403                    String publicRobots = ParamUtil.getString(
404                            actionRequest, "publicRobots",
405                            liveGroup.getTypeSettingsProperty("false-robots.txt"));
406                    String privateRobots = ParamUtil.getString(
407                            actionRequest, "privateRobots",
408                            liveGroup.getTypeSettingsProperty("true-robots.txt"));
409    
410                    typeSettingsProperties.setProperty("false-robots.txt", publicRobots);
411                    typeSettingsProperties.setProperty("true-robots.txt", privateRobots);
412    
413                    // Virtual hosts
414    
415                    LayoutSet publicLayoutSet = liveGroup.getPublicLayoutSet();
416    
417                    String publicVirtualHost = ParamUtil.getString(
418                            actionRequest, "publicVirtualHost",
419                            publicLayoutSet.getVirtualHostname());
420    
421                    LayoutSetServiceUtil.updateVirtualHost(
422                            liveGroup.getGroupId(), false, publicVirtualHost);
423    
424                    LayoutSet privateLayoutSet = liveGroup.getPrivateLayoutSet();
425    
426                    String privateVirtualHost = ParamUtil.getString(
427                            actionRequest, "privateVirtualHost",
428                            privateLayoutSet.getVirtualHostname());
429    
430                    LayoutSetServiceUtil.updateVirtualHost(
431                            liveGroup.getGroupId(), true, privateVirtualHost);
432    
433                    // Staging
434    
435                    if (liveGroup.hasStagingGroup()) {
436                            Group stagingGroup = liveGroup.getStagingGroup();
437    
438                            oldStagingFriendlyURL = stagingGroup.getFriendlyURL();
439    
440                            friendlyURL = ParamUtil.getString(
441                                    actionRequest, "stagingFriendlyURL",
442                                    stagingGroup.getFriendlyURL());
443    
444                            GroupServiceUtil.updateFriendlyURL(
445                                    stagingGroup.getGroupId(), friendlyURL);
446    
447                            LayoutSet stagingPublicLayoutSet =
448                                    stagingGroup.getPublicLayoutSet();
449    
450                            publicVirtualHost = ParamUtil.getString(
451                                    actionRequest, "stagingPublicVirtualHost",
452                                    stagingPublicLayoutSet.getVirtualHostname());
453    
454                            LayoutSetServiceUtil.updateVirtualHost(
455                                    stagingGroup.getGroupId(), false, publicVirtualHost);
456    
457                            LayoutSet stagingPrivateLayoutSet =
458                                    stagingGroup.getPrivateLayoutSet();
459    
460                            privateVirtualHost = ParamUtil.getString(
461                                    actionRequest, "stagingPrivateVirtualHost",
462                                    stagingPrivateLayoutSet.getVirtualHostname());
463    
464                            LayoutSetServiceUtil.updateVirtualHost(
465                                    stagingGroup.getGroupId(), true, privateVirtualHost);
466                    }
467    
468                    liveGroup = GroupServiceUtil.updateGroup(
469                            liveGroup.getGroupId(), typeSettingsProperties.toString());
470    
471                    // Layout set prototypes
472    
473                    if (!liveGroup.isStaged()) {
474                            long privateLayoutSetPrototypeId = ParamUtil.getLong(
475                                    actionRequest, "privateLayoutSetPrototypeId");
476                            long publicLayoutSetPrototypeId = ParamUtil.getLong(
477                                    actionRequest, "publicLayoutSetPrototypeId");
478    
479                            boolean privateLayoutSetPrototypeLinkEnabled = ParamUtil.getBoolean(
480                                    actionRequest, "privateLayoutSetPrototypeLinkEnabled",
481                                    privateLayoutSet.isLayoutSetPrototypeLinkEnabled());
482                            boolean publicLayoutSetPrototypeLinkEnabled = ParamUtil.getBoolean(
483                                    actionRequest, "publicLayoutSetPrototypeLinkEnabled",
484                                    publicLayoutSet.isLayoutSetPrototypeLinkEnabled());
485    
486                            if ((privateLayoutSetPrototypeId == 0) &&
487                                    (publicLayoutSetPrototypeId == 0) &&
488                                    !privateLayoutSetPrototypeLinkEnabled &&
489                                    !publicLayoutSetPrototypeLinkEnabled) {
490    
491                                    long layoutSetPrototypeId = ParamUtil.getLong(
492                                            actionRequest, "layoutSetPrototypeId");
493                                    int layoutSetVisibility = ParamUtil.getInteger(
494                                            actionRequest, "layoutSetVisibility");
495                                    boolean layoutSetPrototypeLinkEnabled = ParamUtil.getBoolean(
496                                            actionRequest, "layoutSetPrototypeLinkEnabled",
497                                            (layoutSetPrototypeId > 0));
498    
499                                    if (layoutSetVisibility == _LAYOUT_SET_VISIBILITY_PRIVATE) {
500                                            privateLayoutSetPrototypeId = layoutSetPrototypeId;
501    
502                                            privateLayoutSetPrototypeLinkEnabled =
503                                                    layoutSetPrototypeLinkEnabled;
504                                    }
505                                    else {
506                                            publicLayoutSetPrototypeId = layoutSetPrototypeId;
507    
508                                            publicLayoutSetPrototypeLinkEnabled =
509                                                    layoutSetPrototypeLinkEnabled;
510                                    }
511                            }
512    
513                            SitesUtil.updateLayoutSetPrototypesLinks(
514                                    liveGroup, publicLayoutSetPrototypeId,
515                                    privateLayoutSetPrototypeId,
516                                    publicLayoutSetPrototypeLinkEnabled,
517                                    privateLayoutSetPrototypeLinkEnabled);
518                    }
519    
520                    // Staging
521    
522                    String redirect = ParamUtil.getString(actionRequest, "redirect");
523    
524                    long refererPlid = GetterUtil.getLong(
525                            HttpUtil.getParameter(redirect, "refererPlid", false));
526    
527                    if (!privateLayoutSet.isLayoutSetPrototypeLinkActive() &&
528                            !publicLayoutSet.isLayoutSetPrototypeLinkActive()) {
529    
530                            if ((refererPlid > 0) && liveGroup.hasStagingGroup() &&
531                                    (themeDisplay.getScopeGroupId() != liveGroup.getGroupId())) {
532    
533                                    Layout firstLayout = LayoutLocalServiceUtil.fetchFirstLayout(
534                                            liveGroup.getGroupId(), false,
535                                            LayoutConstants.DEFAULT_PARENT_LAYOUT_ID);
536    
537                                    if (firstLayout == null) {
538                                            firstLayout = LayoutLocalServiceUtil.fetchFirstLayout(
539                                                    liveGroup.getGroupId(), true,
540                                                    LayoutConstants.DEFAULT_PARENT_LAYOUT_ID);
541                                    }
542    
543                                    if (firstLayout != null) {
544                                            refererPlid = firstLayout.getPlid();
545                                    }
546                                    else {
547                                            refererPlid = 0;
548                                    }
549                            }
550    
551                            StagingUtil.updateStaging(actionRequest, liveGroup);
552                    }
553    
554                    return new Object[] {
555                            liveGroup, oldFriendlyURL, oldStagingFriendlyURL, refererPlid};
556            }
557    
558            private static final int _LAYOUT_SET_VISIBILITY_PRIVATE = 1;
559    
560    }