Seditio Source
Root |
./othercms/b2evolution_7.2.3/inc/maintenance/upgrade.ctrl.php
<?php
/**
 * Upgrade - This is a LINEAR controller
 *
 * This file is part of b2evolution - {@link http://b2evolution.net/}
 * See also {@link https://github.com/b2evolution/b2evolution}.
 *
 * @license GNU GPL v2 - {@link http://b2evolution.net/about/gnu-gpl-license}
 *
 * @copyright (c)2009-2016 by Francois Planque - {@link http://fplanque.com/}
 * Parts of this file are copyright (c)2009 by The Evo Factory - {@link http://www.evofactory.com/}.
 *
 * Released under GNU GPL License - {@link http://b2evolution.net/about/gnu-gpl-license}
 *
 * @package maintenance
 */
if( !defined('EVO_MAIN_INIT') ) die( 'Please, do not access this page directly.' );

/**
 * @vars string paths
 */
global $basepath, $upgrade_path, $install_path;

// Check minimum permission:
check_user_perm( 'admin', 'normal', true );
check_user_perm( 'maintenance', 'upgrade', true );

// Used in the upgrade process
$script_start_time = $servertimenow;

$tab = param( 'tab', 'string', '', true );

// Set options path:
$AdminUI->set_path( 'options', 'misc', 'upgrade'.$tab );

// Get action parameter from request:
param_action();

switch(
$action )
{
    case
'delete':
       
// Delete already downloaded ZIP file or folder:

        // Check that this action request is not a CSRF hacked request:
       
$Session->assert_received_crumb( 'upgrade_delete' );

       
$file = param( 'file', 'string' );

        if( empty(
$file ) )
        {
           
debug_die( 'You don\'t select a file/folder for deleting!' );
        }

       
// Decide file of folder depending on extension:
       
$is_dir = ! preg_match( '#\.zip$#i', $file );

       
$file_path = $upgrade_path.$file;

        if( !
file_exists( $file_path ) )
        {    
// Display error when a requested file/folder doesn't exist:
            // NOTE: Do NOT translate these messages because it must not occurs normally!
           
$Messages->add( sprintf( $is_dir
               
? 'The directory %s does not exist.'
               
: 'The file %s does not exist.', '<code>'.$file.'</code>' ), 'error' );
            break;
        }

       
// Check real type of the requested file or folder before deleting:
       
$is_dir = is_dir( $file_path );

        if(
$is_dir )
        {    
// Delete a folder:
           
$del_result = rmdir_r( $file_path );
        }
        else
        {    
// Delete a file:
           
$del_result = @unlink( $file_path );
        }

        if(
$del_result )
        {    
// Successful deleting:
           
$Messages->add( sprintf( $is_dir
               
? TB_('The directory &laquo;%s&raquo; has been deleted.')
                :
TB_('The file &laquo;%s&raquo; has been deleted.'), $file ), 'success' );
        }
        else
        {    
// Failed deleting:
           
$Messages->add( sprintf( $is_dir
               
? TB_('Cannot delete directory %s. Please check the permissions or delete it manually.')
                :
TB_('File %s could not be deleted.'), '<code>'.$file.'</code>' ), 'error' );
        }

       
// Redirect back to don't try delete the same file/folder twice:
       
header_redirect( $admin_url.'?ctrl=upgrade' );
       
// Exit here.
       
break;

    case
'download':
    case
'force_download':
       
// Check for STEP 2: DOWNLOAD.
       
if( ! $auto_upgrade_from_any_url )
        {    
// Don't allow upgrade from any URL:
           
global $global_Cache;
           
// Extract array of info about available update:
           
$updates = $global_Cache->getx( 'updates' );
            if( empty(
$updates[0]['url'] ) )
            {    
// No new available version on the upgrade server:
               
$Messages->add( /*Don't translate because it must not happens on normal back-office UI*/'Auto upgrade is not allowed from URL!'
                       
// Display additional messages from upgrade server:
                       
.( empty( $updates[0]['name'] ) ? '' : '<br>'.$updates[0]['name'] )
                        .( empty(
$updates[0]['description'] ) ? '' : '<br>'.$updates[0]['description'] ),
                   
'error' );
               
header_redirect( $admin_url.'?ctrl=upgrade' );
               
// EXIT here!
           
}
        }
        break;
}

