//{ category.module alterations patch category.module: |---------------------------------------------------------------------- --- /home/live/sites/all/modules/category/category.module 2007-10-18 11:12:28.000000000 -0700 +++ /home/dev/sites/all/modules/category.module 2007-11-10 09:34:31.000000000 -0800 @@ -1504,6 +1504,10 @@ function category_activeselect($source, print drupal_to_js($output); } + // !custom + elseif (preg_match('/^filter\d+$/', $targets[0])) { + category_activeselect_filter($source, $targets, $string, $extra); + } exit(); } ----------------------------------------------------------------------| //} //{ style.css additions zen-fixed/style.css |---------------------------------------------------------------------- .view_local { border-bottom: 1px solid #f89838; } .view_local_filter .form-item { /* space above country/state/city drop-downs */ margin: 0 0 10px 0; padding:0; /* IE picks up padding */ } .view_local_filter .form-checkboxes, /* space above type checkboxes */ .view_local_filter .form-checkboxes .form-item { /* space between type checkboxes */ margin: 0; padding: 0; } ----------------------------------------------------------------------| //} //{ template.php template.php: |---------------------------------------------------------------------- /** * CLASSIFIEDS VIEW */ function phptemplate_views_display_filters_classifieds($view) { $form = drupal_retrieve_form('views_filters', $view); // TYPE unset($form['filter0']['#options'][0]); // "-- Select category! --" unset($form['filter0']['#options']['**ALL**']); // extra box when "optional" is set // END TYPE // CLASSIFIED TYPES - CONVERT TO CHECKBOXES $count = 0; // filter # if (is_numeric($count) && $form['filter1']) { if ($form["filter$count"]['#multiple']) { $form["filter$count"]['#type'] = 'checkboxes'; if(is_array($_GET["filter$count"])){ /* This creates doubles of #default_value, omit for now * foreach($_GET["filter$count"] as $value){ $form["filter$count"]['#default_value'][] = $value; }*/ } } $options = array(); if(is_object($form["filter$count"]['#options'][0])){ // required is set? foreach($form["filter$count"]['#options'] as $option){ $option = $option->option; if(is_array($option)){ $key = implode('',array_keys($option)); $option = implode('', $option); $options[$key] = $option; } } } else{ foreach($form["filter$count"]['#options'] as $key => $option){ $options[$key] = $option; // node count $node_count = category_category_count_nodes_filters($key, 'ed_classified'); if ($node_count > 0) { $node_count = " (".$node_count.")"; } else { $node_count = ''; } $options[$key] = $option.$node_count; $node_count = ''; // reset } } $form["filter$count"]['#options'] = $options; unset($form["filter$count"]['#theme']); $form["filter$count"]['#prefix'] = '
'; $form["filter$count"]['#suffix'] = '
'; } // END CLASSIFIED TYPES $activeselect = module_exists('activeselect'); // COUNTRY if ($activeselect) { $form['filter1']['#type'] = 'activeselect'; $activeselect_attrs = array( '#activeselect_path' => 'category/activeselect', '#activeselect_targets' => 'filter2', '#activeselect_extra' => '65,'.$form['filter2']['#default_value'].','.implode(',',$form['filter0']['#default_value']) ); $form['filter1'] += $activeselect_attrs; } // node count $count = 1; // filter # $options = array(); foreach($form["filter$count"]['#options'] as $key => $option){ $options[$key] = $option; // node count $node_count = category_category_count_nodes_filters($key, 'ed_classified', $form['filter0']['#default_value']); if ($node_count > 0) { $node_count = " (".$node_count.")"; } else { $node_count = ''; } $options[$key] = $option.$node_count; $node_count = ''; } $form["filter$count"]['#options'] = $options; // end node count unset($form['filter1']['#options'][0]); // unset "--Select category!--" // END COUNTRY // STATE/PROVINCE $selected_country = $form['filter1']['#default_value']; $options = $form['filter2']['#options']; // ... code to remove options you don't want ... foreach ($options as $option => $text) { $parents = category_get_parents($option, 'cid', true); $parent = $parents[0]->cid; if ($parent && $parent != $selected_country) { // ALL has no parent unset($options[$option]); } } $form['filter2']['#options'] = $options; // If no results, replace with " - - - " if (count($form['filter2']['#options']) <= 1) { // ALL is always present, count == 1 $form['filter2']['#options']['**ALL**'] = ' - - - - - - - - '; } if ($activeselect) { $form['filter2']['#type'] = 'activeselect'; $activeselect_attrs = array( '#activeselect_path' => 'category/activeselect', '#activeselect_targets' => 'filter3', '#activeselect_extra' => '66,'.$form['filter3']['#default_value'].','.implode(',',$form['filter0']['#default_value']) ); $form['filter2'] += $activeselect_attrs; } // node count $count = 2; // filter # $options = array(); foreach($form["filter$count"]['#options'] as $key => $option){ $options[$key] = $option; // node count $node_count = category_category_count_nodes_filters($key, 'ed_classified', $form['filter0']['#default_value']); if ($node_count > 0) { $node_count = " (".$node_count.")"; } else { $node_count = ''; } $options[$key] = $option.$node_count; $node_count = ''; } $form["filter$count"]['#options'] = $options; // end node count // END STATE/PROVINCE // CITY $selected_state = $form['filter2']['#default_value']; $options = $form['filter3']['#options']; // ... code to remove options you don't want ... foreach ($options as $option => $text) { $parents = category_get_parents($option, 'cid', true); $parent = $parents[0]->cid; if ($parent && $parent != $selected_state) { // ALL has no parent unset($options[$option]); } } $form['filter3']['#options'] = $options; // If no results, replace with " - - - " if (count($form['filter3']['#options']) <= 1) { // ALL is always present, count == 1 $form['filter3']['#options']['**ALL**'] = ' - - - - - - - - '; } // node count $count = 3; $options = array(); foreach($form["filter$count"]['#options'] as $key => $option){ $options[$key] = $option; // node count $node_count = category_category_count_nodes_filters($key, 'ed_classified', $form['filter0']['#default_value']); if ($node_count > 0) { $node_count = " (".$node_count.")"; } else { $node_count = ''; } $options[$key] = $option.$node_count; $node_count = ''; } $form["filter$count"]['#options'] = $options; // end node count // END CITY // General UI fixes $form['filter0']['#prefix'] = "
"; $form['filter0']['#suffix'] = '
'; $form['filter1']['#prefix'] = "
"; $form['filter1']['#suffix'] = '
'; $form['filter2']['#prefix'] = "
"; $form['filter2']['#suffix'] = '
'; $form['filter3']['#prefix'] = "
"; $form['filter3']['#suffix'] = '
'; /** * NOTE: When someone clicks on US, then selects a state, and then goes back to ALL * countries while having state selected the state filter still applies. Clicking * submit again clear it. UPDATE: Active Select takes care of this. */ drupal_process_form('views_filters', $form); return drupal_render_form('views_filters', $form); } /** * ACTIVE SELECT FOR DISTANT PARENTS IN VIEWS FILTERS */ function category_activeselect_filter($source, $targets, $string = NULL, $extra = NULL) { /** * DEFINITIONS * Here is a little work-around. Normally, the category module looks for the pattern * "category-65", then takes the number 65 and uses it to get the category id. Views' * Filters doesn't follow this pattern, instead generating filter0, filter1, etc, so we * need a little translation. * A potential problem can occur when using a different set of active select categories * where filter1 may not be 65. Alternate setup will be needed here. */ $filter2cnid = array( 'filter1' => '65', 'filter2' => '66', 'filter3' => '67' ); /** * Another trick we need to do is get the selected classified types from * $form['filter0']['#default_value'] for the node count. Unfortunately $form is * not available here because $view is not passed down, so we're going to use $extra * for that. [0] and [1] are taken by the category active select function, * but the rest of the array is available. */ $types = explode(',', $extra); unset($types[0],$types[1]); // take off the first two values // parse to the #default_value format foreach($types as $key => $value) { unset($types[$key]); $types[$value] = $value; } // category_activeselect top // note: make sure not to include var definitions for $source, $targets, $string and $extra $nid = NULL; $parent_cont = NULL; if (strpos($extra, ',') === FALSE) { $nid = $extra; } else { $extra_array = explode(',', $extra); $nid = $extra_array[0]; $parent_cont = $extra_array[1]; } $array = activeselect_explode_values($string); // end category_activeselect top $output = array(); foreach ($targets as $target) { $options = array(); $cnid = $filter2cnid[$target]; $container = category_get_container($cnid); $node = node_load($nid); $parent_cnid = $filter2cnid[$source]; if ($container->required) { $blank = 0; } else { //$blank = '<'. t('none') .'>'; // use below instead $all = true; } // this takes the second value from #extra and passes it to be selected $node_cats = array(); if ($nid) { // 65 $cats = $node->category; if (isset($cats)) { if (is_array($cats)) { // true, but empty foreach ($cats as $cat) { if ($cat->cnid == $cnid) { $node_cats[] = $cat->cid; } } } elseif (!empty($cats)) { $node_cats[] = $cats; } } } if (isset($parent_cont)) { $node_cats[] = $parent_cont; } if (empty($node_cats)) { $node_cats = NULL; } $options = _category_node_select_options($cnid, $blank, $node_cats); if (isset($options) && is_array($options)) { foreach ($options as $key => $value) { $parents_in_cont = FALSE; $matching_parents = FALSE; $parents = category_get_parents($key); foreach ($parents as $x) { $cid = $x->cid; $parent_cat = category_get_category($cid); if ($parent_cat->cnid == $parent_cnid) { $parents_in_cont = TRUE; if (isset($array[$cid])) { $matching_parents = TRUE; } } } if ($parents_in_cont && !$matching_parents) { unset($options[$key]); } } // All to dynamic list if ($all == true) { $options['**ALL**'] = ''; asort($options); // re-sort array to move to the top } // If no results, replace with " - - - " if (count($options) <= 1) { $options['**ALL**'] = ' - - - - - - - - '; } foreach ($options as $key => $value) { unset($options[$key]); $options[$key]['value'] = $value; $options[$key]['selected'] = in_array($key, $parents); $options[$key] = str_replace('|', '|', $options[$key]); if (is_array($node_cats)) { $options[$key]['selected'] = in_array($key, $node_cats); } else { $options[$key]['selected'] = ($key == $node_cats); } // node count (active select) $node_count = category_category_count_nodes_filters($key, 'ed_classified', $types); if ($node_count > 0) { $node_count = " (".$node_count.")"; } else { $node_count = ''; } $options[$key]['value'] = $value.$node_count; $node_count = ''; } } $multiple = ($container->multiple ? TRUE : FALSE); $output[$target] = array('options' => $options, 'multiple' => $multiple); } activeselect_set_header_nocache(); print drupal_to_js($output); } /** /** * View Filters Rendering * VIEWS FILTERS * views_classifieds.tpl.php */ function phptemplate_views_filters($form) { $view = $form['view']['#value']; if ($view->name == 'classifieds'){ foreach ($view->exposed_filter as $count => $expose) { $row[] = drupal_render($form["op$count"]) ; $box[] = drupal_render($form["filter$count"]); $label[] = $expose['label']; } $row[] = drupal_render($form['submit']); $label[] = ''; // so the column count is the same. $title = $view->page_title; // message if (!$form['filter0']['#default_value']) { $all = 'all'; } $country = $form['filter1']['#options'][$form['filter1']['#default_value']]; $state = $form['filter2']['#options'][$form['filter2']['#default_value']]; $city = $form['filter3']['#options'][$form['filter3']['#default_value']]; if ($country == '') { $country = 'All Countries'; } else { $country = "$country"; } if ($state == '' || $state == ' - - - - - - - - ' || !$state) { $state = ''; } else { $state = "$state, "; } if ($city == '' || $city == ' - - - - - - - - ' || !$city) { $city = ''; } else { $city = "$city, "; } $message = "Showing $all results for $city$state$country"; $message = preg_replace('/\s*\([^\)]*\)/', '', $message); // strip " (*)" return _phptemplate_callback('views_classifieds', array('title' => $title, 'row' => $row, 'box' => $box, 'label' => $label, 'message' => $message)); } else { // do the default rendering from views.module $view = $form['view']['#value']; foreach ($view->exposed_filter as $count => $expose) { $row[] = drupal_render($form["op$count"]) . drupal_render($form["filter$count"]); $label[] = $expose['label']; } $row[] = drupal_render($form['submit']); $label[] = ''; // so the column count is the same. // make the 'q' come first return drupal_render($form['q']) . theme('table', $label, array($row)) . drupal_render($form); } } /** * VIEWS FILTERS COUNT NODES */ function category_category_count_nodes_filters($cid, $type = 0, $types = null) { /* $type here refers to node type (event/ed_classified) * If types (classified types) are passed, a different query is performed that takes * into account cid, type and types. The only time when the types are not passed is * when the types themselves are requesting a node count. */ static $count; static $count2; if (is_array($types)) { $cids = implode(',',array_keys($types)); } //if (!isset($count[$type])) { // to store count results in session if ((!$cids && !isset($count[$type])) || $cids) { /* note: classified types only need to run once, country/state/city need to run every time * This seems to work fine, though it does add a load to the server with every active * select query. */ if ($cid > 0) { // **ALL** doesn't pass // $type == 0 always evaluates true if $type is a string if (is_numeric($type)) { // not used? $result = db_query(db_rewrite_sql('SELECT c.cid, COUNT(n.nid) AS cnt FROM {category_node} c INNER JOIN {node} n ON c.nid = n.nid WHERE n.status = 1 GROUP BY c.cid')); } else { // type is not numeric - 'event', 'ed_classified' if ($cids) { // coutry/city/state - classified types specified, in none, all are passed $result = db_query(db_rewrite_sql(" SELECT c.cid, COUNT(n.nid) AS cnt FROM {category_node} c INNER JOIN {node} n ON c.nid = n.nid WHERE n.status = 1 AND n.type = '%s' AND n.nid IN ( SELECT n.nid FROM {category_node} c INNER JOIN {node} n ON c.nid = n.nid WHERE n.status = 1 AND n.type = '%s' AND c.cid IN (%s) ) AND c.cid IN (%s) GROUP BY c.cid "), $type, $type, $cids, $cid); } else { // classified type - no need to filter by itself $result = db_query(db_rewrite_sql("SELECT c.cid, COUNT(n.nid) AS cnt FROM {category_node} c INNER JOIN {node} n ON c.nid = n.nid WHERE n.status = 1 AND n.type = '%s' GROUP BY c.cid"), $type); } } while ($category = db_fetch_object($result)) { if ($cids) { $count2[$type][$cids.','.$cid] = $category->cnt; } else { $count[$type][$category->cid] = $category->cnt; } } } } // } if ($cids) { return isset($count2[$type][$cids.','.$cid]) ? $count2[$type][$cids.','.$cid] : 0; } else { return isset($count[$type][$cid]) ? $count[$type][$cid] : 0; } } ----------------------------------------------------------------------| //} //{ views_classifieds.tpl.php views_clssifieds.tpl.php: |---------------------------------------------------------------------- */ ?>



Help:
----------------------------------------------------------------------| //} //{ view setup (classifieds) The view must be named "classifieds" for all the above functions to trigger. Some renaming of functions will need to happen if it's changed. It consists of four exposed filters: * Classified Type * Country * State/Province * City ... and these must appear in this particular order for everything to work because views names it's exposed filters "filter0, filter1, etc". //}