/** * Asks for the prefix and sets it on the InputInterface as the 'prefix' option, if this option is not set yet. * Will set the default to a snake_cased namespace when the namespace has been set on the InputInterface. * * @param array $text What you want printed before the prefix is asked. If null is provided it'll write a default text. * @param string $namespace An optional namespace. If this is set it'll create the default based on this prefix. * If it's not provided it'll check if the InputInterface already has the namespace option. * * @return string The prefix. But it's also been set on the InputInterface. */ public function askForPrefix(array $text = null, $namespace = null) { $prefix = $this->input->hasOption('prefix') ? $this->input->getOption('prefix') : null; if (is_null($text)) { $text = array('', 'You can add a prefix to the table names of the generated entities for example: <comment>projectname_bundlename_</comment>', 'Enter an underscore \'_\' if you don\'t want a prefix.', ''); } if (is_null($prefix)) { if (count($text) > 0) { $this->output->writeln($text); } if (is_null($namespace) || empty($namespace)) { $namespace = $this->input->hasOption('namespace') ? $this->input->getOption('namespace') : null; } else { $namespace = $this->fixNamespace($namespace); } $defaultPrefix = GeneratorUtils::cleanPrefix($this->convertNamespaceToSnakeCase($namespace)); $prefix = $this->dialog->ask($this->output, $this->dialog->getQuestion('Tablename prefix', $defaultPrefix), $defaultPrefix); $prefix = GeneratorUtils::cleanPrefix($prefix); if ($this->input->hasOption('prefix')) { $this->input->setOption('prefix', $prefix); } } return $prefix; }
public function addActions(InputInterface $input, OutputInterface $output, DialogHelper $dialog) { $output->writeln(array('', 'Instead of starting with a blank controller, you can add some actions now. An action', 'is a PHP function or method that executes, for example, when a given route is matched.', 'Actions should be suffixed by <comment>Action</comment>.', '')); $templateNameValidator = function ($name) { if ('default' == $name) { return $name; } if (2 != substr_count($name, ':')) { throw new \InvalidArgumentException(sprintf('Template name "%s" does not have 2 colons', $name)); } return $name; }; $actions = $this->parseActions($input->getOption('actions')); while (true) { // name $output->writeln(''); $actionName = $dialog->askAndValidate($output, $dialog->getQuestion('New action name (press <return> to stop adding actions)', null), function ($name) use($actions) { if (null == $name) { return $name; } if (isset($actions[$name])) { throw new \InvalidArgumentException(sprintf('Action "%s" is already defined', $name)); } if ('Action' != substr($name, -6)) { throw new \InvalidArgumentException(sprintf('Name "%s" is not suffixed by Action', $name)); } return $name; }); if (!$actionName) { break; } // route $route = $dialog->ask($output, $dialog->getQuestion('Action route', '/' . substr($actionName, 0, -6)), '/' . substr($actionName, 0, -6)); $placeholders = $this->getPlaceholdersFromRoute($route); // template $defaultTemplate = $input->getOption('controller') . ':' . substr($actionName, 0, -6) . '.html.' . $input->getOption('template-format'); $template = $dialog->askAndValidate($output, $dialog->getQuestion('Templatename (optional)', $defaultTemplate), $templateNameValidator, false, 'default'); // adding action $actions[$actionName] = array('name' => $actionName, 'route' => $route, 'placeholders' => $placeholders, 'template' => $template); } return $actions; }
protected function updateRouting(DialogHelper $dialog, InputInterface $input, OutputInterface $output, $bundle, $format) { $auto = true; if ($input->isInteractive()) { $auto = $dialog->askConfirmation($output, $dialog->getQuestion('Confirm automatic update of the Routing', 'yes', '?'), true); } $output->write('Importing the bundle routing resource: '); $routing = new RoutingManipulator($this->getContainer()->getParameter('kernel.root_dir') . '/config/routing.yml'); $routing->setYamlPrefix($input->getOption('prefix')); try { $ret = $auto ? $routing->addResource($bundle, 'admingenerator') : false; if (!$ret) { $help = sprintf(" <comment>resource: \"@%s/Controller/%s/\"</comment>\n <comment>type: admingenerator</comment>\n", $bundle, ucfirst($input->getOption('prefix'))); $help .= " <comment>prefix: /</comment>\n"; return array('- Import the bundle\'s routing resource in the app main routing file:', '', sprintf(' <comment>%s:</comment>', $bundle), $help, ''); } } catch (\RuntimeException $e) { return array(sprintf('Bundle <comment>%s</comment> is already imported.', $bundle), ''); } }
/** * @param DialogHelper $dialog The dialog helper * @param InputInterface $input The command input * @param OutputInterface $output The command output * @param Bundle $bundle The bundle * @param string $entityClass The classname of the entity * * @return void */ protected function updateRouting(DialogHelper $dialog, InputInterface $input, OutputInterface $output, Bundle $bundle, $entityClass) { $auto = true; $multilang = false; if ($input->isInteractive()) { $multilang = $dialog->askConfirmation($output, $dialog->getQuestion('Is it a multilanguage site', 'yes', '?'), true); $auto = $dialog->askConfirmation($output, $dialog->getQuestion('Do you want to update the routing automatically', 'yes', '?'), true); } $prefix = $multilang ? '/{_locale}' : ''; $code = sprintf("%s:\n", strtolower($bundle->getName()) . '_' . strtolower($entityClass) . '_admin_list'); $code .= sprintf(" resource: @%s/Controller/%sAdminListController.php\n", $bundle->getName(), $entityClass); $code .= " type: annotation\n"; $code .= sprintf(" prefix: %s/admin/%s/\n", $prefix, strtolower($entityClass)); if ($multilang) { $code .= " requirements:\n"; $code .= " _locale: %requiredlocales%\n"; } if ($auto) { $file = $bundle->getPath() . '/Resources/config/routing.yml'; $content = ''; if (file_exists($file)) { $content = file_get_contents($file); } elseif (!is_dir($dir = dirname($file))) { mkdir($dir, 0777, true); } $content .= "\n"; $content .= $code; if (false === file_put_contents($file, $content)) { $output->writeln($dialog->getHelperSet()->get('formatter')->formatBlock("Failed adding the content automatically", 'error')); } else { return; } } $output->writeln('Add the following to your routing.yml'); $output->writeln('/*******************************/'); $output->write($code); $output->writeln('/*******************************/'); }
public function askSelect($question, $choices, $default = null, $multiSelect = false, $errorMessage = 'Value "%s" is invalid') { $bundleQuestion = $this->dialog->getQuestion($question, $default); return $this->dialog->select($this->output, $bundleQuestion, $choices, $default, false, $errorMessage, $multiSelect); }
protected function generateAdmin(DialogHelper $dialog, InputInterface $input, OutputInterface $output, BundleInterface $bundle, $metadata, $entity, $filename) { $auto = true; if ($input->isInteractive()) { $auto = $dialog->askConfirmation($output, $dialog->getQuestion('Confirm automatic generation of the Admin service', 'yes', '?'), true); } if ($auto) { $group = ucfirst(str_replace('_', ' ', Container::underscore(substr($bundle->getName(), 0, -6)))); $label = $entity; $translationDomain = 'Sonata'; $group = $dialog->ask($output, $dialog->getQuestion('Group for the admin service', $group), $group); $label = $dialog->ask($output, $dialog->getQuestion('Label for the admin service', $label), $label); $translationDomain = $dialog->ask($output, $dialog->getQuestion('Translation domain for the admin service', $translationDomain), $translationDomain); $output->write('Creating the service: '); $this->getContainer()->get('filesystem')->mkdir($bundle->getPath() . '/Resources/config/'); $admin = new AdminManipulator($bundle->getPath() . '/Resources/config/' . $filename); try { $ret = $auto ? $admin->addResource($bundle, $entity, $group, $label, $translationDomain) : false; } catch (\RuntimeException $exc) { $ret = false; } if ($ret) { $output->write('Creating the Admin class: '); $generator = $this->getGenerator($bundle); $generator->generateAdminClass($metadata[0], $input->getOption('overwrite')); } } }
private function addFields(InputInterface $input, OutputInterface $output, DialogHelper $dialog) { $fields = $this->parseFields($input->getOption('fields')); $output->writeln(array('', 'Instead of starting with a blank entity, you can add some fields now.', 'Note that the primary key will be added automatically (named <comment>id</comment>).', '')); $output->write('<info>Available types:</info> '); $types = array_keys(Type::getTypesMap()); $count = 20; foreach ($types as $i => $type) { if ($count > 50) { $count = 0; $output->writeln(''); } $count += strlen($type); $output->write(sprintf('<comment>%s</comment>', $type)); if (count($types) != $i + 1) { $output->write(', '); } else { $output->write('.'); } } $output->writeln(''); $fieldValidator = function ($type) use($types) { // FIXME: take into account user-defined field types if (!in_array($type, $types)) { throw new \InvalidArgumentException(sprintf('Invalid type "%s".', $type)); } return $type; }; $lengthValidator = function ($length) { if (!$length) { return $length; } $result = filter_var($length, FILTER_VALIDATE_INT, array('options' => array('min_range' => 1))); if (false === $result) { throw new \InvalidArgumentException(sprintf('Invalid length "%s".', $length)); } return $length; }; while (true) { $output->writeln(''); $self = $this; $name = $dialog->askAndValidate($output, $dialog->getQuestion('New field name (press <return> to stop adding fields)', null), function ($name) use($fields, $self) { if (isset($fields[$name]) || 'id' == $name) { throw new \InvalidArgumentException(sprintf('Field "%s" is already defined.', $name)); } // check reserved words if ($self->getGenerator()->isReservedKeyword($name)) { throw new \InvalidArgumentException(sprintf('Name "%s" is a reserved word.', $name)); } return $name; }); if (!$name) { break; } $defaultType = 'string'; if (substr($name, -3) == '_at') { $defaultType = 'datetime'; } elseif (substr($name, -3) == '_id') { $defaultType = 'integer'; } $type = $dialog->askAndValidate($output, $dialog->getQuestion('Field type', $defaultType), $fieldValidator, false, $defaultType); $data = array('fieldName' => $name, 'type' => $type); if ($type == 'string') { $data['length'] = $dialog->askAndValidate($output, $dialog->getQuestion('Field length', 255), $lengthValidator, false, 255); } $fields[$name] = $data; } return $fields; }
/** * Add the entity fields * * @param InputInterface $input * @param OutputInterface $output * @param DialogHelper $dialog * * @return array */ private function addFields(InputInterface $input, OutputInterface $output, DialogHelper $dialog) { $fields = $this->parseFields($input->getOption('fields')); $output->writeln(array('', 'Instead of starting with a blank entity, you can add some fields now.', 'Note that the primary key will be added automatically (named <comment>id</comment>) as well as the <comment>active</comment> field.', '')); $output->write('<info>Available types:</info> '); $types = array_keys(Type::getTypesMap()); $count = 20; foreach ($types as $i => $type) { if ($count > 50) { $count = 0; $output->writeln(''); } $count += strlen($type); $output->write(sprintf('<comment>%s</comment>', $type)); if (count($types) != $i + 1) { $output->write(', '); } else { $output->write('.'); } } $output->writeln(''); $fieldValidator = function ($type) use($types) { // FIXME: take into account user-defined field types if (!in_array($type, $types)) { throw new \InvalidArgumentException(sprintf('Invalid type "%s".', $type)); } return $type; }; $lengthValidator = function ($length) { if (!$length) { return $length; } $result = filter_var($length, FILTER_VALIDATE_INT, array('options' => array('min_range' => 1))); if (false === $result) { throw new \InvalidArgumentException(sprintf('Invalid length "%s".', $length)); } return $length; }; $i18nValidator = function ($isI18n) { if (!in_array($isI18n, array('Yes', 'No', 'yes', 'no', 'Y', 'N', 'y', 'n'))) { throw new \InvalidArgumentException(sprintf('Invalid answer (Yes/No) "%s".', $isI18n)); } return $isI18n; }; $isNullableValidator = function ($isNullable) { if (!in_array($isNullable, array('Yes', 'No', 'yes', 'no', 'Y', 'N', 'y', 'n'))) { throw new \InvalidArgumentException(sprintf('Invalid answer (Yes/No) "%s".', $isNullable)); } return substr(strtolower($isNullable), 0, 1) == 'y' ? true : false; }; while (true) { $output->writeln(''); $generator = $this->getGenerator(); $columnName = $dialog->askAndValidate($output, $dialog->getQuestion('New field name (press <return> to stop adding fields)', null), function ($name) use($fields, $generator) { if (isset($fields[$name]) || 'id' == $name) { throw new \InvalidArgumentException(sprintf('Field "%s" is already defined.', $name)); } // check reserved words if ($generator->isReservedKeyword($name)) { throw new \InvalidArgumentException(sprintf('Name "%s" is a reserved word.', $name)); } return $name; }); if (!$columnName) { break; } $defaultType = 'string'; // try to guess the type by the column name prefix/suffix if (substr($columnName, -3) == '_at') { $defaultType = 'datetime'; } elseif (substr($columnName, -3) == '_id') { $defaultType = 'integer'; } elseif (substr($columnName, 0, 3) == 'is_') { $defaultType = 'boolean'; } elseif (substr($columnName, 0, 4) == 'has_') { $defaultType = 'boolean'; } $type = $dialog->askAndValidate($output, $dialog->getQuestion('Field type', $defaultType), $fieldValidator, false, $defaultType, $types); $data = array('columnName' => $columnName, 'fieldName' => lcfirst(Container::camelize($columnName)), 'type' => $type); if ($type == 'string') { $data['length'] = $dialog->askAndValidate($output, $dialog->getQuestion('Field length', 255), $lengthValidator, false, 255); } $data['i18n'] = $dialog->askAndValidate($output, $dialog->getQuestion('Field is i18n', 'no'), $i18nValidator, false, 'no'); if ($columnName != 'slug') { $data['nullable'] = $dialog->askAndValidate($output, $dialog->getQuestion('Field is nullable', 'no'), $isNullableValidator, false, 'no'); } $fields[$columnName] = $data; } return $fields; }
protected function updateRouting(DialogHelper $dialog, InputInterface $input, OutputInterface $output, BundleInterface $bundle, $format, $entity, $prefix) { $auto = true; if ($input->isInteractive()) { $auto = $dialog->askConfirmation($output, $dialog->getQuestion('Confirm automatic update of the Routing', 'yes', '?'), true); } $output->write('Importing the CRUD routes: '); $this->getContainer()->get('filesystem')->mkdir($bundle->getPath() . '/Resources/config/'); $routing = new RoutingManipulator($bundle->getPath() . '/Resources/config/routing.yml'); try { $ret = $auto ? $routing->addResource($bundle->getName(), $format, '/' . $prefix, 'routing/' . strtolower(str_replace('\\', '_', $entity))) : false; } catch (\RuntimeException $exc) { $ret = false; } if (!$ret) { $help = sprintf(" <comment>resource: \"@%s/Resources/config/routing/%s.%s\"</comment>\n", $bundle->getName(), strtolower(str_replace('\\', '_', $entity)), $format); $help .= sprintf(" <comment>prefix: /%s</comment>\n", $prefix); return array('- Import the bundle\'s routing resource in the bundle routing file', sprintf(' (%s).', $bundle->getPath() . '/Resources/config/routing.yml'), '', sprintf(' <comment>%s:</comment>', $bundle->getName() . ('' !== $prefix ? '_' . str_replace('/', '_', $prefix) : '')), $help, ''); } }
/** * Update the main routing file by including our two custom routing files. * * @param DialogHelper $dialog * @param InputInterface $input * @param OutputInterface $output * @param $bundle * @param $format * @param $app * * @return array */ protected function _updateRouting(DialogHelper $dialog, InputInterface $input, OutputInterface $output, $bundle, $format, $app) { $auto = true; if ($input->isInteractive()) { $auto = $dialog->askConfirmation($output, $dialog->getQuestion('Confirm automatic update of the Routing for the ' . $app . ' app', 'yes', '?'), true); } $prefix = null; if ($input->isInteractive()) { $prefix = $dialog->ask($output, $dialog->getQuestion('Prefix for the ' . $app . ' app ' . ($app == 'backend' ? '(ex: /admin/news)' : '(leave blank for none)'), null), null); } $output->write('Importing the bundle routing resource: '); $routing = new RoutingManipulator($this->getContainer()->getParameter('kernel.root_dir') . '/config/routing.yml'); try { $ret = $auto ? $routing->addResource($bundle, $format, $prefix, 'routing_' . $app, $app) : false; if (!$ret) { if ('annotation' === $format) { $help = sprintf(" <comment>resource: \"@%s/Controller/\"</comment>\n <comment>type: annotation</comment>\n", $bundle); } else { $help = sprintf(" <comment>resource: \"@%s/Resources/config/routing_%s.%s\"</comment>\n", $app, $bundle, $format); } if ($prefix) { $help .= sprintf(" <comment>prefix: %s</comment>\n", $prefix); } return array('- Import the bundle\'s routing resource in the app main routing file:', '', sprintf(' <comment>%s:</comment>', $bundle), $help, ''); } } catch (\RuntimeException $e) { return array(sprintf('Bundle <comment>%s</comment> is already imported.', $bundle), ''); } }