Completed
Push — 5.0 ( a48099...63af02 )
by
unknown
11:33
created

GeneratorBundle/Helper/InputAssistant.php (1 issue)

Upgrade to new PHP Analysis Engine

These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more

1
<?php
2
3
namespace Kunstmaan\GeneratorBundle\Helper;
4
5
use Sensio\Bundle\GeneratorBundle\Command\Helper\QuestionHelper;
6
use Sensio\Bundle\GeneratorBundle\Command\Validators;
7
use Symfony\Component\Console\Input\InputInterface;
8
use Symfony\Component\Console\Output\OutputInterface;
9
use Symfony\Component\Console\Question\Question;
10
use Symfony\Component\DependencyInjection\ContainerInterface;
11
use Symfony\Component\HttpKernel\Kernel;
12
13
/**
14
 * @deprecated the functions in this class should be moved to the KunstmaanGenerateCommand class.
15
 */
16
class InputAssistant
17
{
18
    /** @var InputInterface */
19
    private $input;
20
21
    /** @var OutputInterface */
22
    private $output;
23
24
    /** @var QuestionHelper */
25
    private $questionHelper;
26
27
    /** @var Kernel */
28
    private $kernel;
29
30
    /** @var ContainerInterface */
31
    private $container;
32
33
    /**
34
     * @param InputInterface $input
35
     * @param OutputInterface $output
36
     * @param QuestionHelper $questionHelper
37
     * @param Kernel $kernel
38
     * @param ContainerInterface $container
39
     */
40
    public function __construct(InputInterface &$input, OutputInterface $output, QuestionHelper $questionHelper, Kernel $kernel, ContainerInterface $container)
41
    {
42
        $this->input = $input;
43
        $this->output = $output;
44
	    $this->questionHelper = $questionHelper;
45
        $this->kernel = $kernel;
46
        $this->container = $container;
47
    }
48
49
    /**
50
     * Asks for the namespace and sets it on the InputInterface as the 'namespace' option, if this option is not set yet.
51
     *
52
     * @param array $text What you want printed before the namespace is asked.
53
     *
54
     * @return string The namespace. But it's also been set on the InputInterface.
55
     */
56
    public function askForNamespace(array $text = null)
57
    {
58
        $namespace = $this->input->hasOption('namespace') ? $this->input->getOption('namespace') : null;
59
60
        // When the Namespace is filled in return it immediately if valid.
61
        try {
62
            if (!is_null($namespace) && !empty($namespace)) {
63
                Validators::validateBundleNamespace($namespace);
64
                return $namespace;
65
            }
66
        } catch (\Exception $error) {
67
            $this->writeError(array("Namespace '$namespace' is incorrect. Please provide a correct value.", $error->getMessage()));
68
            exit;
69
        }
70
71
        $ownBundles = $this->getOwnBundles();
72
        if (count($ownBundles) <= 0) {
73
            $this->writeError("Looks like you don't have created a bundle for your project, create one first.", true);
74
        }
75
76
        $namespace = '';
77
78
        // If we only have 1 or more bundles, we can prefill it.
79
        if (count($ownBundles) > 0) {
80
            $namespace = $ownBundles[1]['namespace'] . '/' . $ownBundles[1]['name'];
81
        }
82
83
84
        $namespaces = $this->getNamespaceAutoComplete($this->kernel);
85
86
        if (!is_null($text) && (count($text) > 0)) {
87
            $this->output->writeln($text);
88
        }
89
90
	$question = new Question($this->questionHelper->getQuestion('Bundle Namespace', $namespace), $namespace);
91
	$question->setValidator(array('Sensio\Bundle\GeneratorBundle\Command\Validators', 'validateBundleNamespace'));
92
	$question->setAutocompleterValues($namespaces);
0 ignored issues
show
$namespaces is of type array, but the function expects a null|object<Symfony\Comp...sole\Question\iterable>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
93
	$namespace = $this->questionHelper->ask($this->input, $this->output, $question);
94
95
        if ($this->input->hasOption('namespace')) {
96
            $this->input->setOption('namespace', $namespace);
97
        }
98
99
        return $namespace;
100
    }
101
102
    /**
103
     * Helper function to display errors in the console.
104
     *
105
     * @param $message
106
     * @param bool $exit
107
     */
108 View Code Duplication
    private function writeError($message, $exit = false)
109
    {
110
    $this->output->writeln($this->questionHelper->getHelperSet()->get('formatter')->formatBlock($message, 'error'));
111
        if ($exit) {
112
            exit;
113
        }
114
    }
115
116
    /**
117
     * Get an array with all the bundles the user has created.
118
     *
119
     * @return array
120
     */
121
    public function getOwnBundles()
122
    {
123
        $bundles = array();
124
        $counter = 1;
125
126
        $dir = dirname($this->container->getParameter('kernel.root_dir') . '/') . '/src/';
127
        $files = scandir($dir);
128
        foreach ($files as $file) {
129
            if (is_dir($dir . $file) && !in_array($file, array('.', '..'))) {
130
                $bundleFiles = scandir($dir . $file);
131
                foreach ($bundleFiles as $bundleFile) {
132
                    if (is_dir($dir . $file . '/' . $bundleFile) && !in_array($bundleFile, array('.', '..'))) {
133
                        $bundles[$counter++] = array(
134
                            'name' => $bundleFile,
135
                            'namespace' => $file,
136
                            'dir' => $dir . $file . '/' . $bundleFile
137
                        );
138
                    }
139
                }
140
            }
141
        }
142
143
        return $bundles;
144
    }
145
146
    /**
147
     * Returns a list of namespaces as array with a forward slash to split the namespace & bundle.
148
     *
149
     * @param Kernel $kernel
150
     * @return array
151
     */
152
    private function getNamespaceAutoComplete(Kernel $kernel)
153
    {
154
        $ret = array();
155
        foreach ($kernel->getBundles() as $k => $v) {
156
            $ret[] = $this->fixNamespace($v->getNamespace());
157
        }
158
159
        return $ret;
160
    }
161
162
    /**
163
     * Replaces '\' with '/'.
164
     *
165
     * @param $namespace
166
     * @return mixed
167
     */
168
    private function fixNamespace($namespace)
169
    {
170
171
        return strtr($namespace, array('\\Bundle\\' => '/', '\\' => '/'));
172
    }
173
174
    /**
175
     * Asks for the prefix and sets it on the InputInterface as the 'prefix' option, if this option is not set yet.
176
     * Will set the default to a snake_cased namespace when the namespace has been set on the InputInterface.
177
     *
178
     * @param array $text What you want printed before the prefix is asked. If null is provided it'll write a default text.
179
     * @param string $namespace An optional namespace. If this is set it'll create the default based on this prefix.
180
     *  If it's not provided it'll check if the InputInterface already has the namespace option.
181
     *
182
     * @return string The prefix. But it's also been set on the InputInterface.
183
     */
184
    public function askForPrefix(array $text = null, $namespace = null)
185
    {
186
        $prefix = $this->input->hasOption('prefix') ? $this->input->getOption('prefix') : null;
187
188
        if (is_null($text)) {
189
            $text = array(
190
                '',
191
                'You can add a prefix to the table names of the generated entities for example: <comment>projectname_bundlename_</comment>',
192
                'Enter an underscore \'_\' if you don\'t want a prefix.',
193
                ''
194
            );
195
        }
196
197
        while (is_null($prefix)) {
198
            if (count($text) > 0) {
199
                $this->output->writeln($text);
200
            }
201
202
            if (is_null($namespace) || empty($namespace)) {
203
                $namespace = $this->input->hasOption('namespace') ? $this->input->getOption('namespace') : null;
204
            } else {
205
                $namespace = $this->fixNamespace($namespace);
206
            }
207
            $defaultPrefix = GeneratorUtils::cleanPrefix($this->convertNamespaceToSnakeCase($namespace));
208
	    $question = new Question($this->questionHelper->getQuestion('Tablename prefix', $defaultPrefix), $defaultPrefix);
209
	    $prefix = $this->questionHelper->ask($this->input, $this->output, $question);
210
            $prefix = GeneratorUtils::cleanPrefix($prefix);
211
            if ($this->input->hasOption('prefix')) {
212
                $this->input->setOption('prefix', $prefix);
213
            }
214
215
            if($prefix == '') {
216
                break;
217
            }
218
219 View Code Duplication
            if(!preg_match('/^[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*$/', $prefix)) {
220
                $this->output->writeln(sprintf('<bg=red> "%s" contains invalid characters</>', $prefix));
221
                $prefix = $text = null;
222
                continue;
223
            }
224
        }
225
226
        return $prefix;
227
    }
228
229
    /**
230
     * Converts something like Namespace\BundleNameBundle to namspace_bundlenamebundle.
231
     *
232
     * @param string $namespace
233
     * @return string
234
     */
235 View Code Duplication
    private function convertNamespaceToSnakeCase($namespace)
236
    {
237
        if (is_null($namespace)) {
238
            return null;
239
        }
240
241
        return str_replace('/', '_', strtolower($this->fixNamespace($namespace)));
242
    }
243
}
244