Seditio Source
Root |
./othercms/xenForo 2.2.8/src/XF/Cli/Command/Development/UpgradeStep.php
<?php

namespace XF\Cli\Command\Development;

use
Symfony\Component\Console\Command\Command;
use
Symfony\Component\Console\Input\InputArgument;
use
Symfony\Component\Console\Input\InputInterface;
use
Symfony\Component\Console\Output\OutputInterface;
use
XF\Cli\Command\CustomAppCommandInterface;
use
XF\Install\Controller\Upgrade;
use
XF\Install\Upgrade\AbstractUpgrade;
use
XF\Mvc\Reply\AbstractReply;

use function
is_array, is_int, strlen;

class
UpgradeStep extends Command implements CustomAppCommandInterface
{
    use
RequiresDevModeTrait;

    public static function
getCustomAppClass()
    {
        return
'XF\Install\App';
    }

    protected function
configure()
    {
       
$this
           
->setName('xf-dev:upgrade-step')
            ->
setDescription('Runs a specific upgrade step from a specified upgrade class.')
            ->
addArgument(
               
'version',
               
InputArgument::REQUIRED,
               
'The upgrade version to execute, e.g. 2000010'
           
)
            ->
addArgument(
               
'step',
               
InputArgument::REQUIRED,
               
'The step number to run'
           
);
    }

    protected function
execute(InputInterface $input, OutputInterface $output)
    {
       
/** @var \XF\Install\App $app */
       
$app = \XF::app();
       
$upgrader = new \XF\Install\Upgrader($app);

       
$controller = new \XF\Install\Controller\Upgrade($app, $app->request());
       
$upgrade = $upgrader->getUpgrade($input->getArgument('version'));

       
$step = $input->getArgument('step');
       
$position = 0;
       
$data = [];

        do
        {
           
$returnCode = $this->runStep($upgrade, $output, $controller, $step, $position, $data);
            if (
is_int($returnCode))
            {
               
$loop = false;
            }
            else if (
is_array($returnCode))
            {
               
$loop = true;
               
$position = $returnCode[0];
               
$data = $returnCode[2] ?? [];
            }
            else
            {
                throw new \
LogicException("Step did not return an expected result");
            }
        }
        while (
$loop);

        return
$returnCode;
    }

    protected function
runStep(AbstractUpgrade $upgrade, OutputInterface $output, Upgrade $controller, $step, $position = 0, $data = [])
    {
       
$versionName = $upgrade->getVersionName();

        if (!
method_exists($upgrade, 'step' . $step))
        {
           
$this->clearStatus($output, "<error>Upgrade to version $versionName does not have a step$step() method.</error>");
            return
2;
        }

        if (
$position)
        {
           
$this->outputStatus($output, "Running upgrade to $versionName, step $step ($position)...");
        }
        else
        {
           
$this->outputStatus($output, "Running upgrade to $versionName, step $step...");
        }

       
$result = $upgrade->{'step' . $step}($position, $data, $controller);
        if (
$result instanceof AbstractReply)
        {
           
$this->clearStatus($output, "<error>This step must be completed via the web interface.</error>");
            return
2;
        }
        else if (
$result === 'complete' || $result === true || $result === null)
        {
           
$this->clearStatus($output, "Running upgrade to $versionName, step $step... done.");
            return
0;
        }
        else if (
is_array($result))
        {
           
// stay on the same step
           
return $result;
        }
        else
        {
           
$this->clearStatus($output, "<error>The upgrade step returned an unexpected result.</error>");
            return
3;
        }
    }

    protected
$lastStatusLength;

    protected function
outputStatus(OutputInterface $output, $status)
    {
        if (
$this->lastStatusLength && $this->lastStatusLength > strlen($status))
        {
           
$status = str_pad($status, $this->lastStatusLength, " ", STR_PAD_RIGHT);
        }

       
$output->write("\r$status");
       
$this->lastStatusLength = strlen($status);
    }

    protected function
clearStatus(OutputInterface $output, $extraMessage = null)
    {
       
$this->outputStatus($output, '');
       
$output->write("\r");
        if (
$extraMessage !== null)
        {
           
$output->writeln($extraMessage);
        }
    }
}