Liferay: How to find all Layouts with the specific JournalArticle in AssetPublisher portlets?

泪湿孤枕 提交于 2019-12-25 05:24:26

问题


The requirements is easy. Someone publish a JournalArticle with some Tags (TagA, TagB). On the other pages (Layouts) we have AssetPublisher portles that show all JournalArticles with those Tags (e.g. TagA or TagB). The question is, how to get this layouts programmaticaly?


回答1:


I solve it with recursive DynamicQuery, enjoy:

public static Set<Layout> getLayoutsWithThisTags(SortedSet<String> tags) throws SystemException, PortalException {
    Set<Layout> layouts = new HashSet<Layout>();

    //build DynamicQuery that contains "assetTags" as "queryName0", see configuration of AssetPublisher
    DynamicQuery query = DynamicQueryFactoryUtil.forClass(com.liferay.portal.model.PortletPreferences.class, PortalClassLoaderUtil.getClassLoader())
            .add(PropertyFactoryUtil.forName("preferences").like("%<preference><name>queryName0</name><value>assetTags</value></preference>%"))
            .add(getTagConditions(tags));

    Set<PortletPreferences> preferences = new HashSet<PortletPreferences>(PortletPreferencesLocalServiceUtil.dynamicQuery(query));
    for (PortletPreferences portletPreferences : preferences) {
        long plid = portletPreferences.getPlid();
        layouts.add(LayoutLocalServiceUtil.getLayout(plid));
    }

    return layouts;
}

private static Criterion getTagConditions(SortedSet<String> tags) {
    //create recursive OR-Criterion that contains any of the tags
    Criterion criterion = RestrictionsFactoryUtil.or(
            PropertyFactoryUtil.forName("preferences").like("%<preference><name>queryValues0</name>%<value>" + tags.first() +"</value>%"),
            (tags.size() > 2) ? getTagConditions(tail(tags)) :
                PropertyFactoryUtil.forName("preferences").like("%<preference><name>queryValues0</name>%<value>" + tags.last() +"</value>%"));
    return criterion;
}

private static SortedSet<String> tail(SortedSet<String> tags) {
    tags.remove(tags.first());
    return tags; 
}

for Portal with 250 Pages (Layouts) this code need 12ms.




回答2:


Suddenly this came to my mind :-)


        List assetPublisherLayouts;
        List<Layout> layouts = LayoutLocalServiceUtil.getLayouts(groupId, privateLayout);
        for (Layout layout : layouts)
        {
            if(layout.getTypeSettings().contains("101_INSTANCE")) {
                assetPublisherLayouts.add(layout);
            }
        }

While 101 being the protlet ID for Asset publisher and it is instantiable..




回答3:


I can think of two ways:

  1. Using DynamicQuery to fetch Layouts that contain Asset Publisher portlets and then processing the Layout list retrieved for those specific layouts which have Asset Publisher with TagA & TagB.
    The code might be something like this (disclaimer: it is just pseudo code :-)):

    layoutDynamicQuery.add(RestrictionFactoryUtil.ilike("typeSettings","%101_INSTANCE%"));
    
    List<Layout> layoutList = LayoutLocalServiceUtil.dynamicQuery(layoutDynamicQuery);
    
    List<Layout> finalLayoutList = new ArrayList<Layout>();
    
    for (Layout layout : layoutList) {
        // 1) fetch portletIds for this layout
        // 2) fetch relevant PortletPreferences for the instance-id for the AssetPublisher portlet, can use PortletPreferencesLocalServiceUtil
        // 3) Check if the tags (TagA & TagB) are present in the preference retrieved.
        // 4) if point-3 is true then: finalLayoutList.add(layout);
    }
    
  2. Using custom-sql to fetch the Layouts in a single complex sql query, by joining/subquerying required tables like AssetTags, Layout, PortletPreferences etc.

This is not a general requirement scenario in liferay, so it is obvious that there won't be a direct way of doing this.

Hope this proves to be of some help.



来源:https://stackoverflow.com/questions/11986218/liferay-how-to-find-all-layouts-with-the-specific-journalarticle-in-assetpublis

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!