Project

General

Profile

Download (12 KB) Statistics
| Branch: | Tag: | Revision:
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
}
(8-8/47)