Liferay:如何在AssetPublisher Portlet中找到具有特定日志文章的所有版面?

Liferay:如何在AssetPublisher Portlet中找到具有特定日志文章的所有版面?,liferay,Liferay,要求很简单。有人发布了一篇带有一些标签(TagA,TagB)的日志文章。在其他页面(布局)上,我们有AssetPublisher端口,显示所有带有这些标记(例如TagA或TagB)的日志文章。问题是,如何让这个布局程序实用呢?我突然想到了这一点:-) 列出资产发布器布局; 列表布局=LayoutLocalServiceUtil.getLayouts(groupId,privateLayout); 用于(布局:布局) { if(layout.getTypeSettings()包含(“101_实例

要求很简单。有人发布了一篇带有一些标签(TagA,TagB)的日志文章。在其他页面(布局)上,我们有AssetPublisher端口,显示所有带有这些标记(例如TagA或TagB)的日志文章。问题是,如何让这个布局程序实用呢?

我突然想到了这一点:-)


列出资产发布器布局;
列表布局=LayoutLocalServiceUtil.getLayouts(groupId,privateLayout);
用于(布局:布局)
{
if(layout.getTypeSettings()包含(“101_实例”)){
assetPublisherLayouts.add(布局);
}
}


101是Asset publisher的Prolet ID,可实例化

我可以想出两种方法:

  • 使用
    DynamicQuery
    获取包含
    Asset Publisher
    portlet的
    Layouts
    ,然后处理为具有
    Asset Publisher
    TagA
    TagB
    的特定版面检索的
    Layout
    列表
    代码可能是这样的(免责声明:它只是伪代码):-):

    layoutDynamicQuery.add(RestrictionFactoryUtil.ilike(“typeSettings”,“%101\u INSTANCE%”);
    List layoutList=LayoutLocalServiceUtil.dynamicQuery(layoutDynamicQuery);
    List finalLayoutList=newarraylist();
    用于(布局:布局列表){
    //1)获取此布局的PortletID
    //2)获取AssetPublisher portlet实例id的相关PortletPreferences,可以使用PortletPreferencesLocalServiceUtil
    //3)检查检索到的首选项中是否存在标签(TagA和TagB)。
    //4)如果第3点为真,则:finalLayoutList.add(布局);
    }
    
  • 使用
    自定义sql
    在单个复杂sql查询中获取
    布局
    s,方法是连接/子查询所需的表,如
    AssetTags
    Layout
    PortletPreferences
  • 这不是liferay中的一般需求场景,因此很明显,没有直接的方法来实现这一点


    希望这能有所帮助。

    我用递归
    动态查询解决它,享受:

    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; 
    }
    
    publicstaticset getLayoutsWithThisTags(SortedSet标记)引发系统异常,PortalException{
    Set layouts=新的HashSet();
    //构建包含“assetTags”作为“queryName0”的DynamicQuery,请参阅AssetPublisher的配置
    DynamicQuery query=DynamicQueryFactoryUtil.forClass(com.liferay.portal.model.PortletPreferences.class,PortalClassLoaderUtil.getClassLoader())
    .add(PropertyFactoryUtil.forName(“首选项”).like(“%queryName0assetTags%”)
    .add(getTagConditions(tags));
    Set preferences=newhashset(PortletPreferencesLocalServiceUtil.dynamicQuery(查询));
    对于(PortletPreferences PortletPreferences:preferences){
    long plid=portletPreferences.getPlid();
    layouts.add(LayoutLocalServiceUtil.getLayout(plid));
    }
    返回布局;
    }
    专用静态标准getTagConditions(SortedSet标签){
    //创建包含任何标记的递归或条件
    标准=限制FactoryUtil.或(
    PropertyFactoryUtil.forName(“首选项”)。例如(“%queryValues0%”+tags.first()+“%”),
    (tags.size()>2)?获取条件(tail(tags)):
    PropertyFactoryUtil.forName(“首选项”)。例如(“%queryValues0%”+tags.last()+“%”);
    返回准则;
    }
    专用静态分拣集尾部(分拣集标签){
    tags.remove(tags.first());
    返回标签;
    }
    

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

    我只查找配置了特定标记的布局(AssetPublisher),像TagA或TagB一样。我不完全确定这是否可行,因为数据库中没有直接的API访问PortletProperties表,该表存储了诸如为AssetPublisher显示哪些标记之类的信息。您必须查看Liferay源代码,以了解它们如何在内部实现对此表的访问。我认为您可能需要采用
    自定义sql
    的方式来连接/子查询表,如PortletPreferences、Layout、AssetEntry、AssetTags、JournalArticle。这是一次完成,而不是多次循环。哇!递归的创新使用。此代码
    layouts.add(LayoutLocalServiceUtil.getLayout(plid))plid
    s,然后只触发一个查询来获得所有布局来优化code>。但是,对于Oracle,它最多只能接受1000个条目(在
    in子句中)
    。我认为这可以通过使用
    for
    循环而不是递归来实现。但答案很好。谢谢
    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);
    }
    
    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; 
    }