Comparing/combining PageList objects for negative filtering

Permalink
Hello all

I'm trying to create a page which has a featured news article at the top, and paginated non-featured articles beneath. This is actually pretty difficult if the interface is to avoid repeating the featured article in the non-featured area, and if the client isn't going to have to manually check that only one article is set as is_featured.

What I'd like to do is compare two PageList objects to get a filtered set for the non-featured list of articles. In other words, the first PageList object will filter out just 1 featured article, while the second will filter out all news articles. If I can compare those two PageList object negatively, so the featured article is removed from the second PageList, then I'll have a properly filtered list of non-featured articles.

Unfortunately the PageList model doesn't seem to allow filtering negatively by individual pages (e.g. pagelist->removePageID() or similar) so this isn't a trivial thing to do.

I might be overegging it a bit but I don't want the client to have to keep track of which articles have the featured attribute set and which don't (otherwise we risk them forgetting to unset the attribute on an old featured article, thus hiding them from the non-featured PageList).

Any thoughts?

melat0nin
 
xaritas replied on at Permalink Reply
If you don't mind adding an extra dependency, and you are on PHP 5.3+, take a look at a port of Underscore for PHP (http://brianhaveri.github.com/Underscore.php/). For your case, you can pull back a single page list result, and then use group by to split it based on some predicate.

E.g.,

// the following is pseudo-code and won't work in the real world
$articles = __::groupBy($pageList->get(), function($article) {
  if ($article->isFeatured()) {
    return "featured";
  } else {
    return "listed";
  }  
});
$featuredArticle = $articles["featured"])[0];
$otherArticles = $articles["listed"];


Of course you'll need to supply your own test for isFeatured, presumably with some attribute check. You'll want to check for the empty case too (if nothing has been featured, or there is only one article).

You can also do this with filter, find, reject, difference, etc. depending on your particular requirements. For example this approach could yield two articles in the "featured" group, and my pseudo-code above only selects the first one. So you might need a different approach based on the user interface.
melat0nin replied on at Permalink Reply
melat0nin
Thanks for the reply!

I'm a bit wary of bringing in outside dependencies for this, only because it makes life that bit more complicated. I've looked at combining objects through vanilla PHP (5.3) but haven't had much luck.