diff --git a/.travis.yml b/.travis.yml index 98e27bedb1..15163dfa71 100644 --- a/.travis.yml +++ b/.travis.yml @@ -16,9 +16,7 @@ before_script: - sh -c 'if [ $(php -r "echo PHP_MINOR_VERSION;") -le 4 ]; then pecl install redis; fi;' - echo 'extension="memcache.so"' > ~/.phpenv/versions/$(phpenv version-name)/etc/conf.d/memcache.ini - echo 'extension="memcached.so"' > ~/.phpenv/versions/$(phpenv version-name)/etc/conf.d/memcached.ini - - bower install - - composer self-update - - composer install --dev --prefer-source + - bin/developer dependencies:all --prefer-source - wget http://sphinxsearch.com/files/sphinx-2.0.6-release.tar.gz - tar xzf sphinx-2.0.6-release.tar.gz - sh -c "cd sphinx-2.0.6-release && wget http://snowball.tartarus.org/dist/libstemmer_c.tgz && tar xzf libstemmer_c.tgz && ./configure --with-libstemmer --with-iconv --with-mysql --enable-id64 --quiet && make -j --quiet && sudo make install" diff --git a/bin/developer b/bin/developer index 496de563be..f52158113e 100755 --- a/bin/developer +++ b/bin/developer @@ -10,13 +10,16 @@ */ use Alchemy\Phrasea\CLI; +use Alchemy\Phrasea\Core\Version; use Alchemy\Phrasea\Command\Developer\APIRoutesDumper; use Alchemy\Phrasea\Command\Developer\Behat; -use Alchemy\Phrasea\Command\Developer\JavascriptBuilder; +use Alchemy\Phrasea\Command\Developer\BowerInstall; +use Alchemy\Phrasea\Command\Developer\ComposerInstall; use Alchemy\Phrasea\Command\Developer\LessCompiler; +use Alchemy\Phrasea\Command\Developer\InstallAll; +use Alchemy\Phrasea\Command\Developer\JavascriptBuilder; use Alchemy\Phrasea\Command\Developer\RegenerateSqliteDb; use Alchemy\Phrasea\Command\Developer\RoutesDumper; -use Alchemy\Phrasea\Core\Version; use Doctrine\DBAL\Tools\Console\Helper\ConnectionHelper; use Doctrine\ORM\Tools\Console\Helper\EntityManagerHelper; @@ -64,6 +67,9 @@ try { $helperSet->set($helper, $name); } + $cli->command(new InstallAll()); + $cli->command(new BowerInstall()); + $cli->command(new ComposerInstall()); $cli->command(new RegenerateSqliteDb()); $cli->command(new APIRoutesDumper()); $cli->command(new RoutesDumper()); diff --git a/lib/Alchemy/Phrasea/Application.php b/lib/Alchemy/Phrasea/Application.php index e3c8a9fc0d..922431cbf0 100644 --- a/lib/Alchemy/Phrasea/Application.php +++ b/lib/Alchemy/Phrasea/Application.php @@ -95,7 +95,6 @@ use Alchemy\Phrasea\Core\Provider\NotificationDelivererServiceProvider; use Alchemy\Phrasea\Core\Provider\ORMServiceProvider; use Alchemy\Phrasea\Core\Provider\PhraseanetServiceProvider; use Alchemy\Phrasea\Core\Provider\PhraseaVersionServiceProvider; -use Alchemy\Phrasea\Core\Provider\PluginServiceProvider; use Alchemy\Phrasea\Core\Provider\RegistrationServiceProvider; use Alchemy\Phrasea\Core\Provider\SearchEngineServiceProvider; use Alchemy\Phrasea\Core\Provider\TaskManagerServiceProvider; @@ -254,7 +253,6 @@ class Application extends SilexApplication $this->register(new InstallerServiceProvider()); $this->register(new PhraseanetServiceProvider()); $this->register(new PhraseaVersionServiceProvider()); - $this->register(new PluginServiceProvider()); $this->register(new PHPExiftoolServiceProvider()); $this->register(new ReCaptchaServiceProvider()); $this->register(new LessCompilerServiceProvider()); @@ -413,6 +411,10 @@ class Application extends SilexApplication $guesser->register(new AudioMimeTypeGuesser()); $guesser->register(new VideoMimeTypeGuesser()); + $app['plugins.directory'] = $app->share(function () { + return realpath(__DIR__ . '/../../../plugins'); + }); + call_user_func(function ($app) { require $app['plugins.directory'] . '/services.php'; }, $this); @@ -517,7 +519,6 @@ class Application extends SilexApplication $event->getResponse()->setCharset('UTF-8'); } - private function setupUrlGenerator() { $this['url_generator'] = $this->share($this->extend('url_generator', function($urlGenerator, $app) { diff --git a/lib/Alchemy/Phrasea/CLI.php b/lib/Alchemy/Phrasea/CLI.php index 821c08caf3..f986c12ab1 100644 --- a/lib/Alchemy/Phrasea/CLI.php +++ b/lib/Alchemy/Phrasea/CLI.php @@ -13,6 +13,8 @@ namespace Alchemy\Phrasea; use Alchemy\Phrasea\Command\CommandInterface; use Symfony\Component\Console; +use Alchemy\Phrasea\Core\CLIProvider\PluginServiceProvider; +use Alchemy\Phrasea\Core\CLIProvider\ComposerSetupServiceProvider; /** * Phraseanet Command Line Application @@ -46,6 +48,9 @@ class CLI extends Application $app['swiftmailer.spooltransport']->getSpool()->flushQueue($app['swiftmailer.transport']); }); + $this->register(new PluginServiceProvider()); + $this->register(new ComposerSetupServiceProvider()); + $this->bindRoutes(); } diff --git a/lib/Alchemy/Phrasea/Command/AbstractCheckCommand.php b/lib/Alchemy/Phrasea/Command/AbstractCheckCommand.php index 0b21b7b48a..7a8b1fae33 100644 --- a/lib/Alchemy/Phrasea/Command/AbstractCheckCommand.php +++ b/lib/Alchemy/Phrasea/Command/AbstractCheckCommand.php @@ -28,7 +28,7 @@ abstract class AbstractCheckCommand extends Command { $ret = static::CHECK_OK; - foreach($this->provideRequirements() as $collection) { + foreach ($this->provideRequirements() as $collection) { $output->writeln(''); $output->writeln($collection->getName() . ' requirements : '); diff --git a/lib/Alchemy/Phrasea/Command/BuildMissingSubdefs.php b/lib/Alchemy/Phrasea/Command/BuildMissingSubdefs.php index 23c1245d24..a0b2dc73ee 100644 --- a/lib/Alchemy/Phrasea/Command/BuildMissingSubdefs.php +++ b/lib/Alchemy/Phrasea/Command/BuildMissingSubdefs.php @@ -11,7 +11,6 @@ namespace Alchemy\Phrasea\Command; -use Monolog\Handler\StreamHandler; use Alchemy\Phrasea\Command\Command; use Symfony\Component\HttpFoundation\File\Exception\FileNotFoundException; use Symfony\Component\Console\Input\InputInterface; diff --git a/lib/Alchemy/Phrasea/Command/Developer/BowerInstall.php b/lib/Alchemy/Phrasea/Command/Developer/BowerInstall.php new file mode 100644 index 0000000000..7a72501091 --- /dev/null +++ b/lib/Alchemy/Phrasea/Command/Developer/BowerInstall.php @@ -0,0 +1,82 @@ +setDescription('Install bower dependencies') + ->addOption('no-dev', 'd', InputOption::VALUE_NONE, 'Do not install dev dependencies') + ->addOption('attempts', 'a', InputOption::VALUE_REQUIRED, 'Number of attempts to install dependencies.', 4); + } + + protected function doExecute(InputInterface $input, OutputInterface $output) + { + $bower = $this->container['driver.bower']; + $output->writeln("Using ".$bower->getProcessBuilderFactory()->getBinary()." for driver"); + + $version = trim($bower->command('-v')); + + if (!version_compare('1.0.0-alpha.1', $version, '<=')) { + throw new RuntimeException(sprintf( + 'Bower version 1.0.0-alpha.1 is required (version %s provided), please install bower-canary : `npm install -g bower-canary`', $version + )); + } + + $attempts = $input->getOption('attempts'); + + if (0 >= $attempts) { + throw new InvalidArgumentException('Attempts number should be a positive value.'); + } + + $output->write("Cleaning bower cache... "); + $bower->command(array('cache', 'clean')); + $output->writeln("OK"); + + $output->write("Removing assets... "); + $this->container['filesystem']->remove($this->container['root.path'] . '/www/assets'); + $output->writeln("OK"); + + $success = false; + $n = 1; + while ($attempts > 0) { + try { + $output->write("\rInstalling assets (attempt #$n)..."); + $bower->command($input->getOption('no-dev') ? array('install', '--production') : 'install'); + $success = true; + $output->writeln("OK"); + break; + } catch (ExecutionFailureException $e) { + $attempts--; + $n++; + } + } + + if (!$success) { + throw new RuntimeException('Unable to install bower dependencies'); + } + + return 0; + } +} diff --git a/lib/Alchemy/Phrasea/Command/Developer/ComposerInstall.php b/lib/Alchemy/Phrasea/Command/Developer/ComposerInstall.php new file mode 100644 index 0000000000..ff694e45d2 --- /dev/null +++ b/lib/Alchemy/Phrasea/Command/Developer/ComposerInstall.php @@ -0,0 +1,62 @@ +setDescription('Install composer dependencies') + ->addOption('no-dev', 'd', InputOption::VALUE_NONE, 'Do not install dev dependencies') + ->addOption('prefer-source', 'p', InputOption::VALUE_NONE, 'Use the --prefer-source composer option'); + } + + protected function doExecute(InputInterface $input, OutputInterface $output) + { + $composer = $this->container['driver.composer']; + + $output->write("Updating composer... "); + $composer->command('self-update'); + $output->writeln("OK"); + + $commands = array('install', '--optimize-autoloader'); + if ($input->getOption('prefer-source')) { + $commands[] = '--prefer-source'; + } + + try { + if ($input->getOption('no-dev')) { + $output->write("Installing dependencies without developer packages "); + $composer->command(array_merge($commands, array('--no-dev'))); + $output->writeln("OK"); + } else { + $output->write("Installing dependencies with developer packages "); + $composer->command(array_merge($commands, array('--dev'))); + $output->writeln("OK"); + } + } catch (ExecutionFailureException $e) { + throw new RuntimeException('Unable to install bower dependencies', $e->getCode(), $e); + } + + return 0; + } +} diff --git a/lib/Alchemy/Phrasea/Command/Developer/InstallAll.php b/lib/Alchemy/Phrasea/Command/Developer/InstallAll.php new file mode 100644 index 0000000000..458f4959aa --- /dev/null +++ b/lib/Alchemy/Phrasea/Command/Developer/InstallAll.php @@ -0,0 +1,43 @@ +setDescription('Install all dependencies') + ->addOption('no-dev', 'd', InputOption::VALUE_NONE, 'Do not install dev dependencies') + ->addOption('prefer-source', 'p', InputOption::VALUE_NONE, 'Use the --prefer-source composer option') + ->addOption('attempts', 'a', InputOption::VALUE_REQUIRED, 'Number of attempts to install bower dependencies.', 4); + } + + protected function doExecute(InputInterface $input, OutputInterface $output) + { + $ret = 0; + + $ret += $this->container['console']->get('dependencies:bower')->execute($input, $output); + $ret += $this->container['console']->get('dependencies:composer')->execute($input, $output); + $ret += $this->container['console']->get('assets:build-javascript')->execute($input, $output); + $ret += $this->container['console']->get('assets:compile-less')->execute($input, $output); + + return min($ret, 255); + } +} diff --git a/lib/Alchemy/Phrasea/Command/Developer/JavascriptBuilder.php b/lib/Alchemy/Phrasea/Command/Developer/JavascriptBuilder.php index b0b2208891..1ec46ae58f 100644 --- a/lib/Alchemy/Phrasea/Command/Developer/JavascriptBuilder.php +++ b/lib/Alchemy/Phrasea/Command/Developer/JavascriptBuilder.php @@ -52,6 +52,7 @@ class JavascriptBuilder extends Command ) ); + $output->writeln('Building JavaScript assets'); foreach ($files as $target => $sources) { $this->buildJavascript($input, $output, $target, $sources); @@ -62,7 +63,7 @@ class JavascriptBuilder extends Command private function buildJavascript(InputInterface $input, OutputInterface $output, $target, $sources) { - $output->writeln("Building ".basename($target).""); + $output->writeln("\t".basename($target)); $this->container['filesystem']->remove($target); $process = ProcessBuilder::create(array_merge(array('cat'), $sources))->getProcess(); @@ -81,19 +82,11 @@ class JavascriptBuilder extends Command private function buildMinifiedJavascript(InputInterface $input, OutputInterface $output, $target, $source) { - $output->writeln("Building ".basename($target).""); + $output->writeln("\t".basename($target)); $this->container['filesystem']->remove($target); - $process = ProcessBuilder::create(array('uglifyjs', $source, '-nc'))->getProcess(); - if ($input->getOption('verbose')) { - $output->writeln("Executing ".$process->getCommandLine()."\n"); - } - $process->run(); + $output = $this->container['driver.uglifyjs']->command(array($source, '-nc')); - if (!$process->isSuccessFul()) { - throw new RuntimeException(sprintf('Failed to generate %s', $target)); - } - - file_put_contents($target, $process->getOutput()); + file_put_contents($target, $output); } } diff --git a/lib/Alchemy/Phrasea/Command/Developer/LessCompiler.php b/lib/Alchemy/Phrasea/Command/Developer/LessCompiler.php index fcb0a9ddda..9666aae123 100644 --- a/lib/Alchemy/Phrasea/Command/Developer/LessCompiler.php +++ b/lib/Alchemy/Phrasea/Command/Developer/LessCompiler.php @@ -12,7 +12,6 @@ namespace Alchemy\Phrasea\Command\Developer; use Alchemy\Phrasea\Command\Command; -use Alchemy\Phrasea\Exception\RuntimeException; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Output\OutputInterface; @@ -33,34 +32,13 @@ class LessCompiler extends Command */ protected function doExecute(InputInterface $input, OutputInterface $output) { - $copies = array( - $this->container['root.path'] . '/www/assets/bootstrap/img/glyphicons-halflings-white.png' => $this->container['root.path'] . '/www/skins/build/bootstrap/img/glyphicons-halflings-white.png', - $this->container['root.path'] . '/www/assets/bootstrap/img/glyphicons-halflings.png' => $this->container['root.path'] . '/www/skins/build/bootstrap/img/glyphicons-halflings.png', - ); - - foreach ($copies as $source => $target) { + foreach ($this->container['phraseanet.less-assets'] as $source => $target) { $this->container['filesystem']->mkdir(dirname($target)); $this->container['filesystem']->copy($source, $target); } - $files = array( - $this->container['root.path'] . '/www/skins/login/less/login.less' => $this->container['root.path'] . '/www/skins/build/login.css', - $this->container['root.path'] . '/www/skins/account/account.less' => $this->container['root.path'] . '/www/skins/build/account.css', - $this->container['root.path'] . '/www/assets/bootstrap/less/bootstrap.less' => $this->container['root.path'] . '/www/skins/build/bootstrap/css/bootstrap.css', - $this->container['root.path'] . '/www/assets/bootstrap/less/responsive.less' => $this->container['root.path'] . '/www/skins/build/bootstrap/css/bootstrap-responsive.css', - ); - - $output->writeln('Building Assets...'); - - try { - $this->container['phraseanet.less-builder']->build($files); - } catch (RuntimeException $e) { - $output->writeln(sprintf('Could not build less files %s', $e->getMessage())); - - return 1; - } - - $output->writeln('Build done !'); + $output->writeln('Building LESS assets'); + $this->container['phraseanet.less-builder']->build($this->container['phraseanet.less-mapping'], $output); return 0; } diff --git a/lib/Alchemy/Phrasea/Command/Developer/Utils/BowerDriver.php b/lib/Alchemy/Phrasea/Command/Developer/Utils/BowerDriver.php new file mode 100644 index 0000000000..905e1ed68f --- /dev/null +++ b/lib/Alchemy/Phrasea/Command/Developer/Utils/BowerDriver.php @@ -0,0 +1,42 @@ +get('bower.binaries', array('bower')); + + return static::load($binaries, $logger, $conf); + } +} diff --git a/lib/Alchemy/Phrasea/Command/Developer/Utils/ComposerDriver.php b/lib/Alchemy/Phrasea/Command/Developer/Utils/ComposerDriver.php new file mode 100644 index 0000000000..a0f71c9d12 --- /dev/null +++ b/lib/Alchemy/Phrasea/Command/Developer/Utils/ComposerDriver.php @@ -0,0 +1,36 @@ +get('composer.binaries', array('composer')); + + return static::load($binaries, $logger, $conf); + } +} diff --git a/lib/Alchemy/Phrasea/Command/Developer/Utils/UglifyJsDriver.php b/lib/Alchemy/Phrasea/Command/Developer/Utils/UglifyJsDriver.php new file mode 100644 index 0000000000..04676406b3 --- /dev/null +++ b/lib/Alchemy/Phrasea/Command/Developer/Utils/UglifyJsDriver.php @@ -0,0 +1,36 @@ +get('uglifyjs.binaries', array('uglifyjs')); + + return static::load($binaries, $logger, $conf); + } +} diff --git a/lib/Alchemy/Phrasea/Command/Plugin/AbstractPluginCommand.php b/lib/Alchemy/Phrasea/Command/Plugin/AbstractPluginCommand.php index 6bf7d21fd1..6ee1a02280 100644 --- a/lib/Alchemy/Phrasea/Command/Plugin/AbstractPluginCommand.php +++ b/lib/Alchemy/Phrasea/Command/Plugin/AbstractPluginCommand.php @@ -38,18 +38,8 @@ abstract class AbstractPluginCommand extends Command $this->container['plugins.autoloader-generator']->write($manifests); $output->writeln(" OK"); - $files = array( - $this->container['root.path'] . '/www/skins/login/less/login.less' => $this->container['root.path'] . '/www/skins/build/login.css', - $this->container['root.path'] . '/www/skins/account/account.less' => $this->container['root.path'] . '/www/skins/build/account.css', - ); - - $output->write('Building Assets...'); - - try { - $this->container['phraseanet.less-builder']->build($files); - $output->writeln(" OK"); - } catch (RuntimeException $e) { - $output->writeln(sprintf('Could not build less files %s', $e->getMessage())); - } + $output->write('Building LESS assets'); + $this->container['phraseanet.less-builder']->build($this->container['phraseanet.less-mapping.customizable'], $output); + $output->writeln(" OK"); } } diff --git a/lib/Alchemy/Phrasea/Command/Plugin/RemovePlugin.php b/lib/Alchemy/Phrasea/Command/Plugin/RemovePlugin.php index f9d9a42f19..788251bfcd 100644 --- a/lib/Alchemy/Phrasea/Command/Plugin/RemovePlugin.php +++ b/lib/Alchemy/Phrasea/Command/Plugin/RemovePlugin.php @@ -35,7 +35,7 @@ class RemovePlugin extends AbstractPluginCommand $output->writeln(" OK"); $path = $this->container['plugins.directory'] . DIRECTORY_SEPARATOR . $name; - + $output->write("Removing $name..."); $this->container['filesystem']->remove($path); $output->writeln(" OK"); diff --git a/lib/Alchemy/Phrasea/Command/Setup/JavascriptBuilder.php b/lib/Alchemy/Phrasea/Command/Setup/JavascriptBuilder.php deleted file mode 100644 index 6dc02b03b2..0000000000 --- a/lib/Alchemy/Phrasea/Command/Setup/JavascriptBuilder.php +++ /dev/null @@ -1,99 +0,0 @@ -setDescription('Compile less files'); - } - - /** - * {@inheritdoc} - */ - protected function doExecute(InputInterface $input, OutputInterface $output) - { - $files = array( - $this->container['root.path'] . '/www/skins/build/bootstrap/js/bootstrap.js' => array( - $this->container['root.path'] . '/www/assets/bootstrap/js/bootstrap-transition.js', - $this->container['root.path'] . '/www/assets/bootstrap/js/bootstrap-alert.js', - $this->container['root.path'] . '/www/assets/bootstrap/js/bootstrap-button.js', - $this->container['root.path'] . '/www/assets/bootstrap/js/bootstrap-carousel.js', - $this->container['root.path'] . '/www/assets/bootstrap/js/bootstrap-collapse.js', - $this->container['root.path'] . '/www/assets/bootstrap/js/bootstrap-dropdown.js', - $this->container['root.path'] . '/www/assets/bootstrap/js/bootstrap-modal.js', - $this->container['root.path'] . '/www/assets/bootstrap/js/bootstrap-tooltip.js', - $this->container['root.path'] . '/www/assets/bootstrap/js/bootstrap-popover.js', - $this->container['root.path'] . '/www/assets/bootstrap/js/bootstrap-scrollspy.js', - $this->container['root.path'] . '/www/assets/bootstrap/js/bootstrap-tab.js', - $this->container['root.path'] . '/www/assets/bootstrap/js/bootstrap-typeahead.js', - $this->container['root.path'] . '/www/assets/bootstrap/js/bootstrap-affix.js', - ) - ); - - foreach ($files as $target => $sources) { - $this->buildJavascript($input, $output, $target, $sources); - - $minifiedTarget = substr($target, 0, -3) . '.min.js'; - $this->buildMinifiedJavascript($input, $output, $minifiedTarget, $target); - } - } - - private function buildJavascript(InputInterface $input, OutputInterface $output, $target, $sources) - { - $output->writeln("Building ".basename($target).""); - $this->container['filesystem']->remove($target); - - $process = ProcessBuilder::create(array_merge(array('cat'), $sources))->getProcess(); - if ($input->getOption('verbose')) { - $output->writeln("Executing ".$process->getCommandLine()."\n"); - } - $process->run(); - - if (!$process->isSuccessFul()) { - throw new RuntimeException(sprintf('Failed to generate %s', $target)); - } - - $this->container['filesystem']->mkdir(dirname($target)); - file_put_contents($target, $process->getOutput()); - } - - private function buildMinifiedJavascript(InputInterface $input, OutputInterface $output, $target, $source) - { - $output->writeln("Building ".basename($target).""); - $this->container['filesystem']->remove($target); - - $process = ProcessBuilder::create(array('uglifyjs', $source, '-nc'))->getProcess(); - if ($input->getOption('verbose')) { - $output->writeln("Executing ".$process->getCommandLine()."\n"); - } - $process->run(); - - if (!$process->isSuccessFul()) { - throw new RuntimeException(sprintf('Failed to generate %s', $target)); - } - - file_put_contents($target, $process->getOutput()); - } -} diff --git a/lib/Alchemy/Phrasea/Command/Setup/LessCompiler.php b/lib/Alchemy/Phrasea/Command/Setup/LessCompiler.php deleted file mode 100644 index ae50540f7f..0000000000 --- a/lib/Alchemy/Phrasea/Command/Setup/LessCompiler.php +++ /dev/null @@ -1,95 +0,0 @@ -setDescription('Compile less files'); - } - - /** - * {@inheritdoc} - */ - protected function doExecute(InputInterface $input, OutputInterface $output) - { - $files = array( - $this->container['root.path'] . '/www/skins/login/less/login.less' => $this->container['root.path'] . '/www/skins/build/login.css', - $this->container['root.path'] . '/www/skins/account/account.less' => $this->container['root.path'] . '/www/skins/build/account.css', - $this->container['root.path'] . '/www/assets/bootstrap/less/bootstrap.less' => $this->container['root.path'] . '/www/skins/build/bootstrap/css/bootstrap.css', - $this->container['root.path'] . '/www/assets/bootstrap/less/responsive.less' => $this->container['root.path'] . '/www/skins/build/bootstrap/css/bootstrap-responsive.css', - ); - - $output->writeln('Building Assets...'); - - $failures = 0; - $errors = array(); - foreach ($files as $lessFile => $buildFile) { - $this->container['filesystem']->mkdir(dirname($buildFile)); - $output->writeln(sprintf('Building %s', basename($lessFile))); - - if (!is_file($lessFile)) { - throw new RuntimeException(realpath($lessFile) . ' does not exists.'); - } - - if (!is_writable(dirname($buildFile))) { - throw new RuntimeException(realpath(dirname($buildFile)) . ' is not writable.'); - } - - $builder = ProcessBuilder::create(array( - 'recess', - '--compile', - $lessFile, - )); - $process = $builder->getProcess(); - $process->run(); - - if (!$process->isSuccessful()) { - $failures++; - $errors[] = $process->getErrorOutput(); - } - file_put_contents($buildFile, $process->getOutput()); - } - - $copies = array( - $this->container['root.path'] . '/www/assets/bootstrap/img/glyphicons-halflings-white.png' => $this->container['root.path'] . '/www/skins/build/bootstrap/img/glyphicons-halflings-white.png', - $this->container['root.path'] . '/www/assets/bootstrap/img/glyphicons-halflings.png' => $this->container['root.path'] . '/www/skins/build/bootstrap/img/glyphicons-halflings.png', - ); - - foreach ($copies as $source => $target) { - $this->container['filesystem']->mkdir(dirname($target)); - $this->container['filesystem']->copy($source, $target); - } - - if (0 === $failures) { - $output->writeln('Build done !'); - - return 0; - } - - $output->writeln(sprintf('%d errors occured during the build %s', $failures, implode(', ', $errors))); - - return 1; - } -} diff --git a/lib/Alchemy/Phrasea/Command/Setup/XSendFileConfigurationDumper.php b/lib/Alchemy/Phrasea/Command/Setup/XSendFileConfigurationDumper.php index b6a2fc5814..c3f3a7f9ae 100644 --- a/lib/Alchemy/Phrasea/Command/Setup/XSendFileConfigurationDumper.php +++ b/lib/Alchemy/Phrasea/Command/Setup/XSendFileConfigurationDumper.php @@ -18,7 +18,8 @@ use Symfony\Component\Console\Output\OutputInterface; class XSendFileConfigurationDumper extends Command { - public function __construct($name = null) { + public function __construct($name = null) + { parent::__construct('xsendfile:dump-configuration'); $this->setDescription('Dump the virtual host configuration depending on Phraseanet configuration'); diff --git a/lib/Alchemy/Phrasea/Controller/Client/Root.php b/lib/Alchemy/Phrasea/Controller/Client/Root.php index e419f271de..e000efd76a 100644 --- a/lib/Alchemy/Phrasea/Controller/Client/Root.php +++ b/lib/Alchemy/Phrasea/Controller/Client/Root.php @@ -19,7 +19,6 @@ use Symfony\Component\Finder\Finder; use Symfony\Component\HttpFoundation\JsonResponse; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Response; -use Symfony\Component\HttpKernel\HttpKernelInterface; class Root implements ControllerProviderInterface { diff --git a/lib/Alchemy/Phrasea/Controller/Prod/Records.php b/lib/Alchemy/Phrasea/Controller/Prod/Records.php index 3d98b7316a..480e791fb4 100644 --- a/lib/Alchemy/Phrasea/Controller/Prod/Records.php +++ b/lib/Alchemy/Phrasea/Controller/Prod/Records.php @@ -227,7 +227,7 @@ class Records implements ControllerProviderInterface $deleted[] = $record->get_serialize_key(); $record->delete(); } catch (\Exception $e) { - + } } diff --git a/lib/Alchemy/Phrasea/Controller/Root/Session.php b/lib/Alchemy/Phrasea/Controller/Root/Session.php index 6bfc17eeb7..6eeba7b679 100644 --- a/lib/Alchemy/Phrasea/Controller/Root/Session.php +++ b/lib/Alchemy/Phrasea/Controller/Root/Session.php @@ -89,7 +89,7 @@ class Session implements ControllerProviderInterface $session = $app['EM']->find('Entities\Session', $app['session']->get('session_id')); $session->setUpdated(new \DateTime()); - + if (!$session->hasModuleId($moduleId)) { $module = new \Entities\SessionModule(); $module->setModuleId($moduleId); diff --git a/lib/Alchemy/Phrasea/Core/CLIProvider/CLIDriversServiceProvider.php b/lib/Alchemy/Phrasea/Core/CLIProvider/CLIDriversServiceProvider.php new file mode 100644 index 0000000000..e928e57152 --- /dev/null +++ b/lib/Alchemy/Phrasea/Core/CLIProvider/CLIDriversServiceProvider.php @@ -0,0 +1,65 @@ +share(function () { + return new ExecutableFinder(); + }); + + $app['driver.bower'] = $app->share(function (Application $app) { + if (isset($this->container['phraseanet.configuration']['binaries']['bower_binary'])) { + $bowerBinary = $this->container['phraseanet.configuration']['binaries']['bower_binary']; + } else { + $bowerBinary = $app['executable-finder']->find('bower'); + } + + if (null === $bowerBinary) { + throw new RuntimeException('Unable to find bower executable.'); + } + + return BowerDriver::create(array('bower.binaries' => $bowerBinary), $this->container['monolog']); + }); + + $app['driver.composer'] = $app->share(function (Application $app) { + if (isset($this->container['phraseanet.configuration']['binaries']['composer_binary'])) { + $composerBinary = $this->container['phraseanet.configuration']['binaries']['composer_binary']; + } else { + $composerBinary = $app['executable-finder']->find('composer'); + } + + if (null === $composerBinary) { + throw new RuntimeException('Unable to find composer executable.'); + } + + return ComposerDriver::create(array('composer.binaries' => $composerBinary), $this->container['monolog']); + }); + + $app['driver.uglifyjs'] = $app->share(function (Application $app) { + return UglifyJsDriver::create(array(), $this->container['monolog']); + }); + } + + public function boot(Application $app) + { + } +} diff --git a/lib/Alchemy/Phrasea/Core/CLIProvider/ComposerSetupServiceProvider.php b/lib/Alchemy/Phrasea/Core/CLIProvider/ComposerSetupServiceProvider.php new file mode 100644 index 0000000000..e5d4af3d75 --- /dev/null +++ b/lib/Alchemy/Phrasea/Core/CLIProvider/ComposerSetupServiceProvider.php @@ -0,0 +1,34 @@ +share(function (Application $app) { + return new Guzzle(); + }); + $app['composer-setup'] = $app->share(function (Application $app) { + return new ComposerSetup($app['composer-setup.guzzle']); + }); + } + + public function boot(Application $app) + { + } +} diff --git a/lib/Alchemy/Phrasea/Core/Provider/PluginServiceProvider.php b/lib/Alchemy/Phrasea/Core/CLIProvider/PluginServiceProvider.php similarity index 90% rename from lib/Alchemy/Phrasea/Core/Provider/PluginServiceProvider.php rename to lib/Alchemy/Phrasea/Core/CLIProvider/PluginServiceProvider.php index 4d2824900d..f990d230a5 100644 --- a/lib/Alchemy/Phrasea/Core/Provider/PluginServiceProvider.php +++ b/lib/Alchemy/Phrasea/Core/CLIProvider/PluginServiceProvider.php @@ -9,7 +9,7 @@ * file that was distributed with this source code. */ -namespace Alchemy\Phrasea\Core\Provider; +namespace Alchemy\Phrasea\Core\CLIProvider; use Alchemy\Phrasea\Plugin\Schema\ManifestValidator; use Alchemy\Phrasea\Plugin\Management\PluginsExplorer; @@ -20,7 +20,6 @@ use Alchemy\Phrasea\Plugin\Importer\ImportStrategy; use Alchemy\Phrasea\Plugin\Importer\FolderImporter; use Alchemy\Phrasea\Plugin\Management\AutoloaderGenerator; use Alchemy\Phrasea\Plugin\Management\AssetsManager; -use Guzzle\Http\Client as Guzzle; use JsonSchema\Validator as JsonValidator; use Symfony\Component\Process\ExecutableFinder; use Silex\Application; @@ -30,7 +29,6 @@ class PluginServiceProvider implements ServiceProviderInterface { public function register(Application $app) { - $app['plugins.directory'] = realpath(__DIR__ . '/../../../../../plugins'); $app['plugins.schema'] = realpath(__DIR__ . '/../../../../conf.d/plugin-schema.json'); $app['plugins.json-validator'] = $app->share(function (Application $app) { @@ -57,10 +55,6 @@ class PluginServiceProvider implements ServiceProviderInterface return new AssetsManager($app['filesystem'], $app['plugins.directory'], $app['root.path']); }); - $app['plugins.guzzle'] = $app->share(function (Application $app) { - return new Guzzle(); - }); - $app['plugins.composer-installer'] = $app->share(function (Application $app) { $binaries = $app['phraseanet.configuration']['binaries']; $phpBinary = isset($binaries['php_binary']) ? $binaries['php_binary'] : null; @@ -70,7 +64,7 @@ class PluginServiceProvider implements ServiceProviderInterface $phpBinary = $finder->find('php'); } - return new ComposerInstaller($app['plugins.directory'], $app['plugins.guzzle'], $phpBinary); + return new ComposerInstaller($app['composer-setup'], $app['plugins.directory'], $phpBinary); }); $app['plugins.explorer'] = $app->share(function (Application $app) { return new PluginsExplorer($app['plugins.directory']); diff --git a/lib/Alchemy/Phrasea/Core/Event/Subscriber/CookiesDisablerSubscriber.php b/lib/Alchemy/Phrasea/Core/Event/Subscriber/CookiesDisablerSubscriber.php index 879682f21e..b7b5f9a763 100644 --- a/lib/Alchemy/Phrasea/Core/Event/Subscriber/CookiesDisablerSubscriber.php +++ b/lib/Alchemy/Phrasea/Core/Event/Subscriber/CookiesDisablerSubscriber.php @@ -67,4 +67,3 @@ class CookiesDisablerSubscriber implements EventSubscriberInterface } } } - diff --git a/lib/Alchemy/Phrasea/Core/Provider/LessBuilderServiceProvider.php b/lib/Alchemy/Phrasea/Core/Provider/LessBuilderServiceProvider.php index 43d3dee191..416c88fb7d 100644 --- a/lib/Alchemy/Phrasea/Core/Provider/LessBuilderServiceProvider.php +++ b/lib/Alchemy/Phrasea/Core/Provider/LessBuilderServiceProvider.php @@ -19,6 +19,34 @@ class LessBuilderServiceProvider implements ServiceProviderInterface { public function register(Application $app) { + $app['phraseanet.less-assets'] = $app->share(function($app) { + return array( + $app['root.path'] . '/www/assets/bootstrap/img/glyphicons-halflings-white.png' => $app['root.path'] . '/www/skins/build/bootstrap/img/glyphicons-halflings-white.png', + $app['root.path'] . '/www/assets/bootstrap/img/glyphicons-halflings.png' => $app['root.path'] . '/www/skins/build/bootstrap/img/glyphicons-halflings.png', + ); + }); + + $app['phraseanet.less-mapping.base'] = $app->share(function($app) { + return array( + $app['root.path'] . '/www/assets/bootstrap/less/bootstrap.less' => $app['root.path'] . '/www/skins/build/bootstrap/css/bootstrap.css', + $app['root.path'] . '/www/assets/bootstrap/less/responsive.less' => $app['root.path'] . '/www/skins/build/bootstrap/css/bootstrap-responsive.css', + ); + }); + + $app['phraseanet.less-mapping.customizable'] = $app->share(function($app) { + return array( + $app['root.path'] . '/www/skins/login/less/login.less' => $app['root.path'] . '/www/skins/build/login.css', + $app['root.path'] . '/www/skins/account/account.less' => $app['root.path'] . '/www/skins/build/account.css', + ); + }); + + $app['phraseanet.less-mapping'] = $app->share(function($app) { + return array_merge( + $app['phraseanet.less-mapping.base'], + $app['phraseanet.less-mapping.customizable'] + ); + }); + $app['phraseanet.less-builder'] = $app->share(function($app) { return new LessBuilder($app['phraseanet.less-compiler'], $app['filesystem']); }); diff --git a/lib/Alchemy/Phrasea/Plugin/Management/ComposerInstaller.php b/lib/Alchemy/Phrasea/Plugin/Management/ComposerInstaller.php index 8169565d65..79394d8fca 100644 --- a/lib/Alchemy/Phrasea/Plugin/Management/ComposerInstaller.php +++ b/lib/Alchemy/Phrasea/Plugin/Management/ComposerInstaller.php @@ -12,28 +12,25 @@ namespace Alchemy\Phrasea\Plugin\Management; use Alchemy\Phrasea\Plugin\Exception\ComposerInstallException; +use Alchemy\Phrasea\Utilities\ComposerSetup; use Symfony\Component\Process\ProcessBuilder; use Symfony\Component\Process\Exception\ExceptionInterface as ProcessException; -use Guzzle\Common\Exception\GuzzleException; -use Guzzle\Http\Client as Guzzle; class ComposerInstaller { private $composer; - private $guzzle; - private $pluginsDirectory; private $phpExecutable; + private $setup; - public function __construct($pluginsDirectory, Guzzle $guzzle, $phpExecutable) + public function __construct(ComposerSetup $setup, $pluginsDirectory, $phpExecutable) { if (!is_executable($phpExecutable)) { throw new ComposerInstallException(sprintf('`%s` is not a valid PHP executable', $phpExecutable)); } - $this->guzzle = $guzzle; - $this->pluginsDirectory = $pluginsDirectory; + $this->setup = $setup; $this->phpExecutable = $phpExecutable; - $this->composer = $this->pluginsDirectory . DIRECTORY_SEPARATOR . 'composer.phar'; + $this->composer = $pluginsDirectory . DIRECTORY_SEPARATOR . 'composer.phar'; } public function install($directory) @@ -63,7 +60,11 @@ class ComposerInstaller private function createProcessBuilder() { if (!file_exists($this->composer)) { - $this->installComposer(); + try { + $this->setup->setup($this->composer); + } catch (RuntimeException $e) { + throw new ComposerInstallException('Unable to install composer.', $e->getCode(), $e); + } } else { $process = ProcessBuilder::create(array( $this->phpExecutable, $this->composer, 'self-update' @@ -73,52 +74,4 @@ class ComposerInstaller return ProcessBuilder::create(array($this->phpExecutable, $this->composer)); } - - private function installComposer() - { - $installer = $this->pluginsDirectory . DIRECTORY_SEPARATOR . 'installer'; - $handle = fopen($installer, 'w+'); - - $request = $this->guzzle->get('https://getcomposer.org/installer', null, $handle); - - try { - $response = $request->send(); - fclose($handle); - } catch (GuzzleException $e) { - fclose($handle); - throw new ComposerInstallException('Unable to download composer install script.'); - } - - if (200 !== $response->getStatusCode()) { - @unlink($installer); - throw new ComposerInstallException('Unable to download composer install script.'); - } - - $dir = getcwd(); - if (!@chdir($this->pluginsDirectory)) { - throw new ComposerInstallException('Unable to move to plugins directory for composer install.'); - } - - $process = ProcessBuilder::create(array($this->phpExecutable, $installer))->getProcess(); - - try { - $process->run(); - @unlink($installer); - } catch (ProcessException $e) { - @unlink($installer); - throw new ComposerInstallException('Unable run composer install script.'); - } - - if (!@chdir($dir)) { - throw new ComposerInstallException('Unable to move to plugins directory for composer install.'); - } - - if (!$process->isSuccessful()) { - throw new ComposerInstallException('Composer install failed.'); - } - - if (!file_exists($this->composer)) { - throw new ComposerInstallException('Composer install failed.'); - } - } } diff --git a/lib/Alchemy/Phrasea/Utilities/ComposerSetup.php b/lib/Alchemy/Phrasea/Utilities/ComposerSetup.php new file mode 100644 index 0000000000..7c122c398f --- /dev/null +++ b/lib/Alchemy/Phrasea/Utilities/ComposerSetup.php @@ -0,0 +1,90 @@ +find(); + } + + if (!is_executable($phpExecutable)) { + throw new RuntimeException(sprintf('`%s` is not a valid PHP executable', $phpExecutable)); + } + + $this->guzzle = $guzzle; + $this->phpExecutable = $phpExecutable; + } + + /** + * Downloads composer installer and setups it to the given target. + * + * @param string $target + * + * @throws RuntimeException + */ + public function setup($target) + { + $installer = tempnam(sys_get_temp_dir(), 'install'); + $handle = fopen($installer, 'w+'); + + $request = $this->guzzle->get('https://getcomposer.org/installer', null, $handle); + + try { + $response = $request->send(); + fclose($handle); + } catch (GuzzleException $e) { + fclose($handle); + throw new RuntimeException('Unable to download composer install script.'); + } + + if (200 !== $response->getStatusCode()) { + @unlink($installer); + throw new RuntimeException('Unable to download composer install script.'); + } + + $dir = getcwd(); + if (!@chdir(dirname($target))) { + throw new RuntimeException('Unable to move to target directory for composer install.'); + } + + $process = ProcessBuilder::create(array($this->phpExecutable, $installer))->getProcess(); + + try { + $process->run(); + @unlink($installer); + } catch (ProcessException $e) { + @unlink($installer); + throw new RuntimeException('Unable run composer install script.'); + } + + if (!@rename(getcwd() . '/composer.phar', $target)) { + throw new RuntimeException('Composer install failed.'); + } + + if (!@chdir($dir)) { + throw new RuntimeException('Unable to move back to origin directory.'); + } + + if (!$process->isSuccessful()) { + throw new RuntimeException('Composer install failed.'); + } + + if (!file_exists($target)) { + throw new RuntimeException('Composer install failed.'); + } + } +} diff --git a/lib/Alchemy/Phrasea/Utilities/Less/Builder.php b/lib/Alchemy/Phrasea/Utilities/Less/Builder.php index 9dd8c71b80..22e09d0d89 100644 --- a/lib/Alchemy/Phrasea/Utilities/Less/Builder.php +++ b/lib/Alchemy/Phrasea/Utilities/Less/Builder.php @@ -12,6 +12,7 @@ namespace Alchemy\Phrasea\Utilities\Less; use Alchemy\Phrasea\Utilities\Less\Compiler as LessCompiler; +use Symfony\Component\Console\Output\OutputInterface; use Symfony\Component\Filesystem\Filesystem; class Builder @@ -38,10 +39,13 @@ class Builder * * @throws RuntimeException */ - public function build($files) + public function build($files, OutputInterface $output = null) { foreach ($files as $lessFile => $target) { $this->filesystem->mkdir(dirname($target)); + if (null !== $output) { + $output->writeln("\t".basename($target)); + } $this->compiler->compile($target, $lessFile); } } diff --git a/lib/Alchemy/Phrasea/Utilities/Less/Compiler.php b/lib/Alchemy/Phrasea/Utilities/Less/Compiler.php index 7e7ab8c52f..9344b19600 100644 --- a/lib/Alchemy/Phrasea/Utilities/Less/Compiler.php +++ b/lib/Alchemy/Phrasea/Utilities/Less/Compiler.php @@ -53,7 +53,7 @@ class Compiler $files = (array) $files; - foreach($files as $file) { + foreach ($files as $file) { if (false === is_file($file)) { throw new RuntimeException($file . ' does not exists.'); } diff --git a/tests/Alchemy/Tests/Phrasea/Command/CheckConfigTest.php b/tests/Alchemy/Tests/Phrasea/Command/CheckConfigTest.php index 2620e8ec55..e0e9d505a5 100644 --- a/tests/Alchemy/Tests/Phrasea/Command/CheckConfigTest.php +++ b/tests/Alchemy/Tests/Phrasea/Command/CheckConfigTest.php @@ -12,7 +12,7 @@ class CheckConfigTest extends \PhraseanetPHPUnitAbstract $output = $this->getMock('Symfony\Component\Console\Output\OutputInterface'); $command = new CheckConfig('check:config'); - $command->setContainer(self::$DI['app']); + $command->setContainer(self::$DI['cli']); $this->assertLessThan(2, $command->execute($input, $output)); } } diff --git a/tests/Alchemy/Tests/Phrasea/Command/Compile/ConfigurationTest.php b/tests/Alchemy/Tests/Phrasea/Command/Compile/ConfigurationTest.php index 132348eab4..7afc9e44b9 100644 --- a/tests/Alchemy/Tests/Phrasea/Command/Compile/ConfigurationTest.php +++ b/tests/Alchemy/Tests/Phrasea/Command/Compile/ConfigurationTest.php @@ -9,10 +9,10 @@ class ConfigurationTest extends \PhraseanetPHPUnitAbstract public function testExecute() { $command = new Configuration(); - $command->setContainer(self::$DI['app']); + $command->setContainer(self::$DI['cli']); - self::$DI['app']['phraseanet.configuration'] = $this->getMock('Alchemy\Phrasea\Core\Configuration\ConfigurationInterface'); - self::$DI['app']['phraseanet.configuration']->expects($this->once()) + self::$DI['cli']['phraseanet.configuration'] = $this->getMock('Alchemy\Phrasea\Core\Configuration\ConfigurationInterface'); + self::$DI['cli']['phraseanet.configuration']->expects($this->once()) ->method('compileAndWrite'); $input = $this->getMock('Symfony\Component\Console\Input\InputInterface'); diff --git a/tests/Alchemy/Tests/Phrasea/Command/Developper/BowerInstallTest.php b/tests/Alchemy/Tests/Phrasea/Command/Developper/BowerInstallTest.php new file mode 100644 index 0000000000..46ed957094 --- /dev/null +++ b/tests/Alchemy/Tests/Phrasea/Command/Developper/BowerInstallTest.php @@ -0,0 +1,73 @@ +getMock('Symfony\Component\Console\Input\InputInterface'); + $output = $this->getMock('Symfony\Component\Console\Output\OutputInterface'); + + $input->expects($this->any()) + ->method('getOption') + ->will($this->returnCallback(function ($name) { + switch ($name) { + case 'attempts': + return 4; + default: + return null; + } + })); + + $input->expects($this->any()) + ->method('getArgument') + ->will($this->returnCallback(function ($name) { + switch ($name) { + default: + return null; + } + })); + + self::$DI['cli']['filesystem'] = $this->getMockBuilder('Symfony\Component\Filesystem\Filesystem') + ->disableOriginalConstructor() + ->getMock(); + + self::$DI['cli']['filesystem']->expects($this->once()) + ->method('remove') + ->with(self::$DI['cli']['root.path'].'/www/assets'); + + self::$DI['cli']['driver.bower'] = $this->getMockBuilder('Alchemy\Phrasea\Command\Developer\Utils\BowerDriver') + ->disableOriginalConstructor() + ->getMock(); + + $processBuilder = $this->getMock('Alchemy\BinaryDriver\ProcessBuilderFactoryInterface'); + $processBuilder->expects($this->once()) + ->method('getBinary') + ->will($this->returnValue('/opt/local/bin/bower')); + + self::$DI['cli']['driver.bower']->expects($this->at(0)) + ->method('getProcessBuilderFactory') + ->will($this->returnValue($processBuilder)); + + self::$DI['cli']['driver.bower']->expects($this->at(1)) + ->method('command') + ->with('-v') + ->will($this->returnValue('1.0.0-alpha.5')); + + self::$DI['cli']['driver.bower']->expects($this->at(2)) + ->method('command') + ->with(array('cache', 'clean')); + + self::$DI['cli']['driver.bower']->expects($this->at(3)) + ->method('command') + ->with('install'); + + $command = new BowerInstall(); + $command->setContainer(self::$DI['cli']); + + $this->assertEquals(0, $command->execute($input, $output)); + } +} diff --git a/tests/Alchemy/Tests/Phrasea/Command/Developper/ComposerInstallTest.php b/tests/Alchemy/Tests/Phrasea/Command/Developper/ComposerInstallTest.php new file mode 100644 index 0000000000..0ddd28279d --- /dev/null +++ b/tests/Alchemy/Tests/Phrasea/Command/Developper/ComposerInstallTest.php @@ -0,0 +1,31 @@ +getMock('Symfony\Component\Console\Input\InputInterface'); + $output = $this->getMock('Symfony\Component\Console\Output\OutputInterface'); + + self::$DI['cli']['driver.composer'] = $this->getMockBuilder('Alchemy\Phrasea\Command\Developer\Utils\ComposerDriver') + ->disableOriginalConstructor() + ->getMock(); + + self::$DI['cli']['driver.composer']->expects($this->at(0)) + ->method('command') + ->with('self-update'); + + self::$DI['cli']['driver.composer']->expects($this->at(1)) + ->method('command') + ->with(array('install', '--optimize-autoloader', '--dev')); + + $command = new ComposerInstall(); + $command->setContainer(self::$DI['cli']); + + $this->assertEquals(0, $command->execute($input, $output)); + } +} diff --git a/tests/Alchemy/Tests/Phrasea/Command/Developper/InstallAllTest.php b/tests/Alchemy/Tests/Phrasea/Command/Developper/InstallAllTest.php new file mode 100644 index 0000000000..d3dd024220 --- /dev/null +++ b/tests/Alchemy/Tests/Phrasea/Command/Developper/InstallAllTest.php @@ -0,0 +1,46 @@ +getMock('Symfony\Component\Console\Input\InputInterface'); + $output = $this->getMock('Symfony\Component\Console\Output\OutputInterface'); + + self::$DI['cli']['console'] = $this->getMockBuilder('Symfony\Component\Console\Application') + ->disableOriginalConstructor() + ->getMock(); + + $n = 0; + foreach (array( + 'dependencies:bower', + 'dependencies:composer', + 'assets:build-javascript', + 'assets:compile-less', + ) as $name) { + $command = $this->getMockBuilder('Symfony\Component\Console\Command\Command') + ->setMethods(array('execute')) + ->disableOriginalConstructor() + ->getMock(); + $command->expects($this->once()) + ->method('execute') + ->with($input, $output) + ->will($this->returnValue(0)); + + self::$DI['cli']['console']->expects($this->at($n)) + ->method('get') + ->with($name) + ->will($this->returnValue($command)); + $n++; + } + + $command = new InstallAll(); + $command->setContainer(self::$DI['cli']); + + $this->assertEquals(0, $command->execute($input, $output)); + } +} diff --git a/tests/Alchemy/Tests/Phrasea/Command/Developper/Utils/BowerDriverTest.php b/tests/Alchemy/Tests/Phrasea/Command/Developper/Utils/BowerDriverTest.php new file mode 100644 index 0000000000..3759fae184 --- /dev/null +++ b/tests/Alchemy/Tests/Phrasea/Command/Developper/Utils/BowerDriverTest.php @@ -0,0 +1,26 @@ +assertInstanceOf('Alchemy\Phrasea\Command\Developer\Utils\BowerDriver', $driver); + $this->assertEquals('bower', $driver->getName()); + } + + public function testCreateWithCustomBinary() + { + $finder = new PhpExecutableFinder(); + $php = $finder->find(); + + $driver = BowerDriver::create(array('bower.binaries' => $php)); + $this->assertInstanceOf('Alchemy\Phrasea\Command\Developer\Utils\BowerDriver', $driver); + $this->assertEquals($php, $driver->getProcessBuilderFactory()->getBinary()); + } +} diff --git a/tests/Alchemy/Tests/Phrasea/Command/Developper/Utils/ComposerDriverTest.php b/tests/Alchemy/Tests/Phrasea/Command/Developper/Utils/ComposerDriverTest.php new file mode 100644 index 0000000000..9f9c1c2082 --- /dev/null +++ b/tests/Alchemy/Tests/Phrasea/Command/Developper/Utils/ComposerDriverTest.php @@ -0,0 +1,26 @@ +assertInstanceOf('Alchemy\Phrasea\Command\Developer\Utils\ComposerDriver', $driver); + $this->assertEquals('composer', $driver->getName()); + } + + public function testCreateWithCustomBinary() + { + $finder = new PhpExecutableFinder(); + $php = $finder->find(); + + $driver = ComposerDriver::create(array('composer.binaries' => $php)); + $this->assertInstanceOf('Alchemy\Phrasea\Command\Developer\Utils\ComposerDriver', $driver); + $this->assertEquals($php, $driver->getProcessBuilderFactory()->getBinary()); + } +} diff --git a/tests/Alchemy/Tests/Phrasea/Command/Developper/Utils/UglifyJsDriverTest.php b/tests/Alchemy/Tests/Phrasea/Command/Developper/Utils/UglifyJsDriverTest.php new file mode 100644 index 0000000000..bb68073093 --- /dev/null +++ b/tests/Alchemy/Tests/Phrasea/Command/Developper/Utils/UglifyJsDriverTest.php @@ -0,0 +1,26 @@ +assertInstanceOf('Alchemy\Phrasea\Command\Developer\Utils\UglifyJsDriver', $driver); + $this->assertEquals('uglifyjs', $driver->getName()); + } + + public function testCreateWithCustomBinary() + { + $finder = new PhpExecutableFinder(); + $php = $finder->find(); + + $driver = UglifyJsDriver::create(array('uglifyjs.binaries' => $php)); + $this->assertInstanceOf('Alchemy\Phrasea\Command\Developer\Utils\UglifyJsDriver', $driver); + $this->assertEquals($php, $driver->getProcessBuilderFactory()->getBinary()); + } +} diff --git a/tests/Alchemy/Tests/Phrasea/Command/MailTestTest.php b/tests/Alchemy/Tests/Phrasea/Command/MailTestTest.php index 1254729a38..c8eb0afc4d 100644 --- a/tests/Alchemy/Tests/Phrasea/Command/MailTestTest.php +++ b/tests/Alchemy/Tests/Phrasea/Command/MailTestTest.php @@ -18,11 +18,11 @@ class MailTestTest extends \PhraseanetPHPUnitAbstract $output = $this->getMock('Symfony\Component\Console\Output\OutputInterface'); - self::$DI['app']['notification.deliverer'] = $this->getMockBuilder('Alchemy\Phrasea\Notification\Deliverer') + self::$DI['cli']['notification.deliverer'] = $this->getMockBuilder('Alchemy\Phrasea\Notification\Deliverer') ->disableOriginalConstructor() ->getMock(); - self::$DI['app']['notification.deliverer']->expects($this->once()) + self::$DI['cli']['notification.deliverer']->expects($this->once()) ->method('deliver') ->with($this->isInstanceOf('Alchemy\Phrasea\Notification\Mail\MailTest'), $this->equalTo(null)) ->will($this->returnCallback(function ($email) use (&$capturedEmail) { @@ -30,7 +30,7 @@ class MailTestTest extends \PhraseanetPHPUnitAbstract })); $command = new MailTest('mail:test'); - $command->setContainer(self::$DI['app']); + $command->setContainer(self::$DI['cli']); $result = $command->execute($input, $output); $this->assertSame(0, $result); diff --git a/tests/Alchemy/Tests/Phrasea/Command/Plugin/AddPluginTest.php b/tests/Alchemy/Tests/Phrasea/Command/Plugin/AddPluginTest.php index b3816695b3..9aabf2f3b0 100644 --- a/tests/Alchemy/Tests/Phrasea/Command/Plugin/AddPluginTest.php +++ b/tests/Alchemy/Tests/Phrasea/Command/Plugin/AddPluginTest.php @@ -19,57 +19,57 @@ class AddPluginTest extends PluginCommandTestCase $output = $this->getMock('Symfony\Component\Console\Output\OutputInterface'); $command = new AddPlugin(); - $command->setContainer(self::$DI['app']); + $command->setContainer(self::$DI['cli']); $manifest = $this->createManifestMock(); $manifest->expects($this->any()) ->method('getName') ->will($this->returnValue($source)); - self::$DI['app']['temporary-filesystem'] = $this->createTemporaryFilesystemMock(); - self::$DI['app']['plugins.autoloader-generator'] = $this->createPluginsAutoloaderGeneratorMock(); - self::$DI['app']['plugins.explorer'] = array(self::$DI['app']['plugins.directory'].'/TestPlugin'); - self::$DI['app']['plugins.plugins-validator'] = $this->createPluginsValidatorMock(); - self::$DI['app']['filesystem'] = $this->createFilesystemMock(); - self::$DI['app']['plugins.composer-installer'] = $this->createComposerInstallerMock(); - self::$DI['app']['plugins.importer'] = $this->createPluginsImporterMock(); + self::$DI['cli']['temporary-filesystem'] = $this->createTemporaryFilesystemMock(); + self::$DI['cli']['plugins.autoloader-generator'] = $this->createPluginsAutoloaderGeneratorMock(); + self::$DI['cli']['plugins.explorer'] = array(self::$DI['cli']['plugins.directory'].'/TestPlugin'); + self::$DI['cli']['plugins.plugins-validator'] = $this->createPluginsValidatorMock(); + self::$DI['cli']['filesystem'] = $this->createFilesystemMock(); + self::$DI['cli']['plugins.composer-installer'] = $this->createComposerInstallerMock(); + self::$DI['cli']['plugins.importer'] = $this->createPluginsImporterMock(); - self::$DI['app']['temporary-filesystem']->expects($this->once()) + self::$DI['cli']['temporary-filesystem']->expects($this->once()) ->method('createTemporaryDirectory') ->will($this->returnValue('tempdir')); - self::$DI['app']['plugins.importer']->expects($this->once()) + self::$DI['cli']['plugins.importer']->expects($this->once()) ->method('import') ->with($source, 'tempdir'); // the plugin is checked when updating config files - self::$DI['app']['plugins.plugins-validator']->expects($this->at(0)) + self::$DI['cli']['plugins.plugins-validator']->expects($this->at(0)) ->method('validatePlugin') ->with('tempdir') ->will($this->returnValue($manifest)); - self::$DI['app']['plugins.plugins-validator']->expects($this->at(1)) + self::$DI['cli']['plugins.plugins-validator']->expects($this->at(1)) ->method('validatePlugin') - ->with(self::$DI['app']['plugins.directory'].'/TestPlugin') + ->with(self::$DI['cli']['plugins.directory'].'/TestPlugin') ->will($this->returnValue($manifest)); - self::$DI['app']['plugins.composer-installer']->expects($this->once()) + self::$DI['cli']['plugins.composer-installer']->expects($this->once()) ->method('install') ->with('tempdir'); - self::$DI['app']['filesystem']->expects($this->at(0)) + self::$DI['cli']['filesystem']->expects($this->at(0)) ->method('mirror') - ->with('tempdir', self::$DI['app']['plugins.directory'].'/TestPlugin'); + ->with('tempdir', self::$DI['cli']['plugins.directory'].'/TestPlugin'); - self::$DI['app']['filesystem']->expects($this->at(1)) + self::$DI['cli']['filesystem']->expects($this->at(1)) ->method('mirror') - ->with(self::$DI['app']['plugins.directory'].'/TestPlugin/public', self::$DI['app']['root.path'].'/www/plugins/TestPlugin'); + ->with(self::$DI['cli']['plugins.directory'].'/TestPlugin/public', self::$DI['cli']['root.path'].'/www/plugins/TestPlugin'); - self::$DI['app']['filesystem']->expects($this->at(2)) + self::$DI['cli']['filesystem']->expects($this->at(2)) ->method('remove') ->with('tempdir'); - self::$DI['app']['plugins.autoloader-generator']->expects($this->once()) + self::$DI['cli']['plugins.autoloader-generator']->expects($this->once()) ->method('write') ->with(array($manifest)); diff --git a/tests/Alchemy/Tests/Phrasea/Command/Plugin/RemovePluginTest.php b/tests/Alchemy/Tests/Phrasea/Command/Plugin/RemovePluginTest.php index fa61354439..29baa854b6 100644 --- a/tests/Alchemy/Tests/Phrasea/Command/Plugin/RemovePluginTest.php +++ b/tests/Alchemy/Tests/Phrasea/Command/Plugin/RemovePluginTest.php @@ -19,16 +19,16 @@ class RemovePluginTest extends PluginCommandTestCase $output = $this->getMock('Symfony\Component\Console\Output\OutputInterface'); $command = new RemovePlugin(); - $command->setContainer(self::$DI['app']); + $command->setContainer(self::$DI['cli']); - self::$DI['app']['filesystem'] = $this->createFilesystemMock(); - self::$DI['app']['filesystem']->expects($this->at(0)) + self::$DI['cli']['filesystem'] = $this->createFilesystemMock(); + self::$DI['cli']['filesystem']->expects($this->at(0)) ->method('remove') - ->with(self::$DI['app']['root.path'].'/www/plugins/'.$name); + ->with(self::$DI['cli']['root.path'].'/www/plugins/'.$name); - self::$DI['app']['filesystem']->expects($this->at(1)) + self::$DI['cli']['filesystem']->expects($this->at(1)) ->method('remove') - ->with(self::$DI['app']['plugins.directory'].'/'.$name); + ->with(self::$DI['cli']['plugins.directory'].'/'.$name); $result = $command->execute($input, $output); diff --git a/tests/Alchemy/Tests/Phrasea/Command/Setup/InstallTest.php b/tests/Alchemy/Tests/Phrasea/Command/Setup/InstallTest.php index 20591b51e0..88f1d6ef34 100644 --- a/tests/Alchemy/Tests/Phrasea/Command/Setup/InstallTest.php +++ b/tests/Alchemy/Tests/Phrasea/Command/Setup/InstallTest.php @@ -78,17 +78,17 @@ class InstallTest extends \PhraseanetPHPUnitAbstract } })); - self::$DI['app']['phraseanet.installer'] = $this->getMockBuilder('Alchemy\Phrasea\Setup\Installer') + self::$DI['cli']['phraseanet.installer'] = $this->getMockBuilder('Alchemy\Phrasea\Setup\Installer') ->disableOriginalConstructor() ->getMock(); - self::$DI['app']['phraseanet.installer']->expects($this->once()) + self::$DI['cli']['phraseanet.installer']->expects($this->once()) ->method('install') ->with($email, $password, $this->isInstanceOf('\connection_interface'), $serverName, $dataPath, $this->isInstanceOf('\connection_interface'), $template, $this->anything()); $command = new Install('system:check'); $command->setHelperSet($helperSet); - $command->setContainer(self::$DI['app']); + $command->setContainer(self::$DI['cli']); $this->assertEquals(0, $command->execute($input, $output)); } } diff --git a/tests/Alchemy/Tests/Phrasea/Command/Setup/XSendFileMappingGeneratorTest.php b/tests/Alchemy/Tests/Phrasea/Command/Setup/XSendFileMappingGeneratorTest.php index 41eaac064d..fe5d2d1b2c 100644 --- a/tests/Alchemy/Tests/Phrasea/Command/Setup/XSendFileMappingGeneratorTest.php +++ b/tests/Alchemy/Tests/Phrasea/Command/Setup/XSendFileMappingGeneratorTest.php @@ -27,19 +27,19 @@ class XSendFileMappingGeneratorTest extends \PhraseanetPHPUnitAbstract $command = new XSendFileMappingGenerator(); $phpunit = $this; - self::$DI['app']['monolog'] = self::$DI['app']->share(function () use ($phpunit) { + self::$DI['cli']['monolog'] = self::$DI['cli']->share(function () use ($phpunit) { return $phpunit->getMockBuilder('Monolog\Logger')->disableOriginalConstructor()->getMock(); }); - self::$DI['app']['phraseanet.configuration'] = $this->getMock('Alchemy\Phrasea\Core\Configuration\ConfigurationInterface'); + self::$DI['cli']['phraseanet.configuration'] = $this->getMock('Alchemy\Phrasea\Core\Configuration\ConfigurationInterface'); if ($option) { - self::$DI['app']['phraseanet.configuration']->expects($this->once()) + self::$DI['cli']['phraseanet.configuration']->expects($this->once()) ->method('offsetSet') ->with('xsendfile'); } else { - self::$DI['app']['phraseanet.configuration']->expects($this->never()) + self::$DI['cli']['phraseanet.configuration']->expects($this->never()) ->method('offsetSet'); } - $command->setContainer(self::$DI['app']); + $command->setContainer(self::$DI['cli']); $this->assertEquals(0, $command->execute($input, $output)); } @@ -55,7 +55,7 @@ class XSendFileMappingGeneratorTest extends \PhraseanetPHPUnitAbstract ->will($this->returnValue(null)); $command = new XSendFileMappingGenerator(); - $command->setContainer(self::$DI['app']); + $command->setContainer(self::$DI['cli']); $this->setExpectedException('Alchemy\Phrasea\Exception\InvalidArgumentException'); $command->execute($input, $output); } diff --git a/tests/Alchemy/Tests/Phrasea/Controller/Root/LoginTest.php b/tests/Alchemy/Tests/Phrasea/Controller/Root/LoginTest.php index 2d67784fa8..0e74c446cd 100644 --- a/tests/Alchemy/Tests/Phrasea/Controller/Root/LoginTest.php +++ b/tests/Alchemy/Tests/Phrasea/Controller/Root/LoginTest.php @@ -456,7 +456,6 @@ class LoginTest extends \PhraseanetWebTestCaseAuthenticatedAbstract $crawler = self::$DI['client']->request('GET', '/login/register-classic/?providerId=provider-test'); - echo self::$DI['client']->getResponse(); $this->assertEquals(200, self::$DI['client']->getResponse()->getStatusCode()); $this->assertEquals(1, $crawler->filterXPath("//input[@value='supermail@superprovider.com' and @name='email']")->count()); } diff --git a/tests/Alchemy/Tests/Phrasea/Core/CLIProvider/CLISDriversServiceProviderTest.php b/tests/Alchemy/Tests/Phrasea/Core/CLIProvider/CLISDriversServiceProviderTest.php new file mode 100644 index 0000000000..8def67d92d --- /dev/null +++ b/tests/Alchemy/Tests/Phrasea/Core/CLIProvider/CLISDriversServiceProviderTest.php @@ -0,0 +1,35 @@ +register(new PluginServiceProvider()); $this->assertFileExists($app['plugins.schema']); @@ -83,7 +77,7 @@ class PluginServiceProvidertest extends ServiceProviderTestCase public function testPluginDirIsDefined() { - $app = new Application(); + $app = self::$DI['cli']; $app->register(new PluginServiceProvider()); $this->assertFileExists($app['plugins.directory']); @@ -99,7 +93,7 @@ class PluginServiceProvidertest extends ServiceProviderTestCase $this->markTestSkipped('Unable to detect PHP binary'); } - $app = new Application(); + $app = self::$DI['cli']; $app['phraseanet.configuration'] = array('binaries' => array('php_binary' => null)); $app->register(new PluginServiceProvider()); $this->assertInstanceOf('Alchemy\Phrasea\Plugin\Management\ComposerInstaller', $app['plugins.composer-installer']); @@ -107,7 +101,7 @@ class PluginServiceProvidertest extends ServiceProviderTestCase public function testInstallerCanDetectPhpConf() { - $app = new Application(); + $app = self::$DI['cli']; $app['phraseanet.configuration'] = array('binaries' => array('php_binary' => null)); $app->register(new PluginServiceProvider()); $this->assertInstanceOf('Alchemy\Phrasea\Plugin\Management\ComposerInstaller', $app['plugins.composer-installer']); diff --git a/tests/Alchemy/Tests/Phrasea/Core/CLIProvider/ServiceProviderTestCase.php b/tests/Alchemy/Tests/Phrasea/Core/CLIProvider/ServiceProviderTestCase.php new file mode 100644 index 0000000000..5df7eb3c47 --- /dev/null +++ b/tests/Alchemy/Tests/Phrasea/Core/CLIProvider/ServiceProviderTestCase.php @@ -0,0 +1,24 @@ +register(new $service()); + + $instance1 = $cli[$key]; + $instance2 = $cli[$key]; + + $this->assertInstanceof($classname, $instance1); + $this->assertEquals($instance1, $instance2); + } + + abstract public function provideServiceDescription(); +} diff --git a/tests/Alchemy/Tests/Phrasea/Core/Provider/FileServeServiceProviderTest.php b/tests/Alchemy/Tests/Phrasea/Core/Provider/FileServeServiceProviderTest.php index ce19687235..749f7288d8 100644 --- a/tests/Alchemy/Tests/Phrasea/Core/Provider/FileServeServiceProviderTest.php +++ b/tests/Alchemy/Tests/Phrasea/Core/Provider/FileServeServiceProviderTest.php @@ -4,7 +4,6 @@ namespace Alchemy\Tests\Phrasea\Core\Provider; use Alchemy\Phrasea\Core\Provider\ConfigurationServiceProvider; use Alchemy\Phrasea\Core\Provider\FileServeServiceProvider; -use Silex\Application; /** * @covers Alchemy\Phrasea\Core\Provider\FileServeServiceProvider diff --git a/tests/Alchemy/Tests/Phrasea/Plugin/Fixtures/PluginDir/TestPlugin/src/Vendor/CustomCommand.php b/tests/Alchemy/Tests/Phrasea/Plugin/Fixtures/PluginDir/TestPlugin/src/Vendor/CustomCommand.php index 82e7e938a3..0051227424 100644 --- a/tests/Alchemy/Tests/Phrasea/Plugin/Fixtures/PluginDir/TestPlugin/src/Vendor/CustomCommand.php +++ b/tests/Alchemy/Tests/Phrasea/Plugin/Fixtures/PluginDir/TestPlugin/src/Vendor/CustomCommand.php @@ -12,7 +12,7 @@ class CustomCommand extends Command { parent::__construct('hello:world'); } - + protected function execute(InputInterface $input, OutputInterface $output) { $output->write('Hello World'); diff --git a/tests/Alchemy/Tests/Phrasea/Plugin/Management/ComposerInstallerTest.php b/tests/Alchemy/Tests/Phrasea/Plugin/Management/ComposerInstallerTest.php index abe7bd7671..07e954e7c8 100644 --- a/tests/Alchemy/Tests/Phrasea/Plugin/Management/ComposerInstallerTest.php +++ b/tests/Alchemy/Tests/Phrasea/Plugin/Management/ComposerInstallerTest.php @@ -3,6 +3,7 @@ namespace Alchemy\Phrasea\Plugin\Management; use Alchemy\Phrasea\Plugin\Management\ComposerInstaller; +use Alchemy\Phrasea\Utilities\ComposerSetup; use Guzzle\Http\Client as Guzzle; use Symfony\Component\Process\ExecutableFinder; use Symfony\Component\Filesystem\Filesystem; @@ -26,7 +27,11 @@ class ComposerInstallerTest extends \PHPUnit_Framework_TestCase $this->markTestSkipped('Unable to find PHP executable.'); } - $installer = new ComposerInstaller(__DIR__, new Guzzle(), $php); + $setupMock = $this->getMockBuilder('Alchemy\Phrasea\Utilities\ComposerSetup') + ->disableOriginalConstructor() + ->getMock(); + + $installer = new ComposerInstaller(new ComposerSetup(new Guzzle()), __DIR__, $php); $installer->install(__DIR__ . '/../Fixtures/PluginDir/TestPlugin'); $this->assertFileExists($composer); diff --git a/tests/Alchemy/Tests/Phrasea/Plugin/PluginTestCase.php b/tests/Alchemy/Tests/Phrasea/Plugin/PluginTestCase.php index e1cd027f17..448d6f29b0 100644 --- a/tests/Alchemy/Tests/Phrasea/Plugin/PluginTestCase.php +++ b/tests/Alchemy/Tests/Phrasea/Plugin/PluginTestCase.php @@ -8,7 +8,7 @@ class PluginTestCase extends \PhraseanetPHPUnitAbstract { protected function createManifestValidator() { - return ManifestValidator::create(self::$DI['app']); + return ManifestValidator::create(self::$DI['cli']); } protected function getPluginDirectory() diff --git a/tests/Alchemy/Tests/Phrasea/Plugin/Schema/ManifestValidatorTest.php b/tests/Alchemy/Tests/Phrasea/Plugin/Schema/ManifestValidatorTest.php index 10e7ef9ee9..992bb9eaaa 100644 --- a/tests/Alchemy/Tests/Phrasea/Plugin/Schema/ManifestValidatorTest.php +++ b/tests/Alchemy/Tests/Phrasea/Plugin/Schema/ManifestValidatorTest.php @@ -62,12 +62,12 @@ class ManifestValidatorTest extends PluginTestCase */ public function testConstructWithInvalidSchema() { - new ManifestValidator(new JsonSchemaValidator(), array(), self::$DI['app']['phraseanet.version']); + new ManifestValidator(new JsonSchemaValidator(), array(), self::$DI['cli']['phraseanet.version']); } public function testCreate() { - $validator = ManifestValidator::create(self::$DI['app']); + $validator = ManifestValidator::create(self::$DI['cli']); $this->assertInstanceOf('Alchemy\Phrasea\Plugin\Schema\ManifestValidator', $validator); } @@ -76,6 +76,6 @@ class ManifestValidatorTest extends PluginTestCase { $schema = json_decode($this->getSchema()); - return new ManifestValidator(new JsonSchemaValidator(), $schema, self::$DI['app']['phraseanet.version']); + return new ManifestValidator(new JsonSchemaValidator(), $schema, self::$DI['cli']['phraseanet.version']); } } diff --git a/tests/Alchemy/Tests/Phrasea/Utilities/ComposerSetupTest.php b/tests/Alchemy/Tests/Phrasea/Utilities/ComposerSetupTest.php new file mode 100644 index 0000000000..109179f58a --- /dev/null +++ b/tests/Alchemy/Tests/Phrasea/Utilities/ComposerSetupTest.php @@ -0,0 +1,34 @@ +setup($target); + + $finder = new PhpExecutableFinder(); + $php = $finder->find(); + + $process = ProcessBuilder::create(array($php, $target, '--version'))->getProcess(); + $process->run(); + + $this->assertTrue($process->isSuccessful()); + $this->assertSame(0, strpos($process->getOutput(), 'Composer version')); + + unlink($target); + } +} diff --git a/tests/classes/PhraseanetPHPUnitAbstract.php b/tests/classes/PhraseanetPHPUnitAbstract.php index 9125980e9b..0499a6aab8 100644 --- a/tests/classes/PhraseanetPHPUnitAbstract.php +++ b/tests/classes/PhraseanetPHPUnitAbstract.php @@ -1,5 +1,6 @@ share(function($DI) use ($phpunit) { + $app = new CLI('cli test', null, 'test'); + + $app['form.csrf_provider'] = $app->share(function () { + return new CsrfTestProvider(); + }); + + $app['url_generator'] = $app->share($app->extend('url_generator', function($generator, $app) { + $host = parse_url($app['phraseanet.configuration']['main']['servername'], PHP_URL_HOST); + $generator->setContext(new RequestContext('', 'GET', $host)); + + return $generator; + })); + + $app['debug'] = true; + + $app['EM'] = $app->share($app->extend('EM', function($em) { + @unlink('/tmp/db.sqlite'); + copy(__DIR__ . '/../db-ref.sqlite', '/tmp/db.sqlite'); + + return $em; + })); + + $app['browser'] = $app->share($app->extend('browser', function($browser) { + + $browser->setUserAgent(PhraseanetPHPUnitAbstract::USER_AGENT_FIREFOX8MAC); + + return $browser; + })); + + $app['notification.deliverer'] = $phpunit->getMockBuilder('Alchemy\Phrasea\Notification\Deliverer') + ->disableOriginalConstructor() + ->getMock(); + $app['notification.deliverer']->expects($phpunit->any()) + ->method('deliver') + ->will($phpunit->returnCallback(function() use ($phpunit) { + $phpunit->fail('Notification deliverer must be mocked'); + })); + + return $app; + }); + self::$DI['client'] = self::$DI->share(function($DI) { return new Client($DI['app'], array()); }); diff --git a/tests/classes/recordutils/imageTest.php b/tests/classes/recordutils/imageTest.php index 0bb7c19a95..dd40755260 100644 --- a/tests/classes/recordutils/imageTest.php +++ b/tests/classes/recordutils/imageTest.php @@ -46,9 +46,9 @@ class recordutils_imageTest extends PhraseanetPHPUnitAbstract $prefs = ' - 0 + 0 - + Date: Record_id: '; @@ -59,9 +59,9 @@ class recordutils_imageTest extends PhraseanetPHPUnitAbstract } $prefs .= ' - 1 - - + 1 + + '; $newdom = new DOMDocument(); @@ -105,4 +105,4 @@ class recordutils_imageTest extends PhraseanetPHPUnitAbstract $this->assertTrue(0 === strpos(basename($path), 'stamp_')); unlink($path); } -} \ No newline at end of file +} diff --git a/vendors.php b/vendors.php deleted file mode 100755 index 83afe27135..0000000000 --- a/vendors.php +++ /dev/null @@ -1,137 +0,0 @@ -#!/usr/bin/env php - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -/** - * Get all dependencies needed for Phraseanet - */ -chdir(__DIR__); - -set_time_limit(0); - -$bower = 'bower'; -$node = 'node'; -$recess = 'recess'; -$uglifyjs = 'uglifyjs'; -$npm = 'npm'; - -// Test if node exists -exec(sprintf('%s -v', $node), $output, $code); - -if (0 !== $code) { - echo sprintf('%s is required to install vendors', $node); - exit(1); -} - -// Test if npm exists -exec(sprintf('%s -v', $npm), $output, $code); - -if (0 !== $code) { - echo sprintf('%s is required to install vendors', $npm), - exit(1); -} - -// Test if bower exists else install it -exec(sprintf('%s -v', $bower), $output, $code); - -if (0 !== $code) { - exec(sprintf('sudo %s install %s -g', $npm, $bower), $output, $code); - - if (0 !== $code) { - echo sprintf('Failed to install %s', $bower); - exit(1); - } -} - -// Tests if recess exists else install it -exec(sprintf('%s -v', $recess), $output, $code); - -if (0 !== $code) { - exec(sprintf('sudo %s install %s -g', $npm, $recess), $output, $code); - - if (0 !== $code) { - echo sprintf('Failed to install %s', $recess); - exit(1); - } -} - -// Tests if recess exists else install it -exec('uglifyjs --version', $output, $code); - -if (0 !== $code) { - exec(sprintf('sudo %s install uglify-js -g', $npm), $output, $code); - - if (0 !== $code) { - echo 'Failed to install uglifyjs'; - exit(1); - } -} - -// Remove previous assets -$assetDir = __DIR__. '/www/assets'; -$code = 0; -if (is_dir($assetDir)) { - system('rm -r ' . escapeshellarg($assetDir), $code); -} - -if (0 !== $code) { - echo sprintf('Warning, failed to remove previous %s dependencies in %s', $bower, $assetDir); - echo "\n"; -} - -// Clean bower cache -system(sprintf('%s cache-clean', $bower), $code); - -if (0 !== $code) { - echo sprintf('Warning, failed to clean %s cache', $bower); - echo "\n"; -} - -// Install asset dependencies with bower -system(sprintf('%s install', $bower), $code); - -if (0 !== $code) { - echo sprintf('Failed to install %s dependencies', $bower); - exit(1); -} - -// Test if composer exists else install it -$composer = __DIR__ . '/composer.phar'; - -exec('composer', $output, $code); - -if (0 !== $code && ! file_exists($composer)) { - system('curl -s http://getcomposer.org/installer | php'); - system('chmod +x ' . $composer); - - if (isset($argv[1]) && $argv[1] == '--no-dev') { - system($composer . ' install --optimize-autoloader --no-dev'); - } else { - system($composer . ' install --dev --optimize-autoloader'); - } -} - -if (0 === $code) { - $composer = 'composer'; -} elseif ( ! is_executable($composer)) { - system('chmod +x ' . $composer); -} - -system($composer . ' self-update'); - -if (isset($argv[1]) && $argv[1] == '--no-dev') { - system($composer . ' install --optimize-autoloader --no-dev'); -} else { - system($composer . ' install --dev --optimize-autoloader'); -} - -system('bin/setup assets:compile-less'); -system('bin/setup assets:build-javascript'); diff --git a/vendors.win.php b/vendors.win.php deleted file mode 100755 index 7d147ae84b..0000000000 --- a/vendors.win.php +++ /dev/null @@ -1,49 +0,0 @@ -#!/usr/bin/env php - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -/** - * Get all dependencies needed for Phraseanet (Windows Version) - */ -/* Set the variables gitDir and phpDir with a trailing slash if it is not set in Windows' %PATH% - * For example : - * $gitDir="c:/msysgit/bin/"; - * $phpDir="c:/php5310/" - */ -$gitDir = ""; -$phpDir = ""; - - -chdir(__DIR__); - -set_time_limit(0); - -$composer = __DIR__ . '/composer.phar'; - -if ( ! file_exists($composer)) { - file_put_contents($composer, file_get_contents('http://getcomposer.org/installer'), LOCK_EX); - system($phpDir . 'php ' . $composer . ' install --dev'); -} - -system($phpDir . 'php ' . $composer . ' self-update'); -system($phpDir . 'php ' . $composer . ' install --dev'); - -system($gitDir . 'git submodule init'); -system($gitDir . 'git submodule update'); - -$iterator = new RecursiveDirectoryIterator(__DIR__ . '/lib/vendor/'); - -foreach ($iterator as $file) { - /* @var $file SplFileInfo */ - if ($file->isDir()) { - $cmd = sprintf('cd %s && ' . $gitDir . 'git submodule init && ' . $gitDir . 'git submodule update', escapeshellarg($file->getPathname())); - system($cmd); - } -}