Filtering by current logged in user

Topics: Customizing Orchard
Jan 4 at 4:53 PM
So... I have the following scenario.

Inside Orchard, I have created Sessions, which have participants. Participants are linked to Orchard users and to one or more sessions. I'd like to extend the built in query with a filter that will let the logged in user see the sessions they are assigned to. For example assume I have created a query called my sessions, attached it to a projection and put it on the main menu. I then created session one and session two, and users Bill, Ben and Fred who are also participants. Bill and Ben are assigned to session one, and Bill and Fred to session two.

If Fred or Ben log in and click on the my sessions link, I want them to see the single session they are assigned to, if Bill logs in, I want him to see two sessions.

So... I found this article on Stack Overflow about creating custom filters, which has got me so far along the route, in that I can create my query, then when I try to preview it I discovered I have my filtering wrong.

What I want to do is get the current user ID, then query the sessionparticipantrecord, which contains the session id and the user id, bring back a list of session ids that the user is associated with and use that to get the sessions.

I modified the code in the example linked to above to give me this
  public void ApplyFilter(dynamic context)
    {
        var query = (IHqlQuery)context.Query;

        context.Query = query.ForType("Session")
            .Where(x => x.ContentPartRecord<SessionPartRecord>(), x => x.InG("Id", GetSessionIdsForCurrentUser(context)));
    }

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

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

        var query = (IHqlQuery)context.Query;

        //dynamic item = currentUser.ContentItem;
        //var sessionContentItems = (IEnumerable<ContentItem>)item.User.Sessions.ContentItems;
        int userID = currentUser.Id;
        var sessionContentItems = query.ForType("SessionParticipantRecord")
            .Where(s => s.ContentPartRecord<Orchard.Users.Models.UserPartRecord>(), s => s.Eq("Id", userID))
            .List();

        return sessionContentItems.Select(i => i.Id).ToList();
    }
I can get the current user's ID, what I can't seem to figure out is how to query the session participants to get my list of sessions back. Does anyone have any hints on how to move forward with this?
Jan 5 at 3:47 PM
Fixed it myself. found this by the wonderful Sipke Schoorstra which helped me out.

Short version, if anyone can use the code to help themselves ;)
 public void ApplyFilter(FilterContext context)
    {
        var query = (IHqlQuery)context.Query;
     
        context.Query = context.Query
            .Where(x => x.ContentPartRecord(typeof(SessionPartRecord)),x=>x.InG("Id", GetSessionIdsForCurrentUser()));
    }

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

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

        int userID = currentUser.Id;

        var session = _sessionLocator.For(typeof(SessionPartRecord));

        var sessionQuery = session.CreateQuery(
            "SELECT spr.SessionPartRecord.Id "
                + "FROM Session.Models.SessionParticipantRecord spr "
                + "WHERE spr.UserPartRecord.Id= "
                + userID
             ).List();

        List<int> numList = new List<int>();
        foreach (int item in sessionQuery)
        {
            numList.Add(item);

        }

        return numList;
    }
Probably not the neatest code, it could almost certainly do with a tidy up, but it is working for me, and has proved the point I needed to.