PageRenderTime 56ms CodeModel.GetById 28ms RepoModel.GetById 1ms app.codeStats 0ms

/mautic/vendor/sensio/distribution-bundle/Sensio/Bundle/DistributionBundle/Composer/ScriptHandler.php

https://gitlab.com/randydanniswara/website
PHP | 261 lines | 160 code | 44 blank | 57 comment | 21 complexity | 78aaee9e10bf47e9c1fc788319bd4ca8 MD5 | raw file
  1. <?php
  2. /*
  3. * This file is part of the Symfony package.
  4. *
  5. * (c) Fabien Potencier <fabien@symfony.com>
  6. *
  7. * For the full copyright and license information, please view the LICENSE
  8. * file that was distributed with this source code.
  9. */
  10. namespace Sensio\Bundle\DistributionBundle\Composer;
  11. use Symfony\Component\ClassLoader\ClassCollectionLoader;
  12. use Symfony\Component\Filesystem\Filesystem;
  13. use Symfony\Component\Process\Process;
  14. use Symfony\Component\Process\PhpExecutableFinder;
  15. use Composer\Script\CommandEvent;
  16. /**
  17. * @author Jordi Boggiano <j.boggiano@seld.be>
  18. */
  19. class ScriptHandler
  20. {
  21. /**
  22. * Builds the bootstrap file.
  23. *
  24. * The bootstrap file contains PHP file that are always needed by the application.
  25. * It speeds up the application bootstrapping.
  26. *
  27. * @param $event CommandEvent A instance
  28. */
  29. public static function buildBootstrap(CommandEvent $event)
  30. {
  31. $options = self::getOptions($event);
  32. $appDir = $options['symfony-app-dir'];
  33. if (!is_dir($appDir)) {
  34. echo 'The symfony-app-dir ('.$appDir.') specified in composer.json was not found in '.getcwd().', can not build bootstrap file.'.PHP_EOL;
  35. return;
  36. }
  37. static::executeBuildBootstrap($appDir, $options['process-timeout']);
  38. }
  39. /**
  40. * Sets up deployment target specific features.
  41. * Could be custom web server configs, boot command files etc.
  42. *
  43. * @param $event CommandEvent An instance
  44. */
  45. public static function prepareDeploymentTarget(CommandEvent $event)
  46. {
  47. self::prepareDeploymentTargetHeroku($event);
  48. }
  49. protected static function prepareDeploymentTargetHeroku(CommandEvent $event)
  50. {
  51. $options = self::getOptions($event);
  52. if (($stack = getenv('STACK')) && ($stack == 'cedar' || $stack == 'cedar-14')) {
  53. $fs = new Filesystem();
  54. if (!$fs->exists('Procfile')) {
  55. $event->getIO()->write('Heroku deploy detected; creating default Procfile for "web" dyno');
  56. $fs->dumpFile('Procfile', sprintf('web: $(composer config bin-dir)/heroku-php-apache2 %s/', $options['symfony-web-dir']));
  57. }
  58. }
  59. }
  60. /**
  61. * Clears the Symfony cache.
  62. *
  63. * @param $event CommandEvent A instance
  64. */
  65. public static function clearCache(CommandEvent $event)
  66. {
  67. $options = self::getOptions($event);
  68. $appDir = $options['symfony-app-dir'];
  69. if (!is_dir($appDir)) {
  70. echo 'The symfony-app-dir ('.$appDir.') specified in composer.json was not found in '.getcwd().', can not clear the cache.'.PHP_EOL;
  71. return;
  72. }
  73. static::executeCommand($event, $appDir, 'cache:clear --no-warmup', $options['process-timeout']);
  74. }
  75. /**
  76. * Installs the assets under the web root directory.
  77. *
  78. * For better interoperability, assets are copied instead of symlinked by default.
  79. *
  80. * Even if symlinks work on Windows, this is only true on Windows Vista and later,
  81. * but then, only when running the console with admin rights or when disabling the
  82. * strict user permission checks (which can be done on Windows 7 but not on Windows
  83. * Vista).
  84. *
  85. * @param $event CommandEvent A instance
  86. */
  87. public static function installAssets(CommandEvent $event)
  88. {
  89. $options = self::getOptions($event);
  90. $appDir = $options['symfony-app-dir'];
  91. $webDir = $options['symfony-web-dir'];
  92. $symlink = '';
  93. if ($options['symfony-assets-install'] == 'symlink') {
  94. $symlink = '--symlink ';
  95. } elseif ($options['symfony-assets-install'] == 'relative') {
  96. $symlink = '--symlink --relative ';
  97. }
  98. if (!is_dir($webDir)) {
  99. echo 'The symfony-web-dir ('.$webDir.') specified in composer.json was not found in '.getcwd().', can not install assets.'.PHP_EOL;
  100. return;
  101. }
  102. static::executeCommand($event, $appDir, 'assets:install '.$symlink.escapeshellarg($webDir));
  103. }
  104. /**
  105. * Updated the requirements file.
  106. *
  107. * @param $event CommandEvent A instance
  108. */
  109. public static function installRequirementsFile(CommandEvent $event)
  110. {
  111. $options = self::getOptions($event);
  112. $appDir = $options['symfony-app-dir'];
  113. if (!is_dir($appDir)) {
  114. echo 'The symfony-app-dir ('.$appDir.') specified in composer.json was not found in '.getcwd().', can not install the requirements file.'.PHP_EOL;
  115. return;
  116. }
  117. copy(__DIR__.'/../Resources/skeleton/app/SymfonyRequirements.php', $appDir.'/SymfonyRequirements.php');
  118. copy(__DIR__.'/../Resources/skeleton/app/check.php', $appDir.'/check.php');
  119. $webDir = $options['symfony-web-dir'];
  120. // if the user has already removed the config.php file, do nothing
  121. // as the file must be removed for production use
  122. if (is_file($webDir.'/config.php')) {
  123. copy(__DIR__.'/../Resources/skeleton/web/config.php', $webDir.'/config.php');
  124. }
  125. }
  126. public static function doBuildBootstrap($appDir)
  127. {
  128. $file = $appDir.'/bootstrap.php.cache';
  129. if (file_exists($file)) {
  130. unlink($file);
  131. }
  132. $classes = array(
  133. 'Symfony\\Component\\HttpFoundation\\ParameterBag',
  134. 'Symfony\\Component\\HttpFoundation\\HeaderBag',
  135. 'Symfony\\Component\\HttpFoundation\\FileBag',
  136. 'Symfony\\Component\\HttpFoundation\\ServerBag',
  137. 'Symfony\\Component\\HttpFoundation\\Request',
  138. 'Symfony\\Component\\HttpFoundation\\Response',
  139. 'Symfony\\Component\\HttpFoundation\\ResponseHeaderBag',
  140. 'Symfony\\Component\\DependencyInjection\\ContainerAwareInterface',
  141. // Cannot be included because annotations will parse the big compiled class file
  142. //'Symfony\\Component\\DependencyInjection\\ContainerAware',
  143. 'Symfony\\Component\\DependencyInjection\\Container',
  144. 'Symfony\\Component\\HttpKernel\\Kernel',
  145. 'Symfony\\Component\\ClassLoader\\ClassCollectionLoader',
  146. 'Symfony\\Component\\ClassLoader\\ApcClassLoader',
  147. 'Symfony\\Component\\HttpKernel\\Bundle\\Bundle',
  148. 'Symfony\\Component\\Config\\ConfigCache',
  149. // cannot be included as commands are discovered based on the path to this class via Reflection
  150. //'Symfony\\Bundle\\FrameworkBundle\\FrameworkBundle',
  151. );
  152. // introspect the autoloader to get the right file
  153. // we cannot use class_exist() here as it would load the class
  154. // which won't be included into the cache then.
  155. // we know that composer autoloader is first (see bin/build_bootstrap.php)
  156. $autoloaders = spl_autoload_functions();
  157. if ($autoloaders[0][0]->findFile('Symfony\\Bundle\\FrameworkBundle\\HttpKernel')) {
  158. $classes[] = 'Symfony\\Bundle\\FrameworkBundle\\HttpKernel';
  159. } else {
  160. $classes[] = 'Symfony\\Component\\HttpKernel\\DependencyInjection\\ContainerAwareHttpKernel';
  161. }
  162. ClassCollectionLoader::load($classes, dirname($file), basename($file, '.php.cache'), false, false, '.php.cache');
  163. file_put_contents($file, sprintf(<<<'EOF'
  164. <?php
  165. namespace {
  166. error_reporting(error_reporting() & ~E_USER_DEPRECATED);
  167. $loader = require_once __DIR__.'/autoload.php';
  168. }
  169. %s
  170. namespace { return $loader; }
  171. EOF
  172. , substr(file_get_contents($file), 5)));
  173. }
  174. protected static function executeCommand(CommandEvent $event, $appDir, $cmd, $timeout = 300)
  175. {
  176. $php = escapeshellarg(self::getPhp());
  177. $console = escapeshellarg($appDir.'/console');
  178. if ($event->getIO()->isDecorated()) {
  179. $console .= ' --ansi';
  180. }
  181. $process = new Process($php.' '.$console.' '.$cmd, null, null, null, $timeout);
  182. $process->run(function ($type, $buffer) { echo $buffer; });
  183. if (!$process->isSuccessful()) {
  184. throw new \RuntimeException(sprintf('An error occurred when executing the "%s" command.', escapeshellarg($cmd)));
  185. }
  186. }
  187. protected static function executeBuildBootstrap($appDir, $timeout = 300)
  188. {
  189. $php = escapeshellarg(self::getPhp());
  190. $cmd = escapeshellarg(__DIR__.'/../Resources/bin/build_bootstrap.php');
  191. $appDir = escapeshellarg($appDir);
  192. $process = new Process($php.' '.$cmd.' '.$appDir, null, null, null, $timeout);
  193. $process->run(function ($type, $buffer) { echo $buffer; });
  194. if (!$process->isSuccessful()) {
  195. throw new \RuntimeException('An error occurred when generating the bootstrap file.');
  196. }
  197. }
  198. protected static function getOptions(CommandEvent $event)
  199. {
  200. $options = array_merge(array(
  201. 'symfony-app-dir' => 'app',
  202. 'symfony-web-dir' => 'web',
  203. 'symfony-assets-install' => 'hard',
  204. ), $event->getComposer()->getPackage()->getExtra());
  205. $options['symfony-assets-install'] = getenv('SYMFONY_ASSETS_INSTALL') ?: $options['symfony-assets-install'];
  206. $options['process-timeout'] = $event->getComposer()->getConfig()->get('process-timeout');
  207. return $options;
  208. }
  209. protected static function getPhp()
  210. {
  211. $phpFinder = new PhpExecutableFinder();
  212. if (!$phpPath = $phpFinder->find()) {
  213. throw new \RuntimeException('The php executable could not be found, add it to your PATH environment variable and try again');
  214. }
  215. return $phpPath;
  216. }
  217. }