1
|
<?php
|
2
|
// $Id $
|
3
|
|
4
|
/**
|
5
|
* @file
|
6
|
* Allows users to create nodes instead of selecting them from a list
|
7
|
*
|
8
|
* @author Obslogic (Mike Smith aka Lionfish)
|
9
|
*/
|
10
|
|
11
|
|
12
|
/**
|
13
|
* Implementation of hook_help
|
14
|
*/
|
15
|
function expertsdb_addnode_help($section='')
|
16
|
{
|
17
|
$output = '';
|
18
|
switch ($section)
|
19
|
{
|
20
|
case "admin/help#expertsdb_addnode":
|
21
|
$output = '<p>'.t("Provides an option to the user to create a new node type.").'</p>';
|
22
|
break;
|
23
|
}
|
24
|
return $output;
|
25
|
}
|
26
|
|
27
|
/**
|
28
|
* Implementation of hook_widget_info.
|
29
|
* Specifies the label and that it is a widget for the nodereference field type
|
30
|
*/
|
31
|
function expertsdb_addnode_widget_info()
|
32
|
{
|
33
|
return array(
|
34
|
'expertsdb_addnode_select' => array(
|
35
|
'label' => 'Expertsdb AddNode List',
|
36
|
'field types' => array('nodereference'),
|
37
|
),
|
38
|
);
|
39
|
}
|
40
|
|
41
|
/**
|
42
|
* Implementation of hook_widget
|
43
|
*/
|
44
|
function expertsdb_addnode_widget($op, &$node, $field, &$node_field)
|
45
|
{
|
46
|
//need this module for the_nodereference_potential_references function.
|
47
|
include_once(drupal_get_path('module', 'content').'/nodereference.module');
|
48
|
|
49
|
if ($field['widget']['type'] == 'expertsdb_addnode_select')
|
50
|
{
|
51
|
switch ($op) {
|
52
|
|
53
|
case 'prepare form values':
|
54
|
//puts node_field (original) values into a temporary bit of the array called default nids
|
55
|
$node_field_transposed = content_transpose_array_rows_cols($node_field);
|
56
|
$node_field['default nids'] = $node_field_transposed['nid'];
|
57
|
break;
|
58
|
|
59
|
case 'form':
|
60
|
//adds javascript
|
61
|
$path = drupal_get_path('module','expertsdb_addnode');
|
62
|
drupal_add_js($path . '/expertsdb_addnode.js');
|
63
|
|
64
|
$form = array();
|
65
|
$selectedoptions = array();
|
66
|
|
67
|
//gets the list of all potential nodes that could be referenced
|
68
|
$options = _nodereference_potential_references($field, true);
|
69
|
|
70
|
foreach ($options as $key => $value) {
|
71
|
$options[$key] = _nodereference_item($field, $value);
|
72
|
}
|
73
|
|
74
|
//string describing what can be added. If there's one type it will be that, otherwise it will be
|
75
|
//just 'item'.
|
76
|
$typedesc = "";
|
77
|
$type_count=0; //counts up how many types there are
|
78
|
$type_list=array(); //list of the types
|
79
|
|
80
|
//If referenceable_types is not an array, give up.
|
81
|
if (!is_array($field['referenceable_types']))
|
82
|
{
|
83
|
return $form;
|
84
|
}
|
85
|
|
86
|
//add referenceable types to the $type_list array
|
87
|
foreach ($field['referenceable_types'] as $ref_type)
|
88
|
{
|
89
|
if ($ref_type)
|
90
|
{
|
91
|
$typedesc = $ref_type;
|
92
|
$type_count++;
|
93
|
$type_list[] = $ref_type;
|
94
|
}
|
95
|
}
|
96
|
|
97
|
//if there are no types available, give up.
|
98
|
if ($type_count==0)
|
99
|
{
|
100
|
//@todo Need to display something explaining the problem.
|
101
|
return $form;
|
102
|
}
|
103
|
//converts the type name to a human readable one
|
104
|
$typedesc = node_get_types('type', $typedesc);
|
105
|
$typedesc = $typedesc->name;
|
106
|
|
107
|
//If there's more than one type available then we use the term 'item' to describe them
|
108
|
if ($type_count>1)
|
109
|
{
|
110
|
$typedesc = "item";
|
111
|
}
|
112
|
|
113
|
$fieldname=$field['field_name'];
|
114
|
$title=t($field['widget']['label']);
|
115
|
|
116
|
//$createmsg is a message such as "Create a new _fund_ or _pot_" with links in.
|
117
|
$createmsg=_expertsdb_addnode_create_new_message($type_count, $fieldname, $type_list);
|
118
|
|
119
|
$prefix = '';
|
120
|
$suffix = '';
|
121
|
$subsuffix = "";
|
122
|
|
123
|
//this prefix builds the table headers etc.
|
124
|
$prefix = "";
|
125
|
$prefix.= "<b>$title:</b>";
|
126
|
$prefix.= '<table class="expertsdb-addnode-select-table">';
|
127
|
$prefix.= "<tr>";
|
128
|
$prefix.= '<th class="expertsdb-addnode-select column-left">';
|
129
|
$prefix.= "<a href='javascript:;' id='$fieldname' class='expertsdb_addnode_select_link'>";
|
130
|
$prefix.= t("Select</a> !typedesc already available</th>", array('!typedesc'=>"$typedesc"));
|
131
|
$prefix.= '<th class="expertsdb-addnode-select-table-header column-right">';
|
132
|
$prefix.= $createmsg;//msg that says 'Create an item' or whatever
|
133
|
$prefix.= "</th>";
|
134
|
$prefix.= "</tr>";
|
135
|
$prefix.= "<tr>";
|
136
|
$prefix.= '<td class="expertsdb-addnode-select column-left">';
|
137
|
//select box goes here
|
138
|
$suffix.= "</td>";
|
139
|
$suffix.= '<td class="expertsdb-addnode-select column-right">';
|
140
|
//the subforms go here
|
141
|
//the last subform must suffix with:
|
142
|
$subsuffix.= "</td>";
|
143
|
$subsuffix.= "</tr>";
|
144
|
$subsuffix.= "</table>";
|
145
|
|
146
|
///This hidden form element has been moved above the subforms to allow it to be processed before their
|
147
|
///#after_build functions run (as they will need the values in this element).
|
148
|
//whether we've selected something from the select box, or created a new item
|
149
|
//is stored in this hidden field. So the submit functions know what to do.
|
150
|
$form["expertsdb_addnode_".$fieldname] = array(
|
151
|
'#type' => 'hidden',
|
152
|
'#title' => t('selection or creation'),
|
153
|
'#default_value' => '',
|
154
|
'#attributes' => array (
|
155
|
'class' => 'expertsdb_addnode_source',
|
156
|
),
|
157
|
);
|
158
|
|
159
|
$weight = $field['weight'];
|
160
|
|
161
|
//select box
|
162
|
$form[$fieldname]['#tree'] = TRUE;
|
163
|
$form[$fieldname]['nids'] = array(
|
164
|
'#type' => 'select',
|
165
|
'#title' => '', //no title for this bit
|
166
|
'#default_value' => $node_field['default nids'],
|
167
|
'#multiple' => TRUE, // @todo: set this to the original multiple value and fix the bug, which makes this module disfunctional, if this is set to FALSE
|
168
|
'#options' => $options,
|
169
|
'#required' => $field['required'],
|
170
|
'#description' => $field['widget']['description'],
|
171
|
'#prefix' => $prefix,
|
172
|
'#suffix' => $suffix,
|
173
|
'#size' => 15,
|
174
|
'#weight' => $weight,
|
175
|
'#attributes' => array(
|
176
|
//'style' => 'width:90%',
|
177
|
'class' => "expertsdb_addnode_select",
|
178
|
'id' => "$fieldname",
|
179
|
),
|
180
|
);
|
181
|
|
182
|
//loops through the types this field can be.
|
183
|
foreach ($type_list as $typename)
|
184
|
{
|
185
|
$weight = $weight + 0.1;//puts them in an order.
|
186
|
|
187
|
$subnode = array('uid' => $node->uid, 'type' => $typename);
|
188
|
//the name of the array below this field type, needed to divide the subforms.
|
189
|
$subfieldname = 'node_'.$typename;
|
190
|
$form[$fieldname][$subfieldname] = array(
|
191
|
'#type' => 'subform',
|
192
|
'#id' => $typename.'_node_form',
|
193
|
'#arguments' => array($subnode),
|
194
|
'#weight' => $weight,
|
195
|
'#prefix' => "<span class='expertsdb_addnode_form $fieldname' id='$typename'>",
|
196
|
'#suffix' => "</span>",
|
197
|
'#after_build' => array('subform_element_build_subform','expertsdb_addnode_fix_subform'),
|
198
|
'#fieldname' => $fieldname,
|
199
|
'#extra_form' => array("#fieldname"=>$fieldname),
|
200
|
);
|
201
|
}
|
202
|
//updates the last suffix to include the subsuffix (which closes the table)
|
203
|
$form[$fieldname][$subfieldname]['#suffix'] .= $subsuffix;
|
204
|
|
205
|
//add submit handlers:
|
206
|
//Add the nids of the newly created sub-nodes to the node
|
207
|
$form['#submit']['expertsdb_addnode_addnids_submit'] = array();
|
208
|
//the subform element submit handler
|
209
|
$form['#submit']['subform_element_submit'] = array();
|
210
|
//the handler for the base node (todo: Is this still necessary, I think subform_element might do this)
|
211
|
$form['#submit']['node_form_submit'] = array();
|
212
|
|
213
|
// @TODO: add the current author to the subform
|
214
|
|
215
|
return $form;
|
216
|
|
217
|
case 'process form values':
|
218
|
$node_field = content_transpose_array_rows_cols(array('nid' => $node_field['nids']));
|
219
|
break;
|
220
|
|
221
|
case 'submit':
|
222
|
break;
|
223
|
}
|
224
|
}
|
225
|
}
|
226
|
|
227
|
/**
|
228
|
* This is called as an #after_build function for each subform.
|
229
|
*It 1) Disables the subform's validation etc if it's unused
|
230
|
* 2) Removes the subform's buttons.
|
231
|
*/
|
232
|
function expertsdb_addnode_fix_subform($form_element, &$form_values)
|
233
|
{
|
234
|
//get the subform array (from the subform_element module)
|
235
|
global $subforms;
|
236
|
|
237
|
//the type of node to create
|
238
|
$nodetype = $form_element['#arguments'][0]['type'];
|
239
|
|
240
|
//the name of the field the expertsdb_addnode widget is for
|
241
|
$current_fieldname = $form_element['#fieldname'];
|
242
|
|
243
|
//for each field in the form, look for expertsdb_addnode_[blah]
|
244
|
foreach($form_values as $key => $value)
|
245
|
{
|
246
|
//if the field key begins 'expertsdb_addnode_' then it's one of the hidden fields, we use these to identify the names of potential subforms
|
247
|
if (strpos($key, 'expertsdb_addnode_') === 0)
|
248
|
{
|
249
|
//get the fieldname (the bit after the 'expertsdb_addnode_' in the key).
|
250
|
$fieldname = substr($key, 18);
|
251
|
if ($fieldname == $current_fieldname)
|
252
|
{
|
253
|
//find out which subform's the source (it will be the value of this key).
|
254
|
$source = $value;
|
255
|
//if it's not '' then we're creating a new node. (if it is '' then we must be using the select box).
|
256
|
//in other words, we disable subform processing if $source = '' or it's not related to this subform
|
257
|
$disable = TRUE;
|
258
|
|
259
|
if (strlen($source)>0) //if we're not using the select box...
|
260
|
{
|
261
|
if ($source == $nodetype) //and we've chosen this subform over any other
|
262
|
{
|
263
|
$disable = FALSE;
|
264
|
}
|
265
|
}
|
266
|
|
267
|
if ($disable) //disable this subform as it's not being used.
|
268
|
{
|
269
|
$form_element['#validate'] = array();
|
270
|
}
|
271
|
}
|
272
|
}
|
273
|
}
|
274
|
|
275
|
//Remove submit and preview buttons from the subform.
|
276
|
$form_element['#form']['submit']['#attributes'] = array(
|
277
|
'style' => 'height:0px; visibility:hidden;',
|
278
|
);
|
279
|
$form_element['#form']['preview']['#attributes'] = array(
|
280
|
'style' => 'height:0px; visibility:hidden;',
|
281
|
);
|
282
|
|
283
|
// bugfix
|
284
|
global $user;
|
285
|
$form_element['#form']['author']['name']['#value'] = $user->name;
|
286
|
// disable authoring information
|
287
|
foreach (array('preview', 'submit', 'delete', 'author','options') as $name) {
|
288
|
$form_element['#form'][$name]['#access'] = FALSE;
|
289
|
}
|
290
|
|
291
|
return $form_element;
|
292
|
}
|
293
|
|
294
|
/**
|
295
|
* Called as a main form submit handler. It submits the subforms and gets the nids then puts them into
|
296
|
* the main node.
|
297
|
*/
|
298
|
function expertsdb_addnode_addnids_submit($form_id, &$form_values)
|
299
|
{
|
300
|
//copied from subform_element_submit, allows us to get hold of the redirects and get the nids from them
|
301
|
global $subforms;
|
302
|
if (isset($subforms)) {
|
303
|
foreach ($subforms as $key => $subform) {
|
304
|
if (!isset($subform['#submitted'])) {
|
305
|
$subforms[$key]['#submitted'] = TRUE;
|
306
|
$redirect = subform_element_call('drupal_submit_form', $subform['#post']['form_id'], $subform);
|
307
|
$fieldname = $subform['#fieldname'];
|
308
|
$split = explode("/", $redirect);
|
309
|
$newnid = $split[1];
|
310
|
//unset the current array, and replace it with a new array.
|
311
|
//note that as multiselect is currently set, this is an array
|
312
|
// @todo allow multi/single select!!
|
313
|
unset($form_values[$fieldname]['nids']);
|
314
|
$form_values[$fieldname]['nids'] = array ( $newnid => $newnid );
|
315
|
|
316
|
}
|
317
|
}
|
318
|
return $redirect;
|
319
|
}
|
320
|
}
|
321
|
|
322
|
/**
|
323
|
* This outputs HTML for the 'create new nodetype' link message.
|
324
|
* @param $type_count
|
325
|
* Number of types that could be added
|
326
|
*
|
327
|
* @param $fieldname
|
328
|
* The fieldname of this expertsdb_addnode field
|
329
|
*
|
330
|
* @param $type_list
|
331
|
* List of types
|
332
|
*/
|
333
|
function _expertsdb_addnode_create_new_message($type_count, $fieldname, $type_list)
|
334
|
{
|
335
|
$msg="";
|
336
|
$spanmsg.= "<span id='$fieldname' class='expertsdb_addnode_links'>";
|
337
|
|
338
|
//if there's only one type then the message is of the form "Create a new blah"
|
339
|
if ($type_count==1)
|
340
|
{
|
341
|
$atype=$type_list[0];
|
342
|
$typedesc = node_get_types('type', $atype);
|
343
|
$typedesc = $typedesc->name;
|
344
|
|
345
|
//pretransmsg is message before translation.
|
346
|
$pretransmsg = "or <a href='javascript:;' class='expertsdb_addnode_item !fieldname' id='!atype'>";
|
347
|
$pretransmsg.= "!spanmsg";
|
348
|
$pretransmsg.= "create a new !typedesc";
|
349
|
$pretransmsg.= "</span>";
|
350
|
$pretransmsg.= "</a>";
|
351
|
$vars = array('!fieldname' => $fieldname, '!atype' => $atype, '!spanmsg' => $spanmsg, '!typedesc' => $typedesc);
|
352
|
$msg.= t($pretransmsg, $vars);
|
353
|
}
|
354
|
|
355
|
//if there's more than one type then the message is of the form "Create a new blah or blah"
|
356
|
if ($type_count>1)
|
357
|
{
|
358
|
$vars = array();
|
359
|
$msg.= t("or create a new ");
|
360
|
$tempcnt=0;
|
361
|
foreach ($type_list as $atype)
|
362
|
{
|
363
|
$typedesc = node_get_types('type', $atype);
|
364
|
$typedesc = $typedesc->name;
|
365
|
$msg.= "<a href='javascript:;' class='expertsdb_addnode_item $fieldname' id='$atype'>";
|
366
|
$msg.= $spanmsg;
|
367
|
$msg.= "$typedesc";
|
368
|
$msg.= "</span>";
|
369
|
$msg.= "</a>";
|
370
|
$tempcnt++;
|
371
|
if ($tempcnt == $type_count-1)
|
372
|
{
|
373
|
$msg.= t(" or ");
|
374
|
}
|
375
|
else
|
376
|
{
|
377
|
$msg.= t(", ");
|
378
|
}
|
379
|
}
|
380
|
}
|
381
|
$msg .= "</span>";
|
382
|
return $msg;
|
383
|
}
|