1: <?php
2:
3: namespace Mapbender\CoreBundle\Command;
4:
5: use Symfony\Bundle\FrameworkBundle\Command\ContainerAwareCommand;
6: use Sensio\Bundle\GeneratorBundle\Generator\Generator;
7: use Symfony\Component\Console\Input\InputArgument;
8: use Symfony\Component\Console\Input\InputOption;
9: use Symfony\Component\Console\Input\InputInterface;
10: use Symfony\Component\Console\Output\OutputInterface;
11: use Symfony\Component\Console\Output\Output;
12:
13: class GenerateElementCommand extends ContainerAwareCommand {
14: private $generator;
15:
16: protected function getGenerator() {
17: if($this->generator === null) {
18: $this->generator = new ElementGenerator();
19: }
20: return $this->generator;
21: }
22: protected function configure() {
23: $this->setDefinition(array(
24: new InputArgument('bundle', InputArgument::REQUIRED, 'The bundle namespace of the Element to create'),
25: new InputArgument('classname', InputArgument::REQUIRED, 'The classname of the Element to create'),
26: new InputArgument('dir', InputArgument::REQUIRED, 'The directory where to find the bundle'),
27: new InputOption('type', '', InputOption::VALUE_REQUIRED, 'Type of Element to create (general, button, map-click, map-box)', 'general')
28: ))
29: ->setHelp(<<<EOT
30: The <info>mapbender:generate:element</info> command generates a new Mapbender element with a basic skeleton.
31:
32: <info>./app/console/ mapbender:generate:element "Vendor\HelloBundle" MyElement src </info>
33:
34: The generated Element class will be Vendor\HelloBundle\Element\MyElement.
35: EOT
36: )
37: ->setName('mapbender:generate:element')
38: ->setDescription('Generates a Mapbender element');
39: }
40:
41: protected function execute(InputInterface $input, OutputInterface $output) {
42: $bundleNamespace = $input->getArgument('bundle');
43: $className = $input->getArgument('classname');
44: $type = $input->getOption('type');
45:
46: if(!in_array($type, array(
47: 'general',
48: 'button',
49: 'map-click',
50: 'map-box'))) {
51: throw new \RuntimeException(sprintf('The element type "%s" is not supported.', $type));
52: }
53:
54: //TODO: Type validation
55: //TODO: Does this work?
56: if (preg_match('[^A-Za-z0-9]', $className)) {
57: throw new \InvalidArgumentException('The classname contains invalid characters.');
58: }
59: // validate namespace
60: $bundleNamespace = strtr($bundleNamespace, '/', '\\');
61: if (preg_match('/[^A-Za-z0-9_\\\-]/', $bundleNamespace)) {
62: throw new \InvalidArgumentException('The bundle namespace contains invalid characters.');
63: }
64:
65: // validate that the namespace is at least one level deep
66: if (false === strpos($bundleNamespace, '\\')) {
67: $msg = array();
68: $msg[] = sprintf('The namespace must contain a vendor namespace (e.g. "VendorName\%s" instead of simply "%s").', $bundleNamespace, $bundleNamespace);
69: $msg[] = 'If you\'ve specified a vendor namespace, did you forget to surround it with quotes (mapbender:generate:element "Acme\BlogBundle")?';
70:
71: throw new \InvalidArgumentException(implode("\n\n", $msg));
72: }
73:
74: $dir = $input->getArgument('dir');
75:
76: // add trailing / if necessary
77: $dir = '/' === substr($dir, -1, 1) ? $dir : $dir.'/';
78: $bundleDir = $dir.strtr($bundleNamespace, '\\', '/');
79: $bundle = strtr($bundleNamespace, array('\\' => ''));
80:
81: if (!file_exists($bundleDir)) {
82: throw new \RuntimeException(sprintf('Bundle directory "%s" does not exist.', $bundleDir));
83: }
84:
85: $files = $this->getGenerator()->create($this->getContainer(),
86: $bundle, $bundleDir, $bundleNamespace, $className, $type);
87:
88: $output->writeln('<comment>Summary of actions</comment>');
89: $output->writeln(sprintf('- Your element %s\Element\%s has been created.', $bundle, $className));
90: $output->writeln('- The following files have been created:');
91: foreach($files as $k => $v) {
92: $output->writeLn(sprintf(' - %s (%s)', $k, $v));
93: }
94: $output->writeln('');
95: $output->writeln('<comment>Follow up actions</comment>');
96: $output->writeln('Read about adapting your bare-bone element at <info>http://mapbender.org/3/cookbook/element-from-skeleton</info>');
97: }
98: }
99:
100: