GenerateModelCommand::generateManagerInterface()   B
last analyzed

Complexity

Conditions 2
Paths 2

Size

Total Lines 69

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 69
rs 8.6763
c 0
b 0
f 0
cc 2
nc 2
nop 4

How to fix   Long Method   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
namespace BWC\Share\Symfony\Command;
4
5
use Symfony\Bundle\FrameworkBundle\Command\ContainerAwareCommand;
6
use Symfony\Component\Console\Helper\DialogHelper;
7
use Symfony\Component\Console\Input\InputInterface;
8
use Symfony\Component\Console\Output\OutputInterface;
9
use Symfony\Component\HttpKernel\Bundle\BundleInterface;
10
11
12
class GenerateModelCommand extends ContainerAwareCommand
13
{
14
    protected function configure() {
15
        $this
16
            ->setName('bwc:share:generate:model')
17
            ->setDescription('Generates single model classes')
18
        ;
19
    }
20
21
    /**
22
     * @param InputInterface $input
23
     * @param OutputInterface $output
24
     * @return int|null|void
25
     */
26
    protected function execute(InputInterface $input, OutputInterface $output)
27
    {
28
        /** @var DialogHelper $dialog */
29
        $dialog = $this->getHelperSet()->get('dialog');
30
31
        $bundle = $this->pickBundle($dialog, $output);
32
33
        $modelName = $this->getModelName($dialog, $output, $bundle);
34
35
        $fields = $this->getFields($dialog, $output);
36
37
        $this->confirm($dialog, $output, $bundle, $modelName, $fields);
38
39
        $this->generate($output, $bundle, $modelName, $fields);
40
    }
41
42
43
    protected function generate(OutputInterface $output, BundleInterface $bundle, $modelName, array $fields)
44
    {
45
        $output->writeln('');
46
        $this->generateModelInterface($output, $bundle, $modelName, $fields);
47
        $this->generateModel($output, $bundle, $modelName, $fields);
48
        $this->generateEntity($output, $bundle, $modelName, $fields);
49
        $this->generateManagerInterface($output, $bundle, $modelName, $fields);
50
        $this->generateManager($output, $bundle, $modelName, $fields);
51
        $this->generateOrmManager($output, $bundle, $modelName, $fields);
52
        $this->generateDoctrineMappings($output, $bundle, $modelName, $fields);
53
    }
54
55
56
    protected function generateDoctrineMappings(OutputInterface $output, BundleInterface $bundle, $modelName, array $fields)
57
    {
58
        $output->writeln(sprintf("Generating Resources/config/doctrine/%s.orm.xml", $modelName));
59
60
        $txtFields = '';
61
        foreach ($fields as $name=>$type) {
62
            if ($name == 'id') {
63
                continue;
64
            }
65
66
            $n = preg_replace_callback(
67
                "|(.+)([A-Z])|",
68
                function($matches) {
69
                    return $matches[1].'_'.strtolower($matches[2]);
70
                },
71
                $name
72
            );
73
74
            $extra = '';
75
76
            if ($type == 'string') {
77
                $extra = 'length="200" ';
78
            } else if ($type == '\DateTime') {
79
                $type = 'datetime';
80
            } else if ($type == 'int') {
81
                $type = 'integer';
82
            } else if ($type == 'bool') {
83
                $type = 'boolean';
84
            }
85
86
            $txtFields .= <<<EOT
87
        <field name="{$name}" column="{$n}" type="{$type}" nullable="false" {$extra}/>
88
89
90
EOT;
91
        }
92
93
        $mn = preg_replace_callback(
94
            "|(.+)([A-Z])|",
95
            function($matches) {
96
                return $matches[1].'_'.strtolower($matches[2]);
97
            },
98
            $modelName
99
        );
100
101
        $ns = $bundle->getNamespace();
102
103
        $txt = <<<EOT
104
<?xml version="1.0" encoding="UTF-8"?>
105
<doctrine-mapping xmlns="http://doctrine-project.org/schemas/orm/doctrine-mapping"
106
          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
107
          xsi:schemaLocation="http://doctrine-project.org/schemas/orm/doctrine-mapping
108
                    http://doctrine-project.org/schemas/orm/doctrine-mapping.xsd">
109
110
    <entity name="{$ns}\Entity\\{$modelName}" table="{$mn}">
111
112
        <!-- unique-constraints>
113
            <unique-constraint name="UDX_entity_first" columns="foo,bar"/>
114
            <unique-constraint name="UDX_entity_second" columns="bar,jazz"/>
115
        </unique-constraints -->
116
117
        <id name="id" column="id" type="integer">
118
            <generator strategy="AUTO" />
119
        </id>
120
121
        <!-- use this if id is other entity together with one-to-one association -->
122
        <!-- id name="account" column="account_id" association-key="true"/ -->
123
124
$txtFields
125
126
        <!-- many-to-one target-entity="Other" field="other" inversed-by?="entities">
127
            <join-column  name="other_id" referenced-column-name="id" nullable="false"/>
128
        </many-to-one -->
129
130
        <!-- many-to-many target-entity="Other" field="others" inversed-by="entities">
131
            <join-table name="other2entity">
132
                <join-columns>
133
                    <join-column name="entity_id" referenced-column-name="id"/>
134
                </join-columns>
135
                <inverse-join-columns>
136
                    <join-column name="other_id" referenced-column-name="id"/>
137
                </inverse-join-columns>
138
            </join-table>
139
        </many-to-many -->
140
141
        <!-- one-to-many target-entity="Other" mapped-by="entity" field="others" / -->
142
143
        <!-- one-to-one target-entity="Other" field="other">
144
            <join-column  name="other_id" referenced-column-name="id" nullable="false"/>
145
        </one-to-one -->
146
147
    </entity>
148
149
</doctrine-mapping>
150
EOT;
151
152
        $dir = sprintf("%s/Resources/config/doctrine", $bundle->getPath());
153
        if (!is_dir($dir)) {
154
            mkdir($dir, 0777, true);
155
        }
156
157
        $fn = sprintf("%s/Resources/config/doctrine/%s.orm.xml", $bundle->getPath(), $modelName);
158
        file_put_contents($fn, $txt);
159
    }
160
161
162
    protected function generateOrmManager(OutputInterface $output, BundleInterface $bundle, $modelName, array $fields)
163
    {
164
        $output->writeln(sprintf("Generating Service/Model/%s/Orm/%sManager.php", $modelName, $modelName));
165
166
        $ns = $bundle->getNamespace();
167
        $txt = <<<EOT
168
<?php
169
170
namespace $ns\\Service\\Model\\{$modelName}\\Orm;
171
172
use Doctrine\ORM\EntityManager;
173
use $ns\\Model\\{$modelName}Interface;
174
175
176
class {$modelName}Manager extends \\$ns\\Service\\Model\\{$modelName}\\{$modelName}Manager
177
{
178
    /** @var EntityManager  */
179
    protected \$entityManager;
180
181
    /** @var string  */
182
    protected \$class;
183
184
    /** @var \Doctrine\Common\Persistence\ObjectRepository  */
185
    protected \$repository;
186
187
188
189
    /**
190
     * @param EntityManager \$entityManager
191
     * @param string|null \$class
192
     */
193
    public function __construct(EntityManager \$entityManager, \$class = null)
194
    {
195
        parent::__construct();
196
197
        if (!\$class) {
198
            \$class = '{$ns}\\Entity\\{$modelName}';
199
        }
200
201
        \$this->entityManager = \$entityManager;
202
        \$this->repository = \$entityManager->getRepository(\$class);
203
204
        \$metadata = \$entityManager->getClassMetadata(\$class);
205
        \$this->class = \$metadata->getName();
206
    }
207
208
209
    /**
210
     * @return string
211
     */
212
    public function getClass()
213
    {
214
        return \$this->class;
215
    }
216
217
    /**
218
     * @param {$modelName}Interface \$object
219
     * @param bool \$andFlush
220
     */
221
    public function delete({$modelName}Interface \$object, \$andFlush = true)
222
    {
223
        \$this->entityManager->remove(\$object);
224
        if (\$andFlush) {
225
            \$this->entityManager->flush();
226
        }
227
    }
228
229
    /**
230
     * @param array \$criteria
231
     * @return {$modelName}Interface|null
232
     */
233
    public function getBy(array \$criteria)
234
    {
235
        return \$this->repository->findOneBy(\$criteria);
236
    }
237
238
    /**
239
     * @param array \$criteria
240
     * @param array|null \$orderBy
241
     * @param int|null \$limit
242
     * @param int|null \$offset
243
     * @return {$modelName}Interface[]
244
     */
245
    public function find(array \$criteria, array \$orderBy = null, \$limit = null, \$offset = null)
246
    {
247
        return \$this->repository->findBy(\$criteria, \$orderBy, \$limit, \$offset);
248
    }
249
250
    /**
251
     * @param {$modelName}Interface \$object
252
     * @param bool \$andFlush
253
     * @return void
254
     */
255
    public function update({$modelName}Interface \$object, \$andFlush = true)
256
    {
257
        \$this->entityManager->persist(\$object);
258
        if (\$andFlush) {
259
            \$this->entityManager->flush();
260
        }
261
    }
262
263
}
264
265
EOT;
266
267
        $dir = sprintf("%s/Service/Model/%s/Orm", $bundle->getPath(), $modelName);
268
        if (!is_dir($dir)) {
269
            mkdir($dir, 0777, true);
270
        }
271
272
        $fn = sprintf("%s/Service/Model/%s/Orm/%sManager.php", $bundle->getPath(), $modelName, $modelName);
273
        file_put_contents($fn, $txt);
274
    }
275
276
277
    protected function generateManager(OutputInterface $output, BundleInterface $bundle, $modelName, array $fields)
278
    {
279
        $output->writeln(sprintf("Generating Service/Model/%s/%sManager.php", $modelName, $modelName));
280
281
        $ns = $bundle->getNamespace();
282
        $txt = <<<EOT
283
<?php
284
285
namespace $ns\\Service\\Model\\{$modelName};
286
287
use $ns\\Model\\{$modelName}Interface;
288
289
290
abstract class {$modelName}Manager implements {$modelName}ManagerInterface
291
{
292
293
    /**
294
     *
295
     */
296
    public function __construct()
297
    {
298
    }
299
300
301
    /**
302
     * @return string
303
     */
304
    public abstract function getClass();
305
306
    /**
307
     * @param {$modelName}Interface \$object
308
     */
309
    public abstract function delete({$modelName}Interface \$object);
310
311
    /**
312
     * @param array \$criteria
313
     * @return {$modelName}Interface|null
314
     */
315
    public abstract function getBy(array \$criteria);
316
317
    /**
318
     * @param array \$criteria
319
     * @param array|null \$orderBy
320
     * @param int|null \$limit
321
     * @param int|null \$offset
322
     * @return {$modelName}Interface[]
323
     */
324
    public abstract function find(array \$criteria, array \$orderBy = null, \$limit = null, \$offset = null);
325
326
    /**
327
     * @param {$modelName}Interface \$object
328
     * @return void
329
     */
330
    public abstract function update({$modelName}Interface \$object);
331
332
333
334
    /**
335
     * @return {$modelName}Interface
336
     */
337
    public function create()
338
    {
339
        \$class = \$this->getClass();
340
        \$result = new \$class;
341
342
        return \$result;
343
    }
344
345
    /**
346
     * @param int \$id
347
     * @return {$modelName}Interface|null
348
     */
349
    public function getById(\$id)
350
    {
351
        return \$this->getBy(array('id'=>\$id));
352
    }
353
354
}
355
356
EOT;
357
358
        $dir = sprintf("%s/Service/Model/%s", $bundle->getPath(), $modelName);
359
        if (!is_dir($dir)) {
360
            mkdir($dir, 0777, true);
361
        }
362
363
        $fn = sprintf("%s/Service/Model/%s/%sManager.php", $bundle->getPath(), $modelName, $modelName);
364
        file_put_contents($fn, $txt);
365
    }
366
367
368
    protected function generateManagerInterface(OutputInterface $output, BundleInterface $bundle, $modelName, array $fields)
369
    {
370
        $output->writeln(sprintf("Generating Service/Model/%s/%sManagerInterface.php", $modelName, $modelName));
371
372
        $ns = $bundle->getNamespace();
373
        $txt = <<<EOT
374
<?php
375
376
namespace $ns\\Service\\Model\\{$modelName};
377
378
use $ns\\Model\\{$modelName}Interface;
379
380
381
interface {$modelName}ManagerInterface
382
{
383
    /**
384
     * @return {$modelName}Interface
385
     */
386
    public function create();
387
388
    /**
389
     * @return string
390
     */
391
    public function getClass();
392
393
    /**
394
     * @param {$modelName}Interface \$object
395
     */
396
    public function delete({$modelName}Interface \$object);
397
398
    /**
399
     * @param array \$criteria
400
     * @return {$modelName}Interface|null
401
     */
402
    public function getBy(array \$criteria);
403
404
    /**
405
     * @param int \$id
406
     * @return {$modelName}Interface|null
407
     */
408
    public function getById(\$id);
409
410
    /**
411
     * @param array \$criteria
412
     * @param array|null \$orderBy
413
     * @param int|null \$limit
414
     * @param int|null \$offset
415
     * @return {$modelName}Interface[]
416
     */
417
    public function find(array \$criteria, array \$orderBy = null, \$limit = null, \$offset = null);
418
419
420
    /**
421
     * @param {$modelName}Interface \$object
422
     * @return void
423
     */
424
    public function update({$modelName}Interface \$object);
425
}
426
427
EOT;
428
429
        $dir = sprintf("%s/Service/Model/%s", $bundle->getPath(), $modelName);
430
        if (!is_dir($dir)) {
431
            mkdir($dir, 0777, true);
432
        }
433
434
        $fn = sprintf("%s/Service/Model/%s/%sManagerInterface.php", $bundle->getPath(), $modelName, $modelName);
435
        file_put_contents($fn, $txt);
436
    }
437
438
439
    protected function generateModelInterface(OutputInterface $output, BundleInterface $bundle, $modelName, array $fields)
440
    {
441
        $output->writeln(sprintf("Generating Model/%sInterface.php", $modelName));
442
443
        $txtMethods = '';
444
        foreach ($fields as $name=>$type) {
445
446
            $txtMethods .= $this->generateFieldGetterHeader($name, $type, ';');
447
            $txtMethods .= "    \n";
448
449
            if ($name == 'id') {
450
                continue;
451
            }
452
453
            $txtMethods .= $this->generateFieldSetterHeader($name, $type, $modelName, ';');
454
            $txtMethods .= "    \n";
455
        }
456
457
        $ns = $bundle->getNamespace();
458
459
        $txt = <<<EOT
460
<?php
461
462
namespace $ns\\Model;
463
464
interface {$modelName}Interface
465
{
466
$txtMethods
467
}
468
EOT;
469
470
        $dir = sprintf("%s/Model", $bundle->getPath());
471
        if (!is_dir($dir)) {
472
            mkdir($dir, 0777, true);
473
        }
474
475
        $fn = sprintf("%s/Model/%sInterface.php", $bundle->getPath(), $modelName);
476
        file_put_contents($fn, $txt);
477
    }
478
479
480
    protected function generateEntity(OutputInterface $output, BundleInterface $bundle, $modelName, array $fields)
481
    {
482
        $output->writeln(sprintf("Generating Entity/%s.php", $modelName));
483
484
        $ns = $bundle->getNamespace();
485
486
        $txt = <<<EOT
487
<?php
488
489
namespace $ns\\Entity;
490
491
class $modelName extends \\{$ns}\\Model\\{$modelName}
492
{
493
494
}
495
EOT;
496
497
        $dir = sprintf("%s/Entity", $bundle->getPath());
498
        if (!is_dir($dir)) {
499
            mkdir($dir, 0777, true);
500
        }
501
502
        $fn = sprintf("%s/Entity/%s.php", $bundle->getPath(), $modelName);
503
        file_put_contents($fn, $txt);
504
    }
505
506
    protected function generateModel(OutputInterface $output, BundleInterface $bundle, $modelName, array $fields)
507
    {
508
        $output->writeln(sprintf("Generating Model/%s.php", $modelName));
509
510
        $txtFields = '';
511
        foreach ($fields as $name=>$type) {
512
            $txtFields .= "    /** @var $type */\n";
513
            $txtFields .= "    protected \${$name};\n";
514
            $txtFields .= "    \n";
515
        }
516
517
        $txtMethods = '';
518
        foreach ($fields as $name=>$type) {
519
520
            $txtMethods .= $this->generateFieldGetterHeader($name, $type);
521
            $txtMethods .= $this->generateFieldGetterBody($name);
522
            $txtMethods .= "    \n";
523
524
            if ($name == 'id') {
525
                continue;
526
            }
527
528
            $txtMethods .= $this->generateFieldSetterHeader($name, $type, $modelName);
529
            $txtMethods .= $this->generateFieldSetterBody($name);
530
            $txtMethods .= "    \n";
531
        }
532
533
        $ns = $bundle->getNamespace();
534
535
        $txt = <<<EOT
536
<?php
537
538
namespace $ns\\Model;
539
540
abstract class $modelName implements {$modelName}Interface
541
{
542
$txtFields
543
544
545
$txtMethods
546
}
547
EOT;
548
549
        $dir = sprintf("%s/Model", $bundle->getPath());
550
        if (!is_dir($dir)) {
551
            mkdir($dir, 0777, true);
552
        }
553
554
        $fn = sprintf("%s/Model/%s.php", $bundle->getPath(), $modelName);
555
        file_put_contents($fn, $txt);
556
    }
557
558
559
    /**
560
     * @param $name
561
     * @param $type
562
     * @param $modelName
563
     * @param $extra
564
     * @return string
565
     */
566
    protected function generateFieldSetterHeader($name, $type, $modelName, $extra = '')
567
    {
568
        if (in_array($type, array('string', 'int', 'float', 'bool'))) {
569
            $s = '';
570
        } else {
571
            $s = $type.' ';
572
        }
573
        $n = ucfirst($name);
574
        $txtFields = '';
575
        $txtFields .= "    /**\n";
576
        $txtFields .= "     * @param $type \$value\n";
577
        $txtFields .= "     * @return {$modelName}Interface|\$this\n";
578
        $txtFields .= "     */\n";
579
        $txtFields .= "    public function set{$n}({$s}\$value){$extra}\n";
580
581
        return $txtFields;
582
    }
583
584
    /**
585
     * @param $name
586
     * @return string
587
     */
588
    protected function generateFieldSetterBody($name)
589
    {
590
        $txtFields = '';
591
        $txtFields .= "    {\n";
592
        $txtFields .= "        \$this->{$name} = \$value;\n";
593
        $txtFields .= "        \n";
594
        $txtFields .= "        return \$this;\n";
595
        $txtFields .= "    }\n";
596
597
        return $txtFields;
598
    }
599
600
    /**
601
     * @param $name
602
     * @param $type
603
     * @param string $extra
604
     * @return string
605
     */
606
    protected function generateFieldGetterHeader($name, $type, $extra = '')
607
    {
608
        $n = ucfirst($name);
609
        $txtFields = '';
610
        $txtFields .= "    /**\n";
611
        $txtFields .= "     * @return $type\n";
612
        $txtFields .= "     */\n";
613
        $txtFields .= "    public function get{$n}(){$extra}\n";
614
615
        return $txtFields;
616
    }
617
618
    /**
619
     * @param $name
620
     * @return string
621
     */
622
    protected function generateFieldGetterBody($name)
623
    {
624
        $txtFields = '';
625
        $txtFields .= "    {\n";
626
        $txtFields .= "        return \$this->{$name};\n";
627
        $txtFields .= "    }\n";
628
629
        return $txtFields;
630
    }
631
632
    protected function confirm(DialogHelper $dialog, OutputInterface $output, BundleInterface $bundle, $modelName, array $fields)
633
    {
634
        $output->writeln('');
635
        $output->writeln($bundle->getName());
636
        $output->writeln($modelName);
637
        foreach ($fields as $name=>$type) {
638
            $output->writeln('    '.$name.' : '.$type);
639
        }
640
641
        $output->writeln('');
642
        $ok = $dialog->askConfirmation($output, "Confirm generation? [y] : ");
643
        if (!$ok) {
644
            throw new \RuntimeException('Aborted');
645
        }
646
    }
647
648
649
    protected function getFields(DialogHelper $dialog, OutputInterface $output)
650
    {
651
        $result = array();
652
653
        $output->writeln('');
654
        $output->writeln("Enter empty field name to stop.");
655
656
        while (true) {
657
            $field = $dialog->askAndValidate($output,
658
                "Field name? : ",
659
                function($a) {
660
                    if (!preg_match("/^(|[a-z][a-zA-Z0-9]*)$/", $a)) {
661
                        throw new \InvalidArgumentException('Invalid field name');
662
                    }
663
                    return $a;
664
                }
665
            );
666
667
            if (!$field) {
668
                break;
669
            }
670
671
            $type = $dialog->ask($output,
672
                "Type? [string] : ",
673
                "string"
674
            );
675
676
            $output->writeln('');
677
678
            $result[$field] = $type;
679
        }
680
681
        if (empty($result)) {
682
            throw new \RuntimeException('Must have at least one field');
683
        }
684
685
        return $result;
686
    }
687
688
    protected function getModelName(DialogHelper $dialog, OutputInterface $output, BundleInterface $bundle)
689
    {
690
        $modelName = $dialog->askAndValidate($output,
691
            "What's the model name? : ",
692
            function($a) {
693
                if (!preg_match("|^[A-Z][a-zA-Z0-9]*$|", $a)) {
694
                    throw new \InvalidArgumentException('Invalid model name');
695
                }
696
                return $a;
697
            }
698
        );
699
700
        $files = array(
701
            sprintf("%s/Model/%s.php", $bundle->getPath(), $modelName),
702
            sprintf("%s/Entity/%s.php", $bundle->getPath(), $modelName),
703
            sprintf("%s/Resources/config/doctrine/%s.orm.xml", $bundle->getPath(), $modelName),
704
            sprintf("%s/Service/Model/%s/%sManagerInterface.php", $bundle->getPath(), $modelName, $modelName),
705
            sprintf("%s/Service/Model/%s/%sManager.php", $bundle->getPath(), $modelName, $modelName),
706
        );
707
        $exist = array();
708
        foreach ($files as $fn) {
709
            if (is_file(($fn))) {
710
                $exist[] = substr($fn, strlen($bundle->getPath())+1);
711
            }
712
        }
713
        if ($exist) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $exist of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using ! empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
714
            throw new \RuntimeException(sprintf("Can not overwrite existing files:\n    %s", implode("\n    ", $exist)));
715
        }
716
717
        return $modelName;
718
    }
