FormGenerator::getAddMethod()   B
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 26
Code Lines 13

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 1 Features 1
Metric Value
c 1
b 1
f 1
dl 0
loc 26
rs 8.8571
cc 1
eloc 13
nc 1
nop 1
1
<?php
2
/**
3
 * Sake
4
 *
5
 * @link      http://github.com/sandrokeil/CodeGenerator for the canonical source repository
6
 * @copyright Copyright (c) 2014 Sandro Keil
7
 * @license   http://github.com/sandrokeil/CodeGenerator/blob/master/LICENSE.txt New BSD License
8
 */
9
10
namespace Sake\CodeGenerator\Code\Generator;
11
12
use Sake\CodeGenerator\Code\Metadata\MetadataInfo;
13
use Zend\Code\Generator\DocBlock\Tag;
14
use Zend\Code\Generator\DocBlockGenerator;
15
use Zend\Code\Generator\FileGenerator;
16
use Zend\Code\Generator\ClassGenerator;
17
use Zend\Code\Generator\MethodGenerator;
18
19
/**
20
 * Form generator
21
 *
22
 * Generates zend framework 2 form depending on given meta data (table or entity definitions).
23
 */
24
class FormGenerator extends AbstractGenerator
25
{
26
    /**
27
     * FCQN of class to extends
28
     *
29
     * @var string
30
     */
31
    protected $classToExtend = '\Zend\Form\Fieldset';
32
33
    /**
34
     * Namespace
35
     *
36
     * @var string
37
     */
38
    protected $namespace = 'Form\Fieldset';
39
40
    /**
41
     * Returns file name for specifc generated type
42
     *
43
     * @param MetadataInfo $metadata
44
     * @return string
45
     */
46
    public function getName(MetadataInfo $metadata)
47
    {
48
        return 'Form/Fieldset/' . $this->convertName($metadata->getTable('name'));
0 ignored issues
show
Documentation introduced by
$metadata->getTable('name') is of type array, but the function expects a string.

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...
49
    }
50
51
    /**
52
     * Generates zend form class
53
     *
54
     * @param MetadataInfo $metadata
55
     * @return FileGenerator
56
     */
57
    public function generateClass(MetadataInfo $metadata)
58
    {
59
        $methods = array($this->getInitMethod($metadata), );
60
61
        foreach ($metadata->getColumns() as $name => $data) {
62
            // dont add primary keys
63
            if (!empty($data['id'])) {
64
                continue;
65
            }
66
            $methods[] = $this->getAddMethod($data);
67
        }
68
        foreach ($metadata->getForeignKeys() as $name => $data) {
69
            // dont add foreign key definition
70
            if (8 === $data['type']) {
71
                continue;
72
            }
73
            $methods[] = $this->getAddMethodForAssociation($data);
74
        }
75
76
        $file = new FileGenerator(array(
77
            'classes' => array(
78
                new ClassGenerator(
79
                    $metadata->getName(),
80
                    'Form',
81
                    null,
82
                    $this->classToExtend,
83
                    array(
84
                        'InitializableInterface'
85
                    ),
86
                    array(),
87
                    $methods,
88
                    new DocBlockGenerator(
89
                        'Form fieldset for ' . $metadata->getName(),
90
                        'This fieldset can be used to build complex forms for ' . $metadata->getName()
91
                    )
92
                ),
93
            ),
94
            'namespace' => $this->namespace,
95
            'uses' => array(
96
                '\Zend\Stdlib\InitializableInterface'
97
            ),
98
            'docBlock' => new DocBlockGenerator(
99
                'Generated by Sake\CodeGenerator http://github.com/sandrokeil/CodeGenerator'
100
            )
101
        ));
102
        return $file;
103
    }
104
105
    /**
106
     * Generate form init method which calls add functions.
107
     *
108
     * @param MetadataInfo $metadataInfo
109
     * @return MethodGenerator
110
     */
111
    protected function getInitMethod(MetadataInfo $metadataInfo)
112
    {
113
        $body = '';
114
115
        foreach ($metadataInfo->getColumns() as $name => $data) {
116
            // dont add primary keys
117
            if (!empty($data['id'])) {
118
                continue;
119
            }
120
            $body .= '$this->addElement' . $this->convertName($data['columnName']) . '();' . PHP_EOL;
121
        }
122
        foreach ($metadataInfo->getForeignKeys() as $name => $data) {
123
            // dont add foreign key definition
124
            if (8 === $data['type']) {
125
                continue;
126
            }
127
            $body .= '$this->addElement' . $this->convertName($data['fieldName']) . '();' . PHP_EOL;
128
        }
129
130
        return new MethodGenerator(
131
            'init',
132
            array(),
133
            MethodGenerator::FLAG_PUBLIC,
134
            $body,
135
            new DocBlockGenerator('Initialize form elements')
136
        );
137
    }
138
139
    /**
140
     * Returns the form element type depending on table information.
141
     *
142
     * @param array $metadata Field metadata
143
     * @return string Element type
144
     */
145
    protected function getElementType(array $metadata)
146
    {
147
        switch ($metadata['type']) {
148
            case 'text':
149
                $type = 'textarea';
150
                break;
151
152
            default:
153
                $type = 'text';
154
                break;
155
        }
156
        return $type;
157
    }
158
159
    /**
160
     * Returns add methods for foreign keys
161
     *
162
     * @param array $data
163
     * @return MethodGenerator
164
     */
165
    protected function getAddMethodForAssociation(array $data)
166
    {
167
        $name = $this->convertName($data['fieldName']);
168
        $attributes = "array('id' => '" . $name . "')";
169
170
        $body = <<<'EOT'
171
    $this->add(
172
    array(
173
        'type' => '%s',
174
        'name' => '%s',
175
        'options' => array(
176
            'label' => '%s',
177
            'empty_option' => 'Please choose %s',
178
            'object_manager' => $this->getObjectManager(),
179
            'target_class' => '%s',
180
            'property' => '%s',
181
        ),
182
        'attributes' => %s,
183
    )
184
);
185
186
EOT;
187
188
        $body = sprintf(
189
            $body,
190
            'DoctrineORMModule\Form\Element\EntitySelect',
191
            lcfirst($name),
192
            $name,
193
            $name,
194
            $data['targetEntity'],
195
            '[SET PROPERTY NAME FOR TEXT]',
196
            $attributes
197
        );
198
        return new MethodGenerator(
199
            'addElement' . $name,
200
            array(),
201
            MethodGenerator::FLAG_PROTECTED,
202
            $body,
203
            new DocBlockGenerator(sprintf('Adds element %s to form, it is a foreign key', lcfirst($name)))
204
        );
205
    }
206
207
    /**
208
     * Returns add method with element defintion
209
     *
210
     * @param array $data
211
     * @return MethodGenerator
212
     */
213
    protected function getAddMethod(array $data)
214
    {
215
        $name = $this->convertName($data['columnName']);
216
        $options = "array('label' => '" . $name . "')";
217
        $attributes = "array('id' => '" . $name . "')";
218
219
        $body = <<<'EOT'
220
    $this->add(
221
    array(
222
        'type' => '%s',
223
        'name' => '%s',
224
        'options' => %s,
225
        'attributes' => %s,
226
    )
227
);
228
229
EOT;
230
231
        return new MethodGenerator(
232
            'addElement' . $name,
233
            array(),
234
            MethodGenerator::FLAG_PROTECTED,
235
            sprintf($body, $this->getElementType($data), lcfirst($name), $options, $attributes),
236
            new DocBlockGenerator(sprintf('Adds element %s to form', lcfirst($name)))
237
        );
238
    }
239
}
240