/** * @see sfTask */ protected function execute($arguments = array(), $options = array()) { $app = $arguments['app']; // Validate the application name if (!preg_match('/^[a-zA-Z_\\x7f-\\xff][a-zA-Z0-9_\\x7f-\\xff]*$/', $app)) { throw new sfCommandException(sprintf('The application name "%s" is invalid.', $app)); } $appDir = sfConfig::get('sf_apps_dir') . '/' . $app; if (is_dir($appDir)) { throw new sfCommandException(sprintf('The application "%s" already exists.', $appDir)); } if (is_readable(sfConfig::get('sf_data_dir') . '/skeleton/app')) { $skeletonDir = sfConfig::get('sf_data_dir') . '/skeleton/app'; } else { $skeletonDir = __DIR__ . '/skeleton/app'; } // Create basic application structure $finder = sfFinder::type('any')->discard('.sf'); $this->getFilesystem()->mirror($skeletonDir . '/app', $appDir, $finder); // Create $app.php or index.php if it is our first app $indexName = 'index'; $firstApp = !file_exists(sfConfig::get('sf_web_dir') . '/index.php'); if (!$firstApp) { $indexName = $app; } if (true === $options['csrf-secret']) { $options['csrf-secret'] = sha1(mt_rand(11111111, 99999999) . getmypid()); } // Set no_script_name value in settings.yml for production environment $finder = sfFinder::type('file')->name('settings.yml'); $this->getFilesystem()->replaceTokens($finder->in($appDir . '/config'), '##', '##', array('NO_SCRIPT_NAME' => $firstApp ? 'true' : 'false', 'CSRF_SECRET' => sfYamlInline::dump(sfYamlInline::parseScalar($options['csrf-secret'])), 'ESCAPING_STRATEGY' => sfYamlInline::dump((bool) sfYamlInline::parseScalar($options['escaping-strategy'])), 'USE_DATABASE' => sfConfig::has('sf_orm') ? 'true' : 'false')); $this->getFilesystem()->copy($skeletonDir . '/web/index.php', sfConfig::get('sf_web_dir') . '/' . $indexName . '.php'); $this->getFilesystem()->copy($skeletonDir . '/web/index.php', sfConfig::get('sf_web_dir') . '/' . $app . '_dev.php'); $this->getFilesystem()->replaceTokens(sfConfig::get('sf_web_dir') . '/' . $indexName . '.php', '##', '##', array('APP_NAME' => $app, 'ENVIRONMENT' => 'prod', 'IS_DEBUG' => 'false', 'IP_CHECK' => '')); $this->getFilesystem()->replaceTokens(sfConfig::get('sf_web_dir') . '/' . $app . '_dev.php', '##', '##', array('APP_NAME' => $app, 'ENVIRONMENT' => 'dev', 'IS_DEBUG' => 'true', 'IP_CHECK' => '// this check prevents access to debug front controllers that are deployed by accident to production servers.' . PHP_EOL . '// feel free to remove this, extend it or make something more sophisticated.' . PHP_EOL . 'if (!in_array(@$_SERVER[\'REMOTE_ADDR\'], array(\'127.0.0.1\', \'::1\')))' . PHP_EOL . '{' . PHP_EOL . ' die(\'You are not allowed to access this file. Check \'.basename(__FILE__).\' for more information.\');' . PHP_EOL . '}' . PHP_EOL)); $this->getFilesystem()->rename($appDir . '/config/ApplicationConfiguration.class.php', $appDir . '/config/' . $app . 'Configuration.class.php'); $this->getFilesystem()->replaceTokens($appDir . '/config/' . $app . 'Configuration.class.php', '##', '##', array('APP_NAME' => $app)); $fixPerms = new sfProjectPermissionsTask($this->dispatcher, $this->formatter); $fixPerms->setCommandApplication($this->commandApplication); $fixPerms->setConfiguration($this->configuration); $fixPerms->run(); // Create test dir $this->getFilesystem()->mkdirs(sfConfig::get('sf_test_dir') . '/functional/' . $app); }
/** * Parses a YAML string to a PHP value. * * @param string $value A YAML string * * @return mixed A PHP value */ public function parse($value) { $this->value = $this->cleanup($value); $this->currentLineNb = -1; $this->currentLine = ''; $this->lines = explode("\n", $this->value); $data = array(); while ($this->moveToNextLine()) { if ($this->isCurrentLineEmpty()) { continue; } // tab? if (preg_match('#^\\t+#', $this->currentLine)) { throw new InvalidArgumentException(sprintf('A YAML file cannot contain tabs as indentation at line %d (%s).', $this->getRealCurrentLineNb() + 1, $this->currentLine)); } $isRef = $isInPlace = $isProcessed = false; if (preg_match('#^\\-(\\s+(?P<value>.+?))?\\s*$#', $this->currentLine, $values)) { if (isset($values['value']) && preg_match('#^&(?P<ref>[^ ]+) *(?P<value>.*)#', $values['value'], $matches)) { $isRef = $matches['ref']; $values['value'] = $matches['value']; } // array if (!isset($values['value']) || '' == trim($values['value'], ' ') || 0 === strpos(ltrim($values['value'], ' '), '#')) { $c = $this->getRealCurrentLineNb() + 1; $parser = new sfYamlParser($c); $parser->refs =& $this->refs; $data[] = $parser->parse($this->getNextEmbedBlock()); } else { if (preg_match('/^([^ ]+)\\: +({.*?)$/', $values['value'], $matches)) { $data[] = array($matches[1] => sfYamlInline::load($matches[2])); } else { $data[] = $this->parseValue($values['value']); } } } else { if (preg_match('#^(?P<key>[^ ].*?) *\\:(\\s+(?P<value>.+?))?\\s*$#', $this->currentLine, $values)) { $key = sfYamlInline::parseScalar($values['key']); if ('<<' === $key) { if (isset($values['value']) && '*' === substr($values['value'], 0, 1)) { $isInPlace = substr($values['value'], 1); if (!array_key_exists($isInPlace, $this->refs)) { throw new InvalidArgumentException(sprintf('Reference "%s" does not exist at line %s (%s).', $isInPlace, $this->getRealCurrentLineNb() + 1, $this->currentLine)); } } else { if (isset($values['value']) && $values['value'] !== '') { $value = $values['value']; } else { $value = $this->getNextEmbedBlock(); } $c = $this->getRealCurrentLineNb() + 1; $parser = new sfYamlParser($c); $parser->refs =& $this->refs; $parsed = $parser->parse($value); $merged = array(); if (!is_array($parsed)) { throw new InvalidArgumentException(sprintf("YAML merge keys used with a scalar value instead of an array at line %s (%s)", $this->getRealCurrentLineNb() + 1, $this->currentLine)); } else { if (isset($parsed[0])) { // Numeric array, merge individual elements foreach (array_reverse($parsed) as $parsedItem) { if (!is_array($parsedItem)) { throw new InvalidArgumentException(sprintf("Merge items must be arrays at line %s (%s).", $this->getRealCurrentLineNb() + 1, $parsedItem)); } $merged = array_merge($parsedItem, $merged); } } else { // Associative array, merge $merged = array_merge($merge, $parsed); } } $isProcessed = $merged; } } else { if (isset($values['value']) && preg_match('#^&(?P<ref>[^ ]+) *(?P<value>.*)#', $values['value'], $matches)) { $isRef = $matches['ref']; $values['value'] = $matches['value']; } } if ($isProcessed) { // Merge keys $data = $isProcessed; } else { if (!isset($values['value']) || '' == trim($values['value'], ' ') || 0 === strpos(ltrim($values['value'], ' '), '#')) { // if next line is less indented or equal, then it means that the current value is null if ($this->isNextLineIndented()) { $data[$key] = null; } else { $c = $this->getRealCurrentLineNb() + 1; $parser = new sfYamlParser($c); $parser->refs =& $this->refs; $data[$key] = $parser->parse($this->getNextEmbedBlock()); } } else { if ($isInPlace) { $data = $this->refs[$isInPlace]; } else { $data[$key] = $this->parseValue($values['value']); } } } } else { // one liner? if (1 == count(explode("\n", rtrim($this->value, "\n")))) { $value = sfYamlInline::load($this->lines[0]); if (is_array($value)) { $first = reset($value); if ('*' === substr($first, 0, 1)) { $data = array(); foreach ($value as $alias) { $data[] = $this->refs[substr($alias, 1)]; } $value = $data; } } return $value; } throw new InvalidArgumentException(sprintf('Unable to parse line %d (%s).', $this->getRealCurrentLineNb() + 1, $this->currentLine)); } } if ($isRef) { $this->refs[$isRef] = end($data); } } return empty($data) ? null : $data; }
/** * Parses a YAML string to a PHP value. * * @param string $value A YAML string * * @return mixed A PHP value * * @throws InvalidArgumentException If the YAML is not valid */ public function parse($value) { $this->currentLineNb = -1; $this->currentLine = ''; $this->lines = explode("\n", $this->cleanup($value)); if (function_exists('mb_internal_encoding') && (int) ini_get('mbstring.func_overload') & 2) { $mbEncoding = mb_internal_encoding(); mb_internal_encoding('UTF-8'); } $data = array(); while ($this->moveToNextLine()) { if ($this->isCurrentLineEmpty()) { continue; } // tab? if (preg_match('#^\\t+#', $this->currentLine)) { throw new InvalidArgumentException(sprintf('A YAML file cannot contain tabs as indentation at line %d (%s).', $this->getRealCurrentLineNb() + 1, $this->currentLine)); } $isRef = $isInPlace = $isProcessed = false; if (preg_match('#^\\-(\\s+(?P<value>.+?))?\\s*$#u', $this->currentLine, $values)) { if (isset($values['value']) && preg_match('#^&(?P<ref>[^ ]+) *(?P<value>.*)#u', $values['value'], $matches)) { $isRef = $matches['ref']; $values['value'] = $matches['value']; } // array if (!isset($values['value']) || '' == trim($values['value'], ' ') || 0 === strpos(ltrim($values['value'], ' '), '#')) { $c = $this->getRealCurrentLineNb() + 1; $parser = new sfYamlParser($c); $parser->refs =& $this->refs; $data[] = $parser->parse($this->getNextEmbedBlock()); } else { if (preg_match('/^([^ ]+)\\: +({.*?)$/u', $values['value'], $matches)) { $data[] = array($matches[1] => sfYamlInline::load($matches[2])); } else { $data[] = $this->parseValue($values['value']); } } } else { if (preg_match('#^(?P<key>' . sfYamlInline::REGEX_QUOTED_STRING . '|[^ ].*?) *\\:(\\s+(?P<value>.+?))?\\s*$#u', $this->currentLine, $values)) { $key = sfYamlInline::parseScalar($values['key']); if ('<<' === $key) { if (isset($values['value']) && '*' === substr($values['value'], 0, 1)) { $isInPlace = substr($values['value'], 1); if (!array_key_exists($isInPlace, $this->refs)) { throw new InvalidArgumentException(sprintf('Reference "%s" does not exist at line %s (%s).', $isInPlace, $this->getRealCurrentLineNb() + 1, $this->currentLine)); } } else { if (isset($values['value']) && $values['value'] !== '') { $value = $values['value']; } else { $value = $this->getNextEmbedBlock(); } $c = $this->getRealCurrentLineNb() + 1; $parser = new sfYamlParser($c); $parser->refs =& $this->refs; $parsed = $parser->parse($value); $merged = array(); if (!is_array($parsed)) { throw new InvalidArgumentException(sprintf("YAML merge keys used with a scalar value instead of an array at line %s (%s)", $this->getRealCurrentLineNb() + 1, $this->currentLine)); } else { if (isset($parsed[0])) { // Numeric array, merge individual elements foreach (array_reverse($parsed) as $parsedItem) { if (!is_array($parsedItem)) { throw new InvalidArgumentException(sprintf("Merge items must be arrays at line %s (%s).", $this->getRealCurrentLineNb() + 1, $parsedItem)); } $merged = array_merge($parsedItem, $merged); } } else { // Associative array, merge $merged = array_merge($merge, $parsed); } } $isProcessed = $merged; } } else { if (isset($values['value']) && preg_match('#^&(?P<ref>[^ ]+) *(?P<value>.*)#u', $values['value'], $matches)) { $isRef = $matches['ref']; $values['value'] = $matches['value']; } } if ($isProcessed) { // Merge keys $data = $isProcessed; } else { if (!isset($values['value']) || '' == trim($values['value'], ' ') || 0 === strpos(ltrim($values['value'], ' '), '#')) { // if next line is less indented or equal, then it means that the current value is null if ($this->isNextLineIndented()) { $data[$key] = null; } else { $c = $this->getRealCurrentLineNb() + 1; $parser = new sfYamlParser($c); $parser->refs =& $this->refs; $data[$key] = $parser->parse($this->getNextEmbedBlock()); } } else { if ($isInPlace) { $data = $this->refs[$isInPlace]; } else { $data[$key] = $this->parseValue($values['value']); } } } } else { // 1-liner followed by newline if (2 == count($this->lines) && empty($this->lines[1])) { $value = sfYamlInline::load($this->lines[0]); if (is_array($value)) { $first = reset($value); if ('*' === substr($first, 0, 1)) { $data = array(); foreach ($value as $alias) { $data[] = $this->refs[substr($alias, 1)]; } $value = $data; } } if (isset($mbEncoding)) { mb_internal_encoding($mbEncoding); } return $value; } switch (preg_last_error()) { case PREG_INTERNAL_ERROR: $error = 'Internal PCRE error on line'; break; case PREG_BACKTRACK_LIMIT_ERROR: $error = 'pcre.backtrack_limit reached on line'; break; case PREG_RECURSION_LIMIT_ERROR: $error = 'pcre.recursion_limit reached on line'; break; case PREG_BAD_UTF8_ERROR: $error = 'Malformed UTF-8 data on line'; break; case PREG_BAD_UTF8_OFFSET_ERROR: $error = 'Offset doesn\'t correspond to the begin of a valid UTF-8 code point on line'; break; default: $error = 'Unable to parse line'; } throw new InvalidArgumentException(sprintf('%s %d (%s).', $error, $this->getRealCurrentLineNb() + 1, $this->currentLine)); } } if ($isRef) { $this->refs[$isRef] = end($data); } } if (isset($mbEncoding)) { mb_internal_encoding($mbEncoding); } return empty($data) ? null : $data; }
/** * Parses a YAML string to a PHP value. * * @param string A YAML string * * @return mixed A PHP value */ public function parse($value) { $this->value = $this->cleanup($value); $this->currentLineNb = -1; $this->currentLine = ''; $this->lines = explode("\n", $this->value); $data = array(); while ($this->moveToNextLine()) { if ($this->isCurrentLineEmpty()) { continue; } // tab? if (preg_match('#^\\t+#', $this->currentLine)) { throw new InvalidArgumentException(sprintf('A YAML file cannot contain tabs as indentation at line %d (%s).', $this->getRealCurrentLineNb(), $this->currentLine)); } $isRef = $isInPlace = false; if (preg_match('#^\\-(\\s+(?P<value>.+?))?\\s*$#', $this->currentLine, $values)) { if (isset($values['value']) && preg_match('#^&(?P<ref>[^ ]+) *(?P<value>.*)#', $values['value'], $matches)) { $isRef = $matches['ref']; $values['value'] = $matches['value']; } // array if (!isset($values['value']) || '' == trim($values['value'], ' ') || 0 === strpos(ltrim($values['value'], ' '), '#')) { $c = $this->getRealCurrentLineNb() + 1; $parser = new sfYamlParser($c); $parser->refs =& $this->refs; $data[] = $parser->parse($this->getNextEmbedBlock()); } else { if (preg_match('/^([^ ]+)\\: +({.*?)$/', $values['value'], $matches)) { $data[] = array($matches[1] => sfYamlInline::load($matches[2])); } else { $data[] = $this->parseValue($values['value']); } } } else { if (preg_match('#^(?P<key>[^ ].*?) *\\:(\\s+(?P<value>.+?))?\\s*$#', $this->currentLine, $values)) { $key = sfYamlInline::parseScalar($values['key']); if ('<<' === $key) { if (isset($values['value']) && '*' === substr($values['value'], 0, 1)) { $isInPlace = substr($values['value'], 1); if (!array_key_exists($isInPlace, $this->refs)) { throw new InvalidArgumentException(sprintf('Reference "%s" does not exist on line %s.', $isInPlace, $this->currentLine)); } } else { throw new InvalidArgumentException(sprintf('In place substitution must point to a reference on line %s.', $this->currentLine)); } } else { if (isset($values['value']) && preg_match('#^&(?P<ref>[^ ]+) *(?P<value>.*)#', $values['value'], $matches)) { $isRef = $matches['ref']; $values['value'] = $matches['value']; } } // hash if (!isset($values['value']) || '' == trim($values['value'], ' ') || 0 === strpos(ltrim($values['value'], ' '), '#')) { // if next line is less indented or equal, then it means that the current value is null if ($this->isNextLineIndented()) { $data[$key] = null; } else { $c = $this->getRealCurrentLineNb() + 1; $parser = new sfYamlParser($c); $parser->refs =& $this->refs; $data[$key] = $parser->parse($this->getNextEmbedBlock()); } } else { if ($isInPlace) { $data = $this->refs[$isInPlace]; } else { $data[$key] = $this->parseValue($values['value']); } } } else { // one liner? if (1 == count(explode("\n", rtrim($this->value, "\n")))) { return sfYamlInline::load($this->lines[0]); } throw new InvalidArgumentException(sprintf('Unable to parse line %d (%s).', $this->getRealCurrentLineNb(), $this->currentLine)); } } if ($isRef) { $this->refs[$isRef] = end($data); } } return empty($data) ? null : $data; }