2010-02-17 13:55:05 +00:00
< ? php
2011-01-15 13:29:43 +00:00
/*
* This file is part of the Symfony package .
*
2011-03-06 11:40:06 +00:00
* ( c ) Fabien Potencier < fabien @ symfony . com >
2011-01-15 13:29:43 +00:00
*
* For the full copyright and license information , please view the LICENSE
* file that was distributed with this source code .
*/
2010-07-09 09:05:26 +01:00
namespace Symfony\Bundle\FrameworkBundle\Command ;
2010-02-17 13:55:05 +00:00
2010-08-20 22:09:55 +01:00
use Symfony\Component\Console\Input\InputArgument ;
use Symfony\Component\Console\Input\InputOption ;
use Symfony\Component\Console\Input\InputInterface ;
use Symfony\Component\Console\Output\OutputInterface ;
2014-07-05 12:15:16 +01:00
use Symfony\Component\Filesystem\Exception\IOException ;
2011-08-25 12:31:27 +01:00
use Symfony\Component\Finder\Finder ;
2010-02-17 13:55:05 +00:00
/**
2011-04-09 15:13:24 +01:00
* Command that places bundle web assets into a given directory .
2010-02-17 13:55:05 +00:00
*
2011-03-06 11:40:06 +00:00
* @ author Fabien Potencier < fabien @ symfony . com >
2010-02-17 13:55:05 +00:00
*/
2011-06-20 20:04:55 +01:00
class AssetsInstallCommand extends ContainerAwareCommand
2010-02-17 13:55:05 +00:00
{
2010-05-06 12:25:53 +01:00
/**
2013-03-07 13:36:36 +00:00
* { @ inheritdoc }
2010-05-06 12:25:53 +01:00
*/
protected function configure ()
2010-02-17 13:55:05 +00:00
{
2010-05-06 12:25:53 +01:00
$this
2012-02-12 15:37:55 +00:00
-> setName ( 'assets:install' )
2010-05-06 12:25:53 +01:00
-> setDefinition ( array (
2012-07-27 16:49:52 +01:00
new InputArgument ( 'target' , InputArgument :: OPTIONAL , 'The target directory' , 'web' ),
2010-05-06 12:25:53 +01:00
))
2010-11-27 16:56:55 +00:00
-> addOption ( 'symlink' , null , InputOption :: VALUE_NONE , 'Symlinks the assets instead of copying it' )
2011-09-28 16:38:41 +01:00
-> addOption ( 'relative' , null , InputOption :: VALUE_NONE , 'Make relative symlinks' )
2012-01-09 09:01:34 +00:00
-> setDescription ( 'Installs bundles web assets under a public web directory' )
2015-12-21 11:01:57 +00:00
-> setHelp ( <<< 'EOT'
2012-02-12 15:37:55 +00:00
The < info >% command . name %</ info > command installs bundle assets into a given
2015-01-04 09:47:47 +00:00
directory ( e . g . the < comment > web </ comment > directory ) .
2011-04-09 15:13:24 +01:00
2015-01-04 09:47:47 +00:00
< info > php % command . full_name % web </ info >
2011-04-09 15:13:24 +01:00
2015-01-04 09:47:47 +00:00
A " bundles " directory will be created inside the target directory and the
2011-04-09 15:13:24 +01:00
" Resources/public " directory of each bundle will be copied into it .
To create a symlink to each bundle instead of copying its assets , use the
2014-07-05 12:15:16 +01:00
< info >-- symlink </ info > option ( will fall back to hard copies when symbolic links aren ' t possible :
2011-09-28 16:38:41 +01:00
2015-01-04 09:47:47 +00:00
< info > php % command . full_name % web -- symlink </ info >
2011-09-28 16:38:41 +01:00
To make symlink relative , add the < info >-- relative </ info > option :
2015-01-04 09:47:47 +00:00
< info > php % command . full_name % web -- symlink -- relative </ info >
2011-04-09 15:13:24 +01:00
EOT
)
2010-05-06 12:25:53 +01:00
;
2010-02-17 13:55:05 +00:00
}
2010-05-06 12:25:53 +01:00
/**
2013-03-07 13:36:36 +00:00
* { @ inheritdoc }
2010-05-06 12:25:53 +01:00
*
2013-03-07 13:36:36 +00:00
* @ throws \InvalidArgumentException When the target directory does not exist or symlink cannot be used
2010-05-06 12:25:53 +01:00
*/
protected function execute ( InputInterface $input , OutputInterface $output )
2010-02-17 13:55:05 +00:00
{
2011-09-05 14:17:10 +01:00
$targetArg = rtrim ( $input -> getArgument ( 'target' ), '/' );
if ( ! is_dir ( $targetArg )) {
2010-05-06 12:25:53 +01:00
throw new \InvalidArgumentException ( sprintf ( 'The target directory "%s" does not exist.' , $input -> getArgument ( 'target' )));
}
2011-05-09 11:11:54 +01:00
2011-06-20 20:04:55 +01:00
$filesystem = $this -> getContainer () -> get ( 'filesystem' );
2010-05-06 12:25:53 +01:00
2010-12-03 19:00:11 +00:00
// Create the bundles directory otherwise symlink will fail.
2013-05-01 07:39:32 +01:00
$bundlesDir = $targetArg . '/bundles/' ;
$filesystem -> mkdir ( $bundlesDir , 0777 );
2010-12-03 19:00:11 +00:00
2014-10-04 07:27:12 +01:00
// relative implies symlink
$symlink = $input -> getOption ( 'symlink' ) || $input -> getOption ( 'relative' );
if ( $symlink ) {
$output -> writeln ( 'Trying to install assets as <comment>symbolic links</comment>.' );
2014-07-05 12:15:16 +01:00
} else {
2014-10-04 07:27:12 +01:00
$output -> writeln ( 'Installing assets as <comment>hard copies</comment>.' );
2014-07-05 12:15:16 +01:00
}
2012-03-16 11:37:18 +00:00
2017-06-15 13:05:42 +01:00
$validAssetDirs = array ();
2011-06-20 20:04:55 +01:00
foreach ( $this -> getContainer () -> get ( 'kernel' ) -> getBundles () as $bundle ) {
2010-05-19 09:24:36 +01:00
if ( is_dir ( $originDir = $bundle -> getPath () . '/Resources/public' )) {
2014-10-22 19:27:13 +01:00
$targetDir = $bundlesDir . preg_replace ( '/bundle$/' , '' , strtolower ( $bundle -> getName ()));
2010-02-17 13:55:05 +00:00
2011-04-09 15:13:24 +01:00
$output -> writeln ( sprintf ( 'Installing assets for <comment>%s</comment> into <comment>%s</comment>' , $bundle -> getNamespace (), $targetDir ));
2010-05-06 12:25:53 +01:00
$filesystem -> remove ( $targetDir );
2010-10-07 20:26:30 +01:00
2014-10-04 07:27:12 +01:00
if ( $symlink ) {
2011-09-28 16:38:41 +01:00
if ( $input -> getOption ( 'relative' )) {
$relativeOriginDir = $filesystem -> makePathRelative ( $originDir , realpath ( $bundlesDir ));
} else {
$relativeOriginDir = $originDir ;
}
2014-07-05 12:15:16 +01:00
try {
$filesystem -> symlink ( $relativeOriginDir , $targetDir );
2014-12-25 08:15:16 +00:00
if ( ! file_exists ( $targetDir )) {
throw new IOException ( 'Symbolic link is broken' );
}
2014-07-05 12:15:16 +01:00
$output -> writeln ( 'The assets were installed using symbolic links.' );
} catch ( IOException $e ) {
2014-10-04 07:27:12 +01:00
if ( ! $input -> getOption ( 'relative' )) {
$this -> hardCopy ( $originDir , $targetDir );
$output -> writeln ( 'It looks like your system doesn\'t support symbolic links, so the assets were installed by copying them.' );
}
// try again without the relative option
try {
$filesystem -> symlink ( $originDir , $targetDir );
2014-12-25 08:15:16 +00:00
if ( ! file_exists ( $targetDir )) {
throw new IOException ( 'Symbolic link is broken' );
}
2014-10-04 07:27:12 +01:00
$output -> writeln ( 'It looks like your system doesn\'t support relative symbolic links, so the assets were installed by using absolute symbolic links.' );
} catch ( IOException $e ) {
$this -> hardCopy ( $originDir , $targetDir );
$output -> writeln ( 'It looks like your system doesn\'t support symbolic links, so the assets were installed by copying them.' );
}
2014-07-05 12:15:16 +01:00
}
2010-10-07 20:26:30 +01:00
} else {
2014-07-05 12:15:16 +01:00
$this -> hardCopy ( $originDir , $targetDir );
2010-10-07 20:26:30 +01:00
}
2017-06-15 13:05:42 +01:00
$validAssetDirs [] = $targetDir ;
}
}
// remove the assets of the bundles that no longer exist
foreach ( new \FilesystemIterator ( $bundlesDir ) as $dir ) {
if ( ! in_array ( $dir , $validAssetDirs )) {
$filesystem -> remove ( $dir );
2010-05-06 12:25:53 +01:00
}
}
2010-02-17 13:55:05 +00:00
}
2014-07-05 12:15:16 +01:00
/**
* @ param string $originDir
* @ param string $targetDir
*/
private function hardCopy ( $originDir , $targetDir )
{
$filesystem = $this -> getContainer () -> get ( 'filesystem' );
$filesystem -> mkdir ( $targetDir , 0777 );
// We use a custom iterator to ignore VCS files
$filesystem -> mirror ( $originDir , $targetDir , Finder :: create () -> ignoreDotFiles ( false ) -> in ( $originDir ));
}
2010-02-17 13:55:05 +00:00
}