diff --git a/httprl.async.inc b/httprl.async.inc index 986d967..f5046e5 100644 --- a/httprl.async.inc +++ b/httprl.async.inc @@ -21,16 +21,8 @@ function httprl_async_page() { httprl_fast403(); } - // See if a full bootstrap has been done given the Drupal version. - if (defined('VERSION') && substr(VERSION, 0, 1) >= 7) { - $level = drupal_bootstrap(); - $full_bootstrap = ($level == DRUPAL_BOOTSTRAP_FULL) ? TRUE : FALSE; - } - else { - $full_bootstrap = isset($GLOBALS['multibyte']) ? TRUE : FALSE; - } // Get the private key. - $private_key = $full_bootstrap ? drupal_get_private_key() : httprl_variable_get('drupal_private_key', 0); + $private_key = httprl_drupal_get_private_key(); // Exit if the master_key does not match the md5 of $private_key. if ( empty($private_key) @@ -56,42 +48,27 @@ function httprl_async_page() { } // Release the lock. - if (variable_get('lock_inc', './includes/lock.inc') !== './includes/lock.inc') { - lock_release($_POST['temp_key']); - } - else { - httprl_lock_release($_POST['temp_key']); - } + httprl_lock_release($_POST['temp_key']); - // Unpack arguments. - $input_args = unserialize($_POST['args']); + $args = unserialize($_POST['args']); - // Pass by reference trick for call_user_func_array(). - $args = array(); - foreach ($input_args as &$arg) { - $args[] = &$arg; + // Run the function. + if (!empty($_POST['function'])) { + $data = httprl_run_function($_POST['function'], $args); + } + // Run an array of functions. + else { + $args = current($args); + $data = httprl_run_array($args); } - - // Caputure anything printed out. - ob_start(); - // Run function. - $return = call_user_func_array($_POST['function'], $args); - $printed = ob_get_contents(); - ob_end_clean(); // Return data to caller. - if (!empty($_POST['mode'])) { + if (!empty($_POST['mode']) && isset($data)) { header('Content-Type: application/x-www-form-urlencoded'); - $data = array('return' => $return, 'args' => $args, 'printed' => $printed); echo http_build_query(array(0 => serialize($data)), '', '&'); } // Exit Script. - if (defined('VERSION') && substr(VERSION, 0, 1) >= 7) { - drupal_exit(); - } - else { - exit; - } + httprl_call_exit(); } diff --git a/httprl.module b/httprl.module index 263493d..7e351d9 100644 --- a/httprl.module +++ b/httprl.module @@ -1205,18 +1205,38 @@ function httprl_extract_background_callback_data(&$result) { $data = unserialize(current($data)); // Set return and printed values. - $result->options['internal_states']['background_function_return'] = $data['return']; - $result->options['internal_states']['background_function_printed'] = $data['printed']; + if (isset($data['return'])) { + $result->options['internal_states']['background_function_return'] = $data['return']; + } + if (isset($data['printed'])) { + $result->options['internal_states']['background_function_printed'] = $data['printed']; + } // Set any pass by reference values. - foreach ($result->options['internal_states']['background_function_args'] as $k => &$value) { - if (isset($data['args'][$k])) { - $value = $data['args'][$k]; + httprl_recursive_array_reference_extract($result->options['internal_states']['background_function_args'], $data['args']); +} + +function httprl_recursive_array_reference_extract(&$array, $data) { + foreach ($array as $key => &$value) { + if (isset($data[$key])) { + if (is_array($data[$key]) && is_array($value)) { + $value = httprl_recursive_array_reference_extract($value, $data[$key]); + } + else { + $value = $data[$key]; + } } else { $value = NULL; } } + // Copy new keys into the data structure. + foreach ($data as $key => $value) { + if (isset($array[$key])) { + continue; + } + $array[$key] = $value; + } } /** @@ -1290,6 +1310,9 @@ function httprl_queue_background_callback(&$args, &$result = NULL) { if (!isset($callback_options['printed'])) { $callback_options['printed'] = ''; } + if (!isset($callback_options['function'])) { + $callback_options['function'] = ''; + } // Acquire lock for this run. $locked = FALSE; @@ -1306,15 +1329,17 @@ function httprl_queue_background_callback(&$args, &$result = NULL) { unset($locks[$id]); // Remove the lock_id reference in the database. - if (defined('VERSION') && substr(VERSION, 0, 1) >= 7) { - db_update('semaphore') - ->fields(array('value' => 'httprl')) - ->condition('name', $id) - ->condition('value', _lock_id()) - ->execute(); - } - else { - db_query("UPDATE {semaphore} SET value = '%s' WHERE name = '%s' AND value = '%s'", 'httprl', $name, _lock_id()); + if (variable_get('lock_inc', './includes/lock.inc') !== './includes/lock.inc') { + if (defined('VERSION') && substr(VERSION, 0, 1) >= 7) { + db_update('semaphore') + ->fields(array('value' => 'httprl')) + ->condition('name', $id) + ->condition('value', _lock_id()) + ->execute(); + } + else { + db_query("UPDATE {semaphore} SET value = '%s' WHERE name = '%s' AND value = '%s'", 'httprl', $id, _lock_id()); + } } } @@ -1561,12 +1586,7 @@ function httprl_fast403() { print ''; // Exit Script. - if (defined('VERSION') && substr(VERSION, 0, 1) >= 7) { - drupal_exit(); - } - else { - exit; - } + httprl_call_exit(); } /** @@ -1578,16 +1598,21 @@ function httprl_fast403() { * The name of the lock. */ function httprl_lock_release($name) { - global $locks; - - unset($locks[$name]); - if (defined('VERSION') && substr(VERSION, 0, 1) >= 7) { - db_delete('semaphore') - ->condition('name', $name) - ->execute(); + if (variable_get('lock_inc', './includes/lock.inc') !== './includes/lock.inc') { + lock_release($_POST['temp_key']); } else { - db_query("DELETE FROM {semaphore} WHERE name = '%s'", $name); + global $locks; + + unset($locks[$name]); + if (defined('VERSION') && substr(VERSION, 0, 1) >= 7) { + db_delete('semaphore') + ->condition('name', $name) + ->execute(); + } + else { + db_query("DELETE FROM {semaphore} WHERE name = '%s'", $name); + } } } @@ -1772,7 +1797,7 @@ function httprl_variable_get($name, $default = NULL) { * ), * 'return' => what was returned from this call. * 'printed' => what was printed from this call. - * 'error' => any errors that might have occured. + * 'error' => any errors that might have occurred. * 'last' => set the last variable to anything. * ) * ) @@ -1780,13 +1805,18 @@ function httprl_variable_get($name, $default = NULL) { function httprl_run_array(&$array) { $last = NULL; foreach ($array as &$data) { + // Skip if no type is set. + if (!isset($data['type'])) { + continue; + } + // Set the last variable if so desired. if (isset($data['last'])) { $last = $data['last']; } // Replace the last key with the last thing that has been returned. - if (array_key_exists('last', $data['args'])) { + if (isset($data['args']) && array_key_exists('last', $data['args'])) { $data['args']['last'] = $last; $data['args'] = array_values($data['args']); } @@ -1798,8 +1828,10 @@ function httprl_run_array(&$array) { // Pass by reference trick for call_user_func_array(). $args = array(); - foreach ($data['args'] as &$arg) { - $args[] = &$arg; + if (isset($data['args']) && is_array($data['args'])) { + foreach ($data['args'] as &$arg) { + $args[] = &$arg; + } } // Start to capture errors. @@ -1835,4 +1867,102 @@ function httprl_run_array(&$array) { $data['return'] = $last; } } + + return array('args' => array($array)); +} + +/** + * Run a single function. + * + * @param $function + * Name of function to run. + * @param $input_args + * list of arguments to pass along to the function. + */ +function httprl_run_function($function, &$input_args) { + // Pass by reference trick for call_user_func_array(). + $args = array(); + foreach ($input_args as &$arg) { + $args[] = &$arg; + } + + // Capture anything printed out. + ob_start(); + + // Start to capture errors. + $track_errors = ini_set('track_errors', '1'); + $php_errormsg = ''; + + // Run function. + $return = call_user_func_array($function, $args); + $printed = ob_get_contents(); + ob_end_clean(); + + // Create data array. + $data = array('return' => $return, 'args' => $args, 'printed' => $printed); + + // Set any errors if any where thrown. + if (!empty($php_errormsg)) { + $data['error'] = $php_errormsg; + ini_set('track_errors', $track_errors); + } + + return $data; +} + +function httprl_boot() { + global $base_root; + $full_url = $base_root . request_uri(); + + // Return if this is not a httprl_async_function_callback request. + if ( strpos($full_url, '/httprl_async_function_callback') === FALSE + || $_SERVER['REQUEST_METHOD'] !== 'POST' + || empty($_POST['master_key']) + || empty($_POST['temp_key']) + || strpos($_POST['temp_key'], 'httprl_') !== 0 + || !empty($_POST['function']) + ) { + return NULL; + } + + module_load_include('inc', 'httprl', 'httprl.async'); + httprl_async_page(); +} + +/** + * Gets the private key variable. + * + * @return + * The private key. + */ +function httprl_drupal_get_private_key() { + // See if a full bootstrap has been done given the Drupal version. + if (defined('VERSION') && substr(VERSION, 0, 1) >= 7) { + $level = drupal_bootstrap(); + $full_bootstrap = ($level == DRUPAL_BOOTSTRAP_FULL) ? TRUE : FALSE; + } + else { + $full_bootstrap = isset($GLOBALS['multibyte']) ? TRUE : FALSE; + } + + $private_key = $full_bootstrap ? drupal_get_private_key() : httprl_variable_get('drupal_private_key', 0); + return $private_key; +} + +/** + * Performs end-of-request tasks and/or call exit directly. + */ +function httprl_call_exit() { + if (defined('VERSION') && substr(VERSION, 0, 1) >= 7 && drupal_get_bootstrap_phase() == DRUPAL_BOOTSTRAP_FULL) { + drupal_exit(); + } + else { + exit; + } +} + +function asdf(&$x, &$y, &$z) { + $x = 'asdf'; + $y = 'qwer'; + $z = 'zxcv'; } diff --git a/httprl.nonblocktest.inc b/httprl.nonblocktest.inc index eb5d4d9..3289b1d 100644 --- a/httprl.nonblocktest.inc +++ b/httprl.nonblocktest.inc @@ -17,23 +17,16 @@ function httprl_nonblockingtest_page() { if ( empty($_GET['id']) || empty($_GET['key']) || strpos($_GET['id'], 'httprl_') !== 0 - || $_GET['key'] != md5(drupal_get_private_key()) + || $_GET['key'] != md5(httprl_drupal_get_private_key()) ) { httprl_fast403(); } // Release the lock, echo out that the lock was cleared and exit. - if (variable_get('lock_inc', './includes/lock.inc') !== './includes/lock.inc') { - lock_release($_GET['id']); - } - else { - httprl_lock_release($_GET['id']); - } + httprl_lock_release($_GET['id']); + echo t('lock @id cleared', array('@id' => $_GET['id'])); - if (defined('VERSION') && substr(VERSION, 0, 1) >= 7) { - drupal_exit(); - } - else { - exit; - } + + // Exit Script. + httprl_call_exit(); }