- #47510: Show JavaScript alert when PHP errors occur
parent
afde65151c
commit
d38429248e
|
|
@ -1171,6 +1171,8 @@ function drupal_call_js($function) {
|
|||
|
||||
/**
|
||||
* Converts a PHP variable into its Javascript equivalent.
|
||||
*
|
||||
* We use HTML-safe strings, i.e. with <, > and & escaped.
|
||||
*/
|
||||
function drupal_to_js($var) {
|
||||
switch (gettype($var)) {
|
||||
|
|
@ -1180,8 +1182,18 @@ function drupal_to_js($var) {
|
|||
return $var;
|
||||
case 'resource':
|
||||
case 'string':
|
||||
return '"'. str_replace(array("\r", "\n"), array('\r', '\n'), addslashes($var)) .'"';
|
||||
return '"'. str_replace(array("\r", "\n", "<", ">", "&"),
|
||||
array('\r', '\n', '\x3c', '\x3e', '\x26'),
|
||||
addslashes($var)) .'"';
|
||||
case 'array':
|
||||
if (array_keys($var) === range(0, sizeof($var) - 1)) {
|
||||
$output = array();
|
||||
foreach($var as $v) {
|
||||
$output[] = drupal_to_js($v);
|
||||
}
|
||||
return '[ '. implode(', ', $output) .' ]';
|
||||
}
|
||||
// Fall through
|
||||
case 'object':
|
||||
$output = array();
|
||||
foreach ($var as $k => $v) {
|
||||
|
|
|
|||
|
|
@ -113,24 +113,8 @@ function HTTPPost(uri, callbackFunction, callbackParameter, object) {
|
|||
* window.parent.iframeHandler() after submission.
|
||||
*/
|
||||
function redirectFormButton(uri, button, handler) {
|
||||
// Insert the iframe
|
||||
// Note: some browsers require the literal name/id attributes on the tag,
|
||||
// some want them set through JS. We do both.
|
||||
var div = document.createElement('div');
|
||||
div.innerHTML = '<iframe name="redirect-target" id="redirect-target" class="redirect"></iframe>';
|
||||
var iframe = div.firstChild;
|
||||
with (iframe) {
|
||||
name = 'redirect-target';
|
||||
setAttribute('name', 'redirect-target');
|
||||
id = 'redirect-target';
|
||||
}
|
||||
with (iframe.style) {
|
||||
position = 'absolute';
|
||||
height = '1px';
|
||||
width = '1px';
|
||||
visibility = 'hidden';
|
||||
}
|
||||
document.body.appendChild(iframe);
|
||||
// Make sure we have an iframe to target
|
||||
createIframe();
|
||||
|
||||
// Trap the button
|
||||
button.onmouseover = button.onfocus = function() {
|
||||
|
|
@ -147,11 +131,34 @@ function redirectFormButton(uri, button, handler) {
|
|||
handler.onsubmit();
|
||||
|
||||
// Set iframe handler for later
|
||||
window.iframeHandler = function (data) {
|
||||
window.iframeHandler = function () {
|
||||
var iframe = $('redirect-target');
|
||||
// Restore form submission
|
||||
button.form.action = action;
|
||||
button.form.target = target;
|
||||
handler.oncomplete(data);
|
||||
|
||||
// Get response from iframe body
|
||||
try {
|
||||
response = (iframe.contentWindow || iframe.contentDocument || iframe).document.body.innerHTML;
|
||||
if (window.opera) {
|
||||
// Opera-hack: it returns innerHTML sanitized.
|
||||
response = response.replace(/"/g, '"');
|
||||
}
|
||||
}
|
||||
catch (e) {
|
||||
response = null;
|
||||
}
|
||||
|
||||
// Recreate the iframe: re-using an old iframe can sometimes cause browser bugs.
|
||||
createIframe();
|
||||
|
||||
response = parseJson(response);
|
||||
// Check response code
|
||||
if (response.status == 0) {
|
||||
handler.onerror(response.data);
|
||||
return;
|
||||
}
|
||||
handler.oncomplete(response.data);
|
||||
}
|
||||
|
||||
return true;
|
||||
|
|
@ -300,6 +307,55 @@ function stopEvent(event) {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse a JSON response.
|
||||
*
|
||||
* The result is either the JSON object, or an object with 'status' 0 and 'data' an error message.
|
||||
*/
|
||||
function parseJson(data) {
|
||||
if (data.substring(0,1) != '{') {
|
||||
return { status: 0, data: data.length ? data : 'Unspecified error' };
|
||||
}
|
||||
return eval('(' + data + ');');
|
||||
}
|
||||
|
||||
/**
|
||||
* Create an invisible iframe for form submissions.
|
||||
*/
|
||||
function createIframe() {
|
||||
// Delete any previous iframe
|
||||
deleteIframe();
|
||||
// Note: some browsers require the literal name/id attributes on the tag,
|
||||
// some want them set through JS. We do both.
|
||||
window.iframeHandler = function () {};
|
||||
var div = document.createElement('div');
|
||||
div.id = 'redirect-holder';
|
||||
div.innerHTML = '<iframe name="redirect-target" id="redirect-target" class="redirect" onload="window.iframeHandler();"></iframe>';
|
||||
var iframe = div.firstChild;
|
||||
with (iframe) {
|
||||
name = 'redirect-target';
|
||||
setAttribute('name', 'redirect-target');
|
||||
id = 'redirect-target';
|
||||
}
|
||||
with (iframe.style) {
|
||||
position = 'absolute';
|
||||
height = '1px';
|
||||
width = '1px';
|
||||
visibility = 'hidden';
|
||||
}
|
||||
document.body.appendChild(div);
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete the invisible iframe for form submissions.
|
||||
*/
|
||||
function deleteIframe() {
|
||||
var holder = $('redirect-holder');
|
||||
if (typeof holder != 'undefined') {
|
||||
removeNode(holder);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Wrapper around document.getElementById().
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
* the DOM afterwards through progressBar.element.
|
||||
*
|
||||
* method is the function which will perform the HTTP request to get the
|
||||
* progress bar status. Either HTTPGet or HTTPPost.
|
||||
* progress bar state. Either HTTPGet or HTTPPost.
|
||||
*
|
||||
* e.g. pb = new progressBar('myProgressBar');
|
||||
* some_element.appendChild(pb.element);
|
||||
|
|
@ -18,14 +18,14 @@ function progressBar(id, callback, method) {
|
|||
this.element.id = id;
|
||||
this.element.className = 'progress';
|
||||
this.element.innerHTML = '<div class="percentage"></div>'+
|
||||
'<div class="status"> </div>'+
|
||||
'<div class="message"> </div>'+
|
||||
'<div class="bar"><div class="filled"></div></div>';
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the percentage and status message for the progressbar.
|
||||
*/
|
||||
progressBar.prototype.setProgress = function (percentage, status) {
|
||||
progressBar.prototype.setProgress = function (percentage, message) {
|
||||
var divs = this.element.getElementsByTagName('div');
|
||||
var div;
|
||||
for (var i = 0; div = divs[i]; ++i) {
|
||||
|
|
@ -37,12 +37,12 @@ progressBar.prototype.setProgress = function (percentage, status) {
|
|||
divs[i].innerHTML = percentage + '%';
|
||||
}
|
||||
}
|
||||
if (hasClass(divs[i], 'status')) {
|
||||
divs[i].innerHTML = status;
|
||||
if (hasClass(divs[i], 'message')) {
|
||||
divs[i].innerHTML = message;
|
||||
}
|
||||
}
|
||||
if (this.callback) {
|
||||
this.callback(percentage, status, this);
|
||||
this.callback(percentage, message, this);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -84,12 +84,16 @@ progressBar.prototype.receivePing = function (string, xmlhttp, pb) {
|
|||
if (xmlhttp.status != 200) {
|
||||
return alert('An HTTP error '+ xmlhttp.status +' occured.\n'+ pb.uri);
|
||||
}
|
||||
// Split into values
|
||||
var matches = string.length > 0 ? string.split('|') : [];
|
||||
// Update progress
|
||||
if (matches.length >= 2) {
|
||||
pb.setProgress(matches[0], matches[1]);
|
||||
// Parse response
|
||||
var progress = parseJson(string);
|
||||
// Display errors
|
||||
if (progress.status == 0) {
|
||||
alert(progress.data);
|
||||
return;
|
||||
}
|
||||
|
||||
// Update display
|
||||
pb.setProgress(progress.percentage, progress.message);
|
||||
// Schedule next timer
|
||||
pb.timer = setTimeout(function() { pb.sendPing(); }, pb.delay);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ if (isJsEnabled()) {
|
|||
}
|
||||
|
||||
var progress = new progressBar('updateprogress', updateCallback, HTTPPost);
|
||||
progress.setProgress(-1, 'Starting updates...');
|
||||
progress.setProgress(-1, 'Starting updates');
|
||||
$('progress').appendChild(progress.element);
|
||||
progress.startMonitoring('update.php?op=do_update', 0);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -54,9 +54,22 @@ jsUpload.prototype.onsubmit = function () {
|
|||
*/
|
||||
jsUpload.prototype.oncomplete = function (data) {
|
||||
// Remove progressbar
|
||||
removeNode(this.progress);
|
||||
removeNode(this.progress.element);
|
||||
this.progress = null;
|
||||
// Replace form and re-attach behaviour
|
||||
$(this.wrapper).innerHTML = data;
|
||||
uploadAutoAttach();
|
||||
}
|
||||
|
||||
/**
|
||||
* Handler for the form redirection error.
|
||||
*/
|
||||
jsUpload.prototype.onerror = function (error) {
|
||||
alert('An error occurred:\n\n'+ error);
|
||||
// Remove progressbar
|
||||
removeNode(this.progress.element);
|
||||
this.progress = null;
|
||||
// Undo hide
|
||||
$(this.hide).style.position = 'static';
|
||||
$(this.hide).style.left = '0px';
|
||||
}
|
||||
|
|
|
|||
|
|
@ -543,6 +543,6 @@ function upload_js() {
|
|||
$output = theme('status_messages') . form_render($form);
|
||||
|
||||
// We send the updated file attachments form.
|
||||
print drupal_call_js('window.parent.iframeHandler', $output);
|
||||
print drupal_to_js(array('status' => TRUE, 'data' => $output));
|
||||
exit;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -543,6 +543,6 @@ function upload_js() {
|
|||
$output = theme('status_messages') . form_render($form);
|
||||
|
||||
// We send the updated file attachments form.
|
||||
print drupal_call_js('window.parent.iframeHandler', $output);
|
||||
print drupal_to_js(array('status' => TRUE, 'data' => $output));
|
||||
exit;
|
||||
}
|
||||
|
|
|
|||
19
update.php
19
update.php
|
|
@ -396,7 +396,7 @@ function update_progress_page() {
|
|||
*
|
||||
* @return
|
||||
* An array indicating the status after doing updates. The first element is
|
||||
* the overall percent finished. The second element is a status message.
|
||||
* the overall percentage finished. The second element is a status message.
|
||||
*/
|
||||
function update_do_updates() {
|
||||
while (($update = reset($_SESSION['update_remaining']))) {
|
||||
|
|
@ -412,12 +412,12 @@ function update_do_updates() {
|
|||
}
|
||||
|
||||
if ($_SESSION['update_total']) {
|
||||
$percent = floor(($_SESSION['update_total'] - count($_SESSION['update_remaining']) + $update_finished) / $_SESSION['update_total'] * 100);
|
||||
$percentage = floor(($_SESSION['update_total'] - count($_SESSION['update_remaining']) + $update_finished) / $_SESSION['update_total'] * 100);
|
||||
}
|
||||
else {
|
||||
$percent = 100;
|
||||
$percentage = 100;
|
||||
}
|
||||
return array($percent, isset($update['module']) ? 'Updating '. $update['module'] .' module' : 'Updating complete');
|
||||
return array($percentage, isset($update['module']) ? 'Updating '. $update['module'] .' module' : 'Updating complete');
|
||||
}
|
||||
|
||||
function update_do_update_page() {
|
||||
|
|
@ -437,26 +437,27 @@ function update_do_update_page() {
|
|||
}
|
||||
ini_set('display_errors', FALSE);
|
||||
|
||||
print implode('|', update_do_updates());
|
||||
list($percentage, $message) = update_do_updates();
|
||||
print drupal_to_js(array('status' => TRUE, 'percentage' => $percentage, 'message' => $message));
|
||||
}
|
||||
|
||||
function update_progress_page_nojs() {
|
||||
$new_op = 'do_update_nojs';
|
||||
if ($_SERVER['REQUEST_METHOD'] == 'GET') {
|
||||
list($percent, $message) = update_do_updates();
|
||||
if ($percent == 100) {
|
||||
list($percentage, $message) = update_do_updates();
|
||||
if ($percentage == 100) {
|
||||
$new_op = 'finished';
|
||||
}
|
||||
}
|
||||
else {
|
||||
// This is the first page so return some output immediately.
|
||||
$percent = 0;
|
||||
$percentage = 0;
|
||||
$message = 'Starting updates';
|
||||
}
|
||||
|
||||
drupal_set_html_head('<meta http-equiv="Refresh" content="0; URL=update.php?op='. $new_op .'">');
|
||||
drupal_set_title('Updating');
|
||||
$output = theme('progress_bar', $percent, $message);
|
||||
$output = theme('progress_bar', $percentage, $message);
|
||||
$output .= '<p>Updating your site will take a few seconds.</p>';
|
||||
|
||||
return $output;
|
||||
|
|
|
|||
Loading…
Reference in New Issue