By rleddy on
It seems costly to query the DB every time a subfilter is selected.
Rather is would be nicer to select filters on the screen and then do a query.
So, I wrote a different one. After picking my way through the form API tricks and tracing down map keys, etc.
I came up with the following, (no claim to an optimal solution):
{One more note: I used a string substitution for the top level checkbox state, where it should have probably been handled with #default_value. But, this code works for now.}
/**
* List node administration filters that can be applied.
*/
function node_filters() {
// Regular filters
$filteroptions = array();;
$filteroptions['status-1'] = t('published');
$filteroptions['status-0'] = t('not published');
if ( module_hook('publisher','fromstatic') ) {
$filteroptions['static_out-1'] = t('static');
$filteroptions['static_out-0'] = t('dynamic');
}
$filteroptions['promote-1'] = t('promoted');
$filteroptions['promote-0'] = t('not promoted');
$filteroptions['sticky-1'] = t('sticky');
$filteroptions['sticky-0'] = t('not sticky');
$filters['status'] = array('title' => t('status'),
'options' => $filteroptions
);
$filters['type'] = array('title' => t('type'), 'options' => node_get_types('names'));
// The taxonomy filter
if ($taxonomies = module_invoke('taxonomy', 'form_all', 1)) {
foreach ( $taxonomies as $vname => $taxonomy ) {
$filters['category-' . $vname] = array('title' => t('Category: ' . $vname), 'options' => $taxonomy);
}
}
return $filters;
}
/**
* Build query for node administration filters based on session.
*/
function node_build_filter_query() {
// Build query
$where = $args = array();
$join = '';
$n = count($_SESSION['node_overview_filter']);
$queryvector = $_SESSION['node_overview_filter'][$n-1];
if ( isset($queryvector) ) {
$index = 0;
if ( isset($queryvector['category']) ) {
$join .= "INNER JOIN {term_node} tnode ON (n.nid = tnode.nid) ";
if ( count($queryvector['category']) > 0 ) {
$termlist = implode(",",$queryvector['category']);
$where[] = "tnode.tid in ($termlist)";
}
}
if ( isset($queryvector['type']) ) {
$termlist = implode("','",$queryvector['type']);
$where[] = "n.type in ('$termlist')";
}
foreach ($queryvector as $filter => $valueset) {
if ( strncmp($filter,'cat',3) != 0 ) {
$n = count($valueset);
for ( $i = 0; $i < $n; $i++ ) {
switch ($filter) {
case 'status':
// Note: no exploitable hole as $key/$value have already been checked when submitted
list($key, $value) = explode('-', $valueset[$i], 2);
$where[] = 'n.'. $key .' = %d';
break;
}
$args[] = $value;
}
}
}
}
///////////////
$where = count($where) ? 'WHERE '. implode(' AND ', $where) : '';
return array('where' => $where, 'join' => $join, 'args' => $args);
}
/**
* Return form for node administration filters.
*/
function node_filter_form() {
$ns = count($_SESSION['node_overview_filter']);
if ( $ns > 0 ) {
$ns--;
$session = &$_SESSION['node_overview_filter'][$ns];
}
$filters = node_filters();
$i = 0;
$form['filters'] = array('#type' => 'fieldset',
'#title' => t('Show only items where'),
'#theme' => 'node_filters',
);
foreach ( $filters as $key => $filter ) {
//////////////
$names[$key] = $filter['title'];
//////////////
$form['filters']['status'][$key]
= array( '#type' => 'checkboxes',
'#options' => $filter['options'],
'#default_value' => $session[$key]
);
}
$form['filters']['filter'] = array('#type' => 'checkboxes', '#options' => $names,
"#attributes" => array('onclick' => "@clickertheme") ); // , '#default_value' => 'status');
$form['filters']['buttons']['submit'] = array('#type' => 'submit', '#value' => (count($session) ? t('Update Filter') : t('Filter')));
if (count($session)) {
$form['filters']['buttons']['undo'] = array('#type' => 'submit', '#value' => t('Undo'));
$form['filters']['buttons']['reset'] = array('#type' => 'submit', '#value' => t('Reset'));
}
return $form;
}
/**
* Theme node administration filter form.
*/
function theme_node_filter_form($form) {
$output .= '<div id="node-admin-filter">';
$output .= drupal_render($form['filters']);
$output .= '</div>';
$output .= drupal_render($form);
return $output;
}
/**
* Theme node administration filter selector.
*/
function theme_node_filters($form) {
$ns = count($_SESSION['node_overview_filter']);
if ( $ns > 0 ) {
$ns--;
$session = &$_SESSION['node_overview_filter'][$ns];
// $session = is_array($session) ? $session : array();
}
$specialtoggle =<<<ETFORM
function specialnodetoggle(key) {
var divname = 'edit-stuff-' + key;
var v = $(divname).style.visibility;
$(divname).style.visibility = (v =='visible') ? 'hidden' : 'visible';
}
ETFORM;
drupal_add_js($specialtoggle,'inline');
// Fisrt caveat: 1 cell for each type of filter.
// Second: Each category has it's own cell.
$selectioncells = "";
foreach ( element_children($form['filter']) as $key ) {
$fff = $key;
$groupviz = isset($session) && isset($session[$fff]) ? "visible" : "hidden";
$filtername = drupal_render($form['filter'][$key]);
$filtername = str_replace("<div","<span",$filtername);
$filtername = str_replace("</div","</span",$filtername);
if ( $groupviz == "visible" ) {
$filtername = str_replace( 'type="checkbox"','type="checkbox" checked ',$filtername);
}
$filtername = str_replace("@clickertheme","specialnodetoggle('$key')",$filtername);
$filtervalues = drupal_render($form['status'][$key]);
////
$selectable =<<<SELECTORS
<div id='edit-stuff-$key' style="visibility:$groupviz;height:90px;overflow:auto;border:2px gold solid;margin:3px">
$filtervalues
</div>
SELECTORS;
$selectioncells .= "<td width=\"250px\">" . $filtername . $selectable . "</td>";
}
/*
*/
$tabdesign =<<<EOTAB
<div style="border: 1px solid darkgreen;overflow:auto;width:100%;padding:4px;margin:4px;" >
<table height="120px" border="1px solid navy" cellspacing="0" cellpadding="1px" >
<tr>
$selectioncells
</tr>
</table>
</div>
EOTAB;
/*
$output = "This is a test.";
*/
$output = $tabdesign;
$output .= '<div class="container-inline" id="node-admin-buttons">'. drupal_render($form['buttons']) .'</div>';
////
return $output;
}
/**
* Process result from node administration filter form.
*/
function node_filter_form_submit($form_id, $form_values) {
switch ($form_values['op']) {
case t('Filter'):
case t('Update Filter'):
if ( !isset($_SESSION['node_overview_filter']) ) {
$_SESSION['node_overview_filter'] = array();
}
$arraychoices = array();
foreach ( $form_values['filter'] as $filter ) {
$fff = $filter;
if ( strncmp($filter,"cat",3) == 0 ) {
$fff = "category";
}
if ( !isset($arraychoices[$fff]) ) {
$arraychoices[$fff] = array();
}
if ( !isset($arraychoices[$filter]) ) {
$arraychoices[$filter] = array();
}
if ( isset($form_values[$filter]) ) {
foreach ( $form_values[$filter] as $value ) {
if ( isset($value) && ( $value != null ) ) {
$arraychoices[$fff][] = $value;
$arraychoices[$filter][] = $value;
}
}
}
}
$_SESSION['node_overview_filter'][] = $arraychoices;
break;
case t('Undo'):
array_pop($_SESSION['node_overview_filter']);
break;
case t('Reset'):
$_SESSION['node_overview_filter'] = array();
break;
}
}