// Display message if the upgrade config file doesn't exist
check_upgrade_config( true );

$AdminUI->breadcrumbpath_init( false );  // fp> I'm playing with the idea of keeping the current blog in the path here...
$AdminUI->breadcrumbpath_add( TB_('System'), $admin_url.'?ctrl=system' );
$AdminUI->breadcrumbpath_add( TB_('Maintenance'), $admin_url.'?ctrl=tools' );
if(
$tab == 'git' )
{
    if( !
$auto_upgrade_from_any_url )
    {    
// Deny upgrade from Git because upgrade from any URL is denied by config:
       
debug_die( 'Auto upgrade is not allowed from URL!' );
    }

   
$AdminUI->breadcrumbpath_add( TB_('Upgrade from Git'), $admin_url.'?ctrl=upgrade&amp;tab='.$tab );

   
// Set an url for manual page:
   
$AdminUI->set_page_manual_link( 'upgrade-from-git' );
}
else
{
   
$AdminUI->breadcrumbpath_add( TB_('Auto Upgrade'), $admin_url.'?ctrl=upgrade' );

   
// Set an url for manual page:
   
$AdminUI->set_page_manual_link( 'auto-upgrade' );
}


// Display <html><head>...</head> section! (Note: should be done early if actions do not redirect)
$AdminUI->disp_html_head();

// Display title, menu, messages, etc. (Note: messages MUST be displayed AFTER the actions)
$AdminUI->disp_body_top();

$AdminUI->disp_payload_begin();

echo
'<h2 class="red">'.TB_('WARNING: USE WITH CAUTION!').'</h2>';

evo_flush();

/**
 * Do Action Display Payload:
 */
