PUBLIC - Liferay Portal Community Edition
  1. PUBLIC - Liferay Portal Community Edition
  2. LPS-29841

Can't create group with Site Templates (LayoutSetPrototype) programmatically

    Details

    • Similar Issues:
      Show 5 results 

      Description

      There is no way (or I couldn't find one) to assign LayoutSetPrototypes when creating a new group: com.liferay.portlet.sites.util.SitesUtil.updateLayoutSetPrototypesLinks is not accessible from a portlet code.

        Activity

        Hide
        Alain Dresse added a comment -

        The following code provides a workaround:

        	//********************************************
        	// LayoutSetPrototype management
        	//
        	// inspired by post by jelmer kuperus in
        	//   http://www.liferay.com/community/forums/-/message_boards/message/10488983
        	//
        	//********************************************
        	
        	/**
        	* Adds a group and load layoutSets from prototypes.
        	* 
        	* Some parameters of the GroupLocalServiceUtil.addGroup are preset:
        	* The creator of the group is set to the admin user
        	* The group created is of entity type Group
        	* The group created is active, has a main site, and is of type Private.
        	*
        	* @param name the entity's name
        	* @param description the group's description (optionally null)
        	* @param friendlyURL the group's friendlyURL (optionally null)
        	* @param publicLayoutSetPrototypeId ID of the LayoutSetPrototype for the public pages
        	* @param privateLayoutSetPrototypeId ID of the LayoutSetPrototype for the private pages 
        	* @param serviceContext the service context to be applied (optionally null).
        	*        Can set asset category IDs and asset tag names for the group, 
        	*        and whether the group is for staging.
        	* @return the group
        	* @throws PortalException if a creator could not be found, if the group's
        	*         information was invalid, if a layout could not be found, or if a
        	*         valid friendly URL could not be created for the group
        	* @throws SystemException if a system exception occurred
        	*/
        	
        	public static Group createGroup(
        			String name, String description, String friendlyURL,
        			long publicLayoutSetPrototypeId, long privateLayoutSetPrototypeId,
        			ServiceContext serviceContext) throws PortalException, SystemException, Exception {
        
        		
        		long userId = serviceContext.getUserId();		
        		Group group = GroupLocalServiceUtil.addGroup(
        				userId, Group.class.getName(), 0,
        				name, description, GroupConstants.TYPE_SITE_PRIVATE, 
        				friendlyURL, true, true,
        				serviceContext);
        		
        		applyLayoutSetPrototypes(group, publicLayoutSetPrototypeId, privateLayoutSetPrototypeId);
        						
        		return group;
        	}
        	
        	
            /**
             * This method applies LayoutSetPrototypes to a newly created group.
             * To do so, it calls the method
             * com.liferay.portlet.sites.util.SitesUtil.updateLayoutSetPrototypesLinks
             * normally unaccessible (it is in portal-impl), but called using 
             * PortalClassInvoker.invoke.
             * 
             * @param group : Group to which you want to add pages
             * @param publicLayoutSetPrototypeId
             * @param privateLayoutSetPrototypeId
             * @throws Exception
             */
            public static void applyLayoutSetPrototypes(
                    Group group, long publicLayoutSetPrototypeId, long privateLayoutSetPrototypeId)
                throws Exception {
        
                MethodKey key = methodKeyFor("updateLayoutSetPrototypesLinks", Group.class, long.class, long.class, boolean.class, boolean.class);
                invokePortalClassMethod(key, group, publicLayoutSetPrototypeId, privateLayoutSetPrototypeId, true, true);
            }
        
            private static MethodKey methodKeyFor(String methodName, Class<?>... parameterTypes) {
                return new MethodKey(DELEGATE_CLASS_NAME, methodName, parameterTypes);
            }
        
            private static Object invokePortalClassMethod(MethodKey key, Object... arguments) throws Exception {
                try {
                    return PortalClassInvoker.invoke(false, key, arguments);
                } catch (PortalException e) {
                    throw e;
                } catch (Exception e) {
                    throw e;
                }
            }
        
            private static final String DELEGATE_CLASS_NAME =
                    "com.liferay.portlet.sites.util.SitesUtil";
        
        
        Show
        Alain Dresse added a comment - The following code provides a workaround: //******************************************** // LayoutSetPrototype management // // inspired by post by jelmer kuperus in // http://www.liferay.com/community/forums/-/message_boards/message/10488983 // //******************************************** /** * Adds a group and load layoutSets from prototypes. * * Some parameters of the GroupLocalServiceUtil.addGroup are preset: * The creator of the group is set to the admin user * The group created is of entity type Group * The group created is active, has a main site, and is of type Private. * * @param name the entity's name * @param description the group's description (optionally null ) * @param friendlyURL the group's friendlyURL (optionally null ) * @param publicLayoutSetPrototypeId ID of the LayoutSetPrototype for the public pages * @param privateLayoutSetPrototypeId ID of the LayoutSetPrototype for the private pages * @param serviceContext the service context to be applied (optionally null ). * Can set asset category IDs and asset tag names for the group, * and whether the group is for staging. * @ return the group * @ throws PortalException if a creator could not be found, if the group's * information was invalid, if a layout could not be found, or if a * valid friendly URL could not be created for the group * @ throws SystemException if a system exception occurred */ public static Group createGroup( String name, String description, String friendlyURL, long publicLayoutSetPrototypeId, long privateLayoutSetPrototypeId, ServiceContext serviceContext) throws PortalException, SystemException, Exception { long userId = serviceContext.getUserId(); Group group = GroupLocalServiceUtil.addGroup( userId, Group.class.getName(), 0, name, description, GroupConstants.TYPE_SITE_PRIVATE, friendlyURL, true , true , serviceContext); applyLayoutSetPrototypes(group, publicLayoutSetPrototypeId, privateLayoutSetPrototypeId); return group; } /** * This method applies LayoutSetPrototypes to a newly created group. * To do so, it calls the method * com.liferay.portlet.sites.util.SitesUtil.updateLayoutSetPrototypesLinks * normally unaccessible (it is in portal-impl), but called using * PortalClassInvoker.invoke. * * @param group : Group to which you want to add pages * @param publicLayoutSetPrototypeId * @param privateLayoutSetPrototypeId * @ throws Exception */ public static void applyLayoutSetPrototypes( Group group, long publicLayoutSetPrototypeId, long privateLayoutSetPrototypeId) throws Exception { MethodKey key = methodKeyFor( "updateLayoutSetPrototypesLinks" , Group.class, long .class, long .class, boolean .class, boolean .class); invokePortalClassMethod(key, group, publicLayoutSetPrototypeId, privateLayoutSetPrototypeId, true , true ); } private static MethodKey methodKeyFor( String methodName, Class <?>... parameterTypes) { return new MethodKey(DELEGATE_CLASS_NAME, methodName, parameterTypes); } private static Object invokePortalClassMethod(MethodKey key, Object ... arguments) throws Exception { try { return PortalClassInvoker.invoke( false , key, arguments); } catch (PortalException e) { throw e; } catch (Exception e) { throw e; } } private static final String DELEGATE_CLASS_NAME = "com.liferay.portlet.sites.util.SitesUtil" ;
        Hide
        Alain Dresse added a comment -

        The workaround proposed works for admin users, but not for other users.
        To solve this, the following bug needs to be fixed in portal-impl/src/com/liferay/portlet/sites/util/SitesUtil.java

        diff --git a/portal-impl/src/com/liferay/portlet/sites/util/SitesUtil.java b/portal-impl/src/com/liferay/portlet/sites/util/SitesUtil.java
        index 0a1603c..cc03940 100644
        --- a/portal-impl/src/com/liferay/portlet/sites/util/SitesUtil.java
        +++ b/portal-impl/src/com/liferay/portlet/sites/util/SitesUtil.java
        @@ -1299,7 +1299,7 @@ public class SitesUtil {
                                }
                        }
         
        -               LayoutSetServiceUtil.updateLayoutSetPrototypeLinkEnabled(
        +               LayoutSetLocalServiceUtil.updateLayoutSetPrototypeLinkEnabled(
                                groupId, privateLayout, layoutSetPrototypeLinkEnabled,
                                layoutSetPrototypeUuid);
        
        Show
        Alain Dresse added a comment - The workaround proposed works for admin users, but not for other users. To solve this, the following bug needs to be fixed in portal-impl/src/com/liferay/portlet/sites/util/SitesUtil.java diff --git a/portal-impl/src/com/liferay/portlet/sites/util/SitesUtil.java b/portal-impl/src/com/liferay/portlet/sites/util/SitesUtil.java index 0a1603c..cc03940 100644 --- a/portal-impl/src/com/liferay/portlet/sites/util/SitesUtil.java +++ b/portal-impl/src/com/liferay/portlet/sites/util/SitesUtil.java @@ -1299,7 +1299,7 @@ public class SitesUtil { } } - LayoutSetServiceUtil.updateLayoutSetPrototypeLinkEnabled( + LayoutSetLocalServiceUtil.updateLayoutSetPrototypeLinkEnabled( groupId, privateLayout, layoutSetPrototypeLinkEnabled, layoutSetPrototypeUuid);
        Hide
        Alain Dresse added a comment -

        My mistake - 6.1.1 introduced new arguments in LayoutSetLocalServiceUtil.updateLayoutSetPrototypeLinkEnabled to assign a LayoutSetPrototype.

        The issues in SitesUtil
        replace LayoutSetServiceUtil.updateLayoutSetPrototypeLinkEnabled
        by LayoutSetLocalServiceUtil.updateLayoutSetPrototypeLinkEnabled

        is probably still valid but minor.

        Show
        Alain Dresse added a comment - My mistake - 6.1.1 introduced new arguments in LayoutSetLocalServiceUtil.updateLayoutSetPrototypeLinkEnabled to assign a LayoutSetPrototype. The issues in SitesUtil replace LayoutSetServiceUtil.updateLayoutSetPrototypeLinkEnabled by LayoutSetLocalServiceUtil.updateLayoutSetPrototypeLinkEnabled is probably still valid but minor.
        Hide
        ASI added a comment -

        More easy way, without modify Liferay core is to set a PermissionChecker with admin user... Like this :

        User admin = UserLocalServiceUtil.getUserByScreenName(companyId, PropsUtil.get("default.admin.screen.name"));
        PermissionThreadLocal.setPermissionChecker(PermissionCheckerFactoryUtil.create(admin));

        Lets make magic

        Show
        ASI added a comment - More easy way, without modify Liferay core is to set a PermissionChecker with admin user... Like this : User admin = UserLocalServiceUtil.getUserByScreenName(companyId, PropsUtil.get("default.admin.screen.name")); PermissionThreadLocal.setPermissionChecker(PermissionCheckerFactoryUtil.create(admin)); Lets make magic
        Hide
        Mika Koivisto added a comment -

        Take a look at resource-importer-web plugin. It creates Site templates using the API from a plugin.

        Show
        Mika Koivisto added a comment - Take a look at resource-importer-web plugin. It creates Site templates using the API from a plugin.
        Hide
        Alain Dresse added a comment -

        Mika,

        Thank you for looking into this. I have a couple comments / questions :

        The question is not to create a site template, but to assign a site template to a group.

        Could you please be a bit more specific on the code you are referring to ? I can't find a resource-importer-web reference.

        What about the permission checking in SitesUtil (call to LayoutSetServiceUtil.updateLayoutSetPrototypeLinkEnabled instead of LayoutSetLocalServiceUtil.updateLayoutSetPrototypeLinkEnabled) ?

        Best regards,
        Alain

        Show
        Alain Dresse added a comment - Mika, Thank you for looking into this. I have a couple comments / questions : The question is not to create a site template, but to assign a site template to a group. Could you please be a bit more specific on the code you are referring to ? I can't find a resource-importer-web reference. What about the permission checking in SitesUtil (call to LayoutSetServiceUtil.updateLayoutSetPrototypeLinkEnabled instead of LayoutSetLocalServiceUtil.updateLayoutSetPrototypeLinkEnabled) ? Best regards, Alain
        Hide
        Mika Koivisto added a comment -

        Resource importer is a plugin https://github.com/liferay/liferay-plugins/tree/6.1.1-ga2/webs/resources-importer-web.

        LayoutSet has two columns layoutSetPrototypeUuid and layoutSetPrototypeLinkEnabled that denote what was the prototype used and if the link is enabled. If you use LayoutSetLocalServiceUtil you can by pass the permission checking. It depends on your usecase whether you want to check permissions or not.

        Show
        Mika Koivisto added a comment - Resource importer is a plugin https://github.com/liferay/liferay-plugins/tree/6.1.1-ga2/webs/resources-importer-web . LayoutSet has two columns layoutSetPrototypeUuid and layoutSetPrototypeLinkEnabled that denote what was the prototype used and if the link is enabled. If you use LayoutSetLocalServiceUtil you can by pass the permission checking. It depends on your usecase whether you want to check permissions or not.
        Hide
        Alain Dresse added a comment -

        Thnaks for the info Mika.

        Show
        Alain Dresse added a comment - Thnaks for the info Mika.

          People

          • Votes:
            0 Vote for this issue
            Watchers:
            3 Start watching this issue

            Dates

            • Created:
              Updated:
              Resolved:
              Days since last comment:
              2 years, 17 weeks, 1 day ago

              Development

                Structure Helper Panel