diff -up addnode/addnode.info ../addnode_changes/addnode.info --- addnode/addnode.info 2007-05-08 06:45:01.000000000 -0500 +++ ../addnode_changes/addnode.info 2008-10-18 13:31:33.000000000 -0500 @@ -1,11 +1,7 @@ -; $Id: addnode.info,v 1.1.2.2 2007/05/08 11:37:13 lionfish Exp $ -name = Add Node Widget -description = "Allows a user to choose to create a new node, rather than select one from a node-reference list. (subform version)" -dependencies = content subform_element -version = "5.x-1.2" -package = CCK - -; Information added by drupal.org packaging script on 2007-05-08 -version = "5.x-1.2" -project = "addnode" - +; $Id: addnode.info,v 1.1.2.3 2007/06/18 23:06:29 dww Exp $ +name = Add Node Widget +description = "Allows a user to choose to create a new node, rather than select one from a node-reference list. (subform version)" +dependencies[] = content +dependencies[] = subform_element +package = CCK +core = 6.x diff -up addnode/addnode.module ../addnode_changes/addnode.module --- addnode/addnode.module 2007-05-08 06:37:13.000000000 -0500 +++ ../addnode_changes/addnode.module 2008-10-18 13:36:07.000000000 -0500 @@ -1,367 +1,361 @@ -'.t("Provides an option to the user to create a new node type.").'

