Commit 91776e20 authored by David Lesieur's avatar David Lesieur

Made specialization easier through a simpler structure. Also ceased to assume...

Made specialization easier through a simpler structure. Also ceased to assume that the generic implementation would work for all types of fields (it did not).
parent 7addc9d4
$Id$
README file for the CCK Facets Drupal module.
README file for the CCK Facets Drupal module package.
Description
***********
CCK Facets integrates with Faceted Search to allow users to navigate Content
Construction Kit (CCK) fields as facets.
CCK Facets is a bundle of modules that integrate with Faceted Search to expose
Content Construction Kit (CCK) fields as facets.
Requirements
......@@ -23,17 +23,24 @@ Requirements
Installation
************
1. Extract the cck_facets module directory into your Drupal modules directory.
1. Extract the cck_facets package directory into your Drupal modules directory.
2. Go to the Administer > Site building > Modules page and enable the CCK Facets
module. If you intend to use Node Reference or User Reference fields as
facets, then enable also the Reference Facets module.
2. Go to the Administer > Site building > Modules page, and enable any of the
following modules, depending on the type of CCK fields you wish to expose as
facets:
3. Go to the Administer > Site configuration > Faceted Search page, choose to
edit the faceted search environment that shall expose CCK-based facets. In
the environment editing form, check each facet you wish to expose.
- CCK Number Facets (for Number fields)
- CCK Text Facets (for Text fields)
- CCK Reference Facets (for Node Reference or User Reference fields)
CAUTION: CCK Facets hands you over the responsibility of deciding what field
Only the above types of fields are supported at the moment (this still means
that all of the core CCK field types are supported).
3. Go to the Administer > Site configuration > Faceted Search page, edit the
faceted search environment that shall expose CCK-based facets. In the
environment editing form, check each facet you wish to expose.
CAUTION: This system hands you over the responsibility of deciding what field
is appropriate for use as a facet. Long text fields should never be used as
facets, since their values are too long to be usable in the Guided search,
and might exceed the maximum URL length in browsers or servers when used as
......
This diff is collapsed.
; $Id$
name = CCK Facets
description = "Provides facets based on CCK fields."
dependencies = content faceted_search search
package = Faceted Search
; $Id$
name = CCK Number Facets
description = "Provides facets based on CCK Number fields."
dependencies = content number faceted_search search
package = Faceted Search
<?php
// $Id$
/**
* Implementation of hook_uninstall().
*/
function number_facets_uninstall() {
db_query("DELETE FROM {faceted_search_facets} WHERE facet_key = 'number'");
}
<?php
// $Id$
/**
* @file
* Provides facets based on CCK Number fields.
*/
require_once('./'. drupal_get_path('module', 'number_facets') .'/cck_facets.inc');
/**
* Implementation of hook_faceted_search_collect().
*/
function number_facets_faceted_search_collect(&$facets, $domain, $env_id, $filter, $arg = NULL) {
switch ($domain) {
case 'all':
$fields = content_fields();
foreach ($fields as $field) {
if ((!isset($filter) || isset($filter['number'][$field['field_name']])) && ($field['type'] == 'number_integer' || $field['type'] == 'number_decimal')) {
$facets[] = new cck_facet('number', $field);
}
}
break;
case 'text':
// Scan the given search text for a 'number:{field_name}:{value}'
// token, and create facets from it.
if ($found_text = search_query_extract($arg, 'number')) {
// Extract separate facets. Using a regex rather than a simple
// explode(',',$found_text) because commas might be used in field values
// and we want to ignore those when splitting the text.
$matches = array();
if (preg_match_all('/((.+?):(.+?))(,| |$)/', $found_text, $matches)) {
$fields = content_fields();
foreach ($matches[1] as $index => $match) {
$field_name = $matches[2][$index];
$value = $matches[3][$index];
if (isset($field_name) && isset($value) && is_numeric($value) && isset($fields[$field_name]) && (!isset($filter) || isset($filter['number'][$field_name]))) {
// Create an active facet with the value found in the search text.
$category = new cck_facet_category($fields[$field_name], $value);
$facets[] = new cck_facet('number', $fields[$field_name], array($category));
}
}
}
// Remove the parsed text
$arg = search_query_insert($arg, 'number');
}
return $arg;
case 'node':
$fields = content_fields();
foreach ($fields as $field) {
if ((!isset($filter) || isset($filter['number'][$field['field_name']])) && isset($arg->{$field['field_name']}) && is_array($arg->{$field['field_name']})) {
// Iterate through the field's multiple values.
foreach ($arg->{$field['field_name']} as $item) {
$category = new cck_facet_category($field, array_shift($item));
$facets[] = new cck_facet('number', $field, array($category));
}
}
}
break;
}
}
; $Id$
name = Reference Facets
description = "Provides facets based on Node Reference and User Reference fields."
dependencies = content faceted_search cck_facets search
name = CCK Reference Facets
description = "Provides facets based on CCK Node Reference and User Reference fields."
dependencies = content faceted_search search
package = Faceted Search
<?php
// $Id$
/**
* Implementation of hook_uninstall().
*/
function reference_facets_uninstall() {
db_query("DELETE FROM {faceted_search_facets} WHERE facet_key = 'reference'");
}
......@@ -3,77 +3,105 @@
/**
* @file
* Provides facets based on Node Reference and User Reference fields.
* Provides facets based on CCK Node Reference and User Reference fields.
*/
require_once('./'. drupal_get_path('module', 'reference_facets') .'/cck_facets.inc');
/**
* Implementation of hook_cck_facets_factory().
*
* @param $type
* Type of object to create, either 'facet' or 'category'.
* @return
* Array of factory functions keyed by field type.
* Implementation of hook_faceted_search_collect().
*/
function reference_facets_cck_facets_factory($type) {
if ($type == 'category') {
return array(
'nodereference' => 'reference_facets_create_category',
'userreference' => 'reference_facets_create_category',
);
function reference_facets_faceted_search_collect(&$facets, $domain, $env_id, $filter, $arg = NULL) {
switch ($domain) {
case 'all':
$fields = content_fields();
foreach ($fields as $field) {
if ((!isset($filter) || isset($filter['reference'][$field['field_name']])) && ($field['type'] == 'nodereference' || $field['type'] == 'userreference')) {
$facets[] = new reference_facet($field);
}
}
break;
case 'text':
// Scan the given search text for a 'reference:{field_name}:{value}'
// token, and create facets from it.
if ($found_text = search_query_extract($arg, 'reference')) {
// Extract separate facets. Using a regex rather than a simple
// explode(',',$found_text) because commas might be used in field values
// and we want to ignore those when splitting the text.
$matches = array();
if (preg_match_all('/((.+?):(.+?))(,| |$)/', $found_text, $matches)) {
$fields = content_fields();
foreach ($matches[1] as $index => $match) {
$field_name = $matches[2][$index];
$value = $matches[3][$index];
if (isset($field_name) && isset($value) && is_numeric($value) && $value > 0 && isset($fields[$field_name]) && (!isset($filter) || isset($filter['reference'][$field_name]))) {
// Create an active facet with the value found in the search text.
$category = new reference_facet_category($fields[$field_name], $value);
$facets[] = new reference_facet($fields[$field_name], array($category));
}
}
}
// Remove the parsed text
$arg = search_query_insert($arg, 'reference');
}
return $arg;
case 'node':
$fields = content_fields();
foreach ($fields as $field) {
if ((!isset($filter) || isset($filter['reference'][$field['field_name']])) && isset($arg->{$field['field_name']}) && is_array($arg->{$field['field_name']})) {
// Iterate through the field's multiple values.
foreach ($arg->{$field['field_name']} as $item) {
$category = new reference_facet_category($field, array_shift($item));
$facets[] = new reference_facet($field, array($category));
}
}
}
break;
}
}
/**
* Create category, or a path of categories for the specified field value.
* A facet for CCK Node Reference and User Reference fields.
*
* @see cck_facets_create_category
* @see reference_facet_category
*/
function reference_facets_create_category($field, $value, $count = NULL, $get_path = TRUE) {
$db_info = _cck_facets_db_info($field);
$column = reset($db_info['columns']); // Get the first database column. Other columns are ignored.
if (is_array($value)) {
// Value is coming from the database.
$key = key($db_info['columns']);
$value = $value[$key];
class reference_facet extends cck_facet {
function reference_facet($field, $active_path = array()) {
parent::cck_facet('reference', $field, $active_path);
}
// Perform basic validation on user-specified value.
if (is_numeric($value) && $value > 0) {
$category = new reference_facet_category($field, $value, $count);
return $get_path ? array($category) : $category;
function build_categories($results) {
$categories = array();
while ($result = db_fetch_object($results)) {
$categories[] = new reference_facet_category($this->_field, $result->{$this->_field['field_name']}, $result->count);
}
return $categories;
}
}
/**
* A facet category for Node Reference and User Reference fields.
* A facet category for CCK Node Reference and User Reference fields.
*
* @see reference_facet
*/
class reference_facet_category extends cck_facet_category {
/**
* Constructor.
*/
function reference_facet_category($field, $value, $count = NULL) {
parent::cck_facet_category($field, $value, $count);
}
/**
* Return the label of this category.
*
* @param $html
* TRUE when HTML is allowed in the label, FALSE otherwise. Checking this
* flag allows implementors to provide a rich-text label if desired, and an
* alternate plain text version for cases where HTML cannot be used. The
* implementor is responsible to ensure adequate security filtering.
*/
function get_label($html = FALSE) {
$db_info = content_database_info($this->_field);
reset($db_info['columns']); // Get the first database column. Other columns are ignored!
$column_name = key($db_info['columns']); // Get the column name (required for the formatter).
$db_info = _cck_facets_db_info($this->_field);
// Get the label using the 'plain' formatter.
$label = content_format($this->_field['field_name'], array($column_name => $this->_value), 'plain');
$label = content_format($this->_field['field_name'], array(key($db_info['columns']) => $this->_value), 'plain');
// Note: The label is already filtered by the CCK formatter and does not
// need to be checked here.
// need to be filtered here.
return $html ? $label : strip_tags($label);
}
}
; $Id$
name = CCK Text Facets
description = "Provides facets based on CCK Text fields."
dependencies = content text faceted_search search
package = Faceted Search
......@@ -4,7 +4,7 @@
/**
* Implementation of hook_uninstall().
*/
function cck_facets_uninstall() {
db_query("DELETE FROM {faceted_search_facets} WHERE facet_key = 'cck'");
function text_facets_uninstall() {
db_query("DELETE FROM {faceted_search_facets} WHERE facet_key = 'text'");
}
<?php
// $Id$
/**
* @file
* Provides facets based on CCK Text fields.
*/
require_once('./'. drupal_get_path('module', 'text_facets') .'/cck_facets.inc');
/**
* Implementation of hook_faceted_search_collect().
*/
function text_facets_faceted_search_collect(&$facets, $domain, $env_id, $filter, $arg = NULL) {
switch ($domain) {
case 'all':
$fields = content_fields();
foreach ($fields as $field) {
if ((!isset($filter) || isset($filter['text'][$field['field_name']])) && $field['type'] == 'text') {
$facets[] = new text_facet($field);
}
}
break;
case 'text':
// Scan the given search text for a 'text:{field_name}:"{value}"'
// token, and create facets from it.
if ($found_text = _cck_facets_quoted_query_extract($arg, 'text')) {
// Extract separate facets. Using a regex rather than a simple
// explode(',',$found_text) because commas might be used in field values
// and we want to ignore those when splitting the text.
$matches = array();
if (preg_match_all('/((.+?):"(.+?)")(,| |$)/', $found_text, $matches)) {
$fields = content_fields();
foreach ($matches[1] as $index => $match) {
$field_name = $matches[2][$index];
$value = strtr($matches[3][$index], '""', '"');
if (isset($field_name) && isset($value) && isset($fields[$field_name]) && (!isset($filter) || isset($filter['text'][$field_name]))) {
// Create an active facet with the value found in the search text.
$category = new cck_facet_category($fields[$field_name], $value);
$facets[] = new text_facet($fields[$field_name], array($category));
}
}
}
// Remove the parsed text
$arg = _cck_facets_quoted_query_insert($arg, 'text');
}
return $arg;
case 'node':
$fields = content_fields();
foreach ($fields as $field) {
if ((!isset($filter) || isset($filter['text'][$field['field_name']])) && isset($arg->{$field['field_name']}) && is_array($arg->{$field['field_name']})) {
// Iterate through the field's multiple values.
foreach ($arg->{$field['field_name']} as $item) {
$category = new cck_facet_category($field, array_shift($item));
$facets[] = new text_facet($field, array($category));
}
}
}
break;
}
}
/**
* A facet for CCK Text fields.
*/
class text_facet extends cck_facet {
function text_facet($field, $active_path = array()) {
parent::cck_facet('text', $field, $active_path);
}
function get_text() {
if ($category = $this->get_active_category()) {
// Enclose value in double-quotes and escape double-quotes within the value.
return $this->_field['field_name'] .':"'. strtr($category->_value, '"', '""') .'"';
}
return '';
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment