array( 'label' => t('Auto-create node'), 'field types' => array('nodereference'), 'multiple values' => CONTENT_HANDLE_CORE, 'callbacks' => array( 'default value' => CONTENT_CALLBACK_DEFAULT, ), ), ); } /** * Implementation of hook_widget_settings(). */ function nodereference_autocreate_widget_settings($op, $widget) { switch ($op) { case 'form': $types = content_types(); $options_fields = array(); foreach($types as $content_name => $content_type) { $fields = $content_type['fields']; foreach ($fields as $name => $field) { //only allow field type text if ($field['type'] == 'text') { $options_fields[$field['field_name']] = strip_tags(t('Field %field in content type %content_type', array('%field' => check_plain(filter_xss($field['widget']['label'])), '%content_type' => check_plain(filter_xss($content_type['name']))))); } } $fields = $content_type['extra']; $exclude_fields = array( 'revision_information', 'author', 'options', 'comment_settings', 'menu', 'path', ); foreach ($fields as $name => $field) { if (!in_array($name, $exclude_fields)) { $options_fields[$content_type['type']. '_' . $name] = strip_tags(t('Field %field in content type %content_type', array('%field' => check_plain(filter_xss($field['label'])), '%content_type' => check_plain(filter_xss($content_type['name']))))); } } } $option = (isset($widget['nodereference_save_field_type']) && $options_fields[$widget['nodereference_save_field_type']]) ? $widget['nodereference_save_field_type'] : ''; $form = array(); $form['nodereference_save_field'] = array( '#type' => 'fieldset', '#title' => t('Auto-created node based in fields'), '#description' => t('Settings auto-created node based in fields.'), ); $form['nodereference_save_field']['nodereference_save_field_type'] = array( '#type' => 'select', '#title' => t('Save data in content field'), '#default_value' => $option, '#options' => $options_fields, '#required' => TRUE, ); $options = array( 'text_textfield' => 'textfield', 'text_textarea' => 'textarea', ); $option = (isset($widget['nodereference_field_type']) && $options[$widget['nodereference_field_type']]) ? $widget['nodereference_field_type'] : ''; $form['nodereference_save_field']['nodereference_field_type'] = array( '#type' => 'select', '#title' => t('Save data in content field'), '#default_value' => $option, '#options' => $options, '#required' => TRUE, ); $form['nodereference_save_field']['nodereference_title_default'] = array( '#title' => t('Title default'), '#type' => 'textfield', '#default_value' => isset($widget['nodereference_title_default']) ? $widget['nodereference_title_default'] : NULL, '#maxlength' => 255, ); $form['nodereference_save_field']['nodereference_title_delta'] = array( '#type' => 'checkbox', '#title' => t('Add delta in title'), '#default_value' => isset($widget['nodereference_title_delta']) ? $widget['nodereference_title_delta'] : NULL, '#return_value' => 1, ); return $form; break; case 'save': return array( 'nodereference_save_field_type', 'nodereference_field_type', 'nodereference_title_default', 'nodereference_title_delta', ); break; } } /** * Implementation of hook_widget(). */ function nodereference_autocreate_widget(&$form, &$form_state, $field, $items, $delta = 0) { switch ($field['widget']['type']) { case 'nodereference_autocreate': $element = array( '#type' => 'text_textfield', '#default_value' => isset($items[$delta]) ? $items[$delta] : NULL, '#value_callback' => 'nodereference_autocreate_value', '#process' => array('nodereference_autocreate_process'), ); $element['#type'] = $field['widget']['nodereference_field_type']; break; } return $element; } /** * Value for a nodereference auto-create element. * * Substitute in the node title for the node ID. */ function nodereference_autocreate_value($element, $edit = FALSE) { //get field data $field_name = $element['#field_name']; $type_name = $element['#type_name']; $field = content_fields($field_name, $type_name); $content_type = nodereference_autocreate_type_get($field['referenceable_types']); $type = content_types($content_type); $nodereference_save_field_type = $field['widget']['nodereference_save_field_type']; $pos = strpos($nodereference_save_field_type, $content_type); $field = $nodereference_save_field_type; if ($pos == 0) { $field = str_replace($content_type . '_', '', $nodereference_save_field_type); $field = str_replace('_field', '', $field); } $field_key = $element['#columns'][0]; if ($nid = $element['#default_value'][$field_key]) { if ($element['#nid'][$field_key]) { $nid = $element['#nid'][$field_key]; } $current_node = node_load($nid); $value = $current_node->{$field}; $current_value = $value; if (is_array($value)) { $current_value = $value[0]['value']; } else { $current_value = $value; } return array($field_key => $current_value); } return array($field_key => NULL); } /** * Process an individual element. * * @see nodereference_autocomplete_process() */ function nodereference_autocreate_process($element, $edit, $form_state, $form) { $field_key = $element['#columns'][0]; $element[$field_key] = array( '#type' => $element['#type'], '#default_value' => isset($element['#value']) ? $element['#value'] : '', // The following values were set by the content module and need to be // passed down to the nested element. '#title' => $element['#title'], '#required' => $element['#required'], '#description' => $element['#description'], '#field_name' => $element['#field_name'], '#type_name' => $element['#type_name'], '#delta' => $element['#delta'], '#columns' => $element['#columns'], '#nid' => 'casaloca', ); if (empty($element[$field_key]['#element_validate'])) { $element[$field_key]['#element_validate'] = array(); } array_unshift($element[$field_key]['#element_validate'], 'nodereference_autocreate_validate'); return $element; } /** * Validate an individual element. * * Create a node with the specified value on first save. Update title of * referenced node on each additional save. */ function nodereference_autocreate_validate($element, &$form_state) { $field_name = $element['#field_name']; $type_name = $element['#type_name']; $field = content_fields($field_name, $type_name); $field_key = $element['#columns'][0]; $delta = $element['#delta']; $value = $element['#value'][$field_key]; $nid = NULL; if ($value) { // Load the current value stored in the database. $self_nid = $form_state['values']['nid']; //get nid if lost(case editablefields) if(!$self_nid && $form_state['node']->nid) { $self_nid = $form_state['node']->nid; } $self = node_load($self_nid); $current_nid = $self->$field_name; $current_nid = $current_nid[$delta]['nid']; $default_title = 'node'; if (trim($field['widget']['nodereference_title_default'])) { $default_title = $field['widget']['nodereference_title_default']; } if ($field['widget']['nodereference_title_delta']) { $count = $delta + 1; $default_title .= $count; } $default_title = check_plain($default_title); $nodereference_save_field_type = $field['widget']['nodereference_save_field_type']; $content_type = nodereference_autocreate_type_get($field['referenceable_types']); $pos = strpos($nodereference_save_field_type, $content_type); $replace_field = $nodereference_save_field_type; $extra_field = FALSE; if ($pos == 0) { $replace_field = str_replace($content_type . '_', '', $nodereference_save_field_type); $replace_field = str_replace('_field', '', $replace_field); $extra_node->$replace_field = $value; } else { $extra_node->$replace_field[0]['value'] = $value; } if ($current_nid) { // Referenced node exists, update its title if changed. $referenced_node = node_load($current_nid); if ($referenced_node->{$replace_field} != $extra_node->{$replace_field} || $referenced_node->title != $default_title) { $referenced_node->title = $default_title; $referenced_node->$replace_field = $extra_node->$replace_field; node_save($referenced_node); } $nid = $referenced_node->nid; } else { // Create a new node with the specified title. global $user; $node = new stdClass(); $node->type = nodereference_autocreate_type_get($field['referenceable_types']); $node->title = $default_title; $node->uid = $user->uid; $node->{$replace_field} = $extra_node->{$replace_field}; node_save($node); if (!$node->nid) { form_error($element[$field_key], t('%name: failed to create sub node.', array('%name' => t($field['widget']['label'])))); } else { $nid = $node->nid; } } } form_set_value($element, $nid, $form_state); } /** * Implementation of hook_form_FORM_ID_alter(): content_field_edit_form. */ function nodereference_autocreate_form_content_field_edit_form_alter(&$form, $form_state) { if ($form['#field']['widget']['type'] == 'nodereference_autocreate') { $form['field']['referenceable_types']['#description'] .= t('Only one type can be referenced when using the ' . 'auto-create node widget. The node type referenced will be used when creating a node.'); $form['#validate'][] = 'nodereference_autocreate_content_field_edit_form_validate'; } } /** * Validate nodereference setting form. * * If widget type is nodereference_autocreate then check for multiple selected * referenceable types. */ function nodereference_autocreate_content_field_edit_form_validate($form, &$form_state) { if ($form_state['values']['widget_type'] == 'nodereference_autocreate') { $count = 0; if ($form_state['values']['referenceable_types']) { foreach ($form_state['values']['referenceable_types'] as $type => $enabled) { if ($enabled) { $count++; } } if ($count > 1) { form_set_error('referenceable_types', t('Only one content type can be referenced for widgets of type Auto-create node.')); } } } } /** * Get the referenced type. * * @param $referenceable_types * Referenceable types from field form. * @return * Referenced type. */ function nodereference_autocreate_type_get(array $referenceable_types) { foreach ($referenceable_types as $type => $enabled) { if ($enabled) { return $type; } } return NULL; }