You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
464 lines
15 KiB
464 lines
15 KiB
<?php |
|
// $Id$ |
|
|
|
/** |
|
* @file |
|
* An example to define a simple field, widget, and formatter. |
|
* A module could define only a field, only a widget, only a |
|
* formatter, or any combination. Widgets and formatters must |
|
* declare what kind of field they work with, which can be any |
|
* existing field as well as any new field the module creates. |
|
*/ |
|
|
|
//==========================================// |
|
// DEFINING A FIELD |
|
//==========================================// |
|
|
|
/** |
|
* Implementation of hook_field_info(). |
|
*/ |
|
function pidfield_field_info() { |
|
return array( |
|
// The machine name of the field, |
|
// no more than 32 characters. |
|
'pidfield' => array( |
|
// The human-readable label of the field that will be |
|
// seen in the Manage fields screen. |
|
'label' => t('Fedora PID field'), |
|
// A description of what type of data the field stores. |
|
'description' => t('Store a reference to a PID in this site\'s Fedora repository.'), |
|
// An icon to use in Panels. |
|
'content_icon' => 'icon_content_text.png', |
|
), |
|
); |
|
} |
|
|
|
/** |
|
* Implementation of hook_field_settings(). |
|
*/ |
|
function pidfield_field_settings($op, $field) { |
|
switch ($op) { |
|
// Create the form element to be used on the field |
|
// settings form. Field settings will be the same for |
|
// all shared instances of the same field and should |
|
// define the way the value will be stored |
|
// in the database. |
|
case 'form': |
|
$form = array(); |
|
$form['max_length'] = array( |
|
'#type' => 'textfield', |
|
'#title' => t('Maximum length'), |
|
'#default_value' => is_numeric($field['max_length']) ? $field['max_length'] : 64, |
|
'#required' => FALSE, |
|
|
|
// Use #element_validate to validate the settings. |
|
'#element_validate' => array('_pidfield_length_validate'), |
|
'#description' => t('The maximum length of the field in characters. Must be a number between 1 and 255'), |
|
); |
|
return $form; |
|
|
|
// Return an array of the names of the field settings |
|
// defined by this module. These are the items that |
|
// CCK will store in the field definition |
|
// and they will be available in the $field array. |
|
// This should match the items defined in 'form' above. |
|
case 'save': |
|
return array('max_length'); |
|
|
|
// Define the database storage for this field using |
|
// the same construct used by schema API. Most fields |
|
// have only one column, but there can be any number |
|
// of different columns. After the schema API values, |
|
// add two optional values to each column, |
|
// 'views', to define a Views field |
|
// 'sortable', to add a Views sort field |
|
case 'database columns': |
|
$columns['value'] = array( |
|
'type' => 'varchar', |
|
'length' => is_numeric($field['max_length']) ? $field['max_length'] : 64, |
|
'not null' => FALSE, |
|
'sortable' => TRUE, |
|
'views' => TRUE, |
|
); |
|
return $columns; |
|
|
|
// Optional: Make changes to the default $data array |
|
// created for Views. Omit this if no changes are |
|
// needed, use it to add a custom handler or make |
|
// other changes. |
|
case 'views data': |
|
// Start with the $data created by CCK |
|
// and alter it as needed. The following |
|
// code illustrates how you would retrieve |
|
// the necessary data. |
|
$data = content_views_field_views_data($field); |
|
$db_info = content_database_info($field); |
|
$table_alias = content_views_tablename($field); |
|
$field_data = $data[$table_alias][$field['field_name'] .'_value']; |
|
// Make changes to $data as needed here. |
|
return $data; |
|
} |
|
} |
|
|
|
/** |
|
* Custom validation of settings values. |
|
* |
|
* Create callbacks like this to do settings validation. |
|
*/ |
|
function _pidfield_length_validate($element, &$form_state) { |
|
$value = $form_state['values']['max_length']; |
|
if ($value && !is_numeric($value)|| $value < 1 || $value > 255) { |
|
form_set_error('max_length', t('"Max length" must be a number between 1 and 64.')); |
|
} |
|
} |
|
|
|
/** |
|
* Implementation of hook_field(). |
|
*/ |
|
function pidfield_field($op, &$node, $field, &$items, $teaser, $page) { |
|
switch ($op) { |
|
// Do validation on the field values here. The widget |
|
// will do its own validation and you cannot make any |
|
// assumptions about what kind of widget has been used, |
|
// so don't validate widget values, only field values. |
|
case 'validate': |
|
if (is_array($items)) { |
|
foreach ($items as $delta => $item) { |
|
// The error_element is needed so that CCK can |
|
// set an error on the right sub-element when |
|
// fields are deeply nested in the form. |
|
$error_element = isset($item['_error_element']) ? $item['_error_element'] : ''; |
|
if (is_array($item) && isset($item['_error_element'])) unset($item['_error_element']); |
|
if (!empty($item['value'])) { |
|
if (!empty($field['max_length']) && drupal_strlen($item['value']) > $field['max_length']) { |
|
form_set_error($error_element, t('%name: the value may not be longer than %max characters.', array('%name' => $field['widget']['label'], '%max' => $field['max_length']))); |
|
} |
|
} |
|
} |
|
} |
|
return $items; |
|
|
|
// This is where you make sure that user-provided |
|
// data is sanitized before being displayed. |
|
case 'sanitize': |
|
foreach ($items as $delta => $item) { |
|
$pid_field_text = check_plain($item['value']); |
|
$items[$delta]['safe'] = $pid_field_text; |
|
} |
|
} |
|
} |
|
|
|
/** |
|
* Implementation of hook_content_is_empty(). |
|
* |
|
* CCK has no way to know if something like a zero is |
|
* an empty value or a valid value, so return |
|
* TRUE or FALSE to a populated field $item array. |
|
* CCK uses this to remove empty multi-value elements |
|
* from forms. |
|
*/ |
|
function pidfield_content_is_empty($item, $field) { |
|
if (empty($item['value'])) { |
|
return TRUE; |
|
} |
|
return FALSE; |
|
} |
|
|
|
/** |
|
* Implementation of hook content_generate(). |
|
* |
|
* Optional, provide dummy value for nodes created |
|
* by the Devel Generate module. |
|
*/ |
|
function pidfield_content_generate($node, $field) { |
|
$node_field = array(); |
|
// Generate a value that respects max_length. |
|
if (empty($field['max_length'])) { |
|
$field['max_length'] = 12; |
|
} |
|
$node_field['value'] = user_password($field['max_length']); |
|
return $node_field; |
|
} |
|
|
|
/** |
|
* Implementation of hook_token_list() |
|
* and hook_token_values(). |
|
* |
|
* Optional, provide token values for this field. |
|
*/ |
|
function pidfield_token_list($type = 'all') { |
|
if ($type == 'field' || $type == 'all') { |
|
$tokens = array(); |
|
|
|
$tokens['pidfield']['raw'] = t('Just the PID itself.'); |
|
$tokens['pidfield']['formatted'] = t('A PID with a hyperlink'); |
|
|
|
return $tokens; |
|
} |
|
} |
|
|
|
function pidfield_token_values($type, $object = NULL) { |
|
if ($type == 'field') { |
|
$item = $object[0]; |
|
|
|
$tokens['raw'] = $item['value']; |
|
$tokens['formatted'] = isset($item['view']) ? $item['view'] : ''; |
|
return $tokens; |
|
} |
|
} |
|
|
|
//==========================================// |
|
// DEFINING A FORMATTER |
|
//==========================================// |
|
|
|
/** |
|
* Implementation of hook_theme(). |
|
*/ |
|
function pidfield_theme() { |
|
return array( |
|
// Themes for the formatters. |
|
'pidfield_formatter_default' => array( |
|
'arguments' => array('element' => NULL), |
|
), |
|
'pidfield_formatter_plain' => array( |
|
'arguments' => array('element' => NULL), |
|
), |
|
); |
|
} |
|
|
|
/** |
|
* Implementation of hook_field_formatter_info(). |
|
* |
|
* All fields should have a 'default' formatter. |
|
* Any number of other formatters can be defined as well. |
|
* It's nice for there always to be a 'plain' option |
|
* for the raw value, but that is not required. |
|
* |
|
*/ |
|
function pidfield_field_formatter_info() { |
|
return array( |
|
// The machine name of the formatter. |
|
'default' => array( |
|
// The human-readable label shown on the Display |
|
// fields screen. |
|
'label' => t('Default'), |
|
// An array of the field types this formatter |
|
// can be used on. |
|
'field types' => array('pidfield'), |
|
// CONTENT_HANDLE_CORE: CCK will pass the formatter |
|
// a single value. |
|
// CONTENT_HANDLE_MODULE: CCK will pass the formatter |
|
// an array of all the values. None of CCK's core |
|
// formatters use multiple values, that is an option |
|
// available to other modules that want it. |
|
'multiple values' => CONTENT_HANDLE_CORE, |
|
), |
|
'plain' => array( |
|
'label' => t('Plain text'), |
|
'field types' => array('pidfield'), |
|
'multiple values' => CONTENT_HANDLE_CORE, |
|
), |
|
); |
|
} |
|
|
|
/** |
|
* Theme function for 'default' example field formatter. |
|
* |
|
* $element['#item']: the sanitized $delta value for the item, |
|
* $element['#field_name']: the field name, |
|
* $element['#type_name']: the $node->type, |
|
* $element['#formatter']: the $formatter_name, |
|
* $element'#node']: the $node, |
|
* $element['#delta']: the delta of this item, like '0', |
|
* |
|
*/ |
|
function theme_pidfield_formatter_default($element) { |
|
//return $element['#item']['safe']; |
|
$pid = $element['#item']['safe']; |
|
|
|
module_load_include('inc', 'fedora_repository', 'api/fedora_item'); |
|
$item = new Fedora_Item($pid); |
|
|
|
return fedora_repository_get_items($pid); |
|
//return $item->objectProfile->objLabel; |
|
} |
|
|
|
/** |
|
* Theme function for 'plain' example field formatter. |
|
*/ |
|
function theme_pidfield_formatter_plain($element) { |
|
return strip_tags($element['#item']['safe']); |
|
} |
|
|
|
//==========================================// |
|
// DEFINING A WIDGET |
|
//==========================================// |
|
|
|
/** |
|
* Implementation of hook_widget_info(). |
|
* |
|
* Here we indicate that the content module will handle |
|
* the default value and multiple values for these widgets. |
|
* |
|
* Callbacks can be omitted if default handing is used. |
|
* They're included here just so this module can be used |
|
* as an example for custom modules that might do things |
|
* differently. |
|
*/ |
|
function pidfield_widget_info() { |
|
return array( |
|
// The machine name of the widget, no more than 32 |
|
// characters. |
|
'pidfield_widget' => array( |
|
// The human-readable label of the field that will be |
|
// seen in the Manage fields screen. |
|
'label' => t('PID Field widget'), |
|
// An array of the field types this widget can be |
|
// used with. |
|
'field types' => array('pidfield'), |
|
// Who will handle multiple values, default is core. |
|
// 'CONTENT_HANDLE_MODULE' means the module does it. |
|
// See optionwidgets for an example of a module that |
|
// handles its own multiple values. |
|
'multiple values' => CONTENT_HANDLE_CORE, |
|
'callbacks' => array( |
|
// Who will create the default value, default is core. |
|
// 'CONTENT_CALLBACK_CUSTOM' means the module does it. |
|
// 'CONTENT_CALLBACK_NONE' means this widget has |
|
// no default value. |
|
'default value' => CONTENT_CALLBACK_DEFAULT, |
|
), |
|
), |
|
); |
|
} |
|
|
|
/** |
|
* Implementation of hook_widget_settings(). |
|
*/ |
|
function pidfield_widget_settings($op, $widget) { |
|
switch ($op) { |
|
// Create the form element to be used on the widget |
|
// settings form. Widget settings can be different |
|
// for each shared instance of the same field and |
|
// should define the way the value is displayed to |
|
// the user in the edit form for that content type. |
|
case 'form': |
|
$form = array(); |
|
$size = (isset($widget['size']) && is_numeric($widget['size'])) ? $widget['size'] : 60; |
|
$form['size'] = array( |
|
'#type' => 'textfield', |
|
'#title' => t('Size of textfield'), |
|
'#default_value' => $size, |
|
'#element_validate' => array('_element_validate_integer_positive'), |
|
'#required' => TRUE, |
|
); |
|
return $form; |
|
|
|
// Return an array of the names of the widget settings |
|
// defined by this module. These are the items that |
|
// CCK will store in the widget definition and they |
|
// will be available in the $field['widget'] array. |
|
// This should match the items defined in 'form' above. |
|
case 'save': |
|
return array('size'); |
|
} |
|
} |
|
|
|
/** |
|
* Implementation of hook_widget(). |
|
* |
|
* Attach a single form element to the form. |
|
* |
|
* CCK core fields only add a stub element and builds |
|
* the complete item in #process so reusable elements |
|
* created by hook_elements can be plugged into any |
|
* module that provides valid $field information. |
|
* |
|
* Custom widgets that don't care about using hook_elements |
|
* can be built out completely at this time. |
|
* |
|
* If there are multiple values for this field and CCK is |
|
* handling multiple values, the content module will call |
|
* this function as many times as needed. |
|
* |
|
* @param $form |
|
* the entire form array, |
|
* $form['#node'] holds node information |
|
* @param $form_state |
|
* the form_state, |
|
* $form_state['values'][$field['field_name']] |
|
* holds the field's form values. |
|
* @param $field |
|
* the field array |
|
* @param $items |
|
* array of default values for this field |
|
* @param $delta |
|
* the order of this item in the array of |
|
* subelements (0, 1, 2, etc) |
|
* |
|
* @return |
|
* the form item for a single element for this field |
|
*/ |
|
function pidfield_widget(&$form, &$form_state, $field, $items, $delta = 0) { |
|
|
|
$element['value'] = array( |
|
'#type' => 'textfield', |
|
'#title' => $field['widget']['label'], |
|
'#default_value' => isset($items[$delta]['value']) ? $items[$delta]['value'] : NULL, |
|
'#autocomplete_path' => $element['#autocomplete_path'], |
|
'#size' => !empty($field['widget']['size']) ? $field['widget']['size'] : 60, |
|
'#attributes' => array('class' => 'pidfield'), |
|
'#maxlength' => !empty($field['max_length']) ? $field['max_length'] : NULL, |
|
); |
|
|
|
// Used so that hook_field('validate') knows where to |
|
// flag an error in deeply nested forms. |
|
if (empty($form['#parents'])) { |
|
$form['#parents'] = array(); |
|
} |
|
$element['_error_element'] = array( |
|
'#type' => 'value', |
|
'#value' => implode('][', array_merge($form['#parents'], array('value'))), |
|
); |
|
|
|
return $element; |
|
} |
|
|
|
function get_node_references_for_fedora_item($item) { |
|
$result = db_query("SELECT * |
|
FROM {content_node_field} nf |
|
INNER JOIN {content_node_field_instance} ni ON nf.field_name = ni.field_name |
|
WHERE nf.type = 'pidfield'"); |
|
while ($field = db_fetch_array($result)) { |
|
|
|
|
|
$db_info = content_database_info($field); |
|
|
|
|
|
|
|
|
|
|
|
$ids = db_query("SELECT nid FROM {". $db_info['table'] ."} WHERE ". $field['field_name'] ."_value=\"". $item->pid."\""); |
|
|
|
$results = array(); |
|
while ($data = db_fetch_object($ids)) { |
|
//$additions[] = node_load($data->vid); |
|
|
|
$results[] = $data->nid; |
|
|
|
//$referred_node = node_load(array('nid'=>$data->nid) ); |
|
|
|
} |
|
return $results; |
|
} |
|
|
|
} |
|
|
|
function fedora_pidfield_redirect_to_node($item) { |
|
$node_references = get_node_references_for_fedora_item($item); |
|
if (!empty($node_references)) { |
|
if (strstr( drupal_get_destination(), urlencode('fedora/repository'))) { |
|
drupal_goto(drupal_get_path_alias("node/".$node_references[0])); |
|
} |
|
} |
|
} |