noderefcreate.module in Node Reference Create 7
Same filename and directory in other branches
Defines a widget type for referencing one node from another and creating a new one if the provided doesn't exists.
File
noderefcreate.moduleView source
<?php
/**
* @file
* Defines a widget type for referencing one node from another
* and creating a new one if the provided doesn't exists.
*/
/**
* Implements hook_field_widget_info().
*
*/
function noderefcreate_field_widget_info() {
return array(
'noderefcreate_autocomplete' => array(
'label' => t('Autocomplete text field with create'),
'description' => t('Display the list of referenceable nodes as a textfield with autocomplete behaviour, if the node doesn´t exist, create it.'),
'field types' => array(
'node_reference',
),
'settings' => array(
'autocomplete_match' => 'contains',
'size' => 60,
'autocomplete_path' => 'node_reference/autocomplete',
),
),
);
}
/**
* Implements of hook_field_widget_settings_form
*/
function noderefcreate_field_widget_settings_form($field, $instance) {
$widget = $instance['widget'];
$defaults = field_info_widget_settings($widget['type']);
$settings = array_merge($defaults, $widget['settings']);
if ($widget['type'] == 'noderefcreate_autocomplete') {
$form['autocomplete_match'] = array(
'#type' => 'select',
'#title' => t('Autocomplete matching'),
'#default_value' => $settings['autocomplete_match'],
'#options' => array(
'starts_with' => t('Starts with'),
'contains' => t('Contains'),
),
'#description' => t('Select the method used to collect autocomplete suggestions. Note that <em>Contains</em> can cause performance issues on sites with thousands of nodes.'),
);
$form['size'] = array(
'#type' => 'textfield',
'#title' => t('Size of textfield'),
'#default_value' => $settings['size'],
'#element_validate' => array(
'_element_validate_integer_positive',
),
'#required' => TRUE,
);
}
return $form;
}
/**
* Implements hook_field_widget_form().
*/
function noderefcreate_field_widget_form(&$form, &$form_state, $field, $instance, $langcode, $items, $delta, $element) {
switch ($instance['widget']['type']) {
case 'noderefcreate_autocomplete':
$element += array(
'#type' => 'textfield',
'#default_value' => isset($items[$delta]['nid']) ? $items[$delta]['nid'] : NULL,
'#autocomplete_path' => $instance['widget']['settings']['autocomplete_path'] . '/' . $instance['entity_type'] . '/' . $instance['bundle'] . '/' . $field['field_name'],
'#size' => $instance['widget']['settings']['size'],
'#element_validate' => array(
'noderefcreate_autocomplete_validate',
),
'#value_callback' => 'node_reference_autocomplete_value',
);
break;
}
return array(
'nid' => $element,
);
}
/**
* Validation callback for a noderefcreate autocomplete element.
*
* This is mostly a copy of node_reference validate function,
* and we just create new node in case no node with provided title exists.
*/
function noderefcreate_autocomplete_validate($element, &$form_state, $form) {
$field = field_widget_field($element, $form_state);
$instance = field_widget_instance($element, $form_state);
$value = $element['#value'];
$nid = NULL;
if (strlen(trim($value)) > 0) {
// Check whether we have an explicit "[nid:n]" input.
preg_match('/^(?:\\s*|(.*) )?\\[\\s*nid\\s*:\\s*(\\d+)\\s*\\]$/', $value, $matches);
if (!empty($matches)) {
// Explicit nid. Check that the 'title' part matches the actual title for
// the nid.
list(, $title, $nid) = $matches;
if (!empty($title)) {
$real_title = db_select('node', 'n')
->fields('n', array(
'title',
))
->condition('n.nid', $nid)
->execute()
->fetchField();
if (trim($title) != trim($real_title)) {
form_error($element, t('%name: title mismatch. Please check your selection.', array(
'%name' => $instance['label'],
)));
}
}
}
else {
// No explicit nid (the submitted value was not populated by autocomplete
// selection). Get the nid of a referencable node from the entered title.
$options = array(
'string' => $value,
'match' => 'equals',
'ids' => NULL,
'limit' => 1,
);
$reference = node_reference_potential_references($field, $options);
if ($reference) {
// @todo The best thing would be to present the user with an
// additional form, allowing the user to choose between valid
// candidates with the same title. ATM, we pick the first
// matching candidate...
$nid = key($reference);
}
else {
$newnode = NULL;
if (is_array($field['settings']['referenceable_types'])) {
foreach (array_filter($field['settings']['referenceable_types']) as $related_type) {
$newnode->type = $related_type;
}
}
global $user;
$newnode->uid = $user->uid;
$newnode->title = $value;
$newnode->language = $element['#language'];
if (module_exists('comment')) {
$newnode->comment = variable_get("comment_{$newnode->type}", COMMENT_NODE_OPEN);
}
node_save($newnode);
$nid = $newnode->nid;
}
}
}
else {
if (strlen($value) > 0) {
// if we got here then the user filled the name with spaces
form_error($element, t('%name: title is empty. Please check your input.', array(
'%name' => $instance['label'],
)));
}
}
// Set the element's value as the node id that was extracted from the entered
// input.
form_set_value($element, $nid, $form_state);
}
/**
* Implements hook_field_widget_error().
*/
function noderefcreate_field_widget_error($element, $error, $form, &$form_state) {
form_error($element['nid'], $error['message']);
}
Functions
Name![]() |
Description |
---|---|
noderefcreate_autocomplete_validate | Validation callback for a noderefcreate autocomplete element. |
noderefcreate_field_widget_error | Implements hook_field_widget_error(). |
noderefcreate_field_widget_form | Implements hook_field_widget_form(). |
noderefcreate_field_widget_info | Implements hook_field_widget_info(). |
noderefcreate_field_widget_settings_form | Implements of hook_field_widget_settings_form |