0

要求很简单。有人发布了带有一些标签(TagA、TagB)的 JournalArticle。在其他页面(布局)上,我们有 AssetPublisher 门户,显示所有带有这些标签(例如 TagA 或 TagB)的 JournalArticles。问题是,如何以编程方式获取此布局?

4

3 回答 3

2

我用递归解决它DynamicQuery,享受:

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; 
}

对于具有 250 个页面(布局)的门户,此代码需要 12 毫秒。

于 2012-08-20T13:31:06.177 回答
0

我突然想到了这个:-)


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

虽然 101 是资产发布者的 protlet ID,但它是可实例化的。

于 2012-08-16T13:49:45.663 回答
0

我可以想到两种方法:

  1. 用于DynamicQuery获取Layouts包含Asset Publisherportlet,然后处理为具有&Layout的特定布局检索到的列表。 代码可能是这样的(免责声明:它只是伪代码:-)):Asset PublisherTagATagB

    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. 用于在单个复杂的 sql 查询中custom-sql获取s,方法是加入/子查询所需的表,如 ,等。LayoutAssetTagsLayoutPortletPreferences

这不是 liferay 中的一般需求场景,因此很明显不会有直接的方法来执行此操作。

希望这被证明会有所帮助。

于 2012-08-17T10:12:35.997 回答