diff --git a/js/shs.js b/js/shs.js index 428711e..54ef073 100644 --- a/js/shs.js +++ b/js/shs.js @@ -125,6 +125,9 @@ cache: true, data: { callback: 'shs_json_term_get_children', + js_module: 'shs', + js_callback: 'json', + js_token: Drupal.settings.js && Drupal.settings.js.tokens && Drupal.settings.js.tokens['shs-json'], arguments: { vid: settings.vid, parent: parent_value, @@ -222,6 +225,9 @@ cache: true, data: { callback: 'shs_json_term_add', + js_module: 'shs', + js_callback: 'json', + js_token: Drupal.settings.js && Drupal.settings.js.tokens && Drupal.settings.js.tokens['shs-json'], arguments: { vid: term.vid, parent: term.parent, diff --git a/shs.module b/shs.module index 486b717..e0b3446 100644 --- a/shs.module +++ b/shs.module @@ -15,7 +15,7 @@ function shs_menu() { $items['js/shs'] = array( 'title' => 'JSON callback', 'description' => 'JSON callbacks for Simple hierarchical select', - 'page callback' => 'shs_json', + 'page callback' => 'shs_js_callback_json', 'access callback' => 'user_access', 'access arguments' => array('access content'), 'type' => MENU_CALLBACK, @@ -26,19 +26,33 @@ function shs_menu() { /** * Implements hook_js(). + * + * Provides the callback information for the 1.x version of the JS module. + * + * @deprecated + * Support will be removed in future versions. */ function shs_js() { - $settings = array( + $info = shs_js_info(); + $info['json']['callback'] = 'shs_js_callback_json'; + $info['json']['access callback'] = 'user_access'; + return $info; +} + +/** + * Implements hook_js_info(). + */ +function shs_js_info() { + return array( 'json' => array( - 'callback' => 'shs_json', - 'access callback' => 'user_access', 'access arguments' => array('access content'), 'includes' => array('path'), 'dependencies' => array('taxonomy', 'field', 'field_sql_storage'), + // Select option values are added using "new Option" and hence do not + // require HTML escaping. + 'xss' => FALSE, ), ); - drupal_alter('shs_js_info', $settings); - return $settings; } /** @@ -68,30 +82,43 @@ function shs_requirements($phase) { } /** - * Menu callback to get data in JSON format. + * Implements MODULE_js_callback_CALLBACK(). */ -function shs_json() { - $result = array( +function shs_js_callback_json($callback = NULL, $arguments = array()) { + // JS module utilizes a global while in it's bootstrap process. + // Use this to detect if this request is invoked using the JS module + // bootstrap process. + global $_js; + + $json = array( 'success' => FALSE, 'data' => array(), ); - if (isset($_POST['callback'])) { - // Get name of function we need to call to get the data. - $_callback = check_plain($_POST['callback']); - // Is this a valid callback? - $valid_callbacks = shs_json_callbacks(); - if (isset($valid_callbacks[$_callback]) && !empty($valid_callbacks[$_callback]['callback']) && function_exists($valid_callbacks[$_callback]['callback'])) { - // Get arguments and validate them. - $post_args = (isset($_POST['arguments']) && is_array($_POST['arguments'])) ? $_POST['arguments'] : array(); - $arguments = _shs_json_callback_get_arguments($valid_callbacks[$_callback], $post_args); - if (($callback_result = call_user_func_array($valid_callbacks[$_callback]['callback'], $arguments)) !== FALSE) { - $result['success'] = TRUE; - $result['data'] = $callback_result; - } + + // Override the callback and arguments if no or 1.x JS module support. + if (!isset($_js) && isset($_POST['callback']) && isset($_POST['arguments'])) { + $callback = check_plain($_POST['callback']); + $arguments = $_POST['arguments']; + } + + // Check if SHS callback is valid. + $valid_callbacks = shs_json_callbacks(); + if ($callback && isset($valid_callbacks[$callback]) && !empty($valid_callbacks[$callback]['callback']) && function_exists($valid_callbacks[$callback]['callback'])) { + // Invoke the SHS callback with any arguments provided. + if (($callback_result = call_user_func_array($valid_callbacks[$callback]['callback'], _shs_json_callback_get_arguments($valid_callbacks[$callback], $arguments))) !== FALSE) { + $json['success'] = TRUE; + $json['data'] = $callback_result; } } - // Return result as JSON string. - drupal_json_output($result); + + // Return the result if a JS 2.x callback request. + if ($_js) { + return $json; + } + else { + // Otherwise just prit out the JSON (no or 1.x JS module support). + drupal_json_output($json); + } } /** @@ -479,6 +506,8 @@ function shs_field_widget_form(&$form, &$form_state, $field, $instance, $langcod '#after_build' => array('shs_field_widget_afterbuild'), '#shs_settings' => $instance['widget']['settings']['shs'], '#shs_vocabularies' => $vocabularies, + // Generates the necessary XSS token to validate JS 2.x requests. + '#js_callback' => array('shs' => 'json'), ); $return = array($field_column => $element);