sfGenerateAppTask.class.php 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159
  1. <?php
  2. /*
  3. * This file is part of the symfony package.
  4. * (c) 2004-2006 Fabien Potencier <fabien.potencier@symfony-project.com>
  5. *
  6. * For the full copyright and license information, please view the LICENSE
  7. * file that was distributed with this source code.
  8. */
  9. require_once(dirname(__FILE__).'/sfGeneratorBaseTask.class.php');
  10. /**
  11. * Generates a new application.
  12. *
  13. * @package symfony
  14. * @subpackage task
  15. * @author Fabien Potencier <fabien.potencier@symfony-project.com>
  16. * @version SVN: $Id: sfGenerateAppTask.class.php 14518 2009-01-06 22:36:41Z Kris.Wallsmith $
  17. */
  18. class sfGenerateAppTask extends sfGeneratorBaseTask
  19. {
  20. /**
  21. * @see sfTask
  22. */
  23. protected function doRun(sfCommandManager $commandManager, $options)
  24. {
  25. $this->process($commandManager, $options);
  26. $this->checkProjectExists();
  27. return $this->execute($commandManager->getArgumentValues(), $commandManager->getOptionValues());
  28. }
  29. /**
  30. * @see sfTask
  31. */
  32. protected function configure()
  33. {
  34. $this->addArguments(array(
  35. new sfCommandArgument('application', sfCommandArgument::REQUIRED, 'The application name'),
  36. ));
  37. $this->addOptions(array(
  38. new sfCommandOption('escaping-strategy', null, sfCommandOption::PARAMETER_REQUIRED, 'Output escaping strategy', false),
  39. new sfCommandOption('csrf-secret', null, sfCommandOption::PARAMETER_REQUIRED, 'Secret to use for CSRF protection', false),
  40. ));
  41. $this->aliases = array('init-app');
  42. $this->namespace = 'generate';
  43. $this->name = 'app';
  44. $this->briefDescription = 'Generates a new application';
  45. $this->detailedDescription = <<<EOF
  46. The [generate:app|INFO] task creates the basic directory structure
  47. for a new application in the current project:
  48. [./symfony generate:app frontend|INFO]
  49. This task also creates two front controller scripts in the
  50. [web/|COMMENT] directory:
  51. [web/%application%.php|INFO] for the production environment
  52. [web/%application%_dev.php|INFO] for the development environment
  53. For the first application, the production environment script is named
  54. [index.php|COMMENT].
  55. If an application with the same name already exists,
  56. it throws a [sfCommandException|COMMENT].
  57. You can enable output escaping (to prevent XSS) by using the [escaping-strategy|COMMENT] option:
  58. [./symfony generate:app frontend --escaping-strategy=on|INFO]
  59. You can enable session token in forms (to prevent CSRF) by defining
  60. a secret with the [csrf-secret|COMMENT] option:
  61. [./symfony generate:app frontend --csrf-secret=UniqueSecret|INFO]
  62. EOF;
  63. }
  64. /**
  65. * @see sfTask
  66. */
  67. protected function execute($arguments = array(), $options = array())
  68. {
  69. $app = $arguments['application'];
  70. // Validate the application name
  71. if (!preg_match('/^[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*$/', $app))
  72. {
  73. throw new sfCommandException(sprintf('The application name "%s" is invalid.', $app));
  74. }
  75. $appDir = sfConfig::get('sf_apps_dir').'/'.$app;
  76. if (is_dir($appDir))
  77. {
  78. throw new sfCommandException(sprintf('The application "%s" already exists.', $appDir));
  79. }
  80. // Create basic application structure
  81. $finder = sfFinder::type('any')->discard('.sf');
  82. $this->getFilesystem()->mirror(dirname(__FILE__).'/skeleton/app/app', $appDir, $finder);
  83. // Create $app.php or index.php if it is our first app
  84. $indexName = 'index';
  85. $firstApp = !file_exists(sfConfig::get('sf_web_dir').'/index.php');
  86. if (!$firstApp)
  87. {
  88. $indexName = $app;
  89. }
  90. // Set no_script_name value in settings.yml for production environment
  91. $finder = sfFinder::type('file')->name('settings.yml');
  92. $this->getFilesystem()->replaceTokens($finder->in($appDir.'/config'), '##', '##', array(
  93. 'NO_SCRIPT_NAME' => $firstApp ? 'on' : 'off',
  94. 'CSRF_SECRET' => sfYamlInline::dump($options['csrf-secret']),
  95. 'ESCAPING_STRATEGY' => sfYamlInline::dump((boolean) sfYamlInline::parseScalar($options['escaping-strategy'])),
  96. ));
  97. $this->getFilesystem()->copy(dirname(__FILE__).'/skeleton/app/web/index.php', sfConfig::get('sf_web_dir').'/'.$indexName.'.php');
  98. $this->getFilesystem()->copy(dirname(__FILE__).'/skeleton/app/web/index.php', sfConfig::get('sf_web_dir').'/'.$app.'_dev.php');
  99. $this->getFilesystem()->replaceTokens(sfConfig::get('sf_web_dir').'/'.$indexName.'.php', '##', '##', array(
  100. 'APP_NAME' => $app,
  101. 'ENVIRONMENT' => 'prod',
  102. 'IS_DEBUG' => 'false',
  103. 'IP_CHECK' => '',
  104. ));
  105. $this->getFilesystem()->replaceTokens(sfConfig::get('sf_web_dir').'/'.$app.'_dev.php', '##', '##', array(
  106. 'APP_NAME' => $app,
  107. 'ENVIRONMENT' => 'dev',
  108. 'IS_DEBUG' => 'true',
  109. 'IP_CHECK' => '// this check prevents access to debug front controllers that are deployed by accident to production servers.'.PHP_EOL.
  110. '// feel free to remove this, extend it or make something more sophisticated.'.PHP_EOL.
  111. 'if (!in_array(@$_SERVER[\'REMOTE_ADDR\'], array(\'127.0.0.1\', \'::1\')))'.PHP_EOL.
  112. '{'.PHP_EOL.
  113. ' die(\'You are not allowed to access this file. Check \'.basename(__FILE__).\' for more information.\');'.PHP_EOL.
  114. '}'.PHP_EOL,
  115. ));
  116. $this->getFilesystem()->rename($appDir.'/config/ApplicationConfiguration.class.php', $appDir.'/config/'.$app.'Configuration.class.php');
  117. $this->getFilesystem()->replaceTokens($appDir.'/config/'.$app.'Configuration.class.php', '##', '##', array('APP_NAME' => $app));
  118. $fixPerms = new sfProjectPermissionsTask($this->dispatcher, $this->formatter);
  119. $fixPerms->setCommandApplication($this->commandApplication);
  120. $fixPerms->run();
  121. // Create test dir
  122. $this->getFilesystem()->mkdirs(sfConfig::get('sf_test_dir').'/functional/'.$app);
  123. }
  124. }