Filtering Page List Block with Multiple Filters

Permalink
I have a custom template to style a Page List Block in a slider. It works great.

Now, I'm trying to display "Event" page types (from the Calendar Events Add-on) that are:
* Featured (custom page attribute)
* Event End Date (page attribute from add-on) >= Today
* Public Date <= Today (page property)

I started by handling this in a custom template "view.php" file, then realized that doesn't work because the display count would be off, etc.

So, my question is,
1) How do I filter with multiple filters, and
2) do I do this in the /blocks/page_list/templates/TEMPLATE_NAME/controller.php file?

I've been racking my brain to headache mode for a few days on this.

Deladroid
 
rge replied on at Permalink Reply
Hi,

As far as I know the filters are by default "AND" statements. So you can call the filter multiple times it will be an AND statement. Personally I would do it from the controller since I had some issues with caching when I hardcoded it in a page.

$pl->filterByAttribute('attr_name');
$pl->filterByAttribute('attr_name');


You can also use
/***
 * comment from the core:
 * Like filterByAttribute(), but wraps values properly for "select" type attributes.
 * Accepts either a single value, or an array of values.
 * If an array of values is provided, they will be combined together with "OR".
 * (If you need to do an "AND" filter on mulitple values, just call this function multiple times).
 */
$pl->filterBySelectAttribute('attr_name', 'value');
Deladroid replied on at Permalink Reply
Deladroid
Thanks rge, I will try this.
Deladroid replied on at Permalink Reply
Deladroid
I'm having the hardest time. I am confusing myself big-time, and I think it's because there is no direct solutions talked about for filtering on the public date on the web.

I copied the getPageList() function to a copied over controller.php file in my page list template, but it's not filtering out future page lists.

<?php
   defined('C5_EXECUTE') or die("Access Denied.");
   class PageListBlockController extends Concrete5_Controller_Block_PageList {
   public function getPageList() {
         Loader::model('page_list');
         $db = Loader::db();
         $bID = $this->bID;
         if ($this->bID) {
            $q = "select num, cParentID, cThis, orderBy, ctID, displayAliases, rss from btPageList where bID = '$bID'";
            $r = $db->query($q);
            if ($r) {
               $row = $r->fetchRow();
            }
         } else {
            $row['num'] = $this->num;
rge replied on at Permalink Reply
I am not sure but maybe this helps.

Filters by number of page children. $comparison can be any MySQL comparison operator.
$pl->filterByAttribute($attributeKeyHandle, $value, $comparison)


In this post they filter on date with the filter method.
http://www.concrete5.org/community/forums/customizing_c5/creating-a...
$pl->filter($column, $value, $comparison)



Documentation Advanced users:
Passes a fliter directly to the "WHERE" clause. The value of $column must be a valid database column that's referenced in the PageList query. Setting the value of $column to false will allow you to pass complex SQL into the $value field ex:
$pl->filter(false, '(ak_age = 10 OR ak_age IN (13,17,25) OR ak_age > 23)');
where 'age' would be the handle of a numeric page attribute
Deladroid replied on at Permalink Reply
Deladroid
Thanks for your reply again rge.

I tried all of that too and none of it is filtering out pages that are in the future (public date). I must either be putting something in the wrong place/file, or something else.
rge replied on at Permalink Reply
I did a quick test via a new page type template that I created. In this page type I instantiate the new pagelist ( $pl = new PageList() ). On the children pages I have set an attribute of is_featured.

<?php
$pl = new PageList();
$pl->filterByParentID($c->getCollectionID()); //get all children pages of the current page
$pl->filterByIsFeatured(1);  //only get featured pages
$pl->filter('cvDatePublic', date('Y-m-d H:i:s'), '<='); 
$pages = $pl->getPage();
foreach ($pages as $page):
$title = $page->getCollectionName();
?>


For me the code above now only shows the pages that are:
1. featured
2. have a public date <= than the current date (today)

I don't have to calender addon. But I asume that when you know the page attribute It should be used in the same way as the public date.

$pl->filter('endDate', date('Y-m-d 23:59:59'), '>=');


Don't hardcode It in a page type like I did. It wil probably go wrong when you turn on caching in Concrete.

Full code of the page type
<?php defined('C5_EXECUTE') or die (_('Acccess denied.')); ?>
<?php $this->inc('elements/header.php'); ?>
<?php $c = Page::getCurrentPage(); ?>
<div class="main-content main-content-full">
 <h2>Filtering mutliple attributes</h2>
<?php
   $pl = new PageList();
   $pl->filterByParentID($c->getCollectionID());
   $pl->filterByIsFeatured(1);
   $pl->filter('cvDatePublic', date('Y-m-d H:i:s'), '<=');
   $pages = $pl->getPage();
   foreach ($pages as $page):
      $title = $page->getCollectionName();
?>
   <h3><?php echo $title; ?></h3>
Deladroid replied on at Permalink Reply
Deladroid
Thanks so much for this. I must had tried all kinds of different ways, but I did get this to work for the Public Date and "Is Featured".

I'm still having issues with the "Event End Date", but am starting to wonder if it's the add-on itself... The page breaks when uncomment that filter (below).

<div class="slider-tabs event flexslider">
  <ul class="slides">
    <?php 
   $pl = new PageList();
      $pl->filter('cvDatePublic', date('Y-m-d H:i:s'), '<=');
   //$pl->filter(date("Y-m-d H:i:s", strtotime('calendar_event_end_date_time')), date('Y-m-d H:i:s'), '>=');
      $pl->filterByIsFeatured(1);
      $pages = $pl->getPage();
   foreach ($pages as $page):
      // Title
      $title = $th->entities($page->getCollectionName());
      // URL
      $url = $nh->getLinkToCollection($page);
...
rge replied on at Permalink Reply
The filter methods is used in an incorrect way (for the end date).
$pl->filter($column, $value, $comparison)


This first param is the column in the database table of the page. I don't know if end date is included in this table as the publicDate. It might be that it is stored in a different way. Like a page attribute our in a different table.

Here is some more documentation regarding to listing:
http://www.concrete5.org/documentation/developers/5.6/pages/searchi...

Hopefully someone with some more experience regarding to the plugin can give some more insights?
Deladroid replied on at Permalink Reply
Deladroid
My mistake. The Calendar Events add-on does add the "End Date" as a page attribute. It's my playing around with testing date/time formatting for comparison that ended up making the filter wrong, I'm sure.