719
720
    /**
721
     * @param DialogHelper $dialog
722
     * @param OutputInterface $output
723
     * @return BundleInterface
724
     */
725
    protected function pickBundle(DialogHelper $dialog, OutputInterface $output)
726
    {
727
        $output->writeln("");
728
        $arr = $this->getContainer()->get('kernel')->getBundles();
729
730
        /** @var BundleInterface[] $arrBundles */
731
        $arrBundles = array();
732
        foreach ($arr as $bundle) {
733
            if (strpos($bundle->getNamespace(), 'Symfony') === 0 ||
734
                strpos($bundle->getNamespace(), 'Sensio') === 0 ||
735
                strpos($bundle->getNamespace(), 'Doctrine') === 0
736
            ) {
737
                continue;
738
            }
739
740
            if (strpos($bundle->getPath(), '/vendor/') > 0 ||
741
                strpos($bundle->getPath(), '\\vendor\\') > 0
742
            ) {
743
                continue;
744
            }
745
746
            $arrBundles[] = $bundle;
747
        }
748
749
        foreach ($arrBundles as $k=>$bundle) {
750
            $output->writeln(sprintf("  %s -  %s", str_pad($k, 3, ' '), $bundle->getNamespace()));
751
        }
752
753
        $output->writeln('');
754
755
        $max = count($arrBundles)-1;
756
757
        $k = $dialog->askAndValidate($output,
758
            "In which bundle you wish to generate new model? [0 - $max] : ",
759
            function($a) use($max) {
760
                if (trim($a) == '') {
761
                    throw new \InvalidArgumentException('You must pick a bundle');
762
                }
763
                $b = intval($a);
764
                if ($b < 0 || $b >  $max) {
765
                    throw new \InvalidArgumentException(sprintf('Enter a number between 1 and %s', $max));
766
                }
767
                return $b;
768
            }
769
        );
770
771
        return $arrBundles[$k];
772
    }
773
774
}