mirror of
https://github.com/shlinkio/shlink.git
synced 2025-02-25 18:45:27 -06:00
Merge branch 'feature/install' into develop
This commit is contained in:
commit
ffa6c0d2ca
1
.gitignore
vendored
1
.gitignore
vendored
@ -3,3 +3,4 @@ build
|
|||||||
composer.lock
|
composer.lock
|
||||||
vendor/
|
vendor/
|
||||||
.env
|
.env
|
||||||
|
data/database.sqlite
|
||||||
|
15
bin/cli
15
bin/cli
@ -1,17 +1,4 @@
|
|||||||
#!/usr/bin/env php
|
#!/usr/bin/env php
|
||||||
<?php
|
<?php
|
||||||
use Interop\Container\ContainerInterface;
|
|
||||||
use Symfony\Component\Console\Application as CliApp;
|
|
||||||
use Symfony\Component\Console\Application;
|
|
||||||
use Zend\I18n\Translator\Translator;
|
|
||||||
|
|
||||||
/** @var ContainerInterface $container */
|
include 'cli.php';
|
||||||
$container = include __DIR__ . '/../config/container.php';
|
|
||||||
|
|
||||||
/** @var Translator $translator */
|
|
||||||
$translator = $container->get('translator');
|
|
||||||
$translator->setLocale(env('CLI_LOCALE', 'en'));
|
|
||||||
|
|
||||||
/** @var Application $app */
|
|
||||||
$app = $container->get(CliApp::class);
|
|
||||||
$app->run();
|
|
||||||
|
10
bin/cli.php
Normal file
10
bin/cli.php
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
<?php
|
||||||
|
use Interop\Container\ContainerInterface;
|
||||||
|
use Symfony\Component\Console\Application as CliApp;
|
||||||
|
|
||||||
|
/** @var ContainerInterface $container */
|
||||||
|
$container = include __DIR__ . '/../config/container.php';
|
||||||
|
|
||||||
|
/** @var CliApp $app */
|
||||||
|
$app = $container->get(CliApp::class);
|
||||||
|
$app->run();
|
4
bin/install
Executable file
4
bin/install
Executable file
@ -0,0 +1,4 @@
|
|||||||
|
#!/usr/bin/env php
|
||||||
|
<?php
|
||||||
|
|
||||||
|
include 'install.php';
|
14
bin/install.php
Executable file
14
bin/install.php
Executable file
@ -0,0 +1,14 @@
|
|||||||
|
#!/usr/bin/env php
|
||||||
|
<?php
|
||||||
|
use Shlinkio\Shlink\CLI\Command\Install\InstallCommand;
|
||||||
|
use Symfony\Component\Console\Application;
|
||||||
|
use Zend\Config\Writer\PhpArray;
|
||||||
|
|
||||||
|
chdir(dirname(__DIR__));
|
||||||
|
|
||||||
|
require __DIR__ . '/../vendor/autoload.php';
|
||||||
|
|
||||||
|
$app = new Application();
|
||||||
|
$app->add(new InstallCommand(new PhpArray()));
|
||||||
|
$app->setDefaultCommand('shlink:install');
|
||||||
|
$app->run();
|
44
build.sh
Executable file
44
build.sh
Executable file
@ -0,0 +1,44 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
set -e
|
||||||
|
|
||||||
|
if [ "$#" -ne 1 ]; then
|
||||||
|
echo "Usage:" >&2
|
||||||
|
echo " $0 {version}" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
version=$1
|
||||||
|
builtcontent=$(readlink -f '../shlink_build_tmp')
|
||||||
|
projectdir=$(pwd)
|
||||||
|
|
||||||
|
# Copy project content to temp dir
|
||||||
|
echo 'Copying project files...'
|
||||||
|
rm -rf "${builtcontent}"
|
||||||
|
mkdir "${builtcontent}"
|
||||||
|
cp -R "${projectdir}"/* "${builtcontent}"
|
||||||
|
cd "${builtcontent}"
|
||||||
|
|
||||||
|
# Install dependencies
|
||||||
|
rm -r vendor
|
||||||
|
rm composer.lock
|
||||||
|
composer self-update
|
||||||
|
composer install --no-dev --optimize-autoloader
|
||||||
|
|
||||||
|
# Delete development files
|
||||||
|
echo 'Deleting dev files...'
|
||||||
|
rm build.sh
|
||||||
|
rm CHANGELOG.md
|
||||||
|
rm composer.*
|
||||||
|
rm LICENSE
|
||||||
|
rm php*
|
||||||
|
rm README.md
|
||||||
|
rm -r build
|
||||||
|
rm -f data/database.sqlite
|
||||||
|
rm -f data/{cache,log,proxies}/{*,.gitignore}
|
||||||
|
rm -f config/params/{*,.gitignore}
|
||||||
|
rm -f config/autoload/{{,*.}local.php{,.dist},.gitignore}
|
||||||
|
|
||||||
|
# Compressing file
|
||||||
|
rm -f "${projectdir}"/build/Shlink_${version}.dist.zip
|
||||||
|
zip -r "${projectdir}"/build/Shlink_${version}.dist.zip "${builtcontent}"
|
||||||
|
rm -rf "${builtcontent}"
|
@ -27,6 +27,7 @@
|
|||||||
"doctrine/orm": "^2.5",
|
"doctrine/orm": "^2.5",
|
||||||
"guzzlehttp/guzzle": "^6.2",
|
"guzzlehttp/guzzle": "^6.2",
|
||||||
"symfony/console": "^3.0",
|
"symfony/console": "^3.0",
|
||||||
|
"symfony/process": "^3.0",
|
||||||
"firebase/php-jwt": "^4.0",
|
"firebase/php-jwt": "^4.0",
|
||||||
"monolog/monolog": "^1.21",
|
"monolog/monolog": "^1.21",
|
||||||
"theorchard/monolog-cascade": "^0.4",
|
"theorchard/monolog-cascade": "^0.4",
|
||||||
|
@ -3,7 +3,7 @@ return [
|
|||||||
|
|
||||||
'app_options' => [
|
'app_options' => [
|
||||||
'name' => 'Shlink',
|
'name' => 'Shlink',
|
||||||
'version' => '1.1.0',
|
'version' => '1.2.0',
|
||||||
'secret_key' => env('SECRET_KEY'),
|
'secret_key' => env('SECRET_KEY'),
|
||||||
],
|
],
|
||||||
|
|
||||||
|
@ -1,11 +1,10 @@
|
|||||||
<?php
|
<?php
|
||||||
use Acelaya\ExpressiveErrorHandler\ConfigProvider as ErrorHandlerProvider;
|
use Acelaya\ExpressiveErrorHandler;
|
||||||
use Shlinkio\Shlink\CLI;
|
use Shlinkio\Shlink\CLI;
|
||||||
use Shlinkio\Shlink\Common;
|
use Shlinkio\Shlink\Common;
|
||||||
use Shlinkio\Shlink\Core;
|
use Shlinkio\Shlink\Core;
|
||||||
use Shlinkio\Shlink\Rest;
|
use Shlinkio\Shlink\Rest;
|
||||||
use Zend\Expressive\ConfigManager\ConfigManager;
|
use Zend\Expressive\ConfigManager;
|
||||||
use Zend\Expressive\ConfigManager\ZendConfigProvider;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Configuration files are loaded in a specific order. First ``global.php``, then ``*.global.php``.
|
* Configuration files are loaded in a specific order. First ``global.php``, then ``*.global.php``.
|
||||||
@ -16,11 +15,11 @@ use Zend\Expressive\ConfigManager\ZendConfigProvider;
|
|||||||
* Obviously, if you use closures in your config you can't cache it.
|
* Obviously, if you use closures in your config you can't cache it.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
return (new ConfigManager([
|
return (new ConfigManager\ConfigManager([
|
||||||
ErrorHandlerProvider::class,
|
ExpressiveErrorHandler\ConfigProvider::class,
|
||||||
Common\ConfigProvider::class,
|
Common\ConfigProvider::class,
|
||||||
Core\ConfigProvider::class,
|
Core\ConfigProvider::class,
|
||||||
CLI\ConfigProvider::class,
|
CLI\ConfigProvider::class,
|
||||||
Rest\ConfigProvider::class,
|
Rest\ConfigProvider::class,
|
||||||
new ZendConfigProvider('config/autoload/{{,*.}global,{,*.}local}.php'),
|
new ConfigManager\ZendConfigProvider('config/{autoload/{{,*.}global,{,*.}local},params/generated_config}.php'),
|
||||||
], 'data/cache/app_config.php'))->getMergedConfig();
|
], 'data/cache/app_config.php'))->getMergedConfig();
|
||||||
|
2
config/params/.gitignore
vendored
Normal file
2
config/params/.gitignore
vendored
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
*
|
||||||
|
!.gitignore
|
@ -4,6 +4,7 @@ use Shlinkio\Shlink\CLI\Command;
|
|||||||
return [
|
return [
|
||||||
|
|
||||||
'cli' => [
|
'cli' => [
|
||||||
|
'locale' => env('CLI_LOCALE', 'en'),
|
||||||
'commands' => [
|
'commands' => [
|
||||||
Command\Shortcode\GenerateShortcodeCommand::class,
|
Command\Shortcode\GenerateShortcodeCommand::class,
|
||||||
Command\Shortcode\ResolveUrlCommand::class,
|
Command\Shortcode\ResolveUrlCommand::class,
|
||||||
|
267
module/CLI/src/Command/Install/InstallCommand.php
Normal file
267
module/CLI/src/Command/Install/InstallCommand.php
Normal file
@ -0,0 +1,267 @@
|
|||||||
|
<?php
|
||||||
|
namespace Shlinkio\Shlink\CLI\Command\Install;
|
||||||
|
|
||||||
|
use Shlinkio\Shlink\Common\Util\StringUtilsTrait;
|
||||||
|
use Shlinkio\Shlink\Core\Service\UrlShortener;
|
||||||
|
use Symfony\Component\Console\Command\Command;
|
||||||
|
use Symfony\Component\Console\Helper\ProcessHelper;
|
||||||
|
use Symfony\Component\Console\Helper\QuestionHelper;
|
||||||
|
use Symfony\Component\Console\Input\InputInterface;
|
||||||
|
use Symfony\Component\Console\Output\OutputInterface;
|
||||||
|
use Symfony\Component\Console\Question\ChoiceQuestion;
|
||||||
|
use Symfony\Component\Console\Question\Question;
|
||||||
|
use Zend\Config\Writer\WriterInterface;
|
||||||
|
|
||||||
|
class InstallCommand extends Command
|
||||||
|
{
|
||||||
|
use StringUtilsTrait;
|
||||||
|
|
||||||
|
const DATABASE_DRIVERS = [
|
||||||
|
'MySQL' => 'pdo_mysql',
|
||||||
|
'PostgreSQL' => 'pdo_pgsql',
|
||||||
|
'SQLite' => 'pdo_sqlite',
|
||||||
|
];
|
||||||
|
const SUPPORTED_LANGUAGES = ['en', 'es'];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var InputInterface
|
||||||
|
*/
|
||||||
|
private $input;
|
||||||
|
/**
|
||||||
|
* @var OutputInterface
|
||||||
|
*/
|
||||||
|
private $output;
|
||||||
|
/**
|
||||||
|
* @var QuestionHelper
|
||||||
|
*/
|
||||||
|
private $questionHelper;
|
||||||
|
/**
|
||||||
|
* @var ProcessHelper
|
||||||
|
*/
|
||||||
|
private $processHelper;
|
||||||
|
/**
|
||||||
|
* @var WriterInterface
|
||||||
|
*/
|
||||||
|
private $configWriter;
|
||||||
|
|
||||||
|
public function __construct(WriterInterface $configWriter)
|
||||||
|
{
|
||||||
|
parent::__construct(null);
|
||||||
|
$this->configWriter = $configWriter;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function configure()
|
||||||
|
{
|
||||||
|
$this->setName('shlink:install')
|
||||||
|
->setDescription('Installs Shlink');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function execute(InputInterface $input, OutputInterface $output)
|
||||||
|
{
|
||||||
|
$this->input = $input;
|
||||||
|
$this->output = $output;
|
||||||
|
$this->questionHelper = $this->getHelper('question');
|
||||||
|
$this->processHelper = $this->getHelper('process');
|
||||||
|
$params = [];
|
||||||
|
|
||||||
|
$output->writeln([
|
||||||
|
'<info>Welcome to Shlink!!</info>',
|
||||||
|
'This process will guide you through the installation.',
|
||||||
|
]);
|
||||||
|
|
||||||
|
// Check if a cached config file exists and drop it if so
|
||||||
|
if (file_exists('data/cache/app_config.php')) {
|
||||||
|
$output->write('Deleting old cached config...');
|
||||||
|
if (unlink('data/cache/app_config.php')) {
|
||||||
|
$output->writeln(' <info>Success</info>');
|
||||||
|
} else {
|
||||||
|
$output->writeln(
|
||||||
|
' <error>Failed!</error> You will have to manually delete the data/cache/app_config.php file to get'
|
||||||
|
. ' new config applied.'
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ask for custom config params
|
||||||
|
$params['DATABASE'] = $this->askDatabase();
|
||||||
|
$params['URL_SHORTENER'] = $this->askUrlShortener();
|
||||||
|
$params['LANGUAGE'] = $this->askLanguage();
|
||||||
|
$params['APP'] = $this->askApplication();
|
||||||
|
|
||||||
|
// Generate config params files
|
||||||
|
$config = $this->buildAppConfig($params);
|
||||||
|
$this->configWriter->toFile('config/params/generated_config.php', $config, false);
|
||||||
|
$output->writeln(['<info>Custom configuration properly generated!</info>', '']);
|
||||||
|
|
||||||
|
// Generate database
|
||||||
|
$output->write('Initializing database...');
|
||||||
|
$this->processHelper->run($output, 'php vendor/bin/doctrine.php orm:schema-tool:create');
|
||||||
|
$output->writeln(' <info>Success!</info>');
|
||||||
|
|
||||||
|
// Generate proxies
|
||||||
|
$output->write('Generating proxies...');
|
||||||
|
$this->processHelper->run($output, 'php vendor/bin/doctrine.php orm:generate-proxies');
|
||||||
|
$output->writeln(' <info>Success!</info>');
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function askDatabase()
|
||||||
|
{
|
||||||
|
$params = [];
|
||||||
|
$this->printTitle('DATABASE');
|
||||||
|
|
||||||
|
// Select database type
|
||||||
|
$databases = array_keys(self::DATABASE_DRIVERS);
|
||||||
|
$dbType = $this->questionHelper->ask($this->input, $this->output, new ChoiceQuestion(
|
||||||
|
'<question>Select database type (defaults to ' . $databases[0] . '):</question>',
|
||||||
|
$databases,
|
||||||
|
0
|
||||||
|
));
|
||||||
|
$params['DRIVER'] = self::DATABASE_DRIVERS[$dbType];
|
||||||
|
|
||||||
|
// Ask for connection params if database is not SQLite
|
||||||
|
if ($params['DRIVER'] !== self::DATABASE_DRIVERS['SQLite']) {
|
||||||
|
$params['NAME'] = $this->ask('Database name', 'shlink');
|
||||||
|
$params['USER'] = $this->ask('Database username');
|
||||||
|
$params['PASSWORD'] = $this->ask('Database password');
|
||||||
|
}
|
||||||
|
|
||||||
|
return $params;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function askUrlShortener()
|
||||||
|
{
|
||||||
|
$this->printTitle('URL SHORTENER');
|
||||||
|
|
||||||
|
// Ask for URL shortener params
|
||||||
|
return [
|
||||||
|
'SCHEMA' => $this->questionHelper->ask($this->input, $this->output, new ChoiceQuestion(
|
||||||
|
'<question>Select schema for generated short URLs (defaults to http):</question>',
|
||||||
|
['http', 'https'],
|
||||||
|
0
|
||||||
|
)),
|
||||||
|
'HOSTNAME' => $this->ask('Hostname for generated URLs'),
|
||||||
|
'CHARS' => $this->ask(
|
||||||
|
'Character set for generated short codes (leave empty to autogenerate one)',
|
||||||
|
null,
|
||||||
|
true
|
||||||
|
) ?: str_shuffle(UrlShortener::DEFAULT_CHARS)
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function askLanguage()
|
||||||
|
{
|
||||||
|
$this->printTitle('LANGUAGE');
|
||||||
|
|
||||||
|
return [
|
||||||
|
'DEFAULT' => $this->questionHelper->ask($this->input, $this->output, new ChoiceQuestion(
|
||||||
|
'<question>Select default language for the application in general (defaults to '
|
||||||
|
. self::SUPPORTED_LANGUAGES[0] . '):</question>',
|
||||||
|
self::SUPPORTED_LANGUAGES,
|
||||||
|
0
|
||||||
|
)),
|
||||||
|
'CLI' => $this->questionHelper->ask($this->input, $this->output, new ChoiceQuestion(
|
||||||
|
'<question>Select default language for CLI executions (defaults to '
|
||||||
|
. self::SUPPORTED_LANGUAGES[0] . '):</question>',
|
||||||
|
self::SUPPORTED_LANGUAGES,
|
||||||
|
0
|
||||||
|
)),
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function askApplication()
|
||||||
|
{
|
||||||
|
$this->printTitle('APPLICATION');
|
||||||
|
|
||||||
|
return [
|
||||||
|
'SECRET' => $this->ask(
|
||||||
|
'Define a secret string that will be used to sign API tokens (leave empty to autogenerate one)',
|
||||||
|
null,
|
||||||
|
true
|
||||||
|
) ?: $this->generateRandomString(32),
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string $text
|
||||||
|
*/
|
||||||
|
protected function printTitle($text)
|
||||||
|
{
|
||||||
|
$text = trim($text);
|
||||||
|
$length = strlen($text) + 4;
|
||||||
|
$header = str_repeat('*', $length);
|
||||||
|
|
||||||
|
$this->output->writeln([
|
||||||
|
'',
|
||||||
|
'<info>' . $header . '</info>',
|
||||||
|
'<info>* ' . strtoupper($text) . ' *</info>',
|
||||||
|
'<info>' . $header . '</info>',
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string $text
|
||||||
|
* @param string|null $default
|
||||||
|
* @param bool $allowEmpty
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
protected function ask($text, $default = null, $allowEmpty = false)
|
||||||
|
{
|
||||||
|
if (isset($default)) {
|
||||||
|
$text .= ' (defaults to ' . $default . ')';
|
||||||
|
}
|
||||||
|
do {
|
||||||
|
$value = $this->questionHelper->ask($this->input, $this->output, new Question(
|
||||||
|
'<question>' . $text . ':</question> ',
|
||||||
|
$default
|
||||||
|
));
|
||||||
|
if (empty($value) && ! $allowEmpty) {
|
||||||
|
$this->output->writeln('<error>Value can\'t be empty</error>');
|
||||||
|
}
|
||||||
|
} while (empty($value) && empty($default) && ! $allowEmpty);
|
||||||
|
|
||||||
|
return $value;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param array $params
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
protected function buildAppConfig(array $params)
|
||||||
|
{
|
||||||
|
// Build simple config
|
||||||
|
$config = [
|
||||||
|
'app_options' => [
|
||||||
|
'secret_key' => $params['APP']['SECRET'],
|
||||||
|
],
|
||||||
|
'entity_manager' => [
|
||||||
|
'connection' => [
|
||||||
|
'driver' => $params['DATABASE']['DRIVER'],
|
||||||
|
],
|
||||||
|
],
|
||||||
|
'translator' => [
|
||||||
|
'locale' => $params['LANGUAGE']['DEFAULT'],
|
||||||
|
],
|
||||||
|
'cli' => [
|
||||||
|
'locale' => $params['LANGUAGE']['CLI'],
|
||||||
|
],
|
||||||
|
'url_shortener' => [
|
||||||
|
'domain' => [
|
||||||
|
'schema' => $params['URL_SHORTENER']['SCHEMA'],
|
||||||
|
'hostname' => $params['URL_SHORTENER']['HOSTNAME'],
|
||||||
|
],
|
||||||
|
'shortcode_chars' => $params['URL_SHORTENER']['CHARS'],
|
||||||
|
],
|
||||||
|
];
|
||||||
|
|
||||||
|
// Build dynamic database config
|
||||||
|
if ($params['DATABASE']['DRIVER'] === 'pdo_sqlite') {
|
||||||
|
$config['entity_manager']['connection']['path'] = 'data/database.sqlite';
|
||||||
|
} else {
|
||||||
|
$config['entity_manager']['connection']['user'] = $params['DATABASE']['USER'];
|
||||||
|
$config['entity_manager']['connection']['password'] = $params['DATABASE']['PASSWORD'];
|
||||||
|
$config['entity_manager']['connection']['dbname'] = $params['DATABASE']['NAME'];
|
||||||
|
}
|
||||||
|
|
||||||
|
return $config;
|
||||||
|
}
|
||||||
|
}
|
@ -3,7 +3,9 @@ namespace Shlinkio\Shlink\CLI\Factory;
|
|||||||
|
|
||||||
use Interop\Container\ContainerInterface;
|
use Interop\Container\ContainerInterface;
|
||||||
use Interop\Container\Exception\ContainerException;
|
use Interop\Container\Exception\ContainerException;
|
||||||
|
use Shlinkio\Shlink\Core\Options\AppOptions;
|
||||||
use Symfony\Component\Console\Application as CliApp;
|
use Symfony\Component\Console\Application as CliApp;
|
||||||
|
use Zend\I18n\Translator\Translator;
|
||||||
use Zend\ServiceManager\Exception\ServiceNotCreatedException;
|
use Zend\ServiceManager\Exception\ServiceNotCreatedException;
|
||||||
use Zend\ServiceManager\Exception\ServiceNotFoundException;
|
use Zend\ServiceManager\Exception\ServiceNotFoundException;
|
||||||
use Zend\ServiceManager\Factory\FactoryInterface;
|
use Zend\ServiceManager\Factory\FactoryInterface;
|
||||||
@ -25,9 +27,12 @@ class ApplicationFactory implements FactoryInterface
|
|||||||
public function __invoke(ContainerInterface $container, $requestedName, array $options = null)
|
public function __invoke(ContainerInterface $container, $requestedName, array $options = null)
|
||||||
{
|
{
|
||||||
$config = $container->get('config')['cli'];
|
$config = $container->get('config')['cli'];
|
||||||
$app = new CliApp('Shlink', '1.0.0');
|
$appOptions = $container->get(AppOptions::class);
|
||||||
|
$translator = $container->get(Translator::class);
|
||||||
|
$translator->setLocale($config['locale']);
|
||||||
|
|
||||||
$commands = isset($config['commands']) ? $config['commands'] : [];
|
$commands = isset($config['commands']) ? $config['commands'] : [];
|
||||||
|
$app = new CliApp($appOptions->getName(), $appOptions->getVersion());
|
||||||
foreach ($commands as $command) {
|
foreach ($commands as $command) {
|
||||||
if (! $container->has($command)) {
|
if (! $container->has($command)) {
|
||||||
continue;
|
continue;
|
||||||
|
101
module/CLI/test/Command/Install/InstallCommandTest.php
Normal file
101
module/CLI/test/Command/Install/InstallCommandTest.php
Normal file
@ -0,0 +1,101 @@
|
|||||||
|
<?php
|
||||||
|
namespace ShlinkioTest\Shlink\CLI\Command\Install;
|
||||||
|
|
||||||
|
use PHPUnit_Framework_TestCase as TestCase;
|
||||||
|
use Prophecy\Argument;
|
||||||
|
use Prophecy\Prophecy\ObjectProphecy;
|
||||||
|
use Shlinkio\Shlink\CLI\Command\Install\InstallCommand;
|
||||||
|
use Symfony\Component\Console\Application;
|
||||||
|
use Symfony\Component\Console\Helper\ProcessHelper;
|
||||||
|
use Symfony\Component\Console\Tester\CommandTester;
|
||||||
|
use Zend\Config\Writer\WriterInterface;
|
||||||
|
|
||||||
|
class InstallCommandTest extends TestCase
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @var CommandTester
|
||||||
|
*/
|
||||||
|
protected $commandTester;
|
||||||
|
/**
|
||||||
|
* @var ObjectProphecy
|
||||||
|
*/
|
||||||
|
protected $configWriter;
|
||||||
|
|
||||||
|
public function setUp()
|
||||||
|
{
|
||||||
|
$processHelper = $this->prophesize(ProcessHelper::class);
|
||||||
|
$processHelper->getName()->willReturn('process');
|
||||||
|
$processHelper->setHelperSet(Argument::any())->willReturn(null);
|
||||||
|
$processHelper->run(Argument::cetera())->willReturn(null);
|
||||||
|
|
||||||
|
$app = new Application();
|
||||||
|
$helperSet = $app->getHelperSet();
|
||||||
|
$helperSet->set($processHelper->reveal());
|
||||||
|
$app->setHelperSet($helperSet);
|
||||||
|
|
||||||
|
$this->configWriter = $this->prophesize(WriterInterface::class);
|
||||||
|
$command = new InstallCommand($this->configWriter->reveal());
|
||||||
|
$app->add($command);
|
||||||
|
|
||||||
|
$questionHelper = $command->getHelper('question');
|
||||||
|
$questionHelper->setInputStream($this->createInputStream());
|
||||||
|
$this->commandTester = new CommandTester($command);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function createInputStream()
|
||||||
|
{
|
||||||
|
$stream = fopen('php://memory', 'r+', false);
|
||||||
|
fputs($stream, <<<CLI_INPUT
|
||||||
|
|
||||||
|
shlink_db
|
||||||
|
alejandro
|
||||||
|
1234
|
||||||
|
0
|
||||||
|
doma.in
|
||||||
|
abc123BCA
|
||||||
|
|
||||||
|
1
|
||||||
|
my_secret
|
||||||
|
CLI_INPUT
|
||||||
|
);
|
||||||
|
rewind($stream);
|
||||||
|
|
||||||
|
return $stream;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @test
|
||||||
|
*/
|
||||||
|
public function testInputIsProperlyParsed()
|
||||||
|
{
|
||||||
|
$this->configWriter->toFile(Argument::any(), [
|
||||||
|
'app_options' => [
|
||||||
|
'secret_key' => 'my_secret',
|
||||||
|
],
|
||||||
|
'entity_manager' => [
|
||||||
|
'connection' => [
|
||||||
|
'driver' => 'pdo_mysql',
|
||||||
|
'dbname' => 'shlink_db',
|
||||||
|
'user' => 'alejandro',
|
||||||
|
'password' => '1234',
|
||||||
|
],
|
||||||
|
],
|
||||||
|
'translator' => [
|
||||||
|
'locale' => 'en',
|
||||||
|
],
|
||||||
|
'cli' => [
|
||||||
|
'locale' => 'es',
|
||||||
|
],
|
||||||
|
'url_shortener' => [
|
||||||
|
'domain' => [
|
||||||
|
'schema' => 'http',
|
||||||
|
'hostname' => 'doma.in',
|
||||||
|
],
|
||||||
|
'shortcode_chars' => 'abc123BCA',
|
||||||
|
],
|
||||||
|
], false)->shouldBeCalledTimes(1);
|
||||||
|
$this->commandTester->execute([
|
||||||
|
'command' => 'shlink:install',
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
}
|
@ -1,5 +1,5 @@
|
|||||||
<?php
|
<?php
|
||||||
namespace ShlinkioTest\Shlink\CLI\Command;
|
namespace ShlinkioTest\Shlink\CLI\Command\Shortcode;
|
||||||
|
|
||||||
use PHPUnit_Framework_TestCase as TestCase;
|
use PHPUnit_Framework_TestCase as TestCase;
|
||||||
use Prophecy\Argument;
|
use Prophecy\Argument;
|
@ -1,5 +1,5 @@
|
|||||||
<?php
|
<?php
|
||||||
namespace ShlinkioTest\Shlink\CLI\Command;
|
namespace ShlinkioTest\Shlink\CLI\Command\Shortcode;
|
||||||
|
|
||||||
use PHPUnit_Framework_TestCase as TestCase;
|
use PHPUnit_Framework_TestCase as TestCase;
|
||||||
use Prophecy\Argument;
|
use Prophecy\Argument;
|
@ -1,5 +1,5 @@
|
|||||||
<?php
|
<?php
|
||||||
namespace ShlinkioTest\Shlink\CLI\Command;
|
namespace ShlinkioTest\Shlink\CLI\Command\Shortcode;
|
||||||
|
|
||||||
use PHPUnit_Framework_TestCase as TestCase;
|
use PHPUnit_Framework_TestCase as TestCase;
|
||||||
use Prophecy\Argument;
|
use Prophecy\Argument;
|
@ -1,5 +1,5 @@
|
|||||||
<?php
|
<?php
|
||||||
namespace ShlinkioTest\Shlink\CLI\Command;
|
namespace ShlinkioTest\Shlink\CLI\Command\Shortcode;
|
||||||
|
|
||||||
use PHPUnit_Framework_TestCase as TestCase;
|
use PHPUnit_Framework_TestCase as TestCase;
|
||||||
use Prophecy\Prophecy\ObjectProphecy;
|
use Prophecy\Prophecy\ObjectProphecy;
|
@ -1,5 +1,5 @@
|
|||||||
<?php
|
<?php
|
||||||
namespace ShlinkioTest\Shlink\CLI\Command;
|
namespace ShlinkioTest\Shlink\CLI\Command\Visit;
|
||||||
|
|
||||||
use PHPUnit_Framework_TestCase as TestCase;
|
use PHPUnit_Framework_TestCase as TestCase;
|
||||||
use Prophecy\Argument;
|
use Prophecy\Argument;
|
@ -3,8 +3,10 @@ namespace ShlinkioTest\Shlink\CLI\Factory;
|
|||||||
|
|
||||||
use PHPUnit_Framework_TestCase as TestCase;
|
use PHPUnit_Framework_TestCase as TestCase;
|
||||||
use Shlinkio\Shlink\CLI\Factory\ApplicationFactory;
|
use Shlinkio\Shlink\CLI\Factory\ApplicationFactory;
|
||||||
|
use Shlinkio\Shlink\Core\Options\AppOptions;
|
||||||
use Symfony\Component\Console\Application;
|
use Symfony\Component\Console\Application;
|
||||||
use Symfony\Component\Console\Command\Command;
|
use Symfony\Component\Console\Command\Command;
|
||||||
|
use Zend\I18n\Translator\Translator;
|
||||||
use Zend\ServiceManager\ServiceManager;
|
use Zend\ServiceManager\ServiceManager;
|
||||||
|
|
||||||
class ApplicationFactoryTest extends TestCase
|
class ApplicationFactoryTest extends TestCase
|
||||||
@ -53,8 +55,10 @@ class ApplicationFactoryTest extends TestCase
|
|||||||
{
|
{
|
||||||
return new ServiceManager(['services' => [
|
return new ServiceManager(['services' => [
|
||||||
'config' => [
|
'config' => [
|
||||||
'cli' => $config,
|
'cli' => array_merge($config, ['locale' => 'en']),
|
||||||
],
|
],
|
||||||
|
AppOptions::class => new AppOptions(),
|
||||||
|
Translator::class => Translator::factory([]),
|
||||||
]]);
|
]]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,9 +0,0 @@
|
|||||||
<?php
|
|
||||||
return [
|
|
||||||
|
|
||||||
'rest' => [
|
|
||||||
'username' => env('REST_USER'),
|
|
||||||
'password' => env('REST_PASSWORD'),
|
|
||||||
],
|
|
||||||
|
|
||||||
];
|
|
@ -25,7 +25,6 @@ class ConfigProviderTest extends TestCase
|
|||||||
|
|
||||||
$this->assertArrayHasKey('error_handler', $config);
|
$this->assertArrayHasKey('error_handler', $config);
|
||||||
$this->assertArrayHasKey('middleware_pipeline', $config);
|
$this->assertArrayHasKey('middleware_pipeline', $config);
|
||||||
$this->assertArrayHasKey('rest', $config);
|
|
||||||
$this->assertArrayHasKey('routes', $config);
|
$this->assertArrayHasKey('routes', $config);
|
||||||
$this->assertArrayHasKey('dependencies', $config);
|
$this->assertArrayHasKey('dependencies', $config);
|
||||||
$this->assertArrayHasKey('translator', $config);
|
$this->assertArrayHasKey('translator', $config);
|
||||||
|
17
public/.htaccess
Normal file
17
public/.htaccess
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
RewriteEngine On
|
||||||
|
# The following rule tells Apache that if the requested filename
|
||||||
|
# exists, simply serve it.
|
||||||
|
RewriteCond %{REQUEST_FILENAME} -s [OR]
|
||||||
|
RewriteCond %{REQUEST_FILENAME} -l [OR]
|
||||||
|
RewriteCond %{REQUEST_FILENAME} -d
|
||||||
|
RewriteRule ^.*$ - [NC,L]
|
||||||
|
|
||||||
|
# The following rewrites all other queries to index.php. The
|
||||||
|
# condition ensures that if you are using Apache aliases to do
|
||||||
|
# mass virtual hosting, the base path will be prepended to
|
||||||
|
# allow proper resolution of the index.php file; it will work
|
||||||
|
# in non-aliased environments as well, providing a safe, one-size
|
||||||
|
# fits all solution.
|
||||||
|
RewriteCond %{REQUEST_URI}::$1 ^(/.+)(.+)::\2$
|
||||||
|
RewriteRule ^(.*) - [E=BASE:%1]
|
||||||
|
RewriteRule ^(.*)$ %{ENV:BASE}index.php [NC,L]
|
Loading…
Reference in New Issue
Block a user