/[drupal]/contributions/modules/netforum_nodes/netforum_node.module
ViewVC logotype

Contents of /contributions/modules/netforum_nodes/netforum_node.module

Parent Directory Parent Directory | Revision Log Revision Log | View Revision Graph Revision Graph


Revision 1.14 - (show annotations) (download) (as text)
Thu Nov 29 03:28:51 2007 UTC (2 years ago) by jamesmichaelhill
Branch: MAIN
CVS Tags: DRUPAL-5--0-8-5, HEAD
Branch point for: DRUPAL-5
Changes since 1.13: +182 -53 lines
File MIME type: text/x-php
Expanded template code options for creating and linking to nodes
1 <?php
2 // $Id: netforum_node.module,v 1.13 2007/11/26 22:11:34 jamesmichaelhill Exp $
3 //IDEA: Popup reference/help for lists and queries in node bodies
4
5 /**
6 * @file
7 * The netFORUM Dynamic Facade Nodes module
8 *
9 * Uses the netFORUM xWeb module to fetch Objects from netFORUM and
10 * turn them into Nodes for viewing. The nodes work as a cross between
11 * netFORUM e-marketing (correspondence) templates and the List content type in eWeb.
12 * Most e-marketing templates should look the same as nodes, but child_form_html and
13 * child_form_text commands are ignored. Much of the functionality can be reproduced using
14 * the list functionality.
15 *
16 * Many functions and behavior of this module is patterend, copied, or adapted from the Node module
17 *
18 */
19
20 /**
21 * Implementation of hook_menu()
22 */
23 function netforum_node_menu($may_cache) {
24 $items = array();
25 //'create netFORUM node', 'edit own netFORUM nodes', 'edit netFORUM nodes', 'administer netFORUM node templates', 'administer netFORUM node special fields'
26 global $user;
27 $node_access_perm = (user_access('administer site configuration') || user_access('create netFORUM node') || user_access('edit netFORUM nodes') || (user_access('edit own netFORUM nodes') && ($user->uid == $node->uid)) );
28 $template_access_perm = (user_access('administer site configuration') || user_access('administer netFORUM node templates'));
29 $special_field_access_perm = (user_access('administer site configuration') || user_access('administer netFORUM node special fields'));
30
31 if ($may_cache) {
32 $items[] = array('path' => 'admin/content/netforum-node-templates',
33 'title' => t('netFORUM Node Templates'),
34 'callback' => 'netforum_node_overview_types',
35 'access' => $template_access_perm,
36 'description' => t('Add and edit netFORUM Node templates'),
37 );
38
39 $items[] = array(
40 'path' => 'admin/content/netforum-node-templates/list',
41 'title' => t('List'),
42 'type' => MENU_DEFAULT_LOCAL_TASK,
43 'weight' => -10,
44 'access' => $template_access_perm,
45 );
46
47 $items[] = array('path' => 'admin/content/netforum-node-templates/add',
48 'title' => t('Add netFORUM Node Template'),
49 'callback' => 'drupal_get_form',
50 'callback arguments' => array('netforum_node_type_form'),
51 'type' => MENU_LOCAL_TASK,
52 'access' => $template_access_perm,
53 );
54
55 $items[] = array('path' => 'admin/settings/netforum/special-fields',
56 'title' => t('netFORUM node special fields'),
57 'callback' => 'netforum_node_overview_special_fields',
58 'description' => t('Add and edit special fields to use in netFORUM nodes'),
59 'access' => $special_field_access_perm,
60 );
61
62 $items[] = array(
63 'path' => 'admin/settings/netforum/special-fields/list',
64 'title' => t('List'),
65 'type' => MENU_DEFAULT_LOCAL_TASK,
66 'weight' => -10,
67 );
68
69 $items[] = array('path' => 'admin/settings/netforum/special-fields/add',
70 'title' => t('Add netFORUM Node Special Field'),
71 'callback' => 'drupal_get_form',
72 'callback arguments' => array('netforum_node_special_field_form'),
73 'type' => MENU_LOCAL_TASK,
74 );
75
76
77 $items[] = array('path' => 'admin/content/netforum-object-autocomplete',
78 'title' => t('Netforum object name autocomplete'),
79 'callback' => 'netforum_objects_autocomplete',
80 'type' => MENU_CALLBACK,
81 'access' => $node_access_perm,
82 );
83
84 $items[] = array('path' => 'admin/content/netforum-object-fields-autocomplete',
85 'title' => t('Netforum object fields autocomplete'),
86 'callback' => 'netforum_node_object_fields_autocomplete',
87 'type' => MENU_CALLBACK,
88 'access' => $node_access_perm,
89 );
90
91 $items[] = array('path' => 'admin/content/netforum-template-code-autocomplete',
92 'title' => t('Netforum object fields autocomplete'),
93 'callback' => 'netforum_node_template_code_autocomplete',
94 'type' => MENU_CALLBACK,
95 'access' => $node_access_perm,
96 );
97
98 $items[] = array('path' => 'admin/content/netforum-node-object-lookup' ,
99 'title' => t('Netforum object key lookup'),
100 'callback' => 'netforum_node_object_lookup',
101 'callback arguments' => array(true),
102 'type' => MENU_CALLBACK,
103 'access' => $node_access_perm,
104 );
105
106 $items[] = array(
107 'path' => 'admin/settings/netforum/nodes',
108 'title' => t('netFORUM Dynamic Facade Nodes'),
109 'description' => t('Configure filtering for netFORUM data'),
110 'callback' => 'drupal_get_form',
111 'callback arguments' => array('netforum_node_settings'),
112 'access' => user_access('administer site configuration'),
113 'weight' => 5,
114 );
115
116 }
117 else {
118 //NEVER CACHE
119
120 // netFORUM node template configuration.
121
122 if (arg(0) == 'admin' && arg(1) == 'content' && arg(2) == 'netforum-node-templates') {
123
124 if (arg(3) != NULL ) {
125 $nftid = (int)arg(3);
126 $res = db_query("SELECT nftid, obj_name as obj_type_name, code, is_default, default_title, default_body, taxonomy, format, a.nft_obj_key as nft_obj_key
127 FROM {netforum_node_types} a JOIN {netforum_object_cache} b ON a.nft_obj_key = b.obj_key WHERE nftid = %d ", $nftid);
128 $node_template = db_fetch_object($res);
129
130 if (!empty($node_template)) {
131 $node_template->obj_type_name = check_plain($node_template->obj_type_name);
132 $node_template->taxonomy = unserialize($node_template->taxonomy);
133 $items[] = array(
134 'path' => 'admin/content/netforum-node-templates/'. $nftid,
135 'title' => t('@object_name Object Template', array('@object_name' => $node_template->obj_type_name)),
136 'callback' => 'drupal_get_form',
137 'callback arguments' => array('netforum_node_type_form', $node_template),
138 'type' => MENU_CALLBACK,
139 'access' => $template_access_perm,
140 );
141 $items[] = array(
142 'path' => 'admin/content/netforum-node-templates/'. $nftid .'/delete',
143 'title' => t('Delete'),
144 'callback' => 'drupal_get_form',
145 'callback arguments' => array('netforum_node_type_delete_confirm', $node_template),
146 'type' => MENU_CALLBACK,
147 'access' => $template_access_perm,
148 );
149 }
150 }
151 }
152
153 if (arg(0) == 'admin' && arg(1) == 'settings' && arg(2) == 'netforum' && arg(3) == 'special-fields' && arg(4) != NULL) {
154 $field_code = arg(4);
155 $field_code = db_result(db_query("SELECT field_code FROM {netforum_node_special_fields} WHERE field_code = '%s'", $field_code));
156 if (!empty($field_code )) {
157 $field_code = check_plain($field_code);
158 $items[] = array(
159 'path' => 'admin/settings/netforum/special-fields/'. $field_code ,
160 'title' => $field_code,
161 'callback' => 'drupal_get_form',
162 'callback arguments' => array('netforum_node_special_field_form', $field_code),
163 'type' => MENU_CALLBACK,
164 );
165 $items[] = array(
166 'path' => 'admin/settings/netforum/special-fields/'. $field_code .'/delete',
167 'title' => t('Delete'),
168 'callback' => 'drupal_get_form',
169 'callback arguments' => array('netforum_node_special_field_delete_confirm', $field_code),
170 'type' => MENU_CALLBACK,
171 );
172 }
173 }
174
175 if (arg(0) == 'node' && is_numeric(arg(1))) {
176 $is_nf_node = db_result(db_query("SELECT count(nfn_key) FROM {netforum_node} WHERE nid=%d", arg(1)));
177 if ($is_nf_node > 0) {
178 $items[] = array('path' => "node/". arg(1) ."/refreshdata",
179 'title' => t('Refresh netFORUM data'),
180 'access' => $node_access_perm,
181 'type' => MENU_LOCAL_TASK,
182 'weight' => 2,
183 'callback' => 'netforum_node_refresh_tab',
184 'callback arguments' => arg(1),
185 );
186 }
187 }
188
189 if (arg(0) == 'node' && netforum_is_valid_guid(arg(1)) && netforum_is_valid_guid(arg(2)) ) {
190 $items[] = array('path' => "node/". arg(1) ."/". arg(2),
191 'title' => t('Create netFORUM Node'),
192 'access' => user_access('access content'),
193 'type' => MENU_CALLBACK,
194 'callback' => 'netforum_node_create_from_template',
195 'callback arguments' => array(arg(1), arg(2), arg(3)), //we're including arg3 because it may include a template id to link to
196 );
197 }
198
199 }
200 return $items;
201 }
202
203 /**
204 * System setting form
205 *
206 */
207 function netforum_node_settings(){
208 $form = array();
209
210 $form['dates'] = array(
211 '#title' => t('Date fields'),
212 '#type' => 'fieldset',
213 );
214
215 $form['dates']['netforum_node_filter_date_fields'] = array(
216 '#title' => t('Reformat date fields'),
217 '#type' => 'checkbox',
218 '#default_value' => variable_get('netforum_node_filter_date_fields', 1),
219 '#description' => t('Check this to re-format any field ending in _date with the format below'),
220 );
221
222 $form['dates']['netforum_node_filter_date_format'] = array(
223 '#title' => t('Date field format'),
224 '#type' => 'textfield',
225 '#default_value' => variable_get('netforum_node_filter_date_format', '%m/%d/%Y'),
226 '#description' => t('The format follows PHPs strftime() function syntax, %Y is the full year, %m is the month as a number, and %d is the day as a number'),
227 );
228
229 $form['descriptions'] = array(
230 '#title' => t('HTML Descriptions'),
231 '#type' => 'fieldset',
232 );
233
234 $form['descriptions']['netforum_node_filter_html'] = array(
235 '#title' => t('Parse HTML descriptions'),
236 '#type' => 'checkbox',
237 '#default_value' => variable_get('netforum_node_filter_html', 1),
238 '#description' => t('Check this to search and parse any field ending in _html. It is recommended to leave this checked.'),
239 );
240
241 return system_settings_form($form);
242 }
243
244 function netforum_node_settings_validate($form_id, $form_values, $form) {
245 if (!empty($form_values['netforum_node_filter_date_format']) && $form_values['netforum_node_filter_date_fields']) {
246 //note - strftime the form value and if it is incorrect it will be the input minus any % signs, so strreplace for percent, strftime and compare.
247 $bad_parsed = str_replace('%', '', $form_values['netforum_node_filter_date_format']);
248 $time_parsed = strftime($form_values['netforum_node_filter_date_format']);
249 if ($bad_parsed == $time_parsed) {
250 form_set_error('netforum_node_filter_date_format', t("The date format entered resolved to !time - an invalid choice", array('!time' => $time_parsed)));
251 }
252 }
253 }
254
255 /**
256 * menu local task callback to refresh a node's data
257 *
258 * @param $nid
259 * integer, the node ide
260 * @return
261 * redirects to the node view
262 */
263 function netforum_node_refresh_tab($nid) {
264 $node = node_load($nid);
265 netforum_node_refresh_fields($node, true);
266 if (isset($node->nfn_data)) {
267 //if the data is set, that means that we successfully got it from netforum
268 netforum_node_save_fields($node);
269 drupal_set_message("Fetched latest data from netFORUM");
270 }
271 else{
272 drupal_set_message("netFORUM currently unavailable", 'error');
273 }
274 drupal_goto("node/". $node->nid);
275 }
276
277 /**
278 * menu callback to search for node fields
279 *
280 * @param $obj
281 * A string containing either the object name or key
282 * @param $search
283 * A string to match against the list of object fields
284 * @return
285 * a JSON object with the results, exits after completion
286 */
287 function netforum_node_object_fields_autocomplete($obj='', $search="") {
288 if ($obj == '' && $search == '') {
289 print drupal_to_js(array('' => 'Try setting the object name before looking for object fields'));
290 exit;
291 }
292
293 $fields = array();
294
295 if ($search == '') {
296 $search = $obj;
297 $fields = netforum_node_special_fields(true);
298 $no_object_set = true;
299 }
300 else {
301 $obj = netforum_is_valid_guid($obj) ? netforum_object_name($obj) : $obj;
302 $fields = array_merge(netforum_object_fields($obj), netforum_node_special_fields(true));
303 }
304
305 $matches = array();
306 foreach ($fields as $k => $v) {
307 if (stristr($v, $search) || stristr($k, $search)) {
308 $matches["{". $k ."}"] = $v;
309 }
310 }
311 if ($no_object_set === true) {
312 $matches = array_merge(array('' => 'Try setting the object name before looking for object fields'), $matches);
313 }
314 print drupal_to_js($matches);
315 exit;
316 }
317
318 /**
319 * menu callback to search for node template codes
320 *
321 * @param $obj
322 * A string containing either the object name or key
323 * @param $search
324 * A string to match against the list of object fields
325 * @return
326 * a JSON object with the results, exits after completion
327 */
328 function netforum_node_template_code_autocomplete($obj='', $search="") {
329 if ($obj == '' && $search == '') {
330 print drupal_to_js(array('' => 'Try setting the object name before looking for templates'));
331 exit;
332 }
333
334 $codes = array();
335
336 if ($search == '') {
337 $search = $obj;
338 $res = db_query("SELECT code FROM {netforum_node_types} WHERE code like '%%s%' ORDER BY code ASC", $search);
339 while ($code_result = db_fetch_array($res)) {
340 $codes[$code_result['code']] = $code_result['code'];
341 }
342 $no_object_set = true;
343 }
344 else {
345 $obj = netforum_is_valid_guid($obj) ? $obj : netforum_object_key($obj);
346 if (netforum_is_valid_guid($obj)) {
347 $res = db_query("SELECT code FROM {netforum_node_types} WHERE nft_obj_key = '%s' AND code like '%%%s%' ORDER BY code ASC", $obj, $search);
348 while ($code_result = db_fetch_array($res)) {
349 $codes[$code_result['code']] = $code_result['code'];
350 }
351 }
352 }
353
354 if ($no_object_set === true) {
355 $codes = array_merge(array('' => 'Try setting the object name before looking for template codes'), $codes);
356 }
357 print drupal_to_js($codes);
358 exit;
359 }
360
361 /**
362 * Implementation of node_form()
363 */
364 function netforum_node_form($node) {
365 $type = node_get_types('type', $node);
366
367 //Get a working object name and key if there isn't one set for the object
368 if (isset($node->obj_type_name)) {
369 $object_name = $node->obj_type_name;
370 $node->nfn_obj_key = netforum_object_key($node->obj_type_name);
371 }
372 else if (isset($_POST['obj_type_name']) ) {
373 $object_name = $_POST['obj_type_name'];
374 $node->nfn_obj_key = netforum_object_key($object_name);
375 }
376 $object_name = trim($object_name) == '' ? "Object" : $object_name;
377
378
379 $form['obj_type_name'] = array(
380 '#type' => 'textfield',
381 '#title' => t('Object Name'),
382 '#size' => 50,
383 '#autocomplete_path' => 'admin/content/netforum-object-autocomplete',
384 '#weight' => -7,
385 '#required' => true,
386 '#default_value' => $node->obj_type_name,
387 '#description' => t("This is the kind of information to pull from netFORUM, usually seen in profile forms in iWeb. Type the object name or the object prefix to search."),
388 );
389
390 $form['nfn_key'] = array(
391 '#type' => 'textfield',
392 '#title' => t('@objectname Key', array('@objectname' => $object_name) ),
393 '#required' => TRUE,
394 '#default_value' => $node->nfn_key,
395 '#weight' => -6,
396 '#description' => t("This is the unique identifier for information in netFORUM. If you don't know the key, click the help find object key link below to look for one."),
397 );
398
399 $form['object_help'] = array(
400 '#type' => 'fieldset',
401 '#title' => t('Help find @objectname key', array('@objectname' => $object_name)),
402 '#collapsible' => TRUE,
403 '#collapsed' => TRUE,
404 '#weight' => -5,
405 '#attributes' => array("id" => 'object_help'),
406 '#suffix' => "<span id='object_help_status' style='display:none'>Updating... &nbsp;<img src='". base_path() . drupal_get_path('module', 'netforum_node') ."/waiting.gif'></span>"
407 );
408
409 $form['object_help']['helpframe'] = array(
410 '#prefix' => "<div id='find_key_help'>",
411 '#value' => theme_netforum_node_object_lookup($object_name),
412 '#suffix' => "</div>",
413 );
414
415 $form['template_code'] = array(
416 '#type' => 'textfield',
417 '#title' => t('Template code'),
418 '#weight' => -1,
419 '#default_value' => $node->template_code,
420 '#description' => t('If creating a node from a template, specify a template code here. If left blank the default template will be used. This is also the template to use for node operations.'),
421 '#autocomplete_path' => 'admin/content/netforum-template-code-autocomplete/',
422 );
423 if ($node->nfn_obj_key) {
424 $form['template_code']['#autocomplete_path'] .= $node->nfn_obj_key;
425 }
426
427 $form['unparsed_title'] = array(
428 '#type' => 'textfield',
429 '#title' => check_plain($type->title_label),
430 '#default_value' => $node->unparsed_title,
431 '#weight' => -2,
432 '#description' => t('Leave empty to use the default title for this @objectname. Anything in curly brackets will be replaced with the information from netFORUM.', array('@objectname' => $object_name)),
433 );
434
435
436 $form['obj_field_help'] = array(
437 '#type' => 'textfield',
438 '#title' => t('Find object fields'),
439 '#size' => 60,
440 '#autocomplete_path' => 'admin/content/netforum-object-fields-autocomplete/',
441 '#weight' => -1,
442 '#default_value' => '',
443 '#description' => t("Type the first few letters of what you're looking for to find the code. Use the code in the title or body to get the information from netFORUM"),
444 );
445 if ($node->nfn_obj_key) {
446 $form['obj_field_help']['#autocomplete_path'] .= $node->nfn_obj_key;
447 }
448
449 $form['body_filter']['unparsed_body'] = array(
450 '#type' => 'textarea',
451 '#title' => check_plain($type->body_label),
452 '#default_value' => $node->unparsed_body,
453 '#rows' => 15,
454 '#description' => t('Leave empty to use the default body for this @objectname. Anything in curly brackets will be replaced with the information from netFORUM.', array('@objectname' => $object_name)),
455 );
456
457 $form['body_filter']['filter'] = filter_form($node->format);
458
459 return $form;
460 }
461
462 /**
463 * Implementation of node_validate()
464 */
465 function netforum_node_validate(&$node, $form) {
466
467 if ( trim($node->unparsed_title) == '' || trim($node->unparsed_body) == '') {
468 $nft_obj_key = netforum_object_key($node->obj_type_name);
469 $template_exists = false;
470 if ( netforum_is_valid_guid($nft_obj_key)) {
471 $count = db_result(db_query("SELECT count(default_title) FROM {netforum_node_types} WHERE nft_obj_key = '%s' ", $nft_obj_key));
472 $template_exists = ($count > 0);
473 }
474 }
475
476
477 if ( trim($node->unparsed_title) == '' && $template_exists == false) {
478 form_set_error('unparsed_title',
479 t('A title is required, and no default title is set for %type objects, perhaps you need to !add_link?', array(
480 '%type' => $node->obj_type_name,
481 '!add_link' => l(t('add a netforum node template'), 'admin/content/netforum-node-templates/add'),
482 )
483 )
484 );
485 }
486
487 if ( trim($node->unparsed_body) == '' && $template_exists == false) {
488 form_set_error('unparsed_body',
489 t('A body is required, and no default body is set for %type objects, perhaps you need to !add_link?', array(
490 '%type' => $node->obj_type_name,
491 '!add_link' => l(t('add a netforum node template'), 'admin/content/netforum-node-templates/add'),
492 )
493 )
494 );
495 }
496
497 if (isset($node->obj_type_name) && isset($node->nfn_key) ) {
498 $valid_key = true;
499 $valid_object = true;
500 if ( netforum_is_valid_guid($node->nfn_key) == false ) {
501 form_set_error('nfn_key', t('The object key an invalid format'));
502 $valid_key = false;
503 }
504
505 if ( netforum_is_valid_guid(netforum_object_key($node->obj_type_name)) == false ) {
506 form_set_error('obj_type_name', t('Could not find any netFORUM objects with that name, perhaps you need to !link ?', array('!link' => l(t('refresh netforum object names'), 'admin/settings/netforum/objectnamesrefresh') ) ));
507 $valid_object = false;
508 }
509
510 if ($valid_key && $valid_object) {
511 $obj_name = $node->obj_type_name;
512 $nfn_key = $node->nfn_key;
513
514 $results = netforum_xweb_request('GetFacadeObject', array('szObjectName' => $obj_name, 'szObjectKey' => $nfn_key) );
515
516 if (is_null($results) || (isset($results->attributes()->recordReturn) && $results->attributes()->recordReturn == 0) ) {
517 form_set_error('nfn_key', t('No %obj_name object found with that key', array('%obj_name' => $node->obj_type_name) ));
518 }
519 }
520 }
521 }
522
523 /**
524 * The help DIV included when editing a netFORUM node to help lookup an object type and key
525 * Included here as part of the form
526 *
527 * @param $obj_type_name
528 * A string containing the name of the object
529 * @return
530 * A string containing HTML
531 */
532 function theme_netforum_node_object_lookup($obj_type_name = '') {
533 drupal_add_css(drupal_get_path('module', 'netforum_node') .'/netforum_node.css');
534 drupal_add_js(drupal_get_path('module', 'netforum_node') .'/jquery.netforum_node.js');
535 $obj_type_name = $obj_type_name == "Object" ? "" : $obj_type_name;
536 return netforum_node_object_lookup(false, $obj_type_name);
537 }
538
539 /**
540 * The contents of the help DIV included when editing a netFORUM node to help lookup an object type and key
541 *
542 * This function is called both by the theme and as a menu callback by ajax requests, possibly searching on
543 * fields for the current object or on a URL from netFORUM
544 *
545 * @param $obj_type_name
546 * A string containing the name of the object
547 * @param $exit_after
548 * A boolean, if true the function will output HTML directly and exit. Default value is false
549 * @return
550 * A string containing html if the $exit_after parameter is empty or set to false
551 */
552 function netforum_node_object_lookup($exit_after = false, $obj_type_name='') {
553 $output = '';
554 $max_rows_return = 40;
555 $form = array();
556 $where_args = array();
557 $table_header = array(''); //We want one blank column in here for the Set Key link
558 $table_rows = array();
559 $search_results = "";
560 $search_on = array();
561
562 $form['url_lookup'] = array(
563 '#type' => 'textfield',
564 '#title' => t('netFORUM URL'),
565 '#default_value' => '',
566 '#maxlength' => 500,
567 '#description' => 'Copy and paste a URL to search for the key and object',
568 );
569
570 if ($obj_type_name != '') {
571 //If any modules invoke hook_netforum_node_obj_search_on or hook_netforum_node_obj_order_by use those, if not set some defaults
572 $search_on = module_invoke_all('netforum_node_obj_search_on', $obj_type_name);
573 $order_by = module_invoke_all('netforum_node_obj_order_by', $obj_type_name);
574
575 if (count($search_on) == 0 || count($order_by) == 0) {
576 $default_columns = array();
577 $res = db_query("SELECT obj_defaultcolumns, obj_defaultorderby FROM {netforum_object_cache} WHERE obj_name = '%s'", $obj_type_name);
578 $obj_defaults = db_fetch_array($res);
579 $default_orderby = $obj_defaults['obj_defaultorderby'];
580
581 //If the default columns are * or empty, try setting it to the default order by
582 if ( ! isset($obj_defaults['obj_defaultcolumns']) || $obj_defaults['obj_defaultcolumns'] == "*" || trim($obj_defaults['obj_defaultcolumns']) == '' ) {
583 $obj_defaults['obj_defaultcolumns'] = $obj_defaults['obj_defaultorderby'];
584 }
585
586 if (isset($obj_defaults['obj_defaultcolumns']) && $obj_defaults['obj_defaultcolumns'] != "*" && trim($obj_defaults['obj_defaultcolumns']) != '' ) {
587 $columns = explode(",", $obj_defaults['obj_defaultcolumns']);
588 foreach ($columns as $col) {
589 $col = trim($col);
590 $default_columns[$col] = ucwords(str_replace("_", " ", $col));
591 }
592 }
593
594 $search_on = count($search_on) == 0 ? $default_columns : $search_on;
595 $order_by = count($order_by) == 0 ? $obj_defaults['obj_defaultorderby'] : $order_by;
596 }
597 $order_by = is_array($order_by) ? implode(",", $order_by) : $order_by;
598
599 if (is_array($search_on)) {
600
601 foreach ($search_on as $col => $friendly_col) {
602 $col = trim($col);
603 $table_header[] = $friendly_col;
604
605 //If they submitted the form, prepare to get some data from netFORUM
606 if (isset($_GET[$col]) && $_GET[$col] != '') {
607 $where_args[] = $col ." LIKE '". $_GET[$col] ."%'";
608 }
609
610 //build the form either way
611 $form[$col] = array(
612 '#type' => 'textfield',
613 '#size' => 20,
614 '#title' => $friendly_col,
615 '#default_value' => $_GET[$col],
616 );
617 }
618 }
619 }
620
621 $form['key_submit'] = array(
622 '#type' => 'button',
623 '#value' => 'Search',
624 );
625
626 $form['key_obj_type_name'] = array(
627 '#type' => 'hidden',
628 '#value' => $obj_type_name,
629 '#disabled' => true,
630 );
631 $form['search_on'] = array(
632 '#type' => 'hidden',
633 '#value' => drupal_to_js(array_keys($search_on)),
634 '#disabled' => true,
635 );
636
637 drupal_prepare_form('key-help', $form);
638
639 if ($obj_type_name != '' && count($where_args) > 0) {
640 $arguments = array(
641 'szObjectName' => $obj_type_name ." @TOP ". $max_rows_return,
642 'szColumnList' => implode(", ", array_keys($search_on)),
643 'szWhereClause' => implode(" AND ", $where_args),
644 'szOrderBy' => $order_by,
645 );
646 $response = netforum_xweb_request('GetQuery', $arguments);
647 if ($response && $response->attributes()->recordReturn > 0) {
648 $response_objects = $obj_type_name ."Object";
649 $obj_count = 0;
650 foreach ($response->$response_objects as $obj) {
651 $fields = get_object_vars($obj);
652 $obj_key = (string)array_shift($fields);
653 $table_rows[] = array_merge( array( l(t("Set Key "), '', array('id' => $obj_key, 'class' => 'key-help'), null, '') ), $fields);
654
655 $obj_count++;
656 if ($obj_count > $max_rows_return) {
657 break;
658 }
659 }
660 }
661 if (count($table_rows) == 0) {
662 $table_rows[] = array(array('data' => t('No results found.'), 'colspan' => count($search_on), 'class' => 'message'));
663 }
664 }
665 else if ($_GET['url_lookup']) {
666 parse_str(strtolower($_GET['url_lookup']), $nf_url); //gets the GET arguments into the $nf_url array
667 $obj_name = '';
668 $table_header = array('', 'Object Key', 'Object Name');
669 if (netforum_is_valid_guid($nf_url['formkey'])) {
670 $arguments = array(
671 'szObjectName' => 'md_dynamic_form',
672 'szColumnList' => 'obj_name',
673 'szWhereClause' => "dyn_key = '". $nf_url['formkey'] ."' ",
674 'szOrderBy' => '',
675 );
676 $response = netforum_xweb_request('GetQuery', $arguments);
677
678 if ($response && $response->attributes()->recordReturn > 0) {
679 $obj_name = $response->md_dynamic_formObject->obj_name;
680 }
681 }
682
683 if (netforum_is_valid_guid($nf_url['key'])) {
684 if ($obj_name == '' ) {
685 $obj_name = "Object name not found";
686 }
687 $table_rows[] = array( l("Set Object name and Key", '', array('class' => 'obj-help'), null, '') ,
688 $nf_url['key'],
689 $obj_name,
690 );
691 //Not the most elegant way of passing data back and forth, but since we're outputting HTML anyway I'll take it.
692 $output .= "<span style='display:none' id='new_obj_key'>". $nf_url['key'] ."</span>";
693 $output .= "<span style='display:none' id='new_obj_name'>". $obj_name ."</span>";
694 }
695 else {
696 $table_rows[] = array(array('data' => t('No results found.'), 'colspan' => 2, 'class' => 'message'));
697 }
698 }
699
700 if (count($table_rows) > 0) {
701 $search_results = theme('table', $table_header, $table_rows);
702 }
703
704 if (count($table_rows) >= $max_rows_return) {
705 $output .= "<h3>". t("More than @numrows matches found, try being more specific.", array('@numrows' => $max_rows_return)) ."</h3>";
706 }
707 $output .= $search_results;
708 $output .= drupal_render($form);
709
710 if ($exit_after) {
711 print $output;
712 //If we got no response, it might have set an error using drupal_message. Since we could be ajaxin' it up here,
713 //clear out those errors.
714 drupal_get_messages();
715 exit;
716 }
717 else {
718 return $output;
719 }
720 }
721
722 /**
723 * Implementation of node_insert()
724 */
725 function netforum_node_insert($node) {
726 db_query("INSERT INTO {netforum_node} (nid, vid, nfn_obj_key, nfn_key, unparsed_title, unparsed_body, template_code) VALUES(%d, %d, '%s', '%s', '%s', '%s', '%s')",
727 $node->nid, $node->vid, netforum_object_key($node->obj_type_name), $node->nfn_key, $node->unparsed_title, $node->unparsed_body, $node->template_code);
728 }
729
730 /**
731 * Implementation of node_update()
732 */
733 function netforum_node_update($node) {
734 if ($node->revision) {
735 netforum_node_insert($node);
736 }
737 else{
738 db_query("UPDATE {netforum_node} set nfn_obj_key = '%s', nfn_key = '%s', unparsed_title = '%s', unparsed_body = '%s', template_code = '%s' WHERE nid='%d' AND vid='%d' ",
739 netforum_object_key($node->obj_type_name), $node->nfn_key, $node->unparsed_title, $node->unparsed_body, $node->template_code, $node->nid, $node->vid);
740 }
741 }
742
743 /**
744 * Implementation of node_submit()
745 */
746 function netforum_node_submit(&$node) {
747 netforum_node_set_to_template($node); //This will only override our input if we pass TRUE as the second parameter, so we're safe
748 netforum_node_refresh_fields($node);
749 }
750
751 /**
752 * Implementation of node_load()
753 */
754 function netforum_node_load($node) {
755
756 $op = isset($_POST['op']) ? $_POST['op'] : '';
757
758 if ($op == 'Preview') {
759 //this data is going to get used to generate a preview, so we ought ot set it...
760 $node_part = new stdClass();
761 $node_part->nfn_key = $_POST['nfn_key'];
762 $node_part->obj_type_name = trim($_POST['obj_type_name']);
763 $node_part->nfn_obj_key = netforum_object_key($node_part->obj_type_name);
764 $node_part->unparsed_body = $_POST['unparsed_body'];
765 $node_part->unparsed_title = $_POST['unparsed_title'];
766 $node_part->template_code = $_POST['template_code'];
767 netforum_node_set_to_template($node_part);
768 }
769 else{
770 $res = db_query("SELECT nfn_obj_key, a.nfn_key as nfn_key, obj_name as obj_type_name, unparsed_title, unparsed_body, template_code FROM
771 {netforum_node} a
772 JOIN {netforum_object_cache} b ON a.nfn_obj_key = b.obj_key
773 WHERE nid=%d
774 AND vid=%d", $node->nid, $node->vid);
775 $node_part = db_fetch_object($res);
776 }
777
778 return $node_part;
779 }
780
781
782 /**
783 * Implementation of node_delete()
784 */
785 function netforum_node_delete($node) {
786 db_query("DELETE FROM {netforum_node} WHERE nid=%d", $node->nid);
787 }
788
789 /**
790 * Implementation of node_view()
791 */
792 function netforum_node_view($node, $teaser = FALSE, $page = FALSE) {
793
794 $op = isset($_POST['op']) ? $_POST['op'] : '';
795
796 if ($op == 'Preview') {
797 netforum_node_set_to_template($node);
798 }
799
800 $obj_key = netforum_is_valid_guid($node->nfn_obj_key) ? $node->nfn_obj_key : netforum_object_key($node->obj_type_name);
801
802 if (! isset($node->nfn_data) || empty($node->nfn_data)) {
803 $page_title = drupal_get_title();
804 $old_node_title = $node->title;
805
806 netforum_node_refresh_fields($node);
807 netforum_node_save_fields($node);
808
809 //Update the title of the page if it changed
810 if ($page_title == $old_node_title && $node->title != $old_node_title) {
811 drupal_set_title($node->title);
812 }
813 }
814 if (!$teaser) {
815 //Mostly this is a sanity check, but if they are editing or previewing a node it will be handy
816 if ($node->body == $node->unparsed_body || empty($node->body)) {
817 $node->body = netforum_node_process_text($node->unparsed_body, $node->nfn_data, $obj_key);
818 }
819 if ($node->title == $node->unparsed_title || empty($node->title) ) {
820 $node->title = netforum_node_process_text($node->unparsed_title, $node->nfn_data);
821 }
822 $node = node_prepare($node, $teaser);
823 }
824
825 if ($teaser) {
826 $node->teaser = netforum_node_process_text($node->teaser, $node->nfn_data, $obj_key);
827 $node = node_prepare($node, $teaser);
828 }
829
830 return $node;
831 }
832
833 /**
834 * Create a new node programatically from a template, or redirect if the node exists
835 *
836 * The node's body and title are set to the default template and inserted in the databse
837 *
838 * @param $nfn_obj_key
839 * A string representing the netFORUM key of the node object type
840 * @param $nfn_key
841 * A string representing the unique key of the netFORUM object
842 * @param $nftid
843 * An integer with the template ID to link to, if unset it will link to the default
844 */
845 function netforum_node_create_from_template($nfn_obj_key, $nfn_key, $nftid = null) {
846
847 $code = '';
848 if (is_null($nftid) == false) {
849 $code = db_result(db_query("SELECT code FROM {netforum_node_types} WHERE nftid=%d", $nftid));
850 }
851
852 if ($code != '') {
853 //first check to see if a node with that key/code exists
854 $nid = db_result(db_query("SELECT nid FROM {netforum_node} WHERE nfn_key = '%s' AND template_code = '%s' LIMIT 1", $nfn_key, $code));
855 if ($nid) { //If a node with that object key and type exists, link to it. If there's more than one node with the same key and object, well, good luck.
856 drupal_goto('node/'. $nid);
857 return;
858 }
859 }
860
861 $node = new stdClass();
862 $node->type = 'netforum_node';
863 $node->log = t('Created on demand by a {BeginLink}{EndLink} tag');
864 $node->nfn_key = $nfn_key;
865 $node->nfn_obj_key = $nfn_obj_key;
866 $node->obj_type_name = netforum_object_name($nfn_obj_key);
867
868 $node_options = variable_get('node_options_'. $node->type, array('status'));
869 foreach (array('status', 'promote', 'sticky', 'revision') as $key) {
870 $node->$key = in_array($key, $node_options);
871 }
872
873 if (false) {
874 drupal_goto($_GET['destination']);
875 }
876 netforum_node_set_to_template($node, false, $nftid);
877 if (isset($node->unparsed_body) == false || isset($node->unparsed_title) == false) {
878 drupal_not_found();
879 return;
880 }
881
882 netforum_node_refresh_fields($node);
883 if (isset($node->nfn_data) == false) {
884 drupal_not_found();
885 return;
886 }
887
888 node_save($node);
889
890 drupal_goto('node/'. $node->nid);
891 }
892
893
894 /**
895 * Set the nodes body and title to the netFORUM node template
896 *
897 * @param &$node
898 * A netFORUM node object with either an object key or name set
899 * @param $overwrite_fields
900 * Boolean, defaults to false. If set to true the body and title will be overwritten with
901 * the template
902 * @param $nftid
903 * An integer with the template ID to link to, if unset it will link to the default
904 * @return
905 * A boolean indicating if any fields were changed
906 */
907 function netforum_node_set_to_template(&$node, $overwrite_fields = false, $nftid = null) {
908 if ($overwrite_fields != true && trim($node->unparsed_body) != '' && trim($node->unparsed_title) != '') {
909 //no overwrite needed because the fields have a value and we weren't instructed to overwrite them
910 return false;
911 }
912
913 $changed_fields = false;
914
915 $obj_key = netforum_is_valid_guid($node->nfn_obj_key) ? $node->nfn_obj_key : netforum_object_key($node->obj_type_name);
916 if ( netforum_is_valid_guid($obj_key)) {
917
918 if (is_null($nftid) && trim($node->template_code) != '') {
919 $res = db_query("SELECT nftid FROM {netforum_node_types} WHERE code = '%s'", $node->template_code);
920 if (db_num_rows($res) == 1) {
921 $nftid = db_result($res);
922 }
923 }
924
925 if ($nftid) {
926 $template = db_fetch_array(db_query("SELECT default_body, default_title, taxonomy, format, code FROM {netforum_node_types} WHERE nft_obj_key = '%s' AND nftid = %d ", $obj_key, $nftid));
927 }
928 else {
929 $template = db_fetch_array(db_query("SELECT default_body, default_title, taxonomy, format, code FROM {netforum_node_types} WHERE nft_obj_key = '%s' ORDER BY is_default desc, code LIMIT 1", $obj_key));
930 }
931 if ($template) {
932 if ($overwrite_fields || trim($node->unparsed_body) == '') {
933 $node->unparsed_body = $template['default_body'];
934 $changed_fields = true;
935 }
936 if ($overwrite_fields || trim($node->unparsed_title) == '') {
937 $node->unparsed_title = $template['default_title'];
938 $changed_fields = true;
939 }
940 if ($overwrite_fields || empty($node->taxonomy) ) {
941 $node->taxonomy = unserialize($template['taxonomy']);
942 $changed_fields = true;
943 }
944 if ($overwrite_fields || empty($node->format) ) {
945 $node->format = $template['format'];
946 $changed_fields = true;
947 }
948 if ($overwrite_fields || trim($node->template_code) == '' ) {
949 $node->template_code = $template['code'];
950 $changed_fields = true;
951 }
952 }
953 }
954
955 return $changed_fields;
956 }
957
958 /**
959 * Fetch new data for the netFORUM node and update the body and title
960 *
961 * $node->nfn_skip_save is set by this function. If the data came from the cache
962 * or doesn't change the body or title nfn_skip_save is set to true
963 *
964 * @param &$node
965 * A netFORUM node object
966 * @param $ignore_cache
967 * Boolean, defaults to false. If set to true the latest data will be fetched from
968 * netFORUM and not from the local DB cache
969 */
970 function netforum_node_refresh_fields(&$node, $ignore_cache = false) {
971 $save_not_needed = false;
972 netforum_node_refresh_data($node, $ignore_cache);
973
974 if (isset($node->nfn_data)) {
975 $obj_key = netforum_is_valid_guid($node->nfn_obj_key) ? $node->nfn_obj_key : netforum_object_key($node->obj_type_name);
976
977 $new_body = netforum_node_process_text($node->unparsed_body, $node->nfn_data, $obj_key, $ignore_cache);
978 $new_title = netforum_node_process_text($node->unparsed_title, $node->nfn_data, '', $ignore_cache);
979
980 $save_not_needed = (strcmp($new_body, $node->body) == 0 && strcmp($new_title, $node->title) == 0);
981
982 $node->body = $new_body;
983 $node->title = $new_title;
984 $node->teaser = isset($node->body) ? node_teaser($node->body, isset($node->format) ? $node->format : NULL) : '';
985 }
986 else{
987 $save_not_needed = true;
988 }
989
990 $node->nfn_skip_save = $save_not_needed;
991
992 }
993
994 /**
995 * Get the latest data for a node from netFORUM
996 *
997 * @param &node
998 * The netFORUM Dynamic Facade Node with an object key and object type key set
999 * @return
1000 * Nothing, the node is passed by reference
1001 */
1002 function netforum_node_refresh_data(&$node, $ignore_cache = false) {
1003
1004 if ( (isset($node->nfn_data) && $ignore_cache == false) ) {
1005 return;
1006 }
1007
1008 $obj_name = $node->obj_type_name;
1009 if (!isset($obj_name) && netforum_is_valid_guid($node->nfn_obj_key) ) {
1010 $obj_name = netforum_object_name($node->nfn_obj_key);
1011 }
1012 $nfn_key = $node->nfn_key;
1013
1014 if ( isset($obj_name) == false || netforum_is_valid_guid($nfn_key == false)) {
1015 return;
1016 }
1017
1018 if ($ignore_cache) {
1019 $cache_time = '1 second';
1020 }
1021 else{
1022 $cache_time = null;
1023 // only look in the default cache, if we're refreshing the information we don't want really old (possibly bad) data
1024 }
1025
1026 $results = netforum_xweb_request('GetFacadeObject', array('szObjectName' => $obj_name, 'szObjectKey' => $nfn_key), $cache_time);
1027
1028 if (is_null($results)) {
1029 watchdog('netforum', t('No data for Dynamic Facade Node type !obj_name found for key !key', array('!obj_name' => $obj_name, '!key' => $nfn_key)), WATCHDOG_ERROR, l(t('node'), 'node/'. $node->nid));
1030 }
1031 else {
1032 $node->nfn_data_from_cache = netforum_response_from_cache();
1033 $node->nfn_data = $results;
1034 }
1035 }
1036
1037 /**
1038 * Implementation of hook_perm()
1039 */
1040 function netforum_node_perm() {
1041 return array('create netFORUM node', 'edit own netFORUM nodes', 'edit netFORUM nodes', 'administer netFORUM node templates', 'administer netFORUM node special fields');
1042 }
1043
1044 /**
1045 * Save the node body and title to the database unless $node->nfn_skip_save is true
1046 *
1047 * This is used to make sure that the content in the database is always the most current, which is important
1048 * in the event that the netFORUM server is unreachable
1049 *
1050 * @param $node
1051 * A netFORUM node object
1052 */
1053 function netforum_node_save_fields($node) {
1054
1055 if ($node->nfn_skip_save == true || !isset($node->nid) || !isset($node->vid) ) {
1056 return;
1057 }
1058
1059 db_query("UPDATE {node_revisions} SET title='%s', body='%s', teaser='%s' WHERE nid='%d' AND vid='%d'",
1060 $node->title, $node->body, $node->teaser, $node->nid, $node->vid);
1061
1062 db_query("UPDATE {node} SET title='%s' WHERE nid='%d' AND vid='%d'", $node->title, $node->nid, $node->vid);
1063
1064 }
1065
1066 /**
1067 * Implementation of hook_access()
1068 */
1069 function netforum_node_access($op, $node) {
1070 global $user;
1071
1072 if ($op == 'create') {
1073 return (user_access('create netFORUM node'));
1074 }
1075
1076 if ($op == 'update' || $op == 'delete') {
1077 return ((user_access('edit own netFORUM nodes') && ($user->uid == $node->uid)) || user_access('edit netFORUM nodes'));
1078 }
1079 }
1080
1081 /**
1082 * Implementation of hook_node_operations()
1083 */
1084 function netforum_node_node_operations() {
1085 $operations = array(
1086 'netforum_node_refresh_data' => array(
1087 'label' => t('Refresh data from netFORUM'),
1088 'callback' => 'netforum_node_operations_refresh',
1089 ),
1090 'netforum_node_template' => array(
1091 'label' <