? .DS_Store
? layer_filters_00.patch
? layer_filters_01.patch
? layer_filters_02.patch
? layer_filters_03.patch
? layer_filters_04.patch
? images/.DS_Store
? images/filter.png
? images/filter_disabled.png
? includes/.DS_Store
Index: index.install
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/index/Attic/index.install,v
retrieving revision 1.1.2.8
diff -u -p -r1.1.2.8 index.install
--- index.install	9 Jan 2010 20:43:18 -0000	1.1.2.8
+++ index.install	9 Jan 2010 22:29:48 -0000
@@ -99,6 +99,35 @@ function index_schema() {
       ),
     ),
   );
+  $schema['index_filter'] = array(
+    'description' => 'The filters for every {index_layer}.',
+    'fields' => array(
+      'lineage' => array(
+        'description' => "The lineage of the {index_layer} this filter is for.",
+        'type' => 'varchar',
+        'length' => 255,
+        'default' => NULL,
+      ),
+      'field' => array(
+        'description' => 'The field this filter applies to.',
+        'type' => 'varchar',
+        'length' => 255,
+        'not null' => TRUE,
+      ),
+      'inverted' => array(
+        'description' => 'Exclude instead of include the values.',
+        'type' => 'int',
+        'size' => 'tiny',
+        'default' => 0,
+      ),
+      'value' => array(
+        'description' => 'A serialized set of values.',
+        'type' => 'blob',
+        'size' => 'normal',
+        'not null' => TRUE,
+      ),
+    ),
+  );
 
   return $schema;
 }
Index: index.module
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/index/Attic/index.module,v
retrieving revision 1.1.2.29
diff -u -p -r1.1.2.29 index.module
--- index.module	1 Jan 2010 17:58:35 -0000	1.1.2.29
+++ index.module	9 Jan 2010 22:29:48 -0000
@@ -272,6 +272,20 @@ function index_index_entity_type_info() 
       'node_type' => 'type',
     ),
     '#primary_key' => 'nid',
+    '#filters' => array(
+      'status' => array(
+        '#title' => t('Published'),
+        '#type' => 'bool',
+      ),
+      'node_type' => array(
+        '#title' => t('Content type'),
+        '#type' => 'list',
+        '#options_callback_info' => array(
+          '#callback' => 'index_entity_filter_node_type',
+          '#file' => 'includes/index.entity.inc',
+        ),
+      ),
+    ),
     '#entity_get_callback_info' => array(
       '#callback' => 'index_entity_get_node',
       '#file' => 'includes/index.entity.inc',
@@ -449,6 +463,13 @@ function index_entity_type_info() {
         $module_mode['#entity_get_callback_info']['#module'] = $module;
         $module_mode['#entity_count_callback_info']['#module'] = $module;
         $module_mode['#theme_info']['#module'] = $module;
+        if (isset($module_mode['#filters'])) {
+          foreach ($module_mode['#filters'] as &$filter) {
+            if (isset($filter['#options_callback_info'])) {
+              $filter['#options_callback_info']['#module'] = $module;
+            }
+          }
+        }
       }
       $entity_types += $module_modes;
     }
Index: css/index.admin.css
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/index/css/Attic/index.admin.css,v
retrieving revision 1.1.2.10
diff -u -p -r1.1.2.10 index.admin.css
--- css/index.admin.css	1 Jan 2010 17:58:35 -0000	1.1.2.10
+++ css/index.admin.css	9 Jan 2010 22:29:48 -0000
@@ -20,6 +20,14 @@
 }
 
 /* Layers */
