webworld888/app/Console/Commands/ShouldOperation.php
2021-10-26 19:14:12 +09:00

235 lines
5.9 KiB
PHP

<?php
/**
* ShouldOperation.php
*
* PHP version 7
*
* @category Commands
* @package App\Console\Commands
* @author XE Developers <developers@xpressengine.com>
* @copyright 2020 Copyright XEHub Corp. <https://www.xehub.io>
* @license http://www.gnu.org/licenses/lgpl-3.0-standalone.html LGPL
* @link https://xpressengine.io
*/
namespace App\Console\Commands;
use App\Console\MultipleOutput;
use Carbon\Carbon;
use Illuminate\Console\Command;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Output\StreamOutput;
use Xpressengine\Foundation\Operator;
/**
* Class ShouldOperation
*
* @category Commands
* @package App\Console\Commands
* @author XE Developers <developers@xpressengine.com>
* @copyright 2020 Copyright XEHub Corp. <https://www.xehub.io>
* @license http://www.gnu.org/licenses/lgpl-3.0-standalone.html LGPL
* @link https://xpressengine.io
*/
abstract class ShouldOperation extends Command
{
use ComposerRunTrait;
/**
* Operator instance
*
* @var Operator
*/
protected $operator;
/**
* ShouldOperation constructor.
*
* @param Operator $operator Operator instance
*/
public function __construct(Operator $operator)
{
parent::__construct();
$this->operator = $operator;
}
/**
* Run the console command.
*
* @param InputInterface $input input
* @param OutputInterface $output output
* @return int
*/
public function run(InputInterface $input, OutputInterface $output)
{
$datetime = Carbon::now()->format('YmdHis');
$file = "logs/operation-{$datetime}.log";
$path = $this->laravel->storagePath().DIRECTORY_SEPARATOR.$file;
$output = new MultipleOutput([$output, new StreamOutput(fopen($path, 'a'))]);
\Log::useFiles($path);
$this->operator->log($file);
$this->operator->save();
return parent::run($input, $output);
}
/**
* Start the operation
*
* @param string $mode operation mode
* @param callable $callback callback
* @param callable|null $onError callback for error
* @return void
* @throws \Throwable
*/
protected function start($mode, callable $callback, callable $onError = null)
{
$this->operator->lock();
$method = 'set'.ucfirst($mode).'Mode';
$this->operator->$method();
$this->operator->expiresAt(Carbon::now()->addSeconds($limit = $this->getTimeLimit())->toDateTimeString());
$this->operator->save();
set_time_limit($limit);
try {
if (0 !== $code = $this->clearCache(true)) {
throw new \RuntimeException('cache clear fail.. check your system.', $code);
}
call_user_func($callback, $this->operator);
} catch (\Exception $e) {
$this->errorHandle($e, $onError);
} catch (\Throwable $e) {
$this->errorHandle($e, $onError);
} finally {
$this->operator->unlock();
}
$this->setSucceed();
}
/**
* Handle error for the operation.
*
* @param \Throwable $e exception
* @param callable|null $callback callback
* @return void
* @throws \Throwable
*/
protected function errorHandle($e, callable $callback = null)
{
$this->setFailed($e->getCode());
if ($callback) {
call_user_func($callback, $e);
}
throw $e;
}
/**
* Start the core operation
*
* @param callable $callback callback
* @param callable|null $onError callback for error
* @return void
* @throws \Throwable
*/
protected function startCore(callable $callback, callable $onError = null)
{
$this->start(Operator::TYPE_CORE, $callback, $onError);
}
/**
* Start the plugin operation
*
* @param callable $callback callback
* @param callable|null $onError callback for error
* @return void
* @throws \Throwable
*/
protected function startPlugin(callable $callback, callable $onError = null)
{
$this->start(Operator::TYPE_PLUGIN, $callback, $onError);
}
/**
* Start the private plugin operation
*
* @param callable $callback callback
* @param callable|null $onError callback for error
* @return void
* @throws \Throwable
*/
protected function startPrivate(callable $callback, callable $onError = null)
{
$this->start(Operator::TYPE_PRIVATE, $callback, $onError);
}
/**
* Run cache clear.
*
* @param bool $exceptProxy except proxy when clears the cache
* @return int
*/
protected function clearCache($exceptProxy = false)
{
$this->warn('Clears the cache before the operation run.');
$result = $this->call('cache:clear', ['--except-proxy' => $exceptProxy]);
$this->line(PHP_EOL);
return $result;
}
/**
* Get time limit.
*
* @return int
*/
protected function getTimeLimit()
{
return config('xe.plugin.operation.time_limit');
}
/**
* Set operation succeed.
*
* @return void
*/
protected function setSucceed()
{
$this->writeResult(0);
}
/**
* Set operation failed.
*
* @param int $code result code
* @return void
*/
protected function setFailed($code = 1)
{
$this->writeResult($code === 0 ? 1 : $code);
}
/**
* Write result.
*
* @param int $result result code
* @return void
*/
protected function writeResult($result)
{
$operation = $this->operator->getOperation();
$result !== 0 ? $operation->failed() : $operation->succeed();
$this->operator->save();
}
}