/** * IPS Upgrade Javascript * * @author Matt Mecham * @started Monday 7th January 2008 * * STEPS----------------- * SQL * App Module * Check for more modules * Templates * Languages * Tasks * Settings * Caches / Done */ ipsUpgrade = new ipsUpgrade(); /* Prototype Ajax Global Responders * Based on code from: http://codejanitor.com/wp/2006/03/23/ajax-timeouts-with-prototype/ * Aborts ajax after a 5 minute delay of nothing happening */ Ajax.Responders.register( { onCreate: function( t ) { t['_t'] = window.setInterval( function() { if ( ipsUpgrade.callInProgress( t.transport) ) { ipsUpgrade.timeOutAjax( t ); } }, 300000 ); t['_t2'] = window.setInterval( function() { switch( t.transport.readyState ) { case 1: case 2: ipsUpgrade.updateProgressImage( 'wait' ); break; case 3: default: case 4: ipsUpgrade.updateProgressImage( 'receive' ); break; } }, 500 ); }, onComplete: function( t ) { window.clearInterval( t['_t'] ); window.clearInterval( t['_t2'] ); } } ); /** * Main Parent Class */ function ipsUpgrade() { /** * Applications array */ this.applications = {}; /** * Upgrade Steps */ this.upgradeSteps = new Array( 'sql_steps', 'app_module', 'next_check', 'templates', 'languages', 'tasks', 'settings', 'finish' ); /** * URLS */ this.baseUrl = ''; this.imageUrl = ''; /* * Stored JSON */ this.storedJSON = {}; /** * Current upgrade app */ this.upgradingApp = {}; /** * Current step */ this.currentStep = ''; /** * Upgrading Version */ this.upgradingVersion = 0; /* * Current Image */ this.currentImage = ''; /** * Init Function * @author Matt Mecham */ this.init = function() { /* Reset buttons */ this.resetApplications(); }; /** * Begin the upgrade procedure */ this.beginUpgrade = function( e, div, app_dir ) { /* Blank out all other rows... */ for( var i in this.applications ) { var _element = $( 'upgradeRowWrapper-' + this.applications[i].app_dir ); if ( this.applications[i].app_dir != app_dir ) { var newdiv = document.createElement('DIV'); newdiv.id = 'upgradeRowWrapper-' + this.applications[i].app_dir + '-HIDDEN'; newdiv.className = (is_ie ) ? 'dragmove-hide-ie' : 'dragmove-hide-moz'; newdiv.style.position = 'absolute'; newdiv.style.top = _element.cumulativeOffset().top + 'px'; newdiv.style.left = _element.cumulativeOffset().left + 'px'; newdiv.style.width = _element.offsetWidth + 'px'; newdiv.style.height = _element.offsetHeight + 'px'; document.body.appendChild( newdiv ); } /* Stop observing any upgrade buttons */ Event.stopObserving( 'upgradeRowButton-' + this.applications[i].app_dir, 'click', this._buttonClicker ); } /* Update array */ this.upgradingApp = this.applications[ app_dir ]; /* Get the next available upgrade */ this.upgradingVersion = this.applications[ app_dir ].next_version; /* Slide out log tray */ if ( ! $( 'upgradeLogDraw' ).visible() ) { Effect.SlideDown( $( 'upgradeLogDraw' ), {duration:0.5} ); } /* Start text output.. */ this.writeToLog( "Starting upgrade for " + this.applications[ app_dir ].real_name + "" ); /* Reset progress bar */ this.updateProgressBar( false ); /* Reset image */ this.updateProgressImage( 'send' ); /* Start off with the SQL */ this.fireAjax( 'sql_step', 'do=sql_steps'); }; /** * Update the progress bar */ this.updateProgressBar = function( step ) { /* INIT */ var _element = $( 'upgradeLogProgressBarInner' ); if ( step != false ) { if ( step == 'finish' ) { _element.style.backgroundImage = 'url(' + this.imageUrl + 'donebar.gif)'; _element.style.width = '100%'; } else { var i = 0; for( var x = 0 ; x <= this.upgradeSteps.length ; x++ ) { i++; if ( step == this.upgradeSteps[x] ) { break; } } _element.style.backgroundImage = 'url(' + this.imageUrl + 'progressbar.gif)'; _element.style.width = Math.round( ( 100 / this.upgradeSteps.length ) * i ) + '%'; } } else { _element.style.width = '1%'; } }; /** * Update progress image */ this.updateProgressImage = function( type ) { /* INIT */ var _img = ''; switch( type ) { default: case 'stop': _img = 'stop.png'; break; case 'ready': _img = 'ready.png'; break; case 'warn': _img = 'warning.png'; break; case 'send': _img = 'sending.png'; break; case 'wait': _img = 'mini-wait.gif'; break; case 'receive': _img = 'receiving.png'; break; } /* Update image */ if ( ipsUpgrade.currentImage != _img ) { $( 'upgradeStatusImage' ).src = ipsUpgrade.imageUrl + _img; ipsUpgrade.currentImage = _img; } //$( 'upgradeLogText' ).innerHTML = ipsUpgrade.imageUrl + _img + "
" + $( 'upgradeLogText' ).innerHTML; }; /** * Fire Ajax */ this.fireAjax = function( step, url) { /* Update image */ this.updateProgressImage( 'send' ); /* Update current step */ this.currentStep = step; new Ajax.Request( this.baseUrl + '&app_directory=' + this.upgradingApp.app_dir + '&version=' + this.upgradingVersion + '&' + url, { method: 'get', onSuccess: this.processAjax.bind(this), onException: this.exceptionAjax.bind(this), onFailure: this.failureAjax.bind(this) } ); }; /** * Checking to see if there's a call in progres... */ this.callInProgress = function( t ) { switch ( t.readyState ) { case 1: case 2: case 3: return true; break; default: return false; break; } }; /** * On Timeout */ this.timeOutAjax = function( t ) { if ( confirm( "No response from the webserver.\nDo you wish to continue waiting?" ) ) { return true; } else { t.transport.abort(); alert( "Request Cancelled" ); } }; /** * On Failure */ this.failureAjax = function( t ) { alert( "Failure: " + t.responseText ); }; /** * On Failure */ this.exceptionAjax = function( t ) { alert( "Exception: " + t.responseText ); }; /** * Process Ajax (Success) */ this.processAjax = function( t ) { /* Update Image */ this.updateProgressImage( 'receive' ); /* Not a JSON response? */ if ( ! t.responseText.match( /^(\s+?)?\{/ ) ) { alert( "Error:\n" + t.responseText ); return; } /* Process results */ eval( "var json = " + t.responseText ); if ( json['error'] ) { this.showError( json ); return false; } if ( json['warning'] ) { alert( 'Warning: ' + json['warning'] ); } /* All good: Update status message... */ this.writeToLog( json['message'] ); /* Update progress bar */ if ( json['current_step'] != json['next_step'] ) { this.updateProgressBar( json['current_step'] ); } /* Update version? */ if ( json['next_version'] != '' ) { this.upgradingVersion = json['next_version']; } /* Finish? If so - say all done and go tubby-bye-bye */ if ( json['next_step'] != '__FINISH__' ) { /* Fire Ajax */ this.fireAjax( json['next_step'], json['next_url'] ); } else { /* All Done */ this.updateProgressBar( 'finish' ); this.updateProgressImage( 'ready' ); this.writeToLog( "Upgrade Completed" ); /* Update version information */ this.applications[ this.upgradingApp.app_dir ].current_human = json['new_human']; this.applications[ this.upgradingApp.app_dir ].current_long = json['new_long']; /* Remove Blanks... */ for( var i in this.applications ) { try { /* Remove any old rows */ document.body.removeChild( $('upgradeRowWrapper-' + this.applications[i].app_dir + '-HIDDEN') ); /* Stop observing any upgrade buttons */ Event.stopObserving( 'upgradeRowButton-' + this.applications[i].app_dir, 'click', this._buttonClicker ); } catch(err) { //alert( err ); } } this.resetApplications(); } }; /** * Show Error */ this.showError = function( json ) { var _parent = $( 'upgradeWrap' ); var _thisone = $( 'upgradeErrorBox' ); _thisone.style.top = _parent.cumulativeOffset().top + 'px'; _thisone.style.left = _parent.cumulativeOffset().left + 'px'; _thisone.style.width = _parent.offsetWidth - 2 + 'px'; _thisone.style.height = _parent.offsetHeight - 23 + 'px'; _thisone.style.position = 'absolute'; _thisone.style.display = ''; /* Store JSON */ this.storedJSON = json; /* Add error message */ $( 'upgradeErrorText' ).innerHTML = json['error']; }; /** * Error; Continue */ this.errorContinue = function() { /* Button has been clicked, so hide error box... */ $( 'upgradeErrorBox' ).hide(); /* Fire Ajax */ ipsUpgrade.fireAjax( ipsUpgrade.storedJSON['next_step'], ipsUpgrade.storedJSON['next_url'] ); }; /** * Write to Log */ this.writeToLog = function( text ) { $( 'upgradeLogText' ).innerHTML = text + "
" + $( 'upgradeLogText' ).innerHTML; }; /** * Reset Application Buttons */ this.resetApplications = function() { /* Loopy */ for( var i in this.applications ) { var _button = $( 'upgradeRowButton-' + this.applications[i].app_dir ); var _version = $( 'upgradeRowVersion-' + this.applications[i].app_dir ); /* Version */ _version.innerHTML = this.applications[i].current_human; /* Button */ if ( this.applications[i].current_long >= this.applications[i].latest ) { _button.className = _button.className.replace( / available$/, '' ); _button.title = ''; _button.innerHTML = "No Upgrade Available"; Event.stopObserving( 'upgradeRowButton-' + this.applications[i].app_dir, 'click', this._buttonClicker ); } else { _button.className = _button.className + ' available'; _button.title = 'Click to begin upgrade'; _button.innerHTML = "Upgrade Available"; this._buttonClicker = this.beginUpgrade.bindAsEventListener( this, 'upgradeRowButton-' + this.applications[i].app_dir, this.applications[i].app_dir ); Event.observe( 'upgradeRowButton-' + this.applications[i].app_dir, 'click', this._buttonClicker ); } } }; /** * Add application to the array */ this.addApplication = function( app_dir, real_name, current_long_version, latest_long_version, current_human_version, latest_human_version, next_version ) { /* INIT */ var _found = 0; /* Loop to see if this already exists */ for( var i in this.applications ) { if ( this.applications[i].app_dir == app_dir ) { _found = 1; break; } } /* Add it */ if ( _found != 1 ) { this.applications[ app_dir ] = { 'app_dir' : app_dir, 'real_name' : real_name, 'latest' : latest_long_version, 'current_long' : current_long_version, 'latest_human' : latest_human_version, 'current_human' : current_human_version, 'next_version' : next_version, 'upgrading' : 0 }; } }; }