'; - break; - } - return $output; -} - -/** - * Implementation of hook_widget_info. - * Specifies the label and that it is a widget for the nodereference field type - */ -function addnode_widget_info() -{ - return array( - 'addnode_select' => array( - 'label' => 'AddNode List', - 'field types' => array('nodereference'), - ), - ); -} - -/** - * Implementation of hook_widget - */ -function addnode_widget($op, &$node, $field, &$node_field) -{ - //need this module for the_nodereference_potential_references function. - include_once(drupal_get_path('module', 'content').'/nodereference.module'); - - if ($field['widget']['type'] == 'addnode_select') - { - switch ($op) { - case 'prepare form values': - //puts node_field (original) values into a temporary bit of the array called default nids - $node_field_transposed = content_transpose_array_rows_cols($node_field); - $node_field['default nids'] = $node_field_transposed['nid']; - break; - case 'form': - //adds javascript - $path = drupal_get_path('module','addnode'); - drupal_add_js($path . '/addnode.js'); - - $form = array(); - $selectedoptions = array(); - - //gets the list of all potential nodes that could be referenced - $options = _nodereference_potential_references($field, true); - - foreach ($options as $key => $value) { - $options[$key] = _nodereference_item($field, $value); - } - - //string describing what can be added. If there's one type it will be that, otherwise it will be - //just 'item'. - $typedesc = ""; - $type_count=0; //counts up how many types there are - $type_list=array(); //list of the types - - //If referenceable_types is not an array, give up. - if (!is_array($field['referenceable_types'])) - { - return $form; - } - - //add referenceable types to the $type_list array - foreach ($field['referenceable_types'] as $ref_type) - { - if ($ref_type) - { - $typedesc = $ref_type; - $type_count++; - $type_list[] = $ref_type; - } - } - - //if there are no types available, give up. - if ($type_count==0) - { - //@todo Need to display something explaining the problem. - return $form; - } - //converts the type name to a human readable one - $typedesc = node_get_types('type', $typedesc); - $typedesc = $typedesc->name; - - //If there's more than one type available then we use the term 'item' to describe them - if ($type_count>1) - { - $typedesc = "item"; - } - - $fieldname=$field['field_name']; - $title=t($field['widget']['label']); - - //$createmsg is a message such as "Create a new _fund_ or _pot_" with links in. - $createmsg=_addnode_create_new_message($type_count, $fieldname, $type_list); - - $prefix = ''; - $suffix = ''; - $subsuffix = ""; - - //this prefix builds the table headers etc. - $prefix = ""; - $prefix.= "$title:"; - $prefix.= ""; - $prefix.= ""; - $prefix.= "", array('!typedesc'=>"$typedesc")); - $prefix.= ""; - $prefix.= ""; - $prefix.= ""; - $prefix.= ""; - $suffix.= ""; - $subsuffix.= ""; - $subsuffix.= "
"; - $prefix.= ""; - $prefix.= t("Select !typedesc already available"; - $prefix.= $createmsg;//msg that says 'Create an item' or whatever - $prefix.= "
"; - //select box goes here - $suffix.= ""; - //the subforms go here - //the last subform must suffix with: - $subsuffix.= "
"; - -///This hidden form element has been moved above the subforms to allow it to be processed before their -///#after_build functions run (as they will need the values in this element). - //whether we've selected something from the select box, or created a new item - //is stored in this hidden field. So the submit functions know what to do. - $form["addnode_".$fieldname] = array( - '#type' => 'hidden', - '#title' => t('selection or creation'), - '#default_value' => '', - '#attributes' => array ( - 'class' => 'addnode_source', - ), - ); - - $weight = $field['weight']; - - //select box - $form[$fieldname]['#tree'] = TRUE; - $form[$fieldname]['nids'] = array( - '#type' => 'select', - '#title' => '', //no title for this bit - '#default_value' => $node_field['default nids'], - '#multiple' => TRUE, - '#options' => $options, - '#required' => $field['required'], - '#description' => $field['widget']['description'], - '#prefix' => $prefix, - '#suffix' => $suffix, - '#size' => 15, - '#weight' => $weight, - '#attributes' => array( - 'style' => 'width:90%', - 'class' => "addnode_select", - 'id' => "$fieldname", - ), - ); - - //loops through the types this field can be. - foreach ($type_list as $typename) - { - $weight = $weight + 0.1;//puts them in an order. - - $subnode = array('uid' => $node->uid, 'type' => $typename); - //the name of the array below this field type, needed to divide the subforms. - $subfieldname = 'node_'.$typename; - $form[$fieldname][$subfieldname] = array( - '#type' => 'subform', - '#id' => $typename.'_node_form', - '#arguments' => array($subnode), - '#weight' => $weight, - '#prefix' => "", - '#suffix' => "", - '#after_build' => array('subform_element_build_subform','addnode_fix_subform'), - '#fieldname' => $fieldname, - '#extra_form' => array("#fieldname"=>$fieldname), - ); - } - //updates the last suffix to include the subsuffix (which closes the table) - $form[$fieldname][$subfieldname]['#suffix'] .= $subsuffix; - - //add submit handlers: - //Add the nids of the newly created sub-nodes to the node - $form['#submit']['addnode_addnids_submit'] = array(); - //the subform element submit handler - $form['#submit']['subform_element_submit'] = array(); - //the handler for the base node (todo: Is this still necessary, I think subform_element might do this) - $form['#submit']['node_form_submit'] = array(); - - return $form; - case 'process form values': - $node_field = content_transpose_array_rows_cols(array('nid' => $node_field['nids'])); - break; - case 'submit': - break; - } - } -} - -/** - * This is called as an #after_build function for each subform. - *It 1) Disables the subform's validation etc if it's unused - * 2) Removes the subform's buttons. - */ -function addnode_fix_subform($form_element, &$form_values) -{ - //get the subform array (from the subform_element module) - global $subforms; - - //the type of node to create - $nodetype = $form_element['#arguments'][0]['type']; - //the name of the field the addnode widget is for - $current_fieldname = $form_element['#fieldname']; - - //for each field in the form, look for addnode_[blah] - foreach($form_values as $key => $value) - { - //if the field key begins 'addnode_' then it's one of the hidden fields, we use these to identify the names of potential subforms - if (strpos($key, 'addnode_') === 0) - { - //get the fieldname (the bit after the 'addnode_' in the key). - $fieldname = substr($key, 8); - if ($fieldname == $current_fieldname) - { - //find out which subform's the source (it will be the value of this key). - $source = $value; - //if it's not '' then we're creating a new node. (if it is '' then we must be using the select box). - //in other words, we disable subform processing if $source = '' or it's not related to this subform - $disable = TRUE; - - if (strlen($source)>0) //if we're not using the select box... - { - if ($source == $nodetype) //and we've chosen this subform over any other - { - $disable = FALSE; - } - } - - if ($disable) //disable this subform as it's not being used. - { - $form_element['#validate'] = array(); - } - } - } - } - -//Remove submit and preview buttons from the subform. - $form_element['#form']['submit']['#attributes'] = array( - 'style' => 'height:0px; visibility:hidden;', - ); - $form_element['#form']['preview']['#attributes'] = array( - 'style' => 'height:0px; visibility:hidden;', - ); - - return $form_element; -} - -/** - * Called as a main form submit handler. It submits the subforms and gets the nids then puts them into - * the main node. - */ -function addnode_addnids_submit($form_id, &$form_values) -{ - //copied from subform_element_submit, allows us to get hold of the redirects and get the nids from them - global $subforms; - if (isset($subforms)) { - foreach ($subforms as $key => $subform) { - if (!isset($subform['#submitted'])) { - $subforms[$key]['#submitted'] = TRUE; - $redirect = subform_element_call('drupal_submit_form', $subform['#post']['form_id'], $subform); - $fieldname = $subform['#fieldname']; - $split = explode("/", $redirect); - $newnid = $split[1]; - //unset the current array, and replace it with a new array. - //note that as multiselect is currently set, this is an array - // @todo allow multi/single select!! - unset($form_values[$fieldname]['nids']); - $form_values[$fieldname]['nids'] = array ( $newnid => $newnid ); - } - } - return $redirect; - } -} - -/** - * This outputs HTML for the 'create new nodetype' link message. - * @param $type_count - * Number of types that could be added - * - * @param $fieldname - * The fieldname of this addnode field - * - * @param $type_list - * List of types - */ -function _addnode_create_new_message($type_count, $fieldname, $type_list) -{ - $msg=""; - $spanmsg.= ""; - - //if there's only one type then the message is of the form "Create a new blah" - if ($type_count==1) - { - $atype=$type_list[0]; - $typedesc = node_get_types('type', $atype); - $typedesc = $typedesc->name; - - //pretransmsg is message before translation. - $pretransmsg = "or "; - $pretransmsg.= "!spanmsg"; - $pretransmsg.= "create a new !typedesc"; - $pretransmsg.= ""; - $pretransmsg.= ""; - $vars = array('!fieldname' => $fieldname, '!atype' => $atype, '!spanmsg' => $spanmsg, '!typedesc' => $typedesc); - $msg.= t($pretransmsg, $vars); - } - - //if there's more than one type then the message is of the form "Create a new blah or blah" - if ($type_count>1) - { - $vars = array(); - $msg.= t("or create a new "); - $tempcnt=0; - foreach ($type_list as $atype) - { - $typedesc = node_get_types('type', $atype); - $typedesc = $typedesc->name; - $msg.= ""; - $msg.= $spanmsg; - $msg.= "$typedesc"; - $msg.= ""; - $msg.= ""; - $tempcnt++; - if ($tempcnt == $type_count-1) - { - $msg.= t(" or "); - } - else - { - $msg.= t(", "); - } - } - } - $msg .= ""; - return $msg; -} + array( + 'label' => 'AddNode List', + 'field types' => array('nodereference'), + ), + ); +} + +/** + * Implementation of hook_widget + */ +function addnode_widget($op, &$node, $field, &$node_field) +{ + //need this module for the_nodereference_potential_references function. + include_once(drupal_get_path('module', 'content').'/nodereference.module'); + + if ($field['widget']['type'] == 'addnode_select') + { + switch ($op) { + case 'prepare form values': + //puts node_field (original) values into a temporary bit of the array called default nids + $node_field_transposed = content_transpose_array_rows_cols($node_field); + $node_field['default nids'] = $node_field_transposed['nid']; + break; + case 'form': + //adds javascript + $path = drupal_get_path('module','addnode'); + drupal_add_js($path . '/addnode.js'); + + $form = array(); + $selectedoptions = array(); + + //gets the list of all potential nodes that could be referenced + $options = _nodereference_potential_references($field, true); + + foreach ($options as $key => $value) { + $options[$key] = _nodereference_item($field, $value); + } + + //string describing what can be added. If there's one type it will be that, otherwise it will be + //just 'item'. + $typedesc = ""; + $type_count=0; //counts up how many types there are + $type_list=array(); //list of the types + + //If referenceable_types is not an array, give up. + if (!is_array($field['referenceable_types'])) + { + return $form; + } + + //add referenceable types to the $type_list array + foreach ($field['referenceable_types'] as $ref_type) + { + if ($ref_type) + { + $typedesc = $ref_type; + $type_count++; + $type_list[] = $ref_type; + } + } + + //if there are no types available, give up. + if ($type_count==0) + { + //@todo Need to display something explaining the problem. + return $form; + } + //converts the type name to a human readable one + $typedesc = node_get_types('type', $typedesc); + $typedesc = $typedesc->name; + + //If there's more than one type available then we use the term 'item' to describe them + if ($type_count>1) + { + $typedesc = "item"; + } + + $fieldname=$field['field_name']; + $title=t($field['widget']['label']); + + //$createmsg is a message such as "Create a new _fund_ or _pot_" with links in. + $createmsg=_addnode_create_new_message($type_count, $fieldname, $type_list); + + $prefix = ''; + $suffix = ''; + $subsuffix = ""; + + //this prefix builds the table headers etc. + $prefix = ""; + $prefix.= "$title:"; + $prefix.= ""; + $prefix.= ""; + $prefix.= "", array('!typedesc'=>"$typedesc")); + $prefix.= ""; + $prefix.= ""; + $prefix.= ""; + $prefix.= ""; + $suffix.= ""; + $subsuffix.= ""; + $subsuffix.= "
"; + $prefix.= ""; + $prefix.= t("Select !typedesc already available"; + $prefix.= $createmsg;//msg that says 'Create an item' or whatever + $prefix.= "
"; + //select box goes here + $suffix.= ""; + //the subforms go here + //the last subform must suffix with: + $subsuffix.= "
"; + +///This hidden form element has been moved above the subforms to allow it to be processed before their +///#after_build functions run (as they will need the values in this element). + //whether we've selected something from the select box, or created a new item + //is stored in this hidden field. So the submit functions know what to do. + $form["addnode_".$fieldname] = array( + '#type' => 'hidden', + '#title' => t('selection or creation'), + '#default_value' => '', + '#attributes' => array ( + 'class' => 'addnode_source', + ), + ); + + $weight = $field['weight']; + + //select box + $form[$fieldname]['#tree'] = TRUE; + $form[$fieldname]['nids'] = array( + '#type' => 'select', + '#title' => '', //no title for this bit + '#default_value' => $node_field['default nids'], + '#multiple' => TRUE, + '#options' => $options, + '#required' => $field['required'], + '#description' => $field['widget']['description'], + '#prefix' => $prefix, + '#suffix' => $suffix, + '#size' => 15, + '#weight' => $weight, + '#attributes' => array( + 'style' => 'width:90%', + 'class' => "addnode_select", + 'id' => "$fieldname", + ), + ); + + //loops through the types this field can be. + foreach ($type_list as $typename) + { + $weight = $weight + 0.1;//puts them in an order. + + $subnode = array('uid' => $node->uid, 'type' => $typename); + //the name of the array below this field type, needed to divide the subforms. + $subfieldname = 'node_'.$typename; + $form[$fieldname][$subfieldname] = array( + '#type' => 'subform', + '#id' => $typename.'_node_form', + '#arguments' => array($subnode), + '#weight' => $weight, + '#prefix' => "", + '#suffix' => "", + '#after_build' => array('subform_element_build_subform','addnode_fix_subform'), + '#fieldname' => $fieldname, + '#extra_form' => array("#fieldname"=>$fieldname), + ); + } + //updates the last suffix to include the subsuffix (which closes the table) + $form[$fieldname][$subfieldname]['#suffix'] .= $subsuffix; + + //add submit handlers: + //Add the nids of the newly created sub-nodes to the node + $form['#submit'][] = 'addnode_addnids_submit'; + //the subform element submit handler + $form['#submit'][] = 'subform_element_submit'; + //the handler for the base node (todo: Is this still necessary, I think subform_element might do this) + $form['#submit'][] = 'node_form_submit'; + + return $form; + case 'process form values': + $node_field = content_transpose_array_rows_cols(array('nid' => $node_field['nids'])); + break; + case 'submit': + break; + } + } +} + +/** + * This is called as an #after_build function for each subform. + *It 1) Disables the subform's validation etc if it's unused + * 2) Removes the subform's buttons. + */ +function addnode_fix_subform($form_element, &$form_values) +{ + //get the subform array (from the subform_element module) + global $subforms; + + //the type of node to create + $nodetype = $form_element['#arguments'][0]['type']; + //the name of the field the addnode widget is for + $current_fieldname = $form_element['#fieldname']; + + //for each field in the form, look for addnode_[blah] + foreach($form_values as $key => $value) + { + //if the field key begins 'addnode_' then it's one of the hidden fields, we use these to identify the names of potential subforms + if (strpos($key, 'addnode_') === 0) + { + //get the fieldname (the bit after the 'addnode_' in the key). + $fieldname = substr($key, 8); + if ($fieldname == $current_fieldname) + { + //find out which subform's the source (it will be the value of this key). + $source = $value; + //if it's not '' then we're creating a new node. (if it is '' then we must be using the select box). + //in other words, we disable subform processing if $source = '' or it's not related to this subform + $disable = TRUE; + + if (strlen($source)>0) //if we're not using the select box... + { + if ($source == $nodetype) //and we've chosen this subform over any other + { + $disable = FALSE; + } + } + + if ($disable) //disable this subform as it's not being used. + { + $form_element['#validate'] = array(); + } + } + } + } + +//Remove submit and preview buttons from the subform. + $form_element['#form']['submit']['#attributes'] = array( + 'style' => 'height:0px; visibility:hidden;', + ); + $form_element['#form']['preview']['#attributes'] = array( + 'style' => 'height:0px; visibility:hidden;', + ); + + return $form_element; +} + +/** + * Called as a main form submit handler. It submits the subforms and gets the nids then puts them into + * the main node. + */ +function addnode_addnids_submit($form, &$form_state) +{ + //copied from subform_element_submit, allows us to get hold of the redirects and get the nids from them + global $subforms; + if (isset($subforms)) { + foreach ($subforms as $key => $subform) { + if (!isset($subform['#submitted'])) { + $subforms[$key]['#submitted'] = TRUE; + $form_state['redirect'] = subform_element_call('drupal_submit_form', $subform['#post']['form_id'], $subform); + $fieldname = $subform['#fieldname']; + $split = explode("/", $redirect); + $newnid = $split[1]; + //unset the current array, and replace it with a new array. + //note that as multiselect is currently set, this is an array + // @todo allow multi/single select!! + unset($form_state['values'][$fieldname]['nids']); + $form_state['values'][$fieldname]['nids'] = array ($newid => $newid); + } + } + } +} + +/** + * This outputs HTML for the 'create new nodetype' link message. + * @param $type_count + * Number of types that could be added + * + * @param $fieldname + * The fieldname of this addnode field + * + * @param $type_list + * List of types + */ +function _addnode_create_new_message($type_count, $fieldname, $type_list) +{ + $msg=""; + $spanmsg.= ""; + + //if there's only one type then the message is of the form "Create a new blah" + if ($type_count==1) + { + $atype=$type_list[0]; + $typedesc = node_get_types('type', $atype); + $typedesc = $typedesc->name; + + //pretransmsg is message before translation. + $pretransmsg = "or "; + $pretransmsg.= "!spanmsg"; + $pretransmsg.= "create a new !typedesc"; + $pretransmsg.= ""; + $pretransmsg.= ""; + $vars = array('!fieldname' => $fieldname, '!atype' => $atype, '!spanmsg' => $spanmsg, '!typedesc' => $typedesc); + $msg.= t($pretransmsg, $vars); + } + + //if there's more than one type then the message is of the form "Create a new blah or blah" + if ($type_count>1) + { + $vars = array(); + $msg.= t("or create a new "); + $tempcnt=0; + foreach ($type_list as $atype) + { + $typedesc = node_get_types('type', $atype); + $typedesc = $typedesc->name; + $msg.= ""; + $msg.= $spanmsg; + $msg.= "$typedesc"; + $msg.= ""; + $msg.= ""; + $tempcnt++; + if ($tempcnt == $type_count-1) + { + $msg.= t(" or "); + } + else + { + $msg.= t(", "); + } + } + } + $msg .= ""; + return $msg; +}