Parent Directory
|
Revision Log
|
Revision Graph
Updating xWeb testing form to smartly display parameters for complex methods.
| 1 | <?php |
| 2 | // $Id: netforum.module,v 1.12 2009/07/11 13:43:51 jamesmichaelhill Exp $ |
| 3 | |
| 4 | /** |
| 5 | * @file |
| 6 | * The netFORUM xWeb Secure module |
| 7 | * |
| 8 | * Provides a foundation for issuing requests and reading responses from xWeb |
| 9 | * |
| 10 | */ |
| 11 | |
| 12 | |
| 13 | /** |
| 14 | * Implementation of hook_menu() |
| 15 | */ |
| 16 | function netforum_menu($may_cache) { |
| 17 | $items = array(); |
| 18 | |
| 19 | if ($may_cache) { |
| 20 | $items[] = array( |
| 21 | 'path' => 'admin/settings/netforum', |
| 22 | 'title' => t('Netforum'), |
| 23 | 'description' => t('Set the connection characteristics for the netFORUM database'), |
| 24 | 'callback' => 'system_admin_menu_block_page', |
| 25 | 'access' => user_access('administer site configuration'), |
| 26 | ); |
| 27 | $items[] = array( |
| 28 | 'path' => 'admin/settings/netforum/connection', |
| 29 | 'title' => t('xWeb settings'), |
| 30 | 'description' => t('Set the connection characteristics for the netFORUM database'), |
| 31 | 'callback' => 'drupal_get_form', |
| 32 | 'callback arguments' => array('netforum_admin_settings'), |
| 33 | 'access' => user_access('administer site configuration'), |
| 34 | ); |
| 35 | $items[] = array( |
| 36 | 'path' => 'admin/settings/netforum/xwebtest', |
| 37 | 'title' => t('xWeb testing'), |
| 38 | 'description' => t('Test xWeb queries to the database'), |
| 39 | 'callback' => 'netforum_test_page', |
| 40 | 'access' => user_access('administer site configuration'), |
| 41 | 'weight' => 5, |
| 42 | ); |
| 43 | |
| 44 | $items[] = array( |
| 45 | 'path' => 'admin/settings/netforum/object-info', |
| 46 | 'title' => t('Object information'), |
| 47 | 'description' => t('View, fetch and delete cached object information'), |
| 48 | 'callback' => 'netforum_objects_page', |
| 49 | 'access' => user_access('administer site configuration'), |
| 50 | 'weight' => 6, |
| 51 | ); |
| 52 | |
| 53 | $items[] = array('path' => 'admin/settings/netforum/object-names-refresh', |
| 54 | 'title' => t('Refresh object names'), |
| 55 | 'callback' => 'netforum_objects_refresh_names', |
| 56 | 'description' => t('Contact netFORUM and re-populate the list of available objects'), |
| 57 | 'access' => user_access('administer site configuration'), |
| 58 | 'weight' => 6, |
| 59 | ); |
| 60 | |
| 61 | $items[] = array('path' => 'admin/settings/netforum/object-autocomplete', |
| 62 | 'title' => t('Netforum object name autocomplete'), |
| 63 | 'callback' => 'netforum_objects_autocomplete', |
| 64 | 'type' => MENU_CALLBACK, |
| 65 | 'access' => user_access('administer site configuration'), |
| 66 | ); |
| 67 | |
| 68 | $items[] = array('path' => 'admin/settings/netforum/xwebtest/params_for', |
| 69 | 'title' => 'xWeb testing - parameters as JSON', |
| 70 | 'callback' => 'netforum_test_page_params', |
| 71 | 'access' => user_access('administer site configuration'), |
| 72 | 'type' => MENU_CALLBACK, |
| 73 | ); |
| 74 | } |
| 75 | else{ |
| 76 | |
| 77 | } |
| 78 | return $items; |
| 79 | } |
| 80 | |
| 81 | /** |
| 82 | * Looks for a function name and returns the parameters as JSON. Used via AJAX |
| 83 | * |
| 84 | * ... |
| 85 | * @ingroup pages |
| 86 | */ |
| 87 | function netforum_test_page_params($fname) { |
| 88 | drupal_set_header('Content-Type: text/javascript; charset=utf-8'); |
| 89 | print drupal_to_js(netforum_xweb_function_struct_parameters($fname)); |
| 90 | exit; |
| 91 | } |
| 92 | |
| 93 | /** |
| 94 | * Provides a testing page for xWeb requests, useful for examining output |
| 95 | * |
| 96 | * ... |
| 97 | * @ingroup pages |
| 98 | * @see netforum_test_form() |
| 99 | */ |
| 100 | function netforum_test_page() { |
| 101 | $output = t('Test a request here by selecting the function from the drop down list and filling in the parameters below. The result of the request and debugging information will be shown below.'); |
| 102 | |
| 103 | |
| 104 | //first, get the functions as an array with function names as keys |
| 105 | //and an array of function parameters as the value |
| 106 | $xweb_functions = array(); |
| 107 | $function_list = _netforum_xweb_soap_functions(); |
| 108 | foreach (array_keys($function_list) as $function_name) { |
| 109 | $xweb_functions[$function_name] = netforum_xweb_function_parameters($function_name); |
| 110 | } |
| 111 | |
| 112 | if (isset($_POST['netforum_request'])) { |
| 113 | if (is_array($_POST['netforum_params'])) { |
| 114 | $request_parameters = array_filter_recursive($_POST['netforum_params']); |
| 115 | } |
| 116 | else { |
| 117 | $request_parameters = array(); |
| 118 | } |
| 119 | |
| 120 | |
| 121 | $request_code = ''; |
| 122 | $request_code .= "\$arguments = ". var_export($request_parameters, TRUE) .";\n"; |
| 123 | $request_code .= "\$response = netforum_xweb_request('". $_POST['netforum_request'] ."', \$arguments); "; |
| 124 | |
| 125 | $response = netforum_xweb_request($_POST['netforum_request'], $request_parameters); |
| 126 | |
| 127 | $form_defaults = array(); |
| 128 | $form_defaults[$_POST['netforum_request']] = $request_parameters; |
| 129 | drupal_set_html_head("<script type=\"text/javascript\"> |
| 130 | var form_defaults = ". drupal_to_js($form_defaults) ."; |
| 131 | </script>"); |
| 132 | |
| 133 | //Overwrite the existing set of parameters (that did shallow inspection) with a deep inspection of the current function |
| 134 | $xweb_functions[$_POST['netforum_request']] = netforum_xweb_function_struct_parameters($_POST['netforum_request']); |
| 135 | |
| 136 | } |
| 137 | |
| 138 | //Turn our array of functions and parameters to json for later use |
| 139 | drupal_set_html_head("<script type=\"text/javascript\"> |
| 140 | var xweb_functions = ". drupal_to_js($xweb_functions) ."; |
| 141 | </script>"); |
| 142 | |
| 143 | //this is the later use referenced above. The js here will adjust the form fields |
| 144 | //and labels based on the selected function |
| 145 | drupal_add_js(drupal_get_path('module', 'netforum') .'/jquery.netforum.js'); |
| 146 | drupal_add_js('misc/collapse.js'); |
| 147 | |
| 148 | |
| 149 | $output .= drupal_get_form('netforum_test_form', $response, $request_code); |
| 150 | return $output; |
| 151 | } |
| 152 | |
| 153 | /** |
| 154 | * The form for the xWeb testing page |
| 155 | * |
| 156 | * ... |
| 157 | * @ingroup forms |
| 158 | * @see netforum_test_page() |
| 159 | */ |
| 160 | function netforum_test_form($response, $request_code = '') { |
| 161 | |
| 162 | $request_options = netforum_xweb_functions(); |
| 163 | if (count($request_options) == 0) { |
| 164 | drupal_set_message("No netFORUM xWeb functions found, perhaps xWeb is currently unavailable?", 'error'); |
| 165 | } |
| 166 | $request_log = ''; |
| 167 | $request_soap_log = ''; |
| 168 | |
| 169 | $request_log = netforum_request_log(); |
| 170 | $request_soap_log = netforum_soap_log(); |
| 171 | |
| 172 | $form['netforum_xweb_request'] = array( |
| 173 | '#title' => 'xWeb Request', |
| 174 | '#type' => 'fieldset', |
| 175 | '#description' => 'Construct the xWeb request' |
| 176 | ); |
| 177 | |
| 178 | $form['netforum_xweb_request']['netforum_request'] = array( |
| 179 | '#type' => 'select', |
| 180 | '#title' => t('netFORUM xWeb Function'), |
| 181 | '#description' => t('The name of the function to call'), |
| 182 | '#default_value' => $form_values['netforum_request'], |
| 183 | '#options' => $request_options, |
| 184 | ); |
| 185 | |
| 186 | $form['netforum_xweb_request']['parameters'] = array( |
| 187 | '#type' => 'fieldset', |
| 188 | '#attributes' => array('id' => 'parameters'), |
| 189 | ); |
| 190 | |
| 191 | /* |
| 192 | * Normally, there would be inputs for the function here, but |
| 193 | * we're relying on some JS and AJAX to build the right form |
| 194 | * for the right function |
| 195 | */ |
| 196 | |
| 197 | $form['netforum_xweb_request']['submit'] = array( |
| 198 | '#type' => 'button', |
| 199 | '#value' => 'submit', |
| 200 | '#name' => 'clickbutton', |
| 201 | ); |
| 202 | |
| 203 | |
| 204 | $form['netforum_xweb_results'] = array( |
| 205 | '#title' => 'xWeb Results', |
| 206 | '#type' => 'fieldset', |
| 207 | '#description' => 'Response from xWeb' |
| 208 | ); |
| 209 | |
| 210 | $form['netforum_xweb_results']['code'] = array( |
| 211 | '#title' => 'PHP Code', |
| 212 | '#type' => 'item', |
| 213 | '#description' => "<pre>". htmlspecialchars($request_code) ."</pre>" , |
| 214 | ); |
| 215 | |
| 216 | $form['netforum_xweb_results']['response'] = array( |
| 217 | '#title' => 'Response', |
| 218 | '#type' => 'item', |
| 219 | '#description' => "<pre>". htmlspecialchars(print_r($response, TRUE)) ."</pre>" , |
| 220 | ); |
| 221 | |
| 222 | $form['netforum_xweb_results']['soap_log'] = array( |
| 223 | '#title' => 'SOAP Log', |
| 224 | '#type' => 'item', |
| 225 | '#description' => "<pre>". htmlspecialchars($request_soap_log) ."</pre>" , |
| 226 | ); |
| 227 | |
| 228 | $form['netforum_xweb_results']['request_log'] = array( |
| 229 | '#title' => 'xWebSecureClient Class Log', |
| 230 | '#type' => 'item', |
| 231 | '#description' => "<pre>". htmlspecialchars($request_log) ."</pre>" , |
| 232 | ); |
| 233 | |
| 234 | $form['#submit'] = array( |
| 235 | 'netforum_test_page' => array(), |
| 236 | ); |
| 237 | |
| 238 | $form['#redirect'] = FALSE; |
| 239 | |
| 240 | return $form; |
| 241 | } |
| 242 | |
| 243 | /** |
| 244 | * The Objects page provides a way to search for objects available for queries and view the columns |
| 245 | * |
| 246 | * ... |
| 247 | * @ingroup pages |
| 248 | * @see netforum_objects_form() |
| 249 | */ |
| 250 | function netforum_objects_page() { |
| 251 | $output = t('Use this page to view columns and column details for netFORUM objects. Each request clears the cache for that object and fetches the details from xWeb. If the object is not found, try ') . l(t('refreshing the object names'), 'admin/settings/netforum/object-names-refresh') .'.'; |
| 252 | $object_details = array(); |
| 253 | $obj = new stdClass(); |
| 254 | $obj->obj_key = $obj->obj_defaultcolumns = $obj->obj_defaultorderby = $obj->obj_name = ''; |
| 255 | |
| 256 | if (isset($_POST['netforum_object_name'])) { |
| 257 | $name = trim($_POST['netforum_object_name']); |
| 258 | $res = db_query("SELECT obj_key, obj_defaultcolumns, obj_defaultorderby, obj_name FROM {netforum_object_cache} WHERE obj_name = '%s' ", $name); |
| 259 | if (db_num_rows($res) > 0) { |
| 260 | $obj = db_fetch_object($res); |
| 261 | db_query("UPDATE {netforum_object_cache} SET data = '' WHERE obj_name='%s' ", $name); |
| 262 | $object_details = netforum_object_fields($name); |
| 263 | } |
| 264 | else { |
| 265 | drupal_set_message(t('Object name not found in the cache, perhaps you need to refresh the object names?'), 'error'); |
| 266 | } |
| 267 | } |
| 268 | |
| 269 | $output .= drupal_get_form('netforum_objects_form', $object_details, $obj); |
| 270 | |
| 271 | return $output; |
| 272 | } |
| 273 | |
| 274 | /** |
| 275 | * The form for the objects page |
| 276 | * |
| 277 | * ... |
| 278 | * @ingroup forms |
| 279 | * @see netforum_objects_page() |
| 280 | */ |
| 281 | function netforum_objects_form($object_details = array(), $obj) { |
| 282 | |
| 283 | $search_on = module_invoke_all('netforum_node_obj_search_on', $obj->obj_name); |
| 284 | $order_by = module_invoke_all('netforum_node_obj_order_by', $obj->obj_name); |
| 285 | |
| 286 | if (count($search_on) == 0) { |
| 287 | //If the default columns are * or empty, try setting it to the default order by |
| 288 | if ( ! isset($obj->obj_defaultcolumns) || $obj->obj_defaultcolumns == "*" || trim($obj->obj_defaultcolumns) == '' ) { |
| 289 | $search_on = $obj->obj_defaultorderby; |
| 290 | } |
| 291 | else { |
| 292 | $search_on = $obj->obj_defaultcolumns; |
| 293 | } |
| 294 | } |
| 295 | else{ |
| 296 | $search_on = implode(",", array_keys($search_on)); |
| 297 | } |
| 298 | |
| 299 | if (count($order_by) == 0) { |
| 300 | $order_by = $obj->obj_defaultorderby; |
| 301 | } |
| 302 | else { |
| 303 | $order_by = implode(",", $order_by); |
| 304 | } |
| 305 | |
| 306 | $form['netforum_object_name'] = array( |
| 307 | '#type' => 'textfield', |
| 308 | '#title' => t('Object Name'), |
| 309 | '#size' => 50, |
| 310 | '#autocomplete_path' => 'admin/settings/netforum/object-autocomplete', |
| 311 | ); |
| 312 | |
| 313 | $form['submit'] = array( |
| 314 | '#type' => 'button', |
| 315 | '#value' => 'Fetch / refresh object details', |
| 316 | '#name' => 'clickbutton', |
| 317 | ); |
| 318 | |
| 319 | |
| 320 | $form['netforum_object_details'] = array( |
| 321 | '#title' => 'Object details', |
| 322 | '#type' => 'fieldset', |
| 323 | '#description' => 'Refreshed object details from xWeb' |
| 324 | ); |
| 325 | |
| 326 | $form['netforum_object_details']['key'] = array( |
| 327 | '#title' => 'Object Key', |
| 328 | '#type' => 'item', |
| 329 | '#description' => $obj->obj_key , |
| 330 | ); |
| 331 | |
| 332 | $form['netforum_object_details']['searchcolumns'] = array( |
| 333 | '#title' => 'Object Search Columns', |
| 334 | '#type' => 'item', |
| 335 | '#description' => $search_on, |
| 336 | ); |
| 337 | |
| 338 | $form['netforum_object_details']['orderby'] = array( |
| 339 | '#title' => 'Object Order By', |
| 340 | '#type' => 'item', |
| 341 | '#description' => $order_by , |
| 342 | ); |
| 343 | |
| 344 | $form['netforum_object_details']['keyfield'] = array( |
| 345 | '#title' => 'Key Field', |
| 346 | '#type' => 'item', |
| 347 | '#description' => netforum_object_key_field($obj->obj_name), |
| 348 | ); |
| 349 | |
| 350 | $form['netforum_object_details']['response'] = array( |
| 351 | '#title' => 'Object Fields', |
| 352 | '#type' => 'item', |
| 353 | '#description' => "<pre>". htmlspecialchars(print_r($object_details, TRUE)) ."</pre>" , |
| 354 | ); |
| 355 | |
| 356 | return $form; |
| 357 | } |
| 358 | |
| 359 | |
| 360 | function netforum_objects_autocomplete($search="") { |
| 361 | drupal_set_header('Content-Type: text/javascript; charset=utf-8'); |
| 362 | $obj_names = array(); |
| 363 | if ($search != "") { |
| 364 | $results = db_query("SELECT obj_name FROM {netforum_object_cache} WHERE obj_name like '%s%%' OR obj_prefix like '%s%%' ORDER BY obj_name", $search, $search); |
| 365 | while ($obj = db_fetch_object($results)) { |
| 366 | $obj_names[$obj->obj_name] = check_plain($obj->obj_name); |
| 367 | } |
| 368 | } |
| 369 | print drupal_to_js($obj_names); |
| 370 | exit; |
| 371 | } |
| 372 | |
| 373 | /** |
| 374 | * Technically a page, this will refresh the cached list of objects and redirect the user to |
| 375 | * the object info page |
| 376 | * |
| 377 | * ... |
| 378 | * @ingroup pages |
| 379 | */ |
| 380 | function netforum_objects_refresh_names() { |
| 381 | netforum_refresh_object_names(); |
| 382 | drupal_set_message(t('netFORUM object names refreshed')); |
| 383 | drupal_goto('admin/settings/netforum/object-info'); |
| 384 | } |
| 385 | |
| 386 | |
| 387 | /** |
| 388 | * The settings form for netFORUM Secure |
| 389 | * |
| 390 | * @ingroup forms |
| 391 | * @see netforum_admin_settings_validate |
| 392 | */ |
| 393 | function netforum_admin_settings() { |
| 394 | |
| 395 | $form['xWeb'] = array( |
| 396 | '#title' => "xWeb connection", |
| 397 | '#type' => 'fieldset', |
| 398 | ); |
| 399 | |
| 400 | $form['xWeb']['netforum_wsdl_url'] = array( |
| 401 | '#type' => 'textfield', |
| 402 | '#title' => t('Netforum WSDL URL'), |
| 403 | '#description' => t('xWeb endpoint, commonly https://example.com/xweb/Secure/netFORUMXML.asmx?WSDL'), |
| 404 | '#default_value' => variable_get('netforum_wsdl_url', 'https://'), |
| 405 | '#required' => TRUE, |
| 406 | '#size' => 50, |
| 407 | ); |
| 408 | |
| 409 | $form['xWeb']['netforum_xweb_username'] = array( |
| 410 | '#type' => 'textfield', |
| 411 | '#title' => t('xWeb User Name'), |
| 412 | '#description' => t('This is the username that is used to authenticate with netFORUM and gain access'), |
| 413 | '#default_value' => variable_get('netforum_xweb_username', ''), |
| 414 | '#size' => 16 |
| 415 | ); |
| 416 | |
| 417 | $form['xWeb']['netforum_xweb_password'] = array( |
| 418 | '#type' => 'password', |
| 419 | '#title' => t('xWeb User Password'), |
| 420 | '#description' => t('The password to go with the xweb user, commonly requires manually setting usr_pwd in fw_user'), |
| 421 | '#default_value' => variable_get('netforum_xweb_password', ''), |
| 422 | '#size' => 16 |
| 423 | ); |
| 424 | |
| 425 | $form['xWeb']['netforum_hide_error_messages'] = array( |
| 426 | '#type' => 'checkbox', |
| 427 | '#title' => t('Hide connection error messages'), |
| 428 | '#description' => t('Should regular visitors be able to see when the connection to netFORUM is not available? Site administrators will always see connection errors.'), |
| 429 | '#default_value' => variable_get('netforum_hide_error_messages', 0), |
| 430 | ); |
| 431 | |
| 432 | $form['cache'] = array( |
| 433 | '#title' => "xWeb caching", |
| 434 | '#type' => 'fieldset', |
| 435 | ); |
| 436 | |
| 437 | $form['cache']['netforum_cache_default'] = array( |
| 438 | '#type' => 'textfield', |
| 439 | '#title' => t('Cache Length'), |
| 440 | '#description' => t('How long should a response be used before fetching new values from xWeb'), |
| 441 | '#default_value' => variable_get('netforum_cache_default', '1 hour'), |
| 442 | '#size' => 16 |
| 443 | ); |
| 444 | |
| 445 | $form['cache']['netforum_cache_max'] = array( |
| 446 | '#type' => 'textfield', |
| 447 | '#title' => t('Maximum Cache Length'), |
| 448 | '#description' => t('If the first request fails how far back in the cache should we search before returning empty data?'), |
| 449 | '#default_value' => variable_get('netforum_cache_max', '4 days'), |
| 450 | '#size' => 16 |
| 451 | ); |
| 452 | |
| 453 | $form['availability'] = array( |
| 454 | '#title' => "xWeb availability", |
| 455 | '#type' => 'fieldset', |
| 456 | ); |
| 457 | |
| 458 | $form['availability']['netforum_slow_query_limit'] = array( |
| 459 | '#type' => 'textfield', |
| 460 | '#title' => t('Slow query limit'), |
| 461 | '#description' => t('Any xWeb requests over this time limit are marked with warnings in the system logs.'), |
| 462 | '#after_field' => t('seconds'), |
| 463 | '#default_value' => variable_get('netforum_slow_query_limit', '1.5'), |
| 464 | '#field_suffix' => t('seconds'), |
| 465 | '#size' => 4 |
| 466 | ); |
| 467 | |
| 468 | |
| 469 | $form['availability']['netforum_verify_timeout'] = array( |
| 470 | '#type' => 'textfield', |
| 471 | '#title' => t('xWeb timeout'), |
| 472 | '#description' => t('If netFORUM cannot be contacted in this time it is logged as an error'), |
| 473 | '#field_suffix' => t('seconds'), |
| 474 | '#default_value' => variable_get('netforum_verify_timeout', 5), |
| 475 | '#size' => 4 |
| 476 | ); |
| 477 | |
| 478 | $form['availability']['netforum_verify_availability'] = array( |
| 479 | '#type' => 'checkbox', |
| 480 | '#title' => t('Verify xWeb availability before requests'), |
| 481 | '#description' => t('Verify that netFORUM is available before issuing requests by trying to open a connection to the server.'), |
| 482 | '#default_value' => variable_get('netforum_verify_availability', 1), |
| 483 | ); |
| 484 | |
| 485 | $form['availability']['netforum_verify_length'] = array( |
| 486 | '#type' => 'textfield', |
| 487 | '#title' => t('xWeb verification length'), |
| 488 | '#description' => t('This sets how frequently netFORUM should be checked for availability. Think of it as the time between verification checks. There is overhead associated with this, so anything less than 2 minutes might not be efficient. Enter zero to disable and check before every request.'), |
| 489 | '#field_suffix' => t('minutes'), |
| 490 | '#default_value' => variable_get('netforum_verify_length', 3), |
| 491 | '#size' => 4 |
| 492 | ); |
| 493 | |
| 494 | $form['#validate'] = array( |
| 495 | 'netforum_admin_settings_validate' => array() |
| 496 | ); |
| 497 | |
| 498 | return system_settings_form($form); |
| 499 | } |
| 500 | |
| 501 | /** |
| 502 | * Validating the system settings form |
| 503 | * |
| 504 | * @see netforum_admin_settings |
| 505 | */ |
| 506 | function netforum_admin_settings_validate($form_id, $form_values, $form) { |
| 507 | $clear_to_connect = TRUE; |
| 508 | |
| 509 | if ( ! valid_url($form_values['netforum_wsdl_url'], TRUE)) { |
| 510 | form_set_error('netforum_wsdl_url', t('Please enter a valid wsdl url for access')); |
| 511 | $clear_to_connect = FALSE; |
| 512 | } |
| 513 | |
| 514 | if ( !isset($form_values['netforum_xweb_username']) || trim($form_values['netforum_xweb_username']) == '') { |
| 515 | form_set_error('netforum_xweb_username', t('Please enter a username')); |
| 516 | $clear_to_connect = FALSE; |
| 517 | } |
| 518 | |
| 519 | if ( !isset($form_values['netforum_xweb_password']) || trim($form_values['netforum_xweb_password']) == '') { |
| 520 | $old_password = variable_get('netforum_xweb_password', FALSE); |
| 521 | if ($old_password) { |
| 522 | form_set_value($form['xWeb']['netforum_xweb_password'], $old_password); |
| 523 | $form_values['netforum_xweb_password'] = $old_password; |
| 524 | } |
| 525 | else { |
| 526 | form_set_error('netforum_xweb_password', t('Please enter a password')); |
| 527 | $clear_to_connect = FALSE; |
| 528 | } |
| 529 | } |
| 530 | |
| 531 | if (isset($form_values['netforum_cache_default'])) { |
| 532 | if (substr(trim($form_values['netforum_cache_default']), 0, 1) == '-') { |
| 533 | form_set_error('netforum_cache_default', t('The default cache cannot be a negative amount of time.')); |
| 534 | } |
| 535 | elseif (strtotime($form_values['netforum_cache_default']) === FALSE || strtotime($form_values['netforum_cache_default']) == -1 ) { |
| 536 | form_set_error('netforum_cache_default', t('The time format was not recognized, please enter something in the format of 4 days or 1 hour')); |
| 537 | } |
| 538 | } |
| 539 | |
| 540 | if (isset($form_values['netforum_cache_max'])) { |
| 541 | if (substr(trim($form_values['netforum_cache_max']), 0, 1) == '-') { |
| 542 | form_set_error('netforum_cache_max', t('The default cache cannot be a negative amount of time.')); |
| 543 | } |
| 544 | elseif (strtotime($form_values['netforum_cache_max']) === FALSE || strtotime($form_values['netforum_cache_max']) == -1 ) { |
| 545 | form_set_error('netforum_cache_max', t('The time format was not recognized, please enter something in the format of 4 days or 1 hour')); |
| 546 | } |
| 547 | } |
| 548 | |
| 549 | if (isset($form_values['netforum_wsdl_url']) && stristr($form_values['netforum_wsdl_url'], 'netForumXMLOnDemand.asmx')) { |
| 550 | variable_set('netforum_xweb_od', 1); |
| 551 | } |
| 552 | else { |
| 553 | variable_set('netforum_xweb_od', 0); |
| 554 | } |
| 555 | |
| 556 | if ($clear_to_connect === TRUE) { |
| 557 | if ($form_values['netforum_verify_availability'] == 1 && netforum_is_available() === FALSE) { |
| 558 | drupal_set_message(t('Could not contact netFORUM server'), 'error'); |
| 559 | return; |
| 560 | } |
| 561 | _netforum_include_xweb(); |
| 562 | try { |
| 563 | $error_level = error_reporting(0); //ignore the errors, only catch exceptions |
| 564 | $verify_timeout = $form_values['netforum_verify_timeout']; |
| 565 | if ($verify_length != 0) { |
| 566 | ini_set('default_socket_timeout', $verify_timeout); |
| 567 | } |
| 568 | $nfh = new xwebSecureClient($form_values['netforum_wsdl_url'], |
| 569 | Array('trace' => TRUE, |
| 570 | 'exceptions' => TRUE, |
| 571 | 'cache_wsdl' => TRUE, |
| 572 | 'xwebUserName' => $form_values['netforum_xweb_username'], |
| 573 | 'xwebUserPass' => $form_values['netforum_xweb_password'])); |
| 574 | $response = $nfh->GetFacadeXMLSchema(array('szObjectName' => 'Customer')); |
| 575 | if ($response) { |
| 576 | drupal_set_message(t('Successfully connected to netFORUM server and retreived data'), "status"); |
| 577 | } |
| 578 | error_reporting($error_level); |
| 579 | } |
| 580 | catch(Exception $exception) { |
| 581 | form_set_error('form_token', t('Could not connect to netFORUM server with specified parameters.<br> @exception_message .', array('@exception_message' => $exception->getMessage())) ); |
| 582 | $wsdl_url_guess = _netforum_guess_xweb_url($form_values['netforum_wsdl_url']); |
| 583 | if (strtolower($form_values['netforum_wsdl_url']) != strtolower($wsdl_url_guess)) { |
| 584 | drupal_set_message(t('Perhaps the following WSDL endpoint would work better:<br> @wsdl_url_guess', array('@wsdl_url_guess' => $wsdl_url_guess)), "status"); |
| 585 | } |
| 586 | } |
| 587 | } |
| 588 | } |
| 589 | |
| 590 | /** |
| 591 | * Implementation of hook_cron() |
| 592 | */ |
| 593 | function netforum_cron() { |
| 594 | $cutoffdate = strftime("%Y-%m-%d %H:%M", strtotime("-". variable_get('netforum_cache_max', '10 days'))); |
| 595 | db_query("DELETE FROM {netforum_request_cache} WHERE add_date <= '$cutoffdate';"); |
| 596 | } |
| 597 | |
| 598 | /** |
| 599 | * Verify that netforum is aailable for queries. |
| 600 | * |
| 601 | * This stores the result in a global varaible to prevent repetitive checks in the same request. |
| 602 | * If the admin setting verify availability is unchecked then this always returns TRUE |
| 603 | * |
| 604 | * @return |
| 605 | * Boolean TRUE or FALSE |
| 606 | */ |
| 607 | function netforum_is_available() { |
| 608 | global $_netforum_is_available; |
| 609 | |
| 610 | if (variable_get('netforum_verify_availability', 1) == 0) { |
| 611 | return TRUE; |
| 612 | } |
| 613 | |
| 614 | if (isset($_netforum_is_available)) { |
| 615 | return $_netforum_is_available; |
| 616 | } |
| 617 | |
| 618 | $verify_length = variable_get('netforum_verify_length', 3); |
| 619 | if ($verify_length != 0) { |
| 620 | $cutoff = strtotime("-". $verify_length ." minutes"); |
| 621 | $last_result = variable_get('netforum_netforum_is_available', array(NULL, NULL)); |
| 622 | if ( is_null($last_result[0]) === FALSE && $last_result[1] >= $cutoff ) { |
| 623 | return $last_result[0]; |
| 624 | } |
| 625 | } |
| 626 | //close down all warnings, because if it does fail we don't want it to show |
| 627 | $error_level = error_reporting(0); |
| 628 | |
| 629 | $address = variable_get('netforum_wsdl_url', NULL); |
| 630 | if ($address == NULL) { |
| 631 | $_netforum_is_available = FALSE; |
| 632 | } |
| 633 | else { |
| 634 | $opts = array('http' => array('timeout' => variable_get('netforum_verify_timeout', 5)), 'https' => array('timeout' => variable_get('netforum_verify_timeout', 5))); |
| 635 | $address_parts = explode('/', $address); |
| 636 | $server = $address_parts[2]; |
| 637 | $fp = fsockopen($server, 80, $errno, $errstr, variable_get('netforum_verify_timeout', 5)); |
| 638 | if ($fp) { |
| 639 | $_netforum_is_available = TRUE; |
| 640 | } |
| 641 | else { |
| 642 | $_netforum_is_available = FALSE; |
| 643 | watchdog('netforum', t("Could not connect to netFORUM server %server - %error", array('%server' => $server, '%error' => $errstr) ), WATCHDOG_ERROR, l(t('settings'), 'admin/settings/netforum/connection')); |
| 644 | } |
| 645 | } |
| 646 | |
| 647 | //restore the error reporting level |
| 648 | error_reporting($error_level); |
| 649 | |
| 650 | if ($verify_length != 0) { |
| 651 | variable_set('netforum_netforum_is_available', array($_netforum_is_available, time())); |
| 652 | } |
| 653 | |
| 654 | return $_netforum_is_available; |
| 655 | } |
| 656 | |
| 657 | /** |
| 658 | * Checks to see if it is netFORUM Enterprise |
| 659 | * |
| 660 | * @return |
| 661 | * Boolean TRUE if enterprise, FALSE otherwise |
| 662 | */ |
| 663 | function netforum_is_enterprise() { |
| 664 | return (variable_get('netforum_xweb_od', 0) == 0); |
| 665 | } |
| 666 | |
| 667 | /** |
| 668 | * Checks to see if it is netFORUM Team or Pro |
| 669 | * |
| 670 | * @return |
| 671 | * Boolean TRUE if Team or Pro, FALSE otherwise |
| 672 | */ |
| 673 | function netforum_is_team() { |
| 674 | return (variable_get('netforum_xweb_od', 0) == 1); |
| 675 | } |
| 676 | |
| 677 | function _netforum_include_xweb() { |
| 678 | $path = drupal_get_path('module', 'netforum'); |
| 679 | if (netforum_is_enterprise()) { |
| 680 | require_once($path .'/xwebSecureClient.class.inc'); |
| 681 | } |
| 682 | else { |
| 683 | require_once($path .'/xwebSecureOD.class.inc'); |
| 684 | } |
| 685 | } |
| 686 | |
| 687 | /** |
| 688 | * Connect to xWeb and return a copy of the global SoapClient handler. |
| 689 | * If the server is not available set it to only check the local cache. |
| 690 | */ |
| 691 | function netforum_connect_xweb() { |
| 692 | |
| 693 | _netforum_include_xweb(); |
| 694 | global $_netforum_xweb_handler; |
| 695 | if (!isset($_netforum_xweb_handler)) { |
| 696 | try{ |
| 697 | $error_level = error_reporting(0); //ignore the errors, only catch exceptions |
| 698 | $verify_timeout = variable_get('netforum_verify_timeout', 5); |
| 699 | if ($verify_timeout != 0) { |
| 700 | ini_set('default_socket_timeout', $verify_timeout); |
| 701 | } |
| 702 | $_netforum_xweb_handler = new xwebSecureClient(variable_get('netforum_wsdl_url', NULL), |
| 703 | Array('trace' => TRUE, |
| 704 | 'exceptions' => TRUE, |
| 705 | 'cache_wsdl' => TRUE, |
| 706 | 'xwebUserName' => variable_get('netforum_xweb_username', NULL), |
| 707 | 'xwebUserPass' => variable_get('netforum_xweb_password', NULL), ) |
| 708 | ); |
| 709 | $_netforum_xweb_handler->setCaching(variable_get('netforum_cache_default', NULL)); |
| 710 | error_reporting($error_level); |
| 711 | } |
| 712 | catch(Exception $exception) { |
| 713 | if (variable_get('netforum_hide_error_messages', 0) == 0 || user_access('administer site configuration')) { |
| 714 | drupal_set_message(t('Could not connect to netFORUM server, please verify connection settings'), 'error'); |
| 715 | } |
| 716 | } |
| 717 | } |
| 718 | |
| 719 | if ( isset($_netforum_xweb_handler) ) { |
| 720 | if (netforum_is_available() === FALSE) { |
| 721 | $_netforum_xweb_handler->enableOfflineMode(); |
| 722 | } |
| 723 | else { |
| 724 | $_netforum_xweb_handler->disableOfflineMode(); |
| 725 | } |
| 726 | } |
| 727 | |
| 728 | return $_netforum_xweb_handler; |
| 729 | } |
| 730 | |
| 731 | /** |
| 732 | * Issue a request to xWeb and return the result, if any |
| 733 | * |
| 734 | * If $cache_max is not set, it recurses with $cache_max set to the admin set option. If $cache_max is set it only makes one attempt. |
| 735 | * |
| 736 | * @param $fname |
| 737 | * A string containing the name of the xWeb function such as GetQuery or InsertFacadeObject; case sensitive |
| 738 | * @param $arguments |
| 739 | * An array with keys set to parameter names and values set to the data. For example, Array('szObjectName'=>'Individual'). |
| 740 | * @param $cache_max |
| 741 | * A string parseable to a time that indicates how far back in the cache to search. For example, '1 day' |
| 742 | * @return |
| 743 | * Bare results, a SimpleXML Object, or NULL if no results are found |
| 744 | * |
| 745 | * @see netforum_xweb_functions |
| 746 | * @see netforum_xweb_function_parameters |
| 747 | * @see netforum_xweb_function_struct_parameters |
| 748 | * @see netforum_request_log |
| 749 | * @see netforum_soap_log |
| 750 | * @see netforum_ind_info_parameters |
| 751 | * @see netforum_org_info_parameters |
| 752 | * @see netforum_facade_object_parameters |
| 753 | */ |
| 754 | function netforum_xweb_request($fname, $arguments = array(), $cache_max = NULL) { |
| 755 | $start_time = microtime(); |
| 756 | $nfh = netforum_connect_xweb(); |
| 757 | |
| 758 | if ( ! $nfh) { |
| 759 | watchdog('netforum', t("Received xWeb request for !fname but could not connect to xWeb", array('!fname' => $fname)), WATCHDOG_ERROR); |
| 760 | return NULL; |
| 761 | } |
| 762 | |
| 763 | $xml_object = NULL; |
| 764 | $results = NULL; |
| 765 | |
| 766 | if (isset($cache_max)) { |
| 767 | $nfh->setCaching($cache_max); |
| 768 | } |
| 769 | |
| 770 | //we're going to turn off errors for a moment here. If there is an SSL error the first time, I don't |
| 771 | //want to display it. We can throw our own thank you. |
| 772 | $error_level = error_reporting(0); |
| 773 | |
| 774 | try{ |
| 775 | $results = $nfh->{$fname}($arguments); |
| 776 | if ( !isset($results)) { |
| 777 | throw new Exception('No results returned from xWeb Query'); |
| 778 | } |
| 779 | } |
| 780 | catch(Exception $e) { |
| 781 | if (isset($cache_max)) { //this implies that we went even further back in the cache and could not connect, so call it quits |
| 782 | if (variable_get('netforum_hide_error_messages', 0) == 0 || user_access('administer site configuration')) { |
| 783 | drupal_set_message(t('Could not retreive data from server or cache.'), 'error'); |
| 784 | } |
| 785 | $nfh->setCaching(variable_get('netforum_cache_default', '4 hours')); |
| 786 | if ($fname == 'GetQuery') { |
| 787 | watchdog('netforum', t("Could not get response to !fname request for !columns from !object: @fault", array('!fname' => $fname, '@fault' => $e->faultstring, '!columns' => $arguments['szColumnList'], '!object' => $arguments['szObjectName'])), WATCHDOG_ERROR); |
| 788 | } |
| 789 | else { |
| 790 | watchdog('netforum', t("Could not get response to !fname request: @fault", array('!fname' => $fname, '@fault' => $e->faultstring)), WATCHDOG_ERROR); |
| 791 | } |
| 792 | } |
| 793 | else { |
| 794 | //recurse if we hit one snag and try it one more time |
| 795 | watchdog('netforum', t("First xWeb request for !fname did not return any arguments", array('!fname' => $fname)), WATCHDOG_WARNING); |
| 796 | $results = netforum_xweb_request($fname, $arguments, variable_get('netforum_cache_max', '4 days')); |
| 797 | } |
| 798 | } |
| 799 | |
| 800 | if (isset($results)) { |
| 801 | $fname_result = $fname ."Result"; |
| 802 | //the following is a test for a response containing yet more xml. If it is a simple request, like WebLogin then the result |
| 803 | //is workable as a simpleobject and does not need to be parsed further. |
| 804 | if (isset($results->{$fname_result}->any) && $fname != "GetFacadeXMLSchema") { |
| 805 | $results = simplexml_load_string($results->{$fname_result}->any, "SimpleXMLElement", LIBXML_NOERROR+LIBXML_NOWARNING); |
| 806 | } |
| 807 | |
| 808 | if ($nfh->cachedLastResponse() == 1) { |
| 809 | $source = t("from database cache"); |
| 810 | } |
| 811 | else { |
| 812 | $source = t("directly from xWeb"); |
| 813 | } |
| 814 | $elapsed_time = microtime()-$start_time; |
| 815 | $max_time = (float)variable_get('netforum_slow_query_limit', '1.5'); |
| 816 | if ($max_time != 0 && $elapsed_time > $max_time) { |
| 817 | watchdog('netforum', t("Slow returning response to xWeb query !fname !source in !elapsed_time seconds, parameters: <br> @arguments", array('!fname' => $fname, '!source' => $source, '!elapsed_time' => $elapsed_time, '@arguments' => print_r($arguments, TRUE))), WATCHDOG_WARNING); |
| 818 | } |
| 819 | } |
| 820 | |
| 821 | //restore the error reporting level |
| 822 | error_reporting($error_level); |
| 823 | |
| 824 | return $results; |
| 825 | |
| 826 | } |
| 827 | |
| 828 | /** |
| 829 | * Find out if the last request came from the database |
| 830 | * |
| 831 | * @return |
| 832 | * TRUE if the last xWeb request came from the local database cache, FALSE otherwise |
| 833 | */ |
| 834 | function netforum_response_from_cache() { |
| 835 | $nfh = netforum_connect_xweb(); |
| 836 | if (!$nfh) { |
| 837 | return; |
| 838 | } |
| 839 | return $nfh->lastResponseFromCache(); |
| 840 | } |
| 841 | |
| 842 | /** |
| 843 | * Return a list of fields for a given object |
| 844 | * |
| 845 | * By default this will return the cached object info. If the object info does not exist or is empty, then it will issue a request to |
| 846 | * xWeb, parse, store, and return the results. The object name must exist in the database in order to return the fields. |
| 847 | * |
| 848 | * @param $obj_name |
| 849 | * A string representing the object name. For example, Individual or EventsRegistrant |
| 850 | * @return |
| 851 | * A hashed array with the keys set to the column names and the values set to the column description |
| 852 | */ |
| 853 | function netforum_object_fields($obj_name) { |
| 854 | static $seen_objects = array(); |
| 855 | $obj_fields = array(); |
| 856 | |
| 857 | if ( !isset($obj_name) || $obj_name == '') { |
| 858 | return $obj_fields; |
| 859 | } |
| 860 | |
| 861 | if (isset($seen_objects[$obj_name])) { |
| 862 | return $seen_objects[$obj_name]; |
| 863 | } |
| 864 | |
| 865 | $cached_result = db_query("SELECT data, obj_prefix, obj_defaultcolumns, obj_defaultorderby FROM {netforum_object_cache} WHERE obj_name = '%s' ", $obj_name); |
| 866 | if (db_num_rows($cached_result) > 0) { |
| 867 | $cached_obj = db_fetch_object($cached_result); |
| 868 | if ($cached_obj->data != '') { |
| 869 | $obj_fields = unserialize($cached_obj->data); |
| 870 | $seen_objects[$obj_name] = $obj_fields; |
| 871 | return $obj_fields; |
| 872 | } |
| 873 | } |
| 874 | else { |
| 875 | watchdog('netforum', t('Could not find object %objectname in list of netFORUM objects, perhaps the the list of objects needs to be refreshed?', array('%objectname' => $obj_name)), WATCHDOG_WARNING, l(t('refresh object list'), 'admin/settings/netforum/object-names-refresh')); |
| 876 | return $obj_fields; |
| 877 | } |
| 878 | |
| 879 | set_time_limit(90); |
| 880 | $updated_object_data = array(); |
| 881 | if (netforum_is_enterprise() ) { |
| 882 | $arguments = array( |
| 883 | 'szObjectName' => "Object", |
| 884 | 'szColumnList' => "obj_prefix, obj_defaultcolumns, obj_defaultorderby", |
| 885 | 'szWhereClause' => "obj_name = '$obj_name'", |
| 886 | 'szOrderBy' => "", |
| 887 | ); |
| 888 | $response = netforum_xweb_request('GetQuery', $arguments); |
| 889 | if ($response) { |
| 890 | $obj = $response->ObjectObject; |
| 891 | $updated_object_data['obj_prefix'] = strval($obj->obj_prefix); |
| 892 | $updated_object_data['obj_defaultcolumns'] = strval($obj->obj_defaultcolumns); |
| 893 | $updated_object_data['obj_defaultorderby'] = strval($obj->obj_defaultorderby); |
| 894 | } |
| 895 | } |
| 896 | |
| 897 | $response = netforum_xweb_request('GetFacadeXMLSchema', array('szObjectName' => $obj_name)); |
| 898 | if (is_null($response)) { |
| 899 | return $obj_fields; |
| 900 | } |
| 901 | |
| 902 | // so this is not the greatest way to parse out the object descriptions, but it's a way, and it works. At least it only goes through each node once, |
| 903 | // even if it does wade through several thousand of them for the large objects. |
| 904 | $p = xml_parser_create(); |
| 905 | xml_parser_set_option($p, XML_OPTION_CASE_FOLDING, 0); |
| 906 | xml_parser_set_option($p, XML_OPTION_SKIP_WHITE, 1); |
| 907 | xml_parse_into_struct($p, $response->GetFacadeXMLSchemaResult->any, $vals); |
| 908 | xml_parser_free($p); |
| 909 | |
| 910 | foreach ($vals as $node) { |
| 911 | if (isset($node['tag']) && $node['tag'] == 'xsd:group' && $node['type'] == 'open') { |
| 912 | $category = $node['attributes']['name']; |
| 913 | $level = $node['level']; |
| 914 | $found_close = FALSE; |
| 915 | while ($found_close === FALSE) { |
| 916 | $node = next($vals); |
| 917 | if ($node['tag'] && $node['tag'] == 'xsd:element' && $node['type'] != 'close' && isset($node['attributes']['ref'])) { |
| 918 | $col = $node['attributes']['ref']; |
| 919 | if (stristr($col, '_')) { |
| 920 | $obj_fields[$col] = $category ."::"; |
| 921 | } |
| 922 | else { |
| 923 | continue; |
| 924 | } |
| 925 | } |
| 926 | elseif ($node['tag'] && $node['tag'] == 'xsd:group' && $node['type'] == 'close' && $node['level'] == $level) { |
| 927 | $found_close = TRUE; |
| 928 | } |
| 929 | } |
| 930 | } |
| 931 | if (isset($node['tag']) && $node['tag'] == 'xsd:element' && $node['type'] == 'open' && isset($node['attributes']) && isset($node['attributes']['name'])) { |
| 932 | $col = $node['attributes']['name']; |
| 933 | if (array_key_exists($col, $obj_fields) === FALSE) { |
| 934 | continue; |
| 935 | } |
| 936 | $level = $node['level']; |
| 937 | $found_close = FALSE; |
| 938 | while ($found_close === FALSE) { |
| 939 | $node = next($vals); |
| 940 | if ($node['tag'] && $node['tag'] == 'xsd:documentation') { |
| 941 | $obj_fields[$col] .= trim($node['value'], '.'); |
| 942 | } |
| 943 | elseif ($node['tag'] && $node['tag'] == 'xsd:element' && $node['type'] == 'close' && $node['level'] == $level) { |
| 944 | $found_close = TRUE; |
| 945 | } |
| 946 | } |
| 947 | } |
| 948 | } |
| 949 | |
| 950 | |
| 951 | $update_query = "UPDATE {netforum_object_cache} SET data='%s', "; |
| 952 | $update_values = array(serialize($obj_fields)); |
| 953 | foreach($updated_object_data as $k => $v) { |
| 954 | $update_query .= $k ." = '%s', "; |
| 955 | $update_values[] = $v; |
| 956 | } |
| 957 | |
| 958 | $update_query = rtrim($update_query, ", "); |
| 959 | $update_query .= " WHERE obj_name = '%s'"; |
| 960 | $update_values[] = $obj_name; |
| 961 | db_query($update_query, $update_values); |
| 962 | |
| 963 | $seen_objects[$obj_name] = $obj_fields; |
| 964 | |
| 965 | return $obj_fields; |
| 966 | } |
| 967 | |
| 968 | /** |
| 969 | * Fetch a list of Objects from netForum and stores any new object names and keys in the cache |
| 970 | * |
| 971 | * netFORUM OnDemand doesn't have many of the features needed, so the names for on demand are loaded from a static file |
| 972 | */ |
| 973 | function netforum_refresh_object_names() { |
| 974 | |
| 975 | if (netforum_is_team()) { |
| 976 | //Individual, Organization, Address, and Customer are the only allowed objects for us, calling GetFacadeXMLSchema on anything else is a nogo. |
| 977 | db_query("INSERT INTO {netforum_object_cache} (obj_name, obj_key, obj_prefix, obj_defaultcolumns, obj_defaultorderby, data, obj_key_field) VALUES ('Individual','f41b6e06-299b-4022-be6f-0641ba87de59','ind','ind_last_name,ind_first_name','ind_last_name,ind_first_name',NULL,NULL); " ); |
| 978 | db_query("INSERT INTO {netforum_object_cache} (obj_name, obj_key, obj_prefix, obj_defaultcolumns, obj_defaultorderby, data, obj_key_field) VALUES ('Organization','9c0100ce-f6c2-4b42-aff2-1c065f3734d9','org','org_name, org_acronym','org_name',NULL,NULL); " ); |
| 979 | db_query("INSERT INTO {netforum_object_cache} (obj_name, obj_key, obj_prefix, obj_defaultcolumns, obj_defaultorderby, data, obj_key_field) VALUES ('Address','0574b4d5-853b-48a9-8b64-8b424b6658bd','adr','*','adr_city',NULL,NULL); " ); |
| 980 | db_query("INSERT INTO {netforum_object_cache} (obj_name, obj_key, obj_prefix, obj_defaultcolumns, obj_defaultorderby, data, obj_key_field) VALUES ('Customer','65f0eb73-0df7-4196-b2ff-11b61f10e532','cst','cst_type,cst_name_cp','cst_sort_name_dn',NULL,NULL); " ); |
| 981 | return; |
| 982 | } |
| 983 | |
| 984 | $empty_obj_struct = array('obj_key' => '', 'obj_name' => '', 'obj_prefix' => '', 'obj_defaultcolumns' => '', 'obj_defaultorderby' => ''); |
| 985 | $columns = array_keys($empty_obj_struct); |
| 986 | |
| 987 | $arguments = array( |
| 988 | 'szObjectName' => "Object @TOP -1", |
| 989 | 'szColumnList' => implode(", ", $columns), |
| 990 | 'szWhereClause' => "obj_prefix is not NULL and obj_delete_flag = 0", |
| 991 | 'szOrderBy' => "", |
| 992 | ); |
| 993 | $response = netforum_xweb_request('GetQuery', $arguments); |
| 994 | |
| 995 | $partial_data = FALSE; |
| 996 | if (is_null($response) || $response->attributes()->recordReturn < 400) { |
| 997 | // If we can't use the @TOP directive to override the maximum records returned in the query limit, try it the slow way. |
| 998 | // according to the avectra wiki, @TOP was added in 2006.01 build |
| 999 | $response = netforum_xweb_request('GetFacadeObjectList'); |
| 1000 | $partial_data = TRUE; |
| 1001 | } |
| 1002 | if ($response) { |
| 1003 | $db_objects = array(); |
| 1004 | $to_add = array(); |
| 1005 | $to_update = array(); |
| 1006 | $db_result = db_query("SELECT ". implode(", ", $columns) ." FROM {netforum_object_cache}"); |
| 1007 | while ($obj = db_fetch_object($db_result)) { |
| 1008 | $db_objects[(string)$obj->obj_key] = $obj; |
| 1009 | } |
| 1010 | if ($partial_data) { |
| 1011 | foreach ($response->ObjectObject as $obj) { |
| 1012 | $object_name = (string)$obj->obj_name; |
| 1013 | $object_key = (string)$obj->obj_key; |
| 1014 | if (array_key_exists($object_key, $db_objects)) { |
| 1015 | if ($db_objects[$object_key]->obj_name != $object_name) { |
| 1016 | $to_update[$object_key] = $empty_obj_struct; |
| 1017 | $to_update[$object_key]['obj_name'] = $object_name; |
| 1018 | } |
| 1019 | } |
| 1020 | else { |
| 1021 | $to_add[$object_key] = $empty_obj_struct; |
| 1022 | $to_add[$object_key]['obj_name'] = $object_name; |
| 1023 | $to_add[$object_key]['obj_key'] = $object_key; |
| 1024 | } |
| 1025 | } |
| 1026 | } |
| 1027 | else { //if we got all the data we want, do the same logic but with more data! |
| 1028 | foreach ($response->ObjectObject as $obj) { |
| 1029 | $object_key = (string)$obj->obj_key; |
| 1030 | if (array_key_exists($object_key, $db_objects)) { |
| 1031 | foreach ($columns as $obj_col) { |
| 1032 | $obj_val = (string)$obj->{$obj_col}; |
| 1033 | if ($db_objects[$object_key]->{$obj_col} != $obj_val) { |
| 1034 | if (!isset($to_update[$object_key])) { |
| 1035 | $to_update[$object_key] = array(); |
| 1036 | } |
| 1037 | $to_update[$object_key][$obj_col] = $obj_val; |
| 1038 | } |
| 1039 | } |
| 1040 | } |
| 1041 | else { |
| 1042 | $to_add[$object_key] = $empty_obj_struct; |
| 1043 | foreach ($columns as $obj_col) { |
| 1044 | $obj_val = (string)$obj->{$obj_col}; |
| 1045 | $to_add[$object_key][$obj_col] = $obj_val; |
| 1046 | } |
| 1047 | } |
| 1048 | } |
| 1049 | } |
| 1050 | |
| 1051 | foreach ($to_add as $obj_key => $obj) { |
| 1052 | $query = "INSERT INTO {netforum_object_cache} (". implode(", ", array_keys($obj)) .") "; |
| 1053 | $query .= " VALUES(". implode(", ", array_pad(array(), count($obj), "'%s'")) .");"; |
| 1054 | db_query($query, array_values($obj) ); |
| 1055 | } |
| 1056 | |
| 1057 | foreach ($to_update as $obj_key => $obj) { |
| 1058 | $updates = array(); |
| 1059 | $values = array(); |
| 1060 | foreach ($obj as $k => $v) { |
| 1061 | $updates[] = "$k = '%s'"; |
| 1062 | $values[] = $v; |
| 1063 | } |
| 1064 | $values[] = $obj_key; |
| 1065 | db_query("UPDATE {netforum_object_cache} SET ". implode(", ", $updates) ." WHERE obj_key = '%s' ;", $values ); |
| 1066 | } |
| 1067 | } |
| 1068 | } |
| 1069 | |
| 1070 | /** |
| 1071 | * Find the name of an object when given the key |
| 1072 | * |
| 1073 | * @param $obj_key |
| 1074 | * String with the object key |
| 1075 | * @return |
| 1076 | * String with the object name if found, empty string otherwise |
| 1077 | */ |
| 1078 | function netforum_object_name($obj_key) { |
| 1079 | static $name_cache = array(); |
| 1080 | $obj_key = (string)$obj_key; |
| 1081 | if ( netforum_is_valid_guid($obj_key) == FALSE ) { |
| 1082 | return ''; |
| 1083 | } |
| 1084 | if (array_key_exists($obj_key, $name_cache)) { |
| 1085 | return $name_cache[$obj_key]; |
| 1086 | } |
| 1087 | else { |
| 1088 | $res = db_query("SELECT obj_name FROM {netforum_object_cache} WHERE obj_key = '%s' ", $obj_key); |
| 1089 | if (db_num_rows($res) > 0) { |
| 1090 | $obj = db_fetch_object($res); |
| 1091 | $name_cache[$obj_key] = $obj->obj_name; |
| 1092 | return $obj->obj_name; |
| 1093 | } |
| 1094 | else{ |
| 1095 | return ''; |
| 1096 | } |
| 1097 | } |
| 1098 | } |
| 1099 | |
| 1100 | /** |
| 1101 | * Find the key of an object when given the name |
| 1102 | * |
| 1103 | * @param $obj_name |
| 1104 | * String with the object name |
| 1105 | * @return |
| 1106 | * String with the object key if found, FALSE otherwise |
| 1107 | */ |
| 1108 | function netforum_object_key($obj_name) { |
| 1109 | static $key_cache = array(); |
| 1110 | |
| 1111 | if (netforum_is_valid_guid($obj_name)) { |
| 1112 | return $obj_name; |
| 1113 | } |
| 1114 | |
| 1115 | if ( array_key_exists($obj_name, $key_cache)) { |
| 1116 | return $key_cache[$obj_name]; |
| 1117 | } |
| 1118 | else { |
| 1119 | $res = db_query("SELECT obj_key FROM {netforum_object_cache} WHERE obj_name = '%s' ", $obj_name); |
| 1120 | if (db_num_rows($res) > 0) { |
| 1121 | $obj = db_fetch_object($res); |
| 1122 | $key_cache[$obj_name] = $obj->obj_key; |
| 1123 | return $obj->obj_key; |
| 1124 | } |
| 1125 | else{ |
| 1126 | return FALSE; |
| 1127 | } |
| 1128 | } |
| 1129 | } |
| 1130 | |
| 1131 | /** |