mirror of
https://github.com/shlinkio/shlink.git
synced 2025-03-14 04:00:57 +03:00
Merge branch 'master' of github.com:shlinkio/shlink
This commit is contained in:
commit
baeba54b06
15 changed files with 259 additions and 55 deletions
|
@ -13,6 +13,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
|||
#### Changed
|
||||
|
||||
* [#312](https://github.com/shlinkio/shlink/issues/312) Now all config files both in `php` and `json` format are loaded from `config/params` folder, easing users to provided customizations to docker image.
|
||||
* [#226](https://github.com/shlinkio/shlink/issues/226) Updated how table are rendered in CLI commands, making use of new features in Symfony 4.2.
|
||||
|
||||
#### Deprecated
|
||||
|
||||
|
|
|
@ -30,10 +30,10 @@
|
|||
"mikehaertl/phpwkhtmltopdf": "^2.2",
|
||||
"monolog/monolog": "^1.21",
|
||||
"roave/security-advisories": "dev-master",
|
||||
"symfony/console": "^4.1",
|
||||
"symfony/filesystem": "^4.1",
|
||||
"symfony/lock": "^4.1",
|
||||
"symfony/process": "^4.1",
|
||||
"symfony/console": "^4.2",
|
||||
"symfony/filesystem": "^4.2",
|
||||
"symfony/lock": "^4.2",
|
||||
"symfony/process": "^4.2",
|
||||
"theorchard/monolog-cascade": "^0.4",
|
||||
"zendframework/zend-config": "^3.0",
|
||||
"zendframework/zend-config-aggregator": "^1.0",
|
||||
|
@ -57,8 +57,8 @@
|
|||
"phpunit/phpcov": "^5.0",
|
||||
"phpunit/phpunit": "^7.3",
|
||||
"shlinkio/php-coding-standard": "~1.0.0",
|
||||
"symfony/dotenv": "^4.0",
|
||||
"symfony/var-dumper": "^4.0",
|
||||
"symfony/dotenv": "^4.2",
|
||||
"symfony/var-dumper": "^4.2",
|
||||
"zendframework/zend-component-installer": "^2.1",
|
||||
"zendframework/zend-expressive-tooling": "^1.0"
|
||||
},
|
||||
|
|
|
@ -26,7 +26,7 @@ $config['entity_manager']['connection'] = [
|
|||
$sm->setService('config', $config);
|
||||
|
||||
// Create database
|
||||
$process = new Process('vendor/bin/doctrine orm:schema-tool:create --no-interaction -q --test', __DIR__);
|
||||
$process = new Process(['vendor/bin/doctrine', 'orm:schema-tool:create', '--no-interaction', '-q', '--test'], __DIR__);
|
||||
$process->inheritEnvironmentVariables()
|
||||
->mustRun();
|
||||
|
||||
|
|
|
@ -3,13 +3,13 @@ declare(strict_types=1);
|
|||
|
||||
namespace Shlinkio\Shlink\CLI\Command\Api;
|
||||
|
||||
use Shlinkio\Shlink\Common\Console\ShlinkTable;
|
||||
use Shlinkio\Shlink\Rest\Entity\ApiKey;
|
||||
use Shlinkio\Shlink\Rest\Service\ApiKeyServiceInterface;
|
||||
use Symfony\Component\Console\Command\Command;
|
||||
use Symfony\Component\Console\Input\InputInterface;
|
||||
use Symfony\Component\Console\Input\InputOption;
|
||||
use Symfony\Component\Console\Output\OutputInterface;
|
||||
use Symfony\Component\Console\Style\SymfonyStyle;
|
||||
use function array_filter;
|
||||
use function array_map;
|
||||
use function sprintf;
|
||||
|
@ -46,7 +46,6 @@ class ListKeysCommand extends Command
|
|||
|
||||
protected function execute(InputInterface $input, OutputInterface $output): void
|
||||
{
|
||||
$io = new SymfonyStyle($input, $output);
|
||||
$enabledOnly = $input->getOption('enabledOnly');
|
||||
|
||||
$rows = array_map(function (ApiKey $apiKey) use ($enabledOnly) {
|
||||
|
@ -62,7 +61,7 @@ class ListKeysCommand extends Command
|
|||
return $rowData;
|
||||
}, $this->apiKeyService->listKeys($enabledOnly));
|
||||
|
||||
$io->table(array_filter([
|
||||
ShlinkTable::fromOutput($output)->render(array_filter([
|
||||
'Key',
|
||||
! $enabledOnly ? 'Is enabled' : null,
|
||||
'Expiration date',
|
||||
|
|
|
@ -4,6 +4,7 @@ declare(strict_types=1);
|
|||
namespace Shlinkio\Shlink\CLI\Command\ShortUrl;
|
||||
|
||||
use Cake\Chronos\Chronos;
|
||||
use Shlinkio\Shlink\Common\Console\ShlinkTable;
|
||||
use Shlinkio\Shlink\Common\Util\DateRange;
|
||||
use Shlinkio\Shlink\Core\Entity\Visit;
|
||||
use Shlinkio\Shlink\Core\Model\VisitsParams;
|
||||
|
@ -69,7 +70,6 @@ class GetVisitsCommand extends Command
|
|||
|
||||
protected function execute(InputInterface $input, OutputInterface $output): void
|
||||
{
|
||||
$io = new SymfonyStyle($input, $output);
|
||||
$shortCode = $input->getArgument('shortCode');
|
||||
$startDate = $this->getDateOption($input, 'startDate');
|
||||
$endDate = $this->getDateOption($input, 'endDate');
|
||||
|
@ -82,7 +82,7 @@ class GetVisitsCommand extends Command
|
|||
$rowData['country'] = $visit->getVisitLocation()->getCountryName();
|
||||
return select_keys($rowData, ['referer', 'date', 'userAgent', 'country']);
|
||||
}, $visits);
|
||||
$io->table(['Referer', 'Date', 'User agent', 'Country'], $rows);
|
||||
ShlinkTable::fromOutput($output)->render(['Referer', 'Date', 'User agent', 'Country'], $rows);
|
||||
}
|
||||
|
||||
private function getDateOption(InputInterface $input, $key)
|
||||
|
|
|
@ -3,8 +3,10 @@ declare(strict_types=1);
|
|||
|
||||
namespace Shlinkio\Shlink\CLI\Command\ShortUrl;
|
||||
|
||||
use Shlinkio\Shlink\Common\Console\ShlinkTable;
|
||||
use Shlinkio\Shlink\Common\Paginator\Adapter\PaginableRepositoryAdapter;
|
||||
use Shlinkio\Shlink\Common\Paginator\Util\PaginatorUtilsTrait;
|
||||
use Shlinkio\Shlink\Common\Rest\DataTransformerInterface;
|
||||
use Shlinkio\Shlink\Core\Service\ShortUrlServiceInterface;
|
||||
use Shlinkio\Shlink\Core\Transformer\ShortUrlDataTransformer;
|
||||
use Symfony\Component\Console\Command\Command;
|
||||
|
@ -12,6 +14,7 @@ use Symfony\Component\Console\Input\InputInterface;
|
|||
use Symfony\Component\Console\Input\InputOption;
|
||||
use Symfony\Component\Console\Output\OutputInterface;
|
||||
use Symfony\Component\Console\Style\SymfonyStyle;
|
||||
use Zend\Paginator\Paginator;
|
||||
use function array_values;
|
||||
use function count;
|
||||
use function explode;
|
||||
|
@ -78,39 +81,56 @@ class ListShortUrlsCommand extends Command
|
|||
$searchTerm = $input->getOption('searchTerm');
|
||||
$tags = $input->getOption('tags');
|
||||
$tags = ! empty($tags) ? explode(',', $tags) : [];
|
||||
$showTags = $input->getOption('showTags');
|
||||
$showTags = (bool) $input->getOption('showTags');
|
||||
$transformer = new ShortUrlDataTransformer($this->domainConfig);
|
||||
|
||||
do {
|
||||
$result = $this->shortUrlService->listShortUrls($page, $searchTerm, $tags, $this->processOrderBy($input));
|
||||
$result = $this->renderPage($input, $output, $page, $searchTerm, $tags, $showTags, $transformer);
|
||||
$page++;
|
||||
|
||||
$headers = ['Short code', 'Short URL', 'Long URL', 'Date created', 'Visits count'];
|
||||
if ($showTags) {
|
||||
$headers[] = 'Tags';
|
||||
}
|
||||
|
||||
$rows = [];
|
||||
foreach ($result as $row) {
|
||||
$shortUrl = $transformer->transform($row);
|
||||
if ($showTags) {
|
||||
$shortUrl['tags'] = implode(', ', $shortUrl['tags']);
|
||||
} else {
|
||||
unset($shortUrl['tags']);
|
||||
}
|
||||
|
||||
unset($shortUrl['originalUrl']);
|
||||
$rows[] = array_values($shortUrl);
|
||||
}
|
||||
$io->table($headers, $rows);
|
||||
|
||||
if ($this->isLastPage($result)) {
|
||||
$continue = false;
|
||||
$io->success('Short URLs properly listed');
|
||||
} else {
|
||||
$continue = $io->confirm(sprintf('Continue with page <options=bold>%s</>?', $page), false);
|
||||
}
|
||||
$continue = $this->isLastPage($result)
|
||||
? false
|
||||
: $io->confirm(sprintf('Continue with page <options=bold>%s</>?', $page), false);
|
||||
} while ($continue);
|
||||
|
||||
$io->newLine();
|
||||
$io->success('Short URLs properly listed');
|
||||
}
|
||||
|
||||
private function renderPage(
|
||||
InputInterface $input,
|
||||
OutputInterface $output,
|
||||
int $page,
|
||||
?string $searchTerm,
|
||||
array $tags,
|
||||
bool $showTags,
|
||||
DataTransformerInterface $transformer
|
||||
): Paginator {
|
||||
$result = $this->shortUrlService->listShortUrls($page, $searchTerm, $tags, $this->processOrderBy($input));
|
||||
|
||||
$headers = ['Short code', 'Short URL', 'Long URL', 'Date created', 'Visits count'];
|
||||
if ($showTags) {
|
||||
$headers[] = 'Tags';
|
||||
}
|
||||
|
||||
$rows = [];
|
||||
foreach ($result as $row) {
|
||||
$shortUrl = $transformer->transform($row);
|
||||
if ($showTags) {
|
||||
$shortUrl['tags'] = implode(', ', $shortUrl['tags']);
|
||||
} else {
|
||||
unset($shortUrl['tags']);
|
||||
}
|
||||
|
||||
unset($shortUrl['originalUrl']);
|
||||
$rows[] = array_values($shortUrl);
|
||||
}
|
||||
|
||||
ShlinkTable::fromOutput($output)->render($headers, $rows, $this->formatCurrentPageMessage(
|
||||
$result,
|
||||
'Page %s of %s'
|
||||
));
|
||||
return $result;
|
||||
}
|
||||
|
||||
private function processOrderBy(InputInterface $input)
|
||||
|
|
|
@ -3,12 +3,12 @@ declare(strict_types=1);
|
|||
|
||||
namespace Shlinkio\Shlink\CLI\Command\Tag;
|
||||
|
||||
use Shlinkio\Shlink\Common\Console\ShlinkTable;
|
||||
use Shlinkio\Shlink\Core\Entity\Tag;
|
||||
use Shlinkio\Shlink\Core\Service\Tag\TagServiceInterface;
|
||||
use Symfony\Component\Console\Command\Command;
|
||||
use Symfony\Component\Console\Input\InputInterface;
|
||||
use Symfony\Component\Console\Output\OutputInterface;
|
||||
use Symfony\Component\Console\Style\SymfonyStyle;
|
||||
use function Functional\map;
|
||||
|
||||
class ListTagsCommand extends Command
|
||||
|
@ -33,8 +33,7 @@ class ListTagsCommand extends Command
|
|||
|
||||
protected function execute(InputInterface $input, OutputInterface $output): void
|
||||
{
|
||||
$io = new SymfonyStyle($input, $output);
|
||||
$io->table(['Name'], $this->getTagsRows());
|
||||
ShlinkTable::fromOutput($output)->render(['Name'], $this->getTagsRows());
|
||||
}
|
||||
|
||||
private function getTagsRows(): array
|
||||
|
|
41
module/Common/src/Console/ShlinkTable.php
Normal file
41
module/Common/src/Console/ShlinkTable.php
Normal file
|
@ -0,0 +1,41 @@
|
|||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Shlinkio\Shlink\Common\Console;
|
||||
|
||||
use Symfony\Component\Console\Helper\Table;
|
||||
use Symfony\Component\Console\Output\OutputInterface;
|
||||
|
||||
final class ShlinkTable
|
||||
{
|
||||
private const DEFAULT_STYLE_NAME = 'default';
|
||||
private const TABLE_TITLE_STYLE = '<options=bold> %s </>';
|
||||
|
||||
/** @var Table|null */
|
||||
private $baseTable;
|
||||
|
||||
public function __construct(Table $baseTable)
|
||||
{
|
||||
$this->baseTable = $baseTable;
|
||||
}
|
||||
|
||||
public static function fromOutput(OutputInterface $output): self
|
||||
{
|
||||
return new self(new Table($output));
|
||||
}
|
||||
|
||||
public function render(array $headers, array $rows, ?string $footerTitle = null, ?string $headerTitle = null): void
|
||||
{
|
||||
$style = Table::getStyleDefinition(self::DEFAULT_STYLE_NAME);
|
||||
$style->setFooterTitleFormat(self::TABLE_TITLE_STYLE)
|
||||
->setHeaderTitleFormat(self::TABLE_TITLE_STYLE);
|
||||
|
||||
$table = clone $this->baseTable;
|
||||
$table->setStyle($style)
|
||||
->setHeaders($headers)
|
||||
->setRows($rows)
|
||||
->setFooterTitle($footerTitle)
|
||||
->setHeaderTitle($headerTitle)
|
||||
->render();
|
||||
}
|
||||
}
|
|
@ -7,6 +7,7 @@ use Shlinkio\Shlink\Common\Rest\DataTransformerInterface;
|
|||
use Zend\Paginator\Paginator;
|
||||
use Zend\Stdlib\ArrayUtils;
|
||||
use function array_map;
|
||||
use function sprintf;
|
||||
|
||||
trait PaginatorUtilsTrait
|
||||
{
|
||||
|
@ -39,4 +40,9 @@ trait PaginatorUtilsTrait
|
|||
{
|
||||
return $paginator->getCurrentPageNumber() >= $paginator->count();
|
||||
}
|
||||
|
||||
private function formatCurrentPageMessage(Paginator $paginator, string $pattern): string
|
||||
{
|
||||
return sprintf($pattern, $paginator->getCurrentPageNumber(), $paginator->count());
|
||||
}
|
||||
}
|
||||
|
|
70
module/Common/test/Console/ShlinkTableTest.php
Normal file
70
module/Common/test/Console/ShlinkTableTest.php
Normal file
|
@ -0,0 +1,70 @@
|
|||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace ShlinkioTest\Shlink\Common\Console;
|
||||
|
||||
use PHPUnit\Framework\TestCase;
|
||||
use Prophecy\Argument;
|
||||
use Prophecy\Prophecy\ObjectProphecy;
|
||||
use ReflectionObject;
|
||||
use Shlinkio\Shlink\Common\Console\ShlinkTable;
|
||||
use Symfony\Component\Console\Helper\Table;
|
||||
use Symfony\Component\Console\Helper\TableStyle;
|
||||
use Symfony\Component\Console\Output\OutputInterface;
|
||||
|
||||
class ShlinkTableTest extends TestCase
|
||||
{
|
||||
/** @var ShlinkTable */
|
||||
private $shlinkTable;
|
||||
/** @var ObjectProphecy */
|
||||
private $baseTable;
|
||||
|
||||
public function setUp()
|
||||
{
|
||||
$this->baseTable = $this->prophesize(Table::class);
|
||||
$this->shlinkTable = new ShlinkTable($this->baseTable->reveal());
|
||||
}
|
||||
|
||||
/**
|
||||
* @test
|
||||
*/
|
||||
public function renderMakesTableToBeRenderedWithProvidedInfo()
|
||||
{
|
||||
$headers = [];
|
||||
$rows = [[]];
|
||||
$headerTitle = 'Header';
|
||||
$footerTitle = 'Footer';
|
||||
|
||||
$setStyle = $this->baseTable->setStyle(Argument::type(TableStyle::class))->willReturn(
|
||||
$this->baseTable->reveal()
|
||||
);
|
||||
$setHeaders = $this->baseTable->setHeaders($headers)->willReturn($this->baseTable->reveal());
|
||||
$setRows = $this->baseTable->setRows($rows)->willReturn($this->baseTable->reveal());
|
||||
$setFooterTitle = $this->baseTable->setFooterTitle($footerTitle)->willReturn($this->baseTable->reveal());
|
||||
$setHeaderTitle = $this->baseTable->setHeaderTitle($headerTitle)->willReturn($this->baseTable->reveal());
|
||||
$render = $this->baseTable->render()->willReturn($this->baseTable->reveal());
|
||||
|
||||
$this->shlinkTable->render($headers, $rows, $footerTitle, $headerTitle);
|
||||
|
||||
$setStyle->shouldHaveBeenCalledOnce();
|
||||
$setHeaders->shouldHaveBeenCalledOnce();
|
||||
$setRows->shouldHaveBeenCalledOnce();
|
||||
$setFooterTitle->shouldHaveBeenCalledOnce();
|
||||
$setHeaderTitle->shouldHaveBeenCalledOnce();
|
||||
$render->shouldHaveBeenCalledOnce();
|
||||
}
|
||||
|
||||
/**
|
||||
* @test
|
||||
*/
|
||||
public function newTableIsCreatedForFactoryMethod()
|
||||
{
|
||||
$instance = ShlinkTable::fromOutput($this->prophesize(OutputInterface::class)->reveal());
|
||||
|
||||
$ref = new ReflectionObject($instance);
|
||||
$baseTable = $ref->getProperty('baseTable');
|
||||
$baseTable->setAccessible(true);
|
||||
|
||||
$this->assertInstanceOf(Table::class, $baseTable->getValue($instance));
|
||||
}
|
||||
}
|
|
@ -11,6 +11,8 @@ use Shlinkio\Shlink\Common\Exception\WrongIpException;
|
|||
use Shlinkio\Shlink\Common\Util\IpAddress;
|
||||
use Shlinkio\Shlink\Core\Model\Visitor;
|
||||
use Shlinkio\Shlink\Core\Repository\VisitRepository;
|
||||
use Shlinkio\Shlink\Core\Visit\Model\UnknownVisitLocation;
|
||||
use Shlinkio\Shlink\Core\Visit\Model\VisitLocationInterface;
|
||||
|
||||
/**
|
||||
* Class Visit
|
||||
|
@ -88,9 +90,9 @@ class Visit extends AbstractEntity implements JsonSerializable
|
|||
return ! empty($this->remoteAddr);
|
||||
}
|
||||
|
||||
public function getVisitLocation(): VisitLocation
|
||||
public function getVisitLocation(): VisitLocationInterface
|
||||
{
|
||||
return $this->visitLocation;
|
||||
return $this->visitLocation ?? new UnknownVisitLocation();
|
||||
}
|
||||
|
||||
public function locate(VisitLocation $visitLocation): self
|
||||
|
|
|
@ -4,8 +4,8 @@ declare(strict_types=1);
|
|||
namespace Shlinkio\Shlink\Core\Entity;
|
||||
|
||||
use Doctrine\ORM\Mapping as ORM;
|
||||
use JsonSerializable;
|
||||
use Shlinkio\Shlink\Common\Entity\AbstractEntity;
|
||||
use Shlinkio\Shlink\Core\Visit\Model\VisitLocationInterface;
|
||||
use function array_key_exists;
|
||||
|
||||
/**
|
||||
|
@ -16,7 +16,7 @@ use function array_key_exists;
|
|||
* @ORM\Entity()
|
||||
* @ORM\Table(name="visit_locations")
|
||||
*/
|
||||
class VisitLocation extends AbstractEntity implements JsonSerializable
|
||||
class VisitLocation extends AbstractEntity implements VisitLocationInterface
|
||||
{
|
||||
/**
|
||||
* @var string
|
||||
|
|
47
module/Core/src/Visit/Model/UnknownVisitLocation.php
Normal file
47
module/Core/src/Visit/Model/UnknownVisitLocation.php
Normal file
|
@ -0,0 +1,47 @@
|
|||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Shlinkio\Shlink\Core\Visit\Model;
|
||||
|
||||
final class UnknownVisitLocation implements VisitLocationInterface
|
||||
{
|
||||
public function getCountryName(): string
|
||||
{
|
||||
return 'Unknown';
|
||||
}
|
||||
|
||||
public function getLatitude(): string
|
||||
{
|
||||
return '0.0';
|
||||
}
|
||||
|
||||
public function getLongitude(): string
|
||||
{
|
||||
return '0.0';
|
||||
}
|
||||
|
||||
public function getCityName(): string
|
||||
{
|
||||
return 'Unknown';
|
||||
}
|
||||
|
||||
/**
|
||||
* Specify data which should be serialized to JSON
|
||||
* @link https://php.net/manual/en/jsonserializable.jsonserialize.php
|
||||
* @return mixed data which can be serialized by <b>json_encode</b>,
|
||||
* which is a value of any type other than a resource.
|
||||
* @since 5.4.0
|
||||
*/
|
||||
public function jsonSerialize()
|
||||
{
|
||||
return [
|
||||
'countryCode' => 'Unknown',
|
||||
'countryName' => 'Unknown',
|
||||
'regionName' => 'Unknown',
|
||||
'cityName' => 'Unknown',
|
||||
'latitude' => '0.0',
|
||||
'longitude' => '0.0',
|
||||
'timezone' => 'Unknown',
|
||||
];
|
||||
}
|
||||
}
|
17
module/Core/src/Visit/Model/VisitLocationInterface.php
Normal file
17
module/Core/src/Visit/Model/VisitLocationInterface.php
Normal file
|
@ -0,0 +1,17 @@
|
|||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Shlinkio\Shlink\Core\Visit\Model;
|
||||
|
||||
use JsonSerializable;
|
||||
|
||||
interface VisitLocationInterface extends JsonSerializable
|
||||
{
|
||||
public function getCountryName(): string;
|
||||
|
||||
public function getLatitude(): string;
|
||||
|
||||
public function getLongitude(): string;
|
||||
|
||||
public function getCityName(): string;
|
||||
}
|
|
@ -20,7 +20,8 @@ use Symfony\Component\Filesystem\Exception\IOException;
|
|||
use Symfony\Component\Filesystem\Filesystem;
|
||||
use Symfony\Component\Process\PhpExecutableFinder;
|
||||
use Zend\Config\Writer\WriterInterface;
|
||||
use function sprintf;
|
||||
use function array_unshift;
|
||||
use function implode;
|
||||
|
||||
class InstallCommand extends Command
|
||||
{
|
||||
|
@ -133,7 +134,7 @@ class InstallCommand extends Command
|
|||
if (! $this->isUpdate) {
|
||||
$this->io->write('Initializing database...');
|
||||
if (! $this->execPhp(
|
||||
'vendor/doctrine/orm/bin/doctrine.php orm:schema-tool:create',
|
||||
['vendor/doctrine/orm/bin/doctrine.php', 'orm:schema-tool:create'],
|
||||
'Error generating database.',
|
||||
$output
|
||||
)) {
|
||||
|
@ -144,7 +145,7 @@ class InstallCommand extends Command
|
|||
// Run database migrations
|
||||
$this->io->write('Updating database...');
|
||||
if (! $this->execPhp(
|
||||
'vendor/doctrine/migrations/bin/doctrine-migrations.php migrations:migrate',
|
||||
['vendor/doctrine/migrations/bin/doctrine-migrations.php', 'migrations:migrate'],
|
||||
'Error updating database.',
|
||||
$output
|
||||
)) {
|
||||
|
@ -154,16 +155,16 @@ class InstallCommand extends Command
|
|||
// Generate proxies
|
||||
$this->io->write('Generating proxies...');
|
||||
if (! $this->execPhp(
|
||||
'vendor/doctrine/orm/bin/doctrine.php orm:generate-proxies',
|
||||
['vendor/doctrine/orm/bin/doctrine.php', 'orm:generate-proxies'],
|
||||
'Error generating proxies.',
|
||||
$output
|
||||
)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Download GeoLite2 db filte
|
||||
// Download GeoLite2 db file
|
||||
$this->io->write('Downloading GeoLite2 db...');
|
||||
if (! $this->execPhp('bin/cli visit:update-db', 'Error downloading GeoLite2 db.', $output)) {
|
||||
if (! $this->execPhp(['bin/cli', 'visit:update-db'], 'Error downloading GeoLite2 db.', $output)) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -215,7 +216,7 @@ class InstallCommand extends Command
|
|||
return $config;
|
||||
}
|
||||
|
||||
private function execPhp(string $command, string $errorMessage, OutputInterface $output): bool
|
||||
private function execPhp(array $command, string $errorMessage, OutputInterface $output): bool
|
||||
{
|
||||
if ($this->processHelper === null) {
|
||||
$this->processHelper = $this->getHelper('process');
|
||||
|
@ -225,12 +226,13 @@ class InstallCommand extends Command
|
|||
$this->phpBinary = $this->phpFinder->find(false) ?: 'php';
|
||||
}
|
||||
|
||||
array_unshift($command, $this->phpBinary);
|
||||
$this->io->write(
|
||||
' <options=bold>[Running "' . sprintf('%s %s', $this->phpBinary, $command) . '"]</> ',
|
||||
' <options=bold>[Running "' . implode(' ', $command) . '"]</> ',
|
||||
false,
|
||||
OutputInterface::VERBOSITY_VERBOSE
|
||||
);
|
||||
$process = $this->processHelper->run($output, sprintf('%s %s', $this->phpBinary, $command));
|
||||
$process = $this->processHelper->run($output, $command);
|
||||
if ($process->isSuccessful()) {
|
||||
$this->io->writeln(' <info>Success!</info>');
|
||||
return true;
|
||||
|
|
Loading…
Add table
Reference in a new issue