switch( $action )
{
    case
'start':
    default:
       
// STEP 1: Check for updates.

       
autoupgrade_display_steps( 1, $tab );

        if(
$tab == '' )
        {
           
$block_item_Widget = new Widget( 'block_item' );
           
$block_item_Widget->title = TB_('Updates from b2evolution.net').get_manual_link( 'auto-upgrade' );
           
$block_item_Widget->disp_template_replaced( 'block_start' );

           
// Note: hopefully, the update will have been downloaded in the shutdown function of a previous page (including the login screen)
            // However if we have outdated info, we will load updates here.
           
load_funcs( 'dashboard/model/_dashboard.funcs.php' );
           
// Let's clear any remaining messages that should already have been displayed before...
           
$Messages->clear();
           
b2evonet_get_updates( true );

           
// Display info & error messages
           
$Messages->display();

           
/**
             * @var AbstractSettings
             */
           
global $global_Cache;

           
// Display the current version info for now. We may remove this in the future.
           
$version_status_msg = $global_Cache->getx( 'version_status_msg' );
            if( !empty(
$version_status_msg) )
            {    
// We have managed to get updates (right now or in the past):
               
echo '<p>'.$version_status_msg.'</p>';
               
$extra_msg = $global_Cache->getx( 'extra_msg' );
                if( !empty(
$extra_msg) )
                {
                    echo
'<p>'.$extra_msg.'</p>';
                }
            }

           
$block_item_Widget->disp_template_replaced( 'block_end' );
            unset(
$block_item_Widget );

           
// Extract array of info about available update:
           
$updates = $global_Cache->getx( 'updates' );

           
$action = 'start';
           
$AdminUI->disp_view( 'maintenance/views/_upgrade.form.php' );
        }
        elseif(
$tab == 'git' )
        {
           
$action = 'start';
           
$AdminUI->disp_view( 'maintenance/views/_upgrade_git.form.php' );
        }
        break;

    case
'export_git':
       
// GIT STEP 2: DOWNLOAD.

        // Check that this action request is not a CSRF hacked request:
       
$Session->assert_received_crumb( 'upgrade_started' );

        if(
$demo_mode )
        {
           
$Messages->clear();
           
$Messages->add( TB_('This feature is disabled on the demo server.'), 'error' );
           
$Messages->display();
            break;
        }

       
$git_url = param( 'git_url', 'string', '', true );
       
$git_branch = param( 'git_branch', 'string', '', true );

       
$UserSettings->set( 'git_upgrade_url', $git_url );
       
$UserSettings->set( 'git_upgrade_branch', $git_branch );
       
$UserSettings->dbupdate();

       
$Messages->clear(); // Clear the messages to avoid a double displaying here

       
if( param_check_not_empty( 'git_url', TB_('Please enter the URL of repository') ) &&
           
param_check_url( 'git_url', 'download_src' ) &&
           
preg_match( '#([^/]+)/([^/]+)/?$#', $git_url, $git_data ) )
        {    
// Generate an URL to download GIT branch as ZIP archive:
           
$git_owner = $git_data[1];
           
$git_repo = preg_replace( '#\.git$#', '', $git_data[2] );
           
set_param( 'upd_url', 'https://github.com/'.$git_owner.'/'.$git_repo.'/archive/'.$git_branch.'.zip' );
           
memorize_param( 'upd_url', 'url', NULL, get_param( 'upd_url' ) );
           
// No break here in order to go to the "download" form below
       
}
        else
        {    
// Display the errors and the config form again to fix data:
           
$Messages->display();
           
autoupgrade_display_steps( 2, $tab );
           
$action = 'start';
           
$AdminUI->disp_view( 'maintenance/views/_upgrade_git.form.php' );
            break;
        }

    case
'download':
    case
'force_download':
       
// STEP 2: DOWNLOAD.

        // Check that this action request is not a CSRF hacked request:
       
$Session->assert_received_crumb( 'upgrade_started' );

        if(
$demo_mode )
        {
           
$Messages->clear();
           
$Messages->add( TB_('This feature is disabled on the demo server.'), 'error' );
           
$Messages->display();
            break;
        }

       
$action_success = true;
       
$download_success = true;

       
autoupgrade_display_steps( 2, $tab );

       
$block_item_Widget = new Widget( 'block_item' );
       
$block_item_Widget->title = TB_('Downloading package...');
       
$block_item_Widget->disp_template_replaced( 'block_start' );

       
$Messages->clear(); // Clear the messages to avoid a double displaying here

       
if( $auto_upgrade_from_any_url )
        {    
// Allow to upgrade from any URL:
           
$download_url = param( 'upd_url', 'string', '', true );
           
param_check_not_empty( 'upd_url', TB_('Please enter the URL to download ZIP archive') );
        }
        elseif( ! empty(
$updates[0]['url'] ) )
        {    
// New available version on the upgrade server:
           
$download_url = $updates[0]['url'];
           
// Set global param for additional check server URL by same as for any not trust URL:
           
set_param( 'upd_url', $download_url );
        }
        else
        {    
// This must not happens because of redirect on checking above:
           
debug_die( 'Auto upgrade is not allowed from URL!' );
        }

       
// Check the download url for correct http, https, ftp URI
       
$success = param_check_url( 'upd_url', 'download_src', NULL );
        if(
$success && ! preg_match( '#\.zip$#i', $download_url ) )
        {
// Check the download url is a .zip or .ZIP
           
param_error( 'upd_url', sprintf( TB_('The URL "%s" must point to a ZIP archive.'), $download_url ) );
        }

        if(
$Messages->count() )
        {
// Display the errors and the download form again to fix url
           
$Messages->display();

           
// Extract array of info about available update:
           
$updates = $global_Cache->getx( 'updates' );

           
$action = 'start';
           
$AdminUI->disp_view( 'maintenance/views/_upgrade.form.php' );
            break;
        }

       
$upgrade_name = pathinfo( $download_url );
       
$upgrade_name = $upgrade_name['filename'].'.zip';
       
$upgrade_file = $upgrade_path.$upgrade_name;

       
// Memorize ZIP file name for next step submitting:
       
memorize_param( 'upd_file', 'string', NULL, $upgrade_name );

        if(
file_exists( $upgrade_file ) )
        {
// The downloading file already exists
           
if( $action == 'force_download' )
            {
// Try to delete previous package if the downloading is forced
               
if( ! @unlink( $upgrade_file ) )
                {
                    echo
'<p class="red">'.sprintf( TB_('Unable to delete previously downloaded package %s before forcing the download.'), '<b>'.$upgrade_file.'</b>' ).'</p>';
                   
$action_success = false;
                }
            }
            else
            {
                echo
'<div class="action_messages"><div class="log_error" style="text-align:center;font-weight:bold">'
                   
.sprintf( TB_('The package %s is already downloaded.'), $upgrade_name ).'</div></div>';
               
$action_success = false;
            }
           
evo_flush();
        }

        if(
$action_success && ( $download_success = prepare_maintenance_dir( $upgrade_path, true ) ) )
        {
           
// Set maximum execution time
           
set_max_execution_time( 1800 ); // 30 minutes

           
echo '<p>'.sprintf( TB_('Downloading package to &laquo;<strong>%s</strong>&raquo;...'), $upgrade_file );
           
evo_flush();

           
// Downloading
           
$file_contents = fetch_remote_page( $download_url, $info, 1800 );

            if(
$info['status'] != 200 || empty( $file_contents ) )
            {
// Impossible to download
               
$download_success = false;
                echo
'</p><p style="color:red">'.sprintf( TB_('Unable to download package from &laquo;%s&raquo;'), $download_url ).'</p>';
            }
            elseif( !
save_to_file( $file_contents, $upgrade_file, 'w' ) )
            {
// Impossible to save file...
               
$download_success = false;
                echo
'</p><p style="color:red">'.sprintf( TB_('Unable to create file: &laquo;%s&raquo;'), $upgrade_file ).'</p>';

                if(
file_exists( $upgrade_file ) )
                {
// Remove file from disk
                   
if( ! @unlink( $upgrade_file ) )
                    {
                        echo
'<p style="color:red">'.sprintf( TB_('Unable to remove file: &laquo;%s&raquo;'), $upgrade_file ).'</p>';
                    }
                }
            }
            else
            {
// The package is downloaded successfully
               
echo ' OK '.bytesreadable( filesize( $upgrade_file ), false, false ).'.</p>';
            }
           
evo_flush();
        }

       
// Pause the process before next step
       
$AdminUI->disp_view( 'maintenance/views/_upgrade_downloaded.form.php' );
        unset(
$block_item_Widget );
        break;

    case
'unzip':
    case
'force_unzip':
       
// STEP 3: UNZIP.

        // Check that this action request is not a CSRF hacked request:
       
$Session->assert_received_crumb( 'upgrade_downloaded' );

        if(
$demo_mode )
        {
           
$Messages->clear();
           
$Messages->add( TB_('This feature is disabled on the demo server.'), 'error' );
           
$Messages->display();
            break;
        }

       
$action_success = true;
       
$unzip_success = true;

       
autoupgrade_display_steps( 3, $tab );

       
$block_item_Widget = new Widget( 'block_item' );
       
$block_item_Widget->title = TB_('Unzipping package...');
       
$block_item_Widget->disp_template_replaced( 'block_start' );
       
evo_flush();

       
$upd_file = param( 'upd_file', 'string', '', true );

        if( !
preg_match( '#\.zip$#i', $upd_file ) )
        {    
// Check the provided file is a .zip or .ZIP:
           
debug_die( 'The file "'.$upd_file.'" must be a ZIP archive!' );
        }

       
$upgrade_dir_name = substr( $upd_file, 0, -4 );

       
$upgrade_dir = $upgrade_path.$upgrade_dir_name;
       
$upgrade_file = $upgrade_path.$upd_file;

       
// Memorize folder name for next step submitting:
       
memorize_param( 'upd_dir', 'string', NULL, $upgrade_dir_name );

        if(
file_exists( $upgrade_dir ) )
        {
// The downloading file already exists
           
if( $action == 'force_unzip' )
            {
// Try to delete previous package if the downloading is forced
               
if( ! rmdir_r( $upgrade_dir ) )
                {
                    echo
'<p class="red">'.sprintf( TB_('Unable to delete previous unzipped package %s before forcing the unzip.'), '<b>'.$upgrade_dir.'</b>' ).'</p>';
                   
$action_success = false;
                }
            }
            else
            {
                echo
'<div class="action_messages"><div class="log_error" style="text-align:center;font-weight:bold">'
                   
.sprintf( TB_('The package %s is already unzipped.'), $upd_file ).'</div></div>';
               
$action_success = false;
            }
           
evo_flush();
        }

        if(
$action_success )
        {
           
// Set maximum execution time
           
set_max_execution_time( 1800 ); // 30 minutes

           
echo '<p>'.sprintf( TB_('Unpacking package to &laquo;<strong>%s</strong>&raquo;...'), $upgrade_dir );
           
evo_flush();

           
// Unpack package
           
if( $unzip_success = unpack_archive( $upgrade_file, $upgrade_dir, true ) )
            {
                echo
' OK.</p>';
               
evo_flush();
            }
            else
            {
                echo
'</p>';
               
// Additional check
               
rmdir_r( $upgrade_dir );
            }
        }

       
// Pause the process before next step
       
$AdminUI->disp_view( 'maintenance/views/_upgrade_unzip.form.php' );
        unset(
$block_item_Widget );
        break;

    case
'ready':
       
// STEP 4: READY TO UPGRADE.

        // Check that this action request is not a CSRF hacked request:
       
$Session->assert_received_crumb( 'upgrade_is_ready' );

       
autoupgrade_display_steps( 4, $tab );

       
$upgrade_name = param( 'upd_dir', 'string', '', true );

       
$block_item_Widget = new Widget( 'block_item' );
       
$block_item_Widget->title = TB_('Ready to upgrade').'...';
       
$block_item_Widget->disp_template_replaced( 'block_start' );
       
evo_flush();

       
// Pause the process before next step
       
$AdminUI->disp_view( 'maintenance/views/_upgrade_ready.form.php' );
        unset(
$block_item_Widget );
        break;

    case
'backup_and_overwrite':
       
// STEP 5: BACKUP & UPGRADE.

        // Check that this action request is not a CSRF hacked request:
       
$Session->assert_received_crumb( 'upgrade_is_launched' );

       
autoupgrade_display_steps( 5, $tab );

        if(
$demo_mode )
        {
           
$Messages->clear();
           
$Messages->add( TB_('This feature is disabled on the demo server.'), 'error' );
           
$Messages->display();
            break;
        }

       
// Load Backup class (PHP4) and backup all of the folders and files
       
load_class( 'maintenance/model/_backup.class.php', 'Backup' );
       
$Backup = new Backup();
       
// Memorize all form params in order t oresubmit form if some errors exist
       
$Backup->load_from_Request( true );

       
// File options:
       
if( param( 'fm_default_chmod_dir', 'string', NULL ) !== NULL )
        {
           
param_check_regexp( 'fm_default_chmod_dir', '~^[0-7]{3}$~', TB_('Invalid CHMOD value. Use 3 digits.') );
           
$Settings->set( 'fm_default_chmod_dir', $fm_default_chmod_dir );
        }
        if(
param( 'fm_default_chmod_file', 'string', NULL ) !== NULL )
        {
           
param_check_regexp( 'fm_default_chmod_file', '~^[0-7]{3}$~', TB_('Invalid CHMOD value. Use 3 digits.') );
           
$Settings->set( 'fm_default_chmod_file', $fm_default_chmod_file );
        }

        if(
param_errors_detected() )
        {    
// Display the previous step form in order to fix the detected errors:
           
$upgrade_name = param( 'upd_dir', 'string', '', true );

           
$Messages->display();

           
$block_item_Widget = new Widget( 'block_item' );
           
$block_item_Widget->title = TB_('Ready to upgrade').'...';
           
$block_item_Widget->disp_template_replaced( 'block_start' );
           
evo_flush();

           
$AdminUI->disp_view( 'maintenance/views/_upgrade_ready.form.php' );
            unset(
$block_item_Widget );
            break;
        }

       
// Update file options:
       
$Settings->dbupdate();

        if( !isset(
$block_item_Widget ) )
        {
           
$block_item_Widget = new Widget( 'block_item' );
           
$block_item_Widget->title = TB_('Installing package...');
           
$block_item_Widget->disp_template_replaced( 'block_start' );

           
$upgrade_name = param( 'upd_name', 'string', NULL, true );
            if(
$upgrade_name === NULL )
            {
// Get an upgrade name from url (Used for auto-upgrade, not git)
               
forget_param( 'upd_name' );
               
$upgrade_name = param( 'upd_dir', 'string', '', true );
            }

           
$success = true;
        }

       
// Enable maintenance mode:
       
$success = ( $success && switch_maintenance_mode( true, 'upgrade', TB_('System upgrade is in progress. Please reload this page in a few minutes.') ) );

        if(
$success )
        {
           
// Set maximum execution time
           
set_max_execution_time( 1800 ); // 30 minutes

            // Verify that all destination files can be overwritten
           
echo '<h4>'.TB_('Verifying that all destination files can be overwritten...').'</h4>';
           
evo_flush();

           
$read_only_list = array();

           
// Get a folder path where we should get the files
           
$upgrade_folder_path = get_upgrade_folder_path( $upgrade_name );

           
$success = verify_overwrite( $upgrade_folder_path, no_trailing_slash( $basepath ), 'Verifying', false, $read_only_list );

            if(
$success && empty( $read_only_list ) )
            {
// We can backup files and database
               
if( ! function_exists( 'gzopen' ) )
                {
                   
$Backup->pack_backup_files = false;
                }

               
// Start backup
               
if( $success = $Backup->start_backup() )
                {
// We can upgrade files and database

                    // Copying new folders and files
                   
echo '<h4>'.TB_('Copying new folders and files...').'</h4>';
                   
evo_flush();

                   
$success = verify_overwrite( $upgrade_folder_path, no_trailing_slash( $basepath ), 'Copying', true, $read_only_list );
                    if( ( !
$success ) || ( ! empty( $read_only_list ) ) )
                    {
// In case if something was changed before the previous verify_overwrite check
                       
echo '<p style="color:red"><strong>'.TB_('The files and database backup was created successfully but all folders and files could not be overwritten');
                        if( empty(
$read_only_list ) )
                        {
// There was some error in the verify_overwrite() function, but the corresponding error message was already displayed.
                           
echo '.</strong></p>';
                        }
                        else
                        {
// Some file/folder could not be overwritten, display it
                           
echo ':</strong></p>';
                            foreach(
$read_only_list as $read_only_file )
                            {
                                echo
$read_only_file.'<br/>';
                            }
                        }
                        echo
'<p style="color:red"><strong>'.sprintf( TB_('Please restore the backup files from the &laquo;%s&raquo; package. The database was not changed.'), $backup_path ).'</strong></p>';
                       
evo_flush();
                    }

                   
// Flag to know files were upgraded, in order to don't include new files below,
                    // because they may contain new functions which are not loaded yet when this script was started:
                   
$files_upgraded = true;
                }
            }
            else
            {
                echo
'<p style="color:red">'.TB_('<strong>The following folders and files can\'t be overwritten:</strong>').'</p>';
               
evo_flush();
                foreach(
$read_only_list as $read_only_file )
                {
                    echo
$read_only_file.'<br/>';
                }
               
$success = false;
            }
        }

        if(
$success )
        {
// Pause a process before upgrading, and display a link to the normal upgrade action
           
$block_item_Widget->disp_template_replaced( 'block_end' );
           
$Form = new Form();
           
$Form->begin_form( 'fform' );
           
$Form->begin_fieldset( TB_('Actions') );
            echo
'<p><b>'.TB_('All new b2evolution files are in place. You will now be redirected to the installer to perform a DB upgrade.').'</b> '.TB_('Note: the User Interface will look different.').'</p>';
           
$continue_onclick = 'location.href=\''.$baseurl.'install/index.php?action=auto_upgrade&locale='.$current_locale.'\'';
           
$Form->end_form( array( array( 'button', 'continue', TB_('Continue to installer'), 'SaveButton', $continue_onclick ) ) );
            unset(
$block_item_Widget );
        }
        else
        {
// Disable maintenance mode
           
switch_maintenance_mode( false, 'upgrade' );
            echo
'<h4 style="color:red">'.TB_('Upgrade failed!').'</h4>';

           
// Display a form to resubmit a previous form
           
$block_item_Widget->disp_template_replaced( 'block_end' );
           
$Form = new Form( NULL, 'upgrade_form', 'post' );
           
$Form->add_crumb( 'upgrade_is_launched' ); // In case we want to continue
           
$Form->hiddens_by_key( get_memorized( 'action' ) );
           
$Form->begin_form( 'fform' );
           
$Form->begin_fieldset( TB_('Actions') );
           
$Form->end_form( array( array( 'submit', 'actionArray['.$action.']', TB_('Retry'), 'SaveButton' ) ) );
            unset(
$block_item_Widget );
        }
        break;
}

if( isset(
$block_item_Widget ) )
{
   
$block_item_Widget->disp_template_replaced( 'block_end' );
}

if( ! empty(
$files_upgraded ) )
{    
// We cannot require new footer files because they may contain new functions
    // which are not loaded yet when this script was started:
   
echo '<span class="small note">'.TB_('No footer is displayed here because we are in between 2 versions.').'</span>';
}
else
{
   
$AdminUI->disp_payload_end();

   
// Display body bottom, debug info and close </html>:
   
$AdminUI->disp_global_footer();
}
?>