+#index-form-add-layers .form-submit {
+	background-color: transparent;
+	background-repeat: no-repeat;
+	border: 0;
+	cursor: pointer;
+	height: 22px;
+	padding-left: 20px;
+}
 .index-form-add-layer-depth {
   background: url('../images/child.png') center no-repeat;
   float: left;
@@ -36,25 +44,25 @@
   width: 0;
 }
 .index-form-add-layer-child-add {
-	background: transparent url('../images/add.png') no-repeat;
-	border: 0;
-	cursor: pointer;
-	padding-left: 20px;
+	background-image: url('../images/add.png');
 }
 .index-form-add-layer-child-add.disabled {
   background-image: url('../images/add_disabled.png');
   color: #999;
 }
 .index-form-add-layer-remove {
-	background: transparent url('../images/remove.png') no-repeat;
-	border: 0;
-	cursor: pointer;
-	padding-left: 20px;
+	background-image: url('../images/remove.png');
 }
 .index-form-add-layer-remove.disabled {
   background-image: url('../images/remove_disabled.png');
   color: #999;
 }
+.index-form-add-layer-filter-configure {
+	background-image: url('../images/filter.png');
+}
+.index-form-add-layer-filter-configure .disabled{
+	background-image: url('../images/filter_disabled.png');
+}
 
 /* Make sure textfields aren't too wide */
 #edit-title {
