Source of file TICCommand.php

Size: 5,436 Bytes - Last Modified: 2023-11-16T22:56:02+01:00

/home/websites/teicee/packagist/site/phpdoc/conf/../vendor/teicee/core-bundle/src/Base/TICCommand.php

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175
<?php
namespace TIC\CoreBundle\Base;

use Symfony\Component\Console\Command\Command;

use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Style\SymfonyStyle;
#use Symfony\Component\Console\Logger\ConsoleLogger;

use Symfony\Component\Routing\RouterInterface;
use Symfony\Contracts\Translation\TranslatorInterface;
use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface;

// @TODO remplacer le ps|grep par https://symfony.com/doc/current/console/lockable_trait.html
use Symfony\Component\Process\Process;

/**
 * Base Command
 * @see https://symfony.com/doc/current/console.html
 * @see https://symfony.com/doc/current/components/console.html
 *
 * $output
 *   - verbosity  : ->isQuiet(), ->isVerbose(), ->isVeryVerbose(), ->isDebug()
 *   - clickable  : ->writeln('<href=https://symfony.com>Symfony Homepage</>');
 *   - style tags : '<info>' '<comment>' '<question>' '<error>'
 *   - color tags : '<fg=green>' '<bg=black;fg=#c0392b>' '<bg=yellow;options=bold,underscore>'
 * 
 * $io (style)
 *   ->title(),->section(), ->text(), ->listing(), ->table(), ->horizontalTable(), ->definitionList()
 *   ->note(), ->caution(), ->info(), ->warning(), ->error(), ->success()
 *   ->ask(), ->askHidden(), ->confirm(), ->choice()
 * 
 */
abstract class TICCommand extends Command
{
	// Initialisation automatique des propriétés à partir du nom de la classe courante
	use \TIC\CoreBundle\Traits\ContextProperties;   // ctxBundle, ctxPath & ctxSnake

	protected $router;
	protected $translator;
	protected $params;

	protected $io;
	protected $out;
	protected $test;
#	protected $logger;

	// the name of the command (the part after "bin/console")
	protected static $defaultName = null;
	// the command description shown when running "php bin/console list"
	protected static $defaultDescription = null;

	/**
	 * {@inheritDoc}
	 */
	public function __construct(
		RouterInterface         $router,
		TranslatorInterface     $translator,
		ParameterBagInterface   $params
	) {
		parent::__construct();
		$this->router         = $router;
		$this->translator     = $translator;
		$this->params         = $params;
	}

	/**
	 * {@inheritDoc}
	 */
	protected function configure(): void
	{
		// appel manuel pour l'initialisation des propriétés de contexte (l'appel auto n'étant fait qu'après)
		$this->setContextProperties('Command');
		
		// détermination du nom de la commande pour la console
		if (null === static::$defaultName) {
			if ($this->ctxBundle) {
				$commandName = \strtolower(\trim(\preg_replace("/([A-Z][^A-Z])/", '_\1', $this->ctxBundle)));
				$commandName = \str_replace(['@','_'], ['',':'], $commandName);
			} else {
				$commandName = empty($this->ctxPath) ? 'app' : \strtolower($this->ctxPath);
			}
			$commandName.= ":" . \strtr($this->ctxSnake, '_', '-');
			$this->setName($commandName);
		}
		
		// définition d'options génériques communes
		$this->addOption('test', 't', InputOption::VALUE_NONE, "test only.");
	}

	/**
	 * {@inheritDoc}
	 */
	protected function initialize(InputInterface $input, OutputInterface $output)
	{
		parent::initialize($input, $output);
		
		// raccourcis utilisables pour toute méthode
		$this->test = $input->getOption('test');
		$this->out = $output;
		
		// @see https://symfony.com/doc/current/console/style.html
		$this->io = new SymfonyStyle($input, $output);
		
		// @see https://symfony.com/doc/current/components/console/logger.html
#		$this->logger = new ConsoleLogger($output);
		
		// entity manager & options (disable logger & softdelete)
		if (isset($this->em)) {
#			$this->EmDisableLogger();
#			$this->EmDisableFilter('softdeleteable');
		}
	}

	/**
	 * {@inheritDoc}
	 */
	protected function execute(InputInterface $input, OutputInterface $output): int
	{
#		$output->writeln("...");
		$this->io->success("Done.");
		
#		return self::INVALID;  // 2
#		return self::FAILURE;  // 1
		return self::SUCCESS;  // 0
	}

	// -------------------------------------------------------------------------

	/**
	 *
	 */
	protected function trans(string $token, array $parameters = []): string
	{
		return $this->translator->trans($token, $parameters);
	}

	/**
	 * Méthode testant si un autre processus pour la même commande est déjà en cours d'exécution.
	 * @see https://symfony.com/doc/current/console/lockable_trait.html
	 */
	protected function isAlreadyRunning($exclude_pid = null): ?bool
	{
		$ps = 'ps axwh -o pid,cmd';
		$cmd = "$ps | sed 's/^ *//'";
		if ($exclude_pid) $cmd.= " | grep -v '^".(\intval($exclude_pid))." '";
		$cmd.= " | grep 'console " . $this->getName() . "'";
#		$cmd.= " | grep -v ' $ps' | grep -v ' grep ' | wc -l";
		$cmd.= " | grep -v ' $ps' | grep -v ' grep ' | grep -v ' /bin/sh -c ' | wc -l";
		
		$process = new Process($cmd);
		$process->run();
		if (! $process->isSuccessful()) return null;
		
		$output = \intval(\trim($process->getOutput()));
		if ($output > 1)  return true;
		if ($output == 1) return false;
	}

	/**
	 * Méthode utile pour afficher un message d'erreur, suivi du synopsis de la commande, puis exit 1.
	 */
	protected function exitError(string $message, int $code=1)
	{
		$this->io->error($message);
		$this->io->text('<info>' . $this->getSynopsis() . '</info>');
		$this->io->newLine();
		exit($code);
	}

}