*/ class FormGenerateCommand extends AbstractCommand { const DEFAULT_FORM_TYPE_DIRECTORY = '/Form/Type'; /** * {@inheritdoc} */ protected function configure() { $this ->setName('propel:form:generate') ->setDescription('Generate Form types stubs based on the schema.xml') ->addOption('force', 'f', InputOption::VALUE_NONE, 'Overwrite existing Form types') ->addOption('platform', null, InputOption::VALUE_REQUIRED, 'The platform') ->addArgument('bundle', InputArgument::REQUIRED, 'The bundle to use to generate Form types (Ex: @AcmeDemoBundle)') ->addArgument('models', InputArgument::IS_ARRAY, 'Model classes to generate Form Types from') ->setHelp(<<%command.name% command allows you to quickly generate Form Type stubs for a given bundle. php app/console %command.full_name% The --force parameter allows you to overwrite existing files. EOT ); } /** * {@inheritdoc} */ protected function execute(InputInterface $input, OutputInterface $output) { $kernel = $this->getApplication()->getKernel(); $models = $input->getArgument('models'); $force = $input->getOption('force'); if (!$this->bundle) { throw new \InvalidArgumentException('No valid bundle given'); } $this->setupBuildTimeFiles(); if (!($schemas = $this->getFinalSchemas($kernel, $this->bundle))) { $output->writeln(sprintf('No *schemas.xml files found in bundle %s.', $this->bundle->getName())); return; } $manager = $this->getModelManager($input, $schemas); foreach ($manager->getDataModels() as $dataModel) { foreach ($dataModel->getDatabases() as $database) { $this->createFormTypeFromDatabase($this->bundle, $database, $models, $output, $force); } } } /** * Create FormTypes from a given database, bundle and models. * * @param BundleInterface $bundle The bundle for which the FormTypes will be generated. * @param Database $database The database to inspect. * @param array $models The models to build. * @param OutputInterface $output An OutputInterface instance * @param boolean $force Override files if present. */ protected function createFormTypeFromDatabase(BundleInterface $bundle, Database $database, $models, OutputInterface $output, $force = false) { $dir = $this->createDirectory($bundle, $output); foreach ($database->getTables() as $table) { if (0 < count($models) && !in_array($table->getPhpName(), $models)) { continue; } $file = new \SplFileInfo(sprintf('%s/%sType.php', $dir, $table->getPhpName())); if (!file_exists($file) || true === $force) { $this->writeFormType($bundle, $table, $file, $force, $output); } else { $output->writeln(sprintf('File %-60s exists, skipped. Try the --force option.', $this->getRelativeFileName($file))); } } } /** * Create the FormType directory and log the result. * * @param BundleInterface $bundle The bundle in which we'll create the directory. * @param OutputInterface $output An OutputInterface instance. * * @return string The path to the created directory. */ protected function createDirectory(BundleInterface $bundle, OutputInterface $output) { $fs = new Filesystem(); if (!$fs->exists($dir = $bundle->getPath() . self::DEFAULT_FORM_TYPE_DIRECTORY)) { $fs->mkdir($dir); $this->writeNewDirectory($output, $dir); } return $dir; } /** * Write a FormType. * * @param BundleInterface $bundle The bundle in which the FormType will be created. * @param Table $table The table for which the FormType will be created. * @param SplFileInfo $file File representing the FormType. * @param boolean $force Is the write forced? * @param OutputInterface $output An OutputInterface instance. */ protected function writeFormType(BundleInterface $bundle, Table $table, \SplFileInfo $file, $force, OutputInterface $output) { $modelName = $table->getPhpName(); $formTypeContent = file_get_contents(__DIR__ . '/../Resources/skeleton/FormType.php'); $formTypeContent = str_replace('##NAMESPACE##', $bundle->getNamespace() . str_replace('/', '\\', self::DEFAULT_FORM_TYPE_DIRECTORY), $formTypeContent); $formTypeContent = str_replace('##CLASS##', $modelName . 'Type', $formTypeContent); $formTypeContent = str_replace('##FQCN##', sprintf('%s\%s', $table->getNamespace(), $modelName), $formTypeContent); $formTypeContent = str_replace('##TYPE_NAME##', strtolower($modelName), $formTypeContent); $formTypeContent = $this->addFields($table, $formTypeContent); file_put_contents($file->getPathName(), $formTypeContent); $this->writeNewFile($output, $this->getRelativeFileName($file) . ($force ? ' (forced)' : '')); } /** * Add the fields in the FormType. * * @param Table $table Table from which the fields will be extracted. * @param string $formTypeContent FormType skeleton. * * @return string The FormType code. */ protected function addFields(Table $table, $formTypeContent) { $buildCode = ''; foreach ($table->getColumns() as $column) { if (!$column->isPrimaryKey()) { $buildCode .= sprintf("\n \$builder->add('%s');", lcfirst($column->getPhpName())); } } return str_replace('##BUILD_CODE##', $buildCode, $formTypeContent); } /** * @param \SplFileInfo $file * @return string */ protected function getRelativeFileName(\SplFileInfo $file) { return substr(str_replace(realpath($this->getContainer()->getParameter('kernel.root_dir') . '/../'), '', $file), 1); } /** * Get the GeneratorConfig instance to use. * * @param InputInterface $input An InputInterface instance. * * @return GeneratorConfig */ protected function getGeneratorConfig(InputInterface $input) { $generatorConfig = array( 'propel.platform.class' => $input->getOption('platform'), 'propel.builder.object.class' => BaseModelBuildCommand::DEFAULT_OBJECT_BUILDER, 'propel.builder.objectstub.class' => BaseModelBuildCommand::DEFAULT_OBJECT_STUB_BUILDER, 'propel.builder.objectmultiextend.class' => BaseModelBuildCommand::DEFAULT_MULTIEXTEND_OBJECT_BUILDER, 'propel.builder.query.class' => BaseModelBuildCommand::DEFAULT_QUERY_BUILDER, 'propel.builder.querystub.class' => BaseModelBuildCommand::DEFAULT_QUERY_STUB_BUILDER, 'propel.builder.queryinheritance.class' => BaseModelBuildCommand::DEFAULT_QUERY_INHERITANCE_BUILDER, 'propel.builder.queryinheritancestub.class' => BaseModelBuildCommand::DEFAULT_QUERY_INHERITANCE_STUB_BUILDER, 'propel.builder.tablemap.class' => BaseModelBuildCommand::DEFAULT_TABLEMAP_BUILDER, 'propel.builder.pluralizer.class' => BaseModelBuildCommand::DEFAULT_PLURALIZER, 'propel.disableIdentifierQuoting' => true, 'propel.packageObjectModel' => true, 'propel.namespace.autoPackage' => true, 'propel.addGenericAccessors' => true, 'propel.addGenericMutators' => true, 'propel.addSaveMethod' => true, 'propel.addTimeStamp' => false, 'propel.addValidateMethod' => true, 'propel.addHooks' => true, 'propel.namespace.map' => 'Map', 'propel.useLeftJoinsInDoJoinMethods' => true, 'propel.emulateForeignKeyConstraints' => false, 'propel.schema.autoPrefix' => false, 'propel.dateTimeClass' => '\DateTime', // MySQL specific 'propel.mysql.tableType' => BaseModelBuildCommand::DEFAULT_MYSQL_ENGINE, 'propel.mysql.tableEngineKeyword' => 'ENGINE', ); // merge the custom build properties $buildProperties = parse_ini_file($this->getCacheDir().'/build.properties'); $generatorConfig = array_merge($generatorConfig, $buildProperties); return new GeneratorConfig($generatorConfig); } /** * Get the ModelManager to use. * * @param InputInterface $input An InputInterface instance. * @param array $schemas A list of schemas. * * @return ModelManager */ protected function getModelManager(InputInterface $input, array $schemas) { $schemaFiles = array(); foreach ($schemas as $data) { $schemaFiles[] = $data[1]; } $manager = new ModelManager(); $manager->setFilesystem(new Filesystem()); $manager->setGeneratorConfig($this->getGeneratorConfig($input)); $manager->setSchemas($schemaFiles); return $manager; } }