Seditio Source
Root |
./othercms/xenForo 2.2.8/src/XF/Install/Controller/Upgrade.php
<?php

namespace XF\Install\Controller;

use
XF\Mvc\ParameterBag;
use
XF\Mvc\Reply\AbstractReply;

use function
is_array;

class
Upgrade extends AbstractController
{
    protected function
preDispatchController($action, ParameterBag $params)
    {
        if (!
$this->getInstallHelper()->isInstalled())
        {
            throw
$this->exception($this->redirect('index.php?install/'));
        }

        if (
method_exists($this->app, 'setupUpgradeSession'))
        {
           
$this->app->setupUpgradeSession();
        }

        if (
strtolower($action) !== 'login')
        {
           
$visitor = \XF::visitor();
            if (!
$visitor->is_admin)
            {
                throw
$this->exception($this->rerouteController(__CLASS__, 'login'));
            }
        }
    }

    public function
actionIndex()
    {
        \
XF\Util\Php::resetOpcache();

       
$installHelper = $this->getInstallHelper();
       
$upgrader = $this->getUpgrader();

        if (
$upgrader->getNewestUpgradeVersionId() > \XF::$versionId)
        {
            return
$this->error(\XF::phrase('upgrade_found_newer_than_version'));
        }

       
$xfAddOn = new \XF\AddOn\AddOn('XF', \XF::app()->addOnManager());
       
$xfAddOn->passesHealthCheck($missing, $inconsistent);

        if (
$upgrader->isUpgradeComplete() && $this->options()->currentVersionId >= \XF::$versionId)
        {
            return
$this->view('XF:Upgrade\Current', 'upgrade_current', [
               
'fileErrors' => array_merge($missing, $inconsistent),
               
'hasHashes' => $xfAddOn->hasHashes(),
            ]);
        }

       
$db = $this->app->db();

       
$needMigration = $this->app->config('legacyExists');

       
$currentVersion = $upgrader->getCurrentVersion();

       
$viewParams = [
           
'errors' => $installHelper->getRequirementErrors($db),
           
'warnings' => $installHelper->getRequirementWarnings($db),
           
'currentVersion' => $currentVersion,
           
'isSignificantUpgrade' => $upgrader->isSignificantUpgrade(),
           
'isCliRecommended' => $upgrader->isCliRecommended(),
           
'addOnConflicts' => $upgrader->getAddOnConflicts($currentVersion),
           
'fileErrors' => array_merge($missing, $inconsistent),
           
'hasHashes' => $xfAddOn->hasHashes(),
           
'needsConfigMigration' => $needMigration
       
];
        return
$this->view('XF:Upgrade\Start', 'upgrade_start', $viewParams);
    }

    public function
actionMigrateConfig()
    {
       
$this->assertPostOnly();

        if (
$this->app->config('exists') || !$this->app->config('legacyExists'))
        {
            return
$this->redirect('index.php?upgrade/');
        }

       
$installHelper = $this->getUpgrader();

       
$config = $installHelper->migrateLegacyConfigIfNeeded($written);

       
$viewParams = [
           
'config' => $config,
           
'written' => $written,
           
'configFile' => $this->app->container('config.file')
        ];
        return
$this->view('XF:Upgrade\MigrateConfig', 'upgrade_migrate_config', $viewParams);
    }

    public function
actionRun()
    {
       
$this->assertPostOnly();

        if (!
$this->app->config('exists'))
        {
            return
$this->error(\XF::phrase('config_file_x_could_not_be_found', [
               
'file' => $this->app->container('config.file')
            ]));
        }

       
$upgrader = $this->getUpgrader();
       
$upgrader->syncUpgradeLogStructure();

       
$lastUpgradeVersion = $upgrader->getLatestUpgradeVersion();

        if (
$lastUpgradeVersion['version_id'] === \XF::$versionId && !$lastUpgradeVersion['last_step'])
        {
            return
$this->actionRebuild();
        }

       
$input = $this->filter([
           
'run_version' => 'uint',
           
'step' => 'str',
           
'position' => 'uint',
           
'step_data' => 'json-array'
       
]);

        if (!
$input['run_version'])
        {
            if (
$lastUpgradeVersion['last_step'])
            {
               
// pick up from the next step
               
$input['run_version'] = $lastUpgradeVersion['version_id'];
               
$input['step'] = $lastUpgradeVersion['last_step'] + 1;
            }
            else
            {
               
// last upgrade is complete, pick up from the next upgrade
               
$input['run_version'] = $upgrader->getNextUpgradeVersionId($lastUpgradeVersion['version_id']);
               
$input['step'] = 1;
            }

           
// starting a new step (or upgrade script), ignore these
           
$input['position'] = 0;
           
$input['step_data'] = [];

            if (
$input['run_version'])
            {
                if (
$input['run_version'] > \XF::$versionId)
                {
                    return
$this->error(\XF::phrase('upgrade_found_newer_than_version'));
                }

               
$upgrade = $upgrader->getUpgrade($input['run_version']);
            }
            else
            {
               
$upgrade = false;
            }
        }
        else
        {
           
$upgrade = $upgrader->getUpgrade($input['run_version']);
        }

        if (!
$upgrade)
        {
           
$upgrader->insertUpgradeLog(\XF::$versionId);
            return
$this->actionRebuild();
        }

       
$upgrader->assertValidUpgradeSteps($upgrade);

        if (!
$input['step'])
        {
           
$input['step'] = 1;
        }

        if (
method_exists($upgrade, 'step' . $input['step']))
        {
           
$result = $upgrade->{'step' . $input['step']}($input['position'], $input['step_data'], $this);
        }
        else
        {
           
$result = 'complete';
        }

        if (
$result instanceof AbstractReply)
        {
            return
$result;
        }

       
$stepMessage = '';
       
$stepData = false;

        if (
$result === 'complete')
        {
           
$upgrader->insertUpgradeLog($input['run_version']);

           
$viewParams = [
               
'newRunVersion' => '',
               
'newStep' => '',
               
'versionName' => $upgrade->getVersionName(),
               
'step' => $input['step']
            ];
        }
        else
        {
            if (
$result === true || $result === null)
            {
               
// step finished
               
$upgrader->insertUpgradeLog($input['run_version'], $input['step']);

               
$result = $input['step'] + 1;
               
$input['position'] = 0;
               
$stepData = [];
            }
            else if (
is_array($result))
            {
               
// step not finished, don't log anything yet
               
$input['position'] = $result[0];
               
$stepMessage = $result[1];
                if (!empty(
$result[2]))
                {
                   
$stepData = $result[2];
                }

               
$result = $input['step']; // stay on same step
           
}

           
$viewParams = [
               
'newRunVersion' => $input['run_version'],
               
'newStep' => $result,
               
'position' => $input['position'],
               
'stepMessage' => $stepMessage,
               
'stepData' => $stepData,
               
'versionName' => $upgrade->getVersionName(),
               
'step' => $input['step']
            ];
        }

        return
$this->view('XF:Upgrade\Run', 'upgrade_run', $viewParams);
    }

    public function
actionRebuild()
    {
       
$upgrader = $this->getUpgrader();

       
$currentVersion = $upgrader->getCurrentVersion();
       
$extraJobs = $upgrader->getExtraUpgradeJobsMap();
       
$this->getInstallHelper()->insertRebuildJob(null, $extraJobs, true, $currentVersion);

        return
$this->rerouteController(__CLASS__, 'runJob');
    }

    public function
actionRunJob()
    {
       
$redirect = 'index.php?upgrade/complete';
       
$session = $this->app->session();

        if (empty(
$this->options()->collectServerStats['configured'])
            ||
$session->repromptStatsCollection
       
)
        {
           
$redirect = 'index.php?upgrade/options';
        }

       
$output = $this->manualJobRunner('index.php?upgrade/run-job', $redirect);

        if (
$output instanceof \XF\Mvc\Reply\Redirect)
        {
           
// if this still exists, it will have a future date which means the process got interrupted
           
if ($this->getInstallHelper()->hasRebuildJobPending())
            {
                return
$this->view('XF:Upgrade\RebuildErrors', 'upgrade_rebuild_errors');
            }

           
$upgrader = $this->getUpgrader();
            if (
$upgrader->isUpgradeComplete())
            {
               
// all complete
               
$upgrader->completeUpgrade();
            }
        }

        return
$output;
    }

    public function
actionOptions()
    {
       
$session = $this->app->session();

        if (
$this->isPost())
        {
           
$options = \XF\Util\Arr::arrayFilterKeys(
               
$this->filter('options', 'array'),
                [
'collectServerStats'],
               
true
           
);

           
/** @var \XF\Repository\Option $optionRepo */
           
$optionRepo = $this->repository('XF:Option');
           
$optionRepo->updateOptions($options);

           
$session->remove('repromptStatsCollection');
           
$session->remove('repromptStatsCollectionReasons');

            return
$this->redirect('index.php?upgrade/complete');
        }
        else
        {
           
/** @var \XF\Repository\CollectStats $collectStatsRepo */
           
$collectStatsRepo = $this->repository('XF:CollectStats');

           
$viewParams = [
               
'isEnabled' => $collectStatsRepo->isEnabled(),
               
'isReprompt' => $session->repromptStatsCollection,
               
'repromptReasons' => $session->repromptStatsCollectionReasons,
            ];
            return
$this->view('XF:Upgrade\Options', 'upgrade_options', $viewParams);
        }
    }

    public function
actionComplete()
    {
        if (
$this->getInstallHelper()->hasRebuildJobPending())
        {
            return
$this->view('XF:Upgrade\RebuildErrors', 'upgrade_rebuild_errors');
        }

        if (
$this->options()->currentVersionId == \XF::$versionId)
        {
           
$schemaErrors = $this->getUpgrader()->getDefaultSchemaErrors();
            if (
$schemaErrors)
            {
               
$viewParams = [
                   
'errors' => $schemaErrors
               
];
                return
$this->view('XF:Upgrade\Errors', 'upgrade_errors', $viewParams);
            }

           
$upgrader = $this->getUpgrader();
           
$upgrader->renameLegacyConfigIfNeeded();

           
$viewParams = [
               
'outdatedTemplates' => $this->app->repository('XF:Template')->countOutdatedTemplates()
            ];

            return
$this->view('XF:Upgrade\Complete', 'upgrade_complete', $viewParams);
        }
        else
        {
            return
$this->error(\XF::phrase('uh_oh_upgrade_did_not_complete'));
        }
    }

    public function
actionLogin()
    {
       
$error = null;

        if (
$this->isPost())
        {
           
$input = $this->filter([
               
'login' => 'str',
               
'password' => 'str'
           
]);

           
$ip = $this->request->getIp();
           
$user = null;
           
$error = null;

            try
            {
               
/** @var \XF\Service\User\Login $loginService */
               
$loginService = $this->service('XF:User\Login', $input['login'], $ip);
                if (
$loginService->isLoginLimited($limitType))
                {
                    return
$this->error(\XF::phrase('your_account_has_temporarily_been_locked_due_to_failed_login_attempts'));
                }

               
$loginService->setAllowPasswordUpgrade(false);

               
$user = $loginService->validate($input['password'], $error);
            }
            catch (\
XF\Db\Exception $e) {}

            if (!
$user)
            {
                return
$this->notFound($error ?: \XF::phrase('requested_user_not_found'));
            }

           
$this->completeLogin($user);

           
$visitor = \XF::visitor();
            if (!
$visitor->is_admin)
            {
                return
$this->error(\XF::phrase('your_account_does_not_have_admin_privileges'));
            }

            return
$this->redirect('index.php?upgrade/');
        }

       
$viewParams = [
           
'error' => $error
       
];
        return
$this->view('XF:Upgrade\Login','upgrade_login', $viewParams);
    }

    protected function
completeLogin(\XF\Entity\User $user)
    {
       
$this->session()->changeUser($user);
        \
XF::setVisitor($user);

       
$ip = $this->request->getIp();

       
// Avoid an exception for *very* legacy upgrades
       
try
        {
           
$this->repository('XF:Ip')->logIp(
               
$user->user_id, $ip,
               
'user', $user->user_id, 'login_upgrade'
           
);
        }
        catch (\
XF\Db\Exception $e) {}

        if (!\
XF\Util\File::installLockExists())
        {
            \
XF\Util\File::writeInstallLock();
        }
    }
}