0

要件は簡単です。誰かがいくつかのタグ(TagA、TagB)を含むJournalArticleを公開しています。他のページ(レイアウト)には、それらのタグ(TagAやTagBなど)を持つすべてのJournalArticlesを表示するAssetPublisherポートがあります。問題は、このレイアウトをプログラムで取得する方法です。

4

3 に答える 3

2

私は recursive でそれを解決し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

次の 2 つの方法が考えられます。

  1. ポートレットを含むDynamicQueryフェッチに使用し、 &を持つ特定のレイアウト用に取得したリストを処理します。 コードは次のようになります (免責事項: これは単なる疑似コードです:-) ):LayoutsAsset PublisherLayoutAsset 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をフェッチするために使用します。LayoutAssetTagsLayoutPortletPreferences

これは liferay の一般的な要件シナリオではないため、これを行う直接的な方法がないことは明らかです。

これが何らかの助けになることを願っています。

于 2012-08-17T10:12:35.997 に答える
0

ふと、これが頭に浮かびました:-)


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

101 は Asset Publisher の protlet ID であり、インスタンス化可能です。

于 2012-08-16T13:49:45.663 に答える