在Orchard中,如何根据当前用户的内容选择器字段进行查询?

时间:2014-11-21 11:35:16

标签: orchardcms

我已使用内容搜索器字段扩展了内置User ContentType ,可用于选择多个Video ContentItems 。这为我提供了每个User的编辑页面上的视频多选择器控件。

Multi Picker on User Edit screen

我喜欢Orchard CMS如此简单易用的设置。

既然我可以将多个VideosUser相关联,我想创建一个查询,它只显示当前的Videos登录User已被授予访问权限。

我希望能够使用Projector模块设置查询,我认为这是显而易见的方式(见下文),但这不会返回任何结果。

Query definition

这是我配置第二个过滤器的方式:

  1. 点击“编辑查询”屏幕上的+ Add a new Filter链接
  2. Videos:Ids部分选择User Content Fields,如下所示:
    Videos:Ids filter option

  3. 配置新的过滤器如下:
    Filter settings

  4. 我做错了什么,或者诊断这个问题最简单的方法是什么?

    这是内容选择器字段的定义方式:

    Content Picker Field definition

1 个答案:

答案 0 :(得分:0)

我发现了我的错误 - 这是因为我没有正确理解过滤器的工作原理。正如我所假设的,Videos:Ids部分中的User Content Fields过滤器无法访问当前用户的视频列表。相反,它提供了在过滤器中使用的字段,如果我要编写查询以生成可以访问特定视频的Users列表,这将非常有用。

一厢情愿地认为它按照我想要的方式工作,但回想起来它显然是如何运作的。

更新:希望它对其他人有用,这是我开发的自定义过滤器:

public interface IFilterProvider : IEventHandler
{
    void Describe(dynamic describe);
}

public class CurrentUserVideosFilter : IFilterProvider
{
    private readonly IWorkContextAccessor _workContextAccessor;

    public CurrentUserVideosFilter(IWorkContextAccessor workContextAccessor)
    {
        _workContextAccessor = workContextAccessor;
        T = NullLocalizer.Instance;
    }

    public Localizer T { get; set; }

    public void Describe(dynamic describe)
    {
        describe.For("My Filter Category", T("My Filter Category"), T("My Filter Category"))
            .Element("Current User's Videos", T("Current User's Videos"), T("Current User's Videos"),
                (Action<dynamic>)ApplyFilter,
                (Func<dynamic, LocalizedString>)DisplayFilter,
                null
            );
    }

    public void ApplyFilter(dynamic context)
    {
        var query = (IHqlQuery)context.Query;

        context.Query = query.ForType("Video")
            .Where(x => x.ContentPartRecord<IdentityPartRecord>(), x => x.InG("Id", GetVideoIdsForCurrentUser()));
    }

    private IList<int> GetVideoIdsForCurrentUser()
    {
        var currentUser = _workContextAccessor.GetContext().CurrentUser;

        if (currentUser == null) return new int[0];

        dynamic item = currentUser.ContentItem;
        var videoContentItems = (IEnumerable<ContentItem>)item.User.Videos.ContentItems;

        return videoContentItems.Select(i => i.Id).ToList();
    }

    public LocalizedString DisplayFilter(dynamic context)
    {
        return T("Videos that have been assigned to the currently logged in user");
    }
}

我在一个新的Orchard模块中创建了这个类,它包含了我正在构建的站点的所有自定义。安装模块后,过滤器立即可用。我假设Orchard使用反射来寻找实现IFilterProvider接口的所有类型。

这是过滤器在Add a Filter屏幕上的显示方式:

Custom filter as it appears on the "Add a Filter" screen

点击过滤器会显示以下屏幕:

Edit details of the custom filter

保存过滤器后,查询就会完全符合我的要求 - 它会显示已分配给当前登录用户的所有视频。