Index: includes/index.admin.inc
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/index/includes/Attic/index.admin.inc,v
retrieving revision 1.1.2.29
diff -u -p -r1.1.2.29 index.admin.inc
--- includes/index.admin.inc	9 Jan 2010 20:43:18 -0000	1.1.2.29
+++ includes/index.admin.inc	9 Jan 2010 22:29:48 -0000
@@ -47,26 +47,31 @@ function index_form_add(array $form_stat
   drupal_add_css(drupal_get_path('module', 'index') . '/css/index.admin.css', 'module', 'all', FALSE);
   drupal_add_css(drupal_get_path('module', 'index') . '/css/index.view.css', 'module', 'all', FALSE);
   drupal_add_js(drupal_get_path('module', 'index') . '/js/index.admin.js');
-
   index_load_include('classes');
   index_load_include('view');
 
-  // Cast the IID to an integer, because the menu system passes it on as a
-  // string.
+  // Cast the IID to an integer if it is passed on as a string by the menu
+  // system.
   if (is_string($iid)) {
     $iid = (int) $iid;
   }
+
   // Load and populate the index.
-  $index_original = new index($iid);
-  $index_edited = clone $index_original;
+  $index_existing = new index($iid);
+  $index_edited = clone $index_existing;
   if (isset($form_state['values'])) {
-    index_form_add_populate_index_rebuild($index_edited, $form_state);
+    index_form_add_populate($index_edited, $form_state);
   }
-  elseif (!$iid) {
-    index_form_add_populate_index_new($index_edited);
+  else {
+    $index_edited->layers[] = new indexLayer(array(
+      'lineage' => '0',
+      'index' => $index_edited,
+      'entity_type' => array_shift(array_keys(index_entity_type_info())),
+    ));
   }
 
   $form = array(
+    '#theme' => 'index_form_add',
     '#cache' => TRUE,
     '#redirect' => 'admin/build/index',
     '#suffix' => '<div id="index-form-add-preview-page" class="index-form-add-preview"><h2>' . t('Page preview') . '</h2><div class="content">' . index_preview($index_edited, 'page') . '</div></div><div id="index-form-add-preview-block" class="index-form-add-preview"><h2>' . t('Block preview') . '</h2><div class="content">' . index_preview($index_edited, 'block') . '</div></div>',
@@ -75,11 +80,11 @@ function index_form_add(array $form_stat
   // Internal settings.
   $form['iid'] = array(
     '#type' => 'value',
-    '#value' => $iid,
+    '#value' => $index_existing->iid,
   );
-  $form['index_original'] = array(
+  $form['index_existing'] = array(
     '#type' => 'value',
-    '#value' => $index_original,
+    '#value' => $index_existing,
   );
   $form['index_edited'] = array(
     '#type' => 'value',
@@ -115,7 +120,7 @@ function index_form_add(array $form_stat
       $block_modes[$callback] = $mode['#title'];
     }
   }
-  $page_path = check_plain($index_original->page_path);
+  $page_path = check_plain($index_existing->page_path);
   $page_path_description = $page_path ? t('Currently located at !location.', array('!location' => l('/' . $page_path, $page_path))) : '';
   $form['create'] = array(
     '#type' => 'fieldset',
@@ -224,7 +229,7 @@ function index_form_add_save(array $form
   $values = $form_state['values'];
   index_load_include('classes');
   $index = new index();
-  index_form_add_populate_index_rebuild($index, $form_state);
+  index_form_add_populate($index, $form_state);
 
   if ($values['iid']) {
     $index->update();
@@ -249,6 +254,8 @@ function index_form_add_update(array $fo
  * Update index_form_add() using AJAX.
  */
 function index_form_add_update_ajax() {
+  index_load_include('classes');
+
   // Build a fake $form_state and get the form.
   $form_state = array(
     'storage' => NULL,
@@ -264,7 +271,6 @@ function index_form_add_update_ajax() {
   $form['#programmed'] = $form['#redirect'] = FALSE;
   drupal_process_form($form_id, $form, $form_state);
   $form = drupal_rebuild_form($form_id, $form_state, $args, $form_build_id);
-  ob_start();
 
   // Suppress (validation) errors.
   form_set_error(NULL, '', TRUE);
@@ -272,8 +278,8 @@ function index_form_add_update_ajax() {
 
   drupal_json(array(
     'layers' => strpos($form_state['clicked_button']['#name'], 'layer_') !== FALSE ? theme('index_form_add_layers', $form['layers']) : NULL,
-    'page' => index_preview($form['index_edited']['#value'], 'page'),
-    'block' => index_preview($form['index_edited']['#value'], 'block'),
+    'page' => index_preview($form_state['values']['index_edited'], 'page'),
+    'block' => index_preview($form_state['values']['index_edited'], 'block'),
   ));
 }
 
@@ -293,7 +299,7 @@ function theme_index_form_add(array $for
  */
 function theme_index_form_add_layers(array $form) {
   $rows = array();
-  foreach ($form['lineages']['#value'] as $lineage) {
+  foreach ($form['layers']['#value'] as $lineage => $layer) {
     $depth = count(explode('_', $lineage)) - 1;
     $rows[] = array(
       theme('indentation', $depth - 1) . theme('index_form_add_layer_depth', $depth) . (isset($form["layer_type_item-$lineage"]) ? drupal_render($form["layer_type_item-$lineage"]) : drupal_render($form["layer_type-$lineage"])),
@@ -307,12 +313,33 @@ function theme_index_form_add_layers(arr
       ),
       drupal_render($form["layer_child_add-$lineage"]),
       drupal_render($form["layer_remove-$lineage"]),
+      drupal_render($form["layer_filter_configure-$lineage"]),
     );
+		$entity_type_info = index_entity_type_info();
+		if (isset($entity_type_info[$layer->entity_type]['#filters'])) {
+			$row_data = NULL;
+			foreach (array_keys($entity_type_info[$layer->entity_type]['#filters']) as $field) {
+				$row_data .= drupal_render($form['layer_filter-' . $lineage . '-' . $field]);
+			}
+			$rows[] = array(
+				'data' => array(
+					array(
+						'data' => format_plural(count($entity_type_info[$layer->entity_type]['#filters']), 'Configure filter for %entity_type', 'Configure filters for %entity_type', array('%entity_type' => $entity_type_info[$layer->entity_type]['#title'])),
+						'header' => TRUE,
+					),
+					array(
+						'data' => $row_data,
+						'colspan' => 5,
+					),
+				),
+				'class' => 'layer-filters',
+			);
+		}
   }
   $rows[] = array(
     array(
       'data' => drupal_render($form['layer_child_add']),
-      'colspan' => 5,
+      'colspan' => 6,
     ),
   );
   $header = array(
@@ -321,7 +348,7 @@ function theme_index_form_add_layers(arr
     t('Hide childless items'),
     array(
       'data' => t('Operations'),
-      'colspan' => 2,
+      'colspan' => 3,
     ),
   );
 
@@ -347,24 +374,10 @@ function theme_index_form_add_layer_dept
  *
  * @param $index index
  *   The index object to populate.
- */
-function index_form_add_populate_index_new(index $index) {
-  $index->layers[] = new indexLayer(array(
-    'lineage' => '0',
-    'index' => $index,
-    'entity_type' => array_shift(array_keys(index_entity_type_info())),
-  ));
-}
-
-/**
- * Populate an index with form submitted data after a form rebuild.
- *
- * @param $index index
- *   The index object to populate.
  * @param $form_state array
- *   The $form_state of the form from which use get the data. 
+ *   The $form_state of the form from which to use the data. 
  */
-function index_form_add_populate_index_rebuild(index $index, array &$form_state) {
+function index_form_add_populate(index $index, array &$form_state) {
   $values = $form_state['values'];
 
   // Loop through all values and add them if the index accepts them.
@@ -392,7 +405,7 @@ function index_form_add_populate_index_r
       $new_lineage = '';
       // Compute the new layer's lineage if the new layer is in the root.
       if (!strlen($clicked_lineage)) {
-        foreach ($values['lineages'] as $lineage) {
+        foreach (array_keys($values['layers']) as $lineage) {
           if (strpos($lineage, '_') === FALSE) {
             $sibling_lineages[] = $lineage;
           }
@@ -402,7 +415,7 @@ function index_form_add_populate_index_r
       // Compute the new layer's lineage if the layer has a parent.
       else {
         $count_children = 0;
-        foreach ($values['lineages'] as $lineage) {
+        foreach (array_keys($values['layers']) as $lineage) {
           if (preg_match('#' . $clicked_lineage . '_\d+?#', $lineage)) {
             $sibling_lineages[] = substr($lineage, strrpos($lineage, '_') + 1);
           }
@@ -413,7 +426,7 @@ function index_form_add_populate_index_r
   }
   // Create layers for every known lineage, either existing or new.
   $new_layer = NULL;
-  foreach (array_merge($values['lineages'], $lineages) as $lineage) {;
+  foreach (array_merge(array_keys($values['layers']), $lineages) as $lineage) {;
     $lineage = (string) $lineage;
     // Don't save this layer and its children into the index if it has been
     // removed.
@@ -421,7 +434,7 @@ function index_form_add_populate_index_r
       continue;
     }
     // Add the current layer.
-    $lineages[] = $lineage;
+
     $layers[$lineage] = new indexLayer(array(
       'lineage' => $lineage,
       'entity_type' => isset($values["layer_type-$lineage"]) ? $values["layer_type-$lineage"] : NULL,
@@ -433,7 +446,7 @@ function index_form_add_populate_index_r
       $new_layer = $layers[$lineage];
     }
   }
-  $values['lineages'] = $lineages;
+  $values['layers'] = $layers;
   $index->setLayers($layers);
   if ($new_layer) {
     // Set the newly added layer's entity type. This can only be done after the
@@ -463,12 +476,12 @@ function index_form_add_layers(index $in
     '#name' => 'layer_child_add',
   );
 
-  $form['lineages'] = array(
+  $form['layers'] = array(
     '#type' => 'value',
     '#value' => array(),
   );
 
-  _index_form_add_layers($form, $index->layers);
+  _index_form_add_layers($form, $form_state, $index->layers);
 
   if (isset($form_state['rebuild']) && $form_state['rebuild']) {
     $form['warning'] = array(
@@ -480,8 +493,10 @@ function index_form_add_layers(index $in
   return $form;
 }
 
-function _index_form_add_layers(array &$form, array $layers, $parent_entity_type = NULL) {
+function _index_form_add_layers(array &$form, array $form_state, array $layers, $parent_entity_type = NULL) {
+  $entity_type_info = index_entity_type_info();
   foreach ($layers as $layer) {
+		// Configuration elements.
     if (count($layer->layers)) {
       // Parent layers cannot be modified and are represented by a value element
       // for processing and an item element for the user to see.
@@ -489,10 +504,9 @@ function _index_form_add_layers(array &$
         '#type' => 'hidden',
         '#value' => $layer->entity_type,
       );
-      $entity_types_info = index_entity_type_info();
       $form['layer_type_item-' . $layer->lineage] = array(
         '#type' => 'item',
-        '#value' => $entity_types_info[$layer->entity_type]['#title'],
+        '#value' => $entity_type_info[$layer->entity_type]['#title'],
       );
       // If there are no child layers there are no child entities to count.
       $form['layer_hide_childless_entities-' . $layer->lineage] = array(
@@ -519,6 +533,36 @@ function _index_form_add_layers(array &$
         );
       }
     }
+ 		if (isset($form_state['clicked_button'])
+ 		&& strpos($form_state['clicked_button']['#name'], 'layer_filter_configure-') === 0
+		&& end(explode('-', $form_state['clicked_button']['#name'])) == $layer->lineage) {
+			if (isset($entity_type_info[$layer->entity_type]['#filters'])) {
+	   		foreach ($entity_type_info[$layer->entity_type]['#filters'] as $field => $filter) {
+					$key = 'layer_filter-' . $layer->lineage . '-' . $field;
+					if ($filter['#type'] == 'bool') {
+						$form[$key] = array(
+							'#type' => 'checkbox',
+						'#title' => $filter['#title'],
+						);
+					}
+					elseif ($filter['#type'] == 'list') {
+						$options = index_callback_execute($filter['#options_callback_info']);
+						$form[$key] = array(
+							'#type' => 'select',
+							'#title' => $filter['#title'],
+							'#options' => $options,
+							'#multiple' => TRUE,
+							'#size' => count($options) > 5 ? 5 : count($options),
+						);
+					}
+				}
+			}
+			else {
+				drupal_set_message(t('There are no filters for %entity_type', array('%entity_type' => $entity_type_info[$layer->entity_type]['#title'])), 'warning');
+			}
+		}
+
+		// Layer control buttons.
     $disabled = (bool) !index_fake_layer_entity_type_options($layer);
     $form['layer_child_add-' . $layer->lineage] = array(
       '#type' => 'submit',
@@ -549,9 +593,23 @@ function _index_form_add_layers(array &$
       // (undocumented feature).
       '#name' => 'layer_remove-' . $layer->lineage,
     );
+    $form['layer_filter_configure-' . $layer->lineage] = array(
+      '#type' => 'submit',
+      '#value' => t('Filter'),
+      '#submit' => array('index_form_add_update'),
+      '#attributes' => array(
+        'class' => 'index-form-add-layer-filter-configure',
+        'title' => t('Configure filters'),
+      ),
+      // By default FAPI gives every button name="op", which makes it
+      // impossible to detect the clicked button if multiple buttons have the
+      // same value. To fix this we configure a custom and unique name
+      // (undocumented feature).
+      '#name' => 'layer_filter_configure-' . $layer->lineage,
+    );
 
-    $form['lineages']['#value'][] = $layer->lineage;
-    _index_form_add_layers($form, $layer->layers, $layer->entity_type);
+    $form['layers']['#value'][$layer->lineage] = $layer;
+    _index_form_add_layers($form, $form_state, $layer->layers, $layer->entity_type);
   }
 }
 
Index: includes/index.entity.inc
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/index/includes/Attic/index.entity.inc,v
retrieving revision 1.1.2.7
diff -u -p -r1.1.2.7 index.entity.inc
--- includes/index.entity.inc	26 Dec 2009 14:11:20 -0000	1.1.2.7
+++ includes/index.entity.inc	9 Jan 2010 22:29:48 -0000
@@ -303,4 +303,17 @@ function index_entity_get_taxonomy_term_
  */
 function index_entity_count_taxonomy_term($key, array $values, $depth_max) {
   return index_entity_count('term_data', $key, $values);
+}
+
+/**
+ * Filter by node type.
+ */
+function index_entity_filter_node_type() {
+  $node_types = array();
+  $result = db_query("SELECT type, name FROM {node_type}");
+  while ($node_type = db_fetch_object($result)) {
+    $node_types[$node_type->type] = $node_type->name;
+  }
+
+  return $node_types;
 }
\ No newline at end of file
