2015-02-01 19:16:27 +00:00
< ? php
namespace Wallabag\CoreBundle\Command ;
use Symfony\Bundle\FrameworkBundle\Command\ContainerAwareCommand ;
use Symfony\Component\Console\Input\InputInterface ;
2015-02-22 13:35:36 +00:00
use Symfony\Component\Console\Input\InputOption ;
use Symfony\Component\Console\Input\ArrayInput ;
2015-02-01 19:16:27 +00:00
use Symfony\Component\Console\Output\OutputInterface ;
2015-02-22 13:35:36 +00:00
use Symfony\Component\Console\Output\NullOutput ;
2015-10-02 12:51:41 +00:00
use Wallabag\UserBundle\Entity\User ;
2015-02-16 20:28:49 +00:00
use Wallabag\CoreBundle\Entity\Config ;
2015-02-01 19:16:27 +00:00
class InstallCommand extends ContainerAwareCommand
{
2015-02-22 13:35:36 +00:00
/**
* @ var InputInterface
*/
protected $defaultInput ;
/**
* @ var OutputInterface
*/
protected $defaultOutput ;
2015-02-01 19:16:27 +00:00
protected function configure ()
{
$this
-> setName ( 'wallabag:install' )
-> setDescription ( 'Wallabag installer.' )
2015-02-22 13:35:36 +00:00
-> addOption (
'reset' ,
null ,
InputOption :: VALUE_NONE ,
'Reset current database'
)
2015-02-01 19:16:27 +00:00
;
}
protected function execute ( InputInterface $input , OutputInterface $output )
{
2015-02-22 13:35:36 +00:00
$this -> defaultInput = $input ;
$this -> defaultOutput = $output ;
$output -> writeln ( '<info>Installing Wallabag...</info>' );
2015-02-01 19:16:27 +00:00
$output -> writeln ( '' );
$this
2015-02-22 13:35:36 +00:00
-> checkRequirements ()
-> setupDatabase ()
-> setupAdmin ()
-> setupAsset ()
2015-02-01 19:16:27 +00:00
;
$output -> writeln ( '<info>Wallabag has been successfully installed.</info>' );
$output -> writeln ( '<comment>Just execute `php app/console server:run` for using wallabag: http://localhost:8000</comment>' );
}
2015-02-22 13:35:36 +00:00
protected function checkRequirements ()
2015-02-01 19:16:27 +00:00
{
2015-02-22 13:35:36 +00:00
$this -> defaultOutput -> writeln ( '<info><comment>Step 1 of 4.</comment> Checking system requirements.</info>' );
2015-02-01 19:16:27 +00:00
$fulfilled = true ;
// @TODO: find a better way to check requirements
2015-02-22 13:35:36 +00:00
$label = '<comment>PCRE</comment>' ;
2015-02-01 19:16:27 +00:00
if ( extension_loaded ( 'pcre' )) {
2015-02-22 13:35:36 +00:00
$status = '<info>OK!</info>' ;
$help = '' ;
2015-02-01 19:16:27 +00:00
} else {
$fulfilled = false ;
2015-02-22 13:35:36 +00:00
$status = '<error>ERROR!</error>' ;
$help = 'You should enabled PCRE extension' ;
2015-02-01 19:16:27 +00:00
}
2015-02-22 13:35:36 +00:00
$rows [] = array ( $label , $status , $help );
2015-02-01 19:16:27 +00:00
2015-02-22 13:35:36 +00:00
$label = '<comment>DOM</comment>' ;
2015-02-01 19:16:27 +00:00
if ( extension_loaded ( 'DOM' )) {
2015-02-22 13:35:36 +00:00
$status = '<info>OK!</info>' ;
$help = '' ;
2015-02-01 19:16:27 +00:00
} else {
$fulfilled = false ;
2015-02-22 13:35:36 +00:00
$status = '<error>ERROR!</error>' ;
$help = 'You should enabled DOM extension' ;
2015-02-01 19:16:27 +00:00
}
2015-02-22 13:35:36 +00:00
$rows [] = array ( $label , $status , $help );
$this -> getHelper ( 'table' )
-> setHeaders ( array ( 'Checked' , 'Status' , 'Recommendation' ))
-> setRows ( $rows )
-> render ( $this -> defaultOutput );
2015-02-01 19:16:27 +00:00
if ( ! $fulfilled ) {
2015-02-22 13:35:36 +00:00
throw new \RuntimeException ( 'Some system requirements are not fulfilled. Please check output messages and fix them.' );
} else {
$this -> defaultOutput -> writeln ( '<info>Success! Your system can run Wallabag properly.</info>' );
2015-02-01 19:16:27 +00:00
}
2015-02-22 13:35:36 +00:00
$this -> defaultOutput -> writeln ( '' );
2015-02-01 19:16:27 +00:00
return $this ;
}
2015-02-22 13:35:36 +00:00
protected function setupDatabase ()
2015-02-01 19:16:27 +00:00
{
2015-02-22 13:35:36 +00:00
$this -> defaultOutput -> writeln ( '<info><comment>Step 2 of 4.</comment> Setting up database.</info>' );
2015-02-01 19:16:27 +00:00
2015-02-22 13:35:36 +00:00
// user want to reset everything? Don't care about what is already here
if ( true === $this -> defaultInput -> getOption ( 'reset' )) {
$this -> defaultOutput -> writeln ( 'Droping database, creating database and schema' );
2015-02-01 19:16:27 +00:00
2015-02-22 13:35:36 +00:00
$this
-> runCommand ( 'doctrine:database:drop' , array ( '--force' => true ))
-> runCommand ( 'doctrine:database:create' )
-> runCommand ( 'doctrine:schema:create' )
;
2015-02-01 19:16:27 +00:00
2015-02-22 13:35:36 +00:00
return $this ;
}
2015-02-01 19:16:27 +00:00
2015-02-22 13:35:36 +00:00
if ( ! $this -> isDatabasePresent ()) {
$this -> defaultOutput -> writeln ( 'Creating database and schema, clearing the cache' );
2015-02-01 19:16:27 +00:00
2015-02-22 13:35:36 +00:00
$this
-> runCommand ( 'doctrine:database:create' )
-> runCommand ( 'doctrine:schema:create' )
-> runCommand ( 'cache:clear' )
;
2015-02-01 19:16:27 +00:00
2015-02-22 13:35:36 +00:00
return $this ;
}
2015-02-01 19:16:27 +00:00
2015-02-22 13:35:36 +00:00
$dialog = $this -> getHelper ( 'dialog' );
2015-02-01 19:16:27 +00:00
2015-02-22 13:35:36 +00:00
if ( $dialog -> askConfirmation ( $this -> defaultOutput , '<question>It appears that your database already exists. Would you like to reset it? (y/N)</question> ' , false )) {
$this -> defaultOutput -> writeln ( 'Droping database, creating database and schema' );
2015-02-01 19:16:27 +00:00
2015-02-22 13:35:36 +00:00
$this
-> runCommand ( 'doctrine:database:drop' , array ( '--force' => true ))
-> runCommand ( 'doctrine:database:create' )
-> runCommand ( 'doctrine:schema:create' )
;
} elseif ( $this -> isSchemaPresent ()) {
if ( $dialog -> askConfirmation ( $this -> defaultOutput , '<question>Seems like your database contains schema. Do you want to reset it? (y/N)</question> ' , false )) {
$this -> defaultOutput -> writeln ( 'Droping schema and creating schema' );
2015-02-01 19:16:27 +00:00
2015-02-22 13:35:36 +00:00
$this
-> runCommand ( 'doctrine:schema:drop' , array ( '--force' => true ))
-> runCommand ( 'doctrine:schema:create' )
;
}
2015-02-01 19:16:27 +00:00
} else {
2015-02-22 13:35:36 +00:00
$this -> defaultOutput -> writeln ( 'Creating schema' );
$this
-> runCommand ( 'doctrine:schema:create' )
;
2015-02-01 19:16:27 +00:00
}
2015-02-22 13:35:36 +00:00
$this -> defaultOutput -> writeln ( 'Clearing the cache' );
$this -> runCommand ( 'cache:clear' );
/*
if ( $this -> getHelperSet () -> get ( 'dialog' ) -> askConfirmation ( $this -> defaultOutput , '<question>Load fixtures (Y/N)?</question>' , false )) {
$doctrineConfig = $this -> getContainer () -> get ( 'doctrine.orm.entity_manager' ) -> getConnection () -> getConfiguration ();
$logger = $doctrineConfig -> getSQLLogger ();
// speed up fixture load
$doctrineConfig -> setSQLLogger ( null );
$this -> runCommand ( 'doctrine:fixtures:load' );
$doctrineConfig -> setSQLLogger ( $logger );
}
*/
2015-02-01 19:16:27 +00:00
2015-02-22 13:35:36 +00:00
$this -> defaultOutput -> writeln ( '' );
return $this ;
2015-02-01 19:16:27 +00:00
}
2015-02-22 13:35:36 +00:00
protected function setupAdmin ()
2015-02-01 19:16:27 +00:00
{
2015-02-22 13:35:36 +00:00
$this -> defaultOutput -> writeln ( '<info><comment>Step 3 of 4.</comment> Administration setup.</info>' );
2015-02-01 19:16:27 +00:00
$dialog = $this -> getHelperSet () -> get ( 'dialog' );
2015-02-22 13:35:36 +00:00
if ( false === $dialog -> askConfirmation ( $this -> defaultOutput , '<question>Would you like to create a new user ? (y/N)</question>' , true )) {
return $this ;
}
2015-02-01 19:16:27 +00:00
$em = $this -> getContainer () -> get ( 'doctrine.orm.entity_manager' );
2015-10-05 20:16:18 +00:00
$userManager = $this -> getContainer () -> get ( 'fos_user.user_manager' );
$user = $userManager -> createUser ();
2015-02-22 13:35:36 +00:00
$user -> setUsername ( $dialog -> ask ( $this -> defaultOutput , '<question>Username</question> <comment>(default: wallabag)</comment> :' , 'wallabag' ));
2015-10-05 20:16:18 +00:00
$user -> setPlainPassword ( $dialog -> ask ( $this -> defaultOutput , '<question>Password</question> <comment>(default: wallabag)</comment> :' , 'wallabag' ));
2015-02-22 13:35:36 +00:00
$user -> setEmail ( $dialog -> ask ( $this -> defaultOutput , '<question>Email:</question>' , '' ));
2015-08-18 09:08:45 +00:00
$user -> setEnabled ( true );
2015-02-01 19:16:27 +00:00
$em -> persist ( $user );
2015-02-22 09:50:27 +00:00
$config = new Config ( $user );
$config -> setTheme ( $this -> getContainer () -> getParameter ( 'theme' ));
$config -> setItemsPerPage ( $this -> getContainer () -> getParameter ( 'items_on_page' ));
2015-03-28 13:27:45 +00:00
$config -> setRssLimit ( $this -> getContainer () -> getParameter ( 'rss_limit' ));
2015-02-22 09:50:27 +00:00
$config -> setLanguage ( $this -> getContainer () -> getParameter ( 'language' ));
2015-02-01 19:16:27 +00:00
2015-02-16 20:28:49 +00:00
$em -> persist ( $config );
2015-02-22 13:35:36 +00:00
$em -> flush ();
$this -> defaultOutput -> writeln ( '' );
return $this ;
2015-02-01 19:16:27 +00:00
}
2015-02-22 13:35:36 +00:00
protected function setupAsset ()
2015-02-01 19:16:27 +00:00
{
2015-02-22 13:35:36 +00:00
$this -> defaultOutput -> writeln ( '<info><comment>Step 4 of 4.</comment> Installing assets.</info>' );
2015-02-01 19:16:27 +00:00
$this
2015-02-22 13:35:36 +00:00
-> runCommand ( 'assets:install' )
-> runCommand ( 'assetic:dump' )
2015-02-01 19:16:27 +00:00
;
2015-02-22 13:35:36 +00:00
$this -> defaultOutput -> writeln ( '' );
return $this ;
}
/**
2015-05-30 11:52:26 +00:00
* Run a command .
2015-02-22 13:35:36 +00:00
*
* @ param string $command
* @ param array $parameters Parameters to this command ( usually 'force' => true )
*/
protected function runCommand ( $command , $parameters = array ())
{
$parameters = array_merge (
array ( 'command' => $command ),
$parameters ,
array (
'--no-debug' => true ,
'--env' => $this -> defaultInput -> getOption ( 'env' ) ? : 'dev' ,
)
);
if ( $this -> defaultInput -> getOption ( 'no-interaction' )) {
$parameters = array_merge ( $parameters , array ( '--no-interaction' => true ));
}
$this -> getApplication () -> setAutoExit ( false );
$exitCode = $this -> getApplication () -> run ( new ArrayInput ( $parameters ), new NullOutput ());
if ( 0 !== $exitCode ) {
$this -> getApplication () -> setAutoExit ( true );
$errorMessage = sprintf ( 'The command "%s" terminated with an error code: %u.' , $command , $exitCode );
$this -> defaultOutput -> writeln ( " <error> $errorMessage </error> " );
$exception = new \Exception ( $errorMessage , $exitCode );
throw $exception ;
}
// PDO does not always close the connection after Doctrine commands.
// See https://github.com/symfony/symfony/issues/11750.
$this -> getContainer () -> get ( 'doctrine' ) -> getManager () -> getConnection () -> close ();
2015-02-01 19:16:27 +00:00
return $this ;
}
2015-02-22 13:35:36 +00:00
/**
2015-05-30 11:52:26 +00:00
* Check if the database already exists .
2015-02-22 13:35:36 +00:00
*
2015-05-30 11:52:26 +00:00
* @ return bool
2015-02-22 13:35:36 +00:00
*/
private function isDatabasePresent ()
{
2015-09-11 14:13:59 +00:00
$connection = $this -> getContainer () -> get ( 'doctrine' ) -> getManager () -> getConnection ();
$databaseName = $connection -> getDatabase ();
2015-02-22 13:35:36 +00:00
try {
2015-09-11 14:13:59 +00:00
$schemaManager = $connection -> getSchemaManager ();
2015-02-22 13:35:36 +00:00
} catch ( \Exception $exception ) {
if ( false !== strpos ( $exception -> getMessage (), sprintf ( " Unknown database '%s' " , $databaseName ))) {
return false ;
}
throw $exception ;
}
2015-02-22 16:18:54 +00:00
// custom verification for sqlite, since `getListDatabasesSQL` doesn't work for sqlite
if ( 'sqlite' == $schemaManager -> getDatabasePlatform () -> getName ()) {
$params = $this -> getContainer () -> get ( 'doctrine.dbal.default_connection' ) -> getParams ();
if ( isset ( $params [ 'path' ]) && file_exists ( $params [ 'path' ])) {
return true ;
}
return false ;
}
2015-02-22 13:35:36 +00:00
return in_array ( $databaseName , $schemaManager -> listDatabases ());
}
/**
2015-03-28 10:29:19 +00:00
* Check if the schema is already created .
2015-05-30 11:52:26 +00:00
* If we found at least oen table , it means the schema exists .
2015-02-22 13:35:36 +00:00
*
2015-05-30 11:52:26 +00:00
* @ return bool
2015-02-22 13:35:36 +00:00
*/
private function isSchemaPresent ()
{
$schemaManager = $this -> getContainer () -> get ( 'doctrine' ) -> getManager () -> getConnection () -> getSchemaManager ();
2015-03-28 10:29:19 +00:00
return count ( $schemaManager -> listTableNames ()) > 0 ? true : false ;
2015-02-22 13:35:36 +00:00
}
2015-02-01 19:16:27 +00:00
}