Test Failed
Push — master ( 4f74c4...a00e28 )
by Vitaly
07:26 queued 03:46
created

Generator::defarraymerge()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 9
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 3
Bugs 0 Features 2
Metric Value
c 3
b 0
f 2
dl 0
loc 9
rs 9.6667
cc 2
eloc 4
nc 2
nop 3
1
<?php
2
//[PHPCOMPRESSOR(remove,start)]
3
namespace samsonphp\generator;
4
5
class Generator
6
{
7
    /** Single quote for string value **/
8
    const QUOTE_SINGLE = "'";
9
10
    /** Double quote for string value **/
11
    const QUOTE_DOUBLE = '"';
12
13
    /** @var string Generated code */
14
    public $code = '';
15
16
    /** @var integer Level of code line tabbing for new lines */
17
    public $tabs = 0;
18
19
    /** @var string Current class name */
20
    public $class;
21
22
    /**
23
     * Add simple text to current code position
24
     * @param string $text Text to add
25
     * @return self
26
     */
27
    public function text($text = '')
28
    {
29
        $this->code .= $text;
30
31
        return $this;
32
    }
33
34
    /**
35
     * Add current tabbing level to current line.
36
     *
37
     * @param string $endText Text to add after tabs
38
     * @param integer $tabs Amount of tabs to add
39
     * @param string $startText Text to add before tabs
40
     * @return Generator Chaining
41
     */
42
    public function tabs($endText = '', $tabs = null, $startText = '')
43
    {
44
        // Generate tabs array
45
        $tabs = isset($tabs) ? array_fill(0, $tabs, "\t") : array();
46
47
        // Add necessary amount of tabs to line and append text
48
        $this->text($startText.implode('', $tabs) . $endText);
49
50
        return $this;
51
    }
52
53
    /**
54
     * Add new line to code.
55
     *
56
     * @param string $text Code to add to new line
57
     * @param integer $tabs Tabs count
58
     * @return self
59
     */
60
    public function newline($text = '', $tabs = null)
61
    {
62
        // If no tabs count is specified set default tabs
63
        if (!isset($tabs)) {
64
            $tabs = $this->tabs;
65
        }
66
67
        return $this->tabs($text, $tabs, "\n");
68
    }
69
70
    /**
71
     * Add single line comment to code
72
     * @param string $text Comment text
73
     * @return self Chaining
74
     */
75
    public function comment($text = '')
76
    {
77
        return isset($text{0}) ? $this->newline("// " . $text) : $this;
78
    }
79
80
    /**
81
     * Add multi-line comment. If array with one line is passed
82
     * we create special syntax comment in one line, usually
83
     * used for class variable definition in more compact form.
84
     *
85
     * @param array $lines Array of comments lines
86
     * @return self Chaining
87
     */
88
    public function multicomment(array $lines = array())
89
    {
90
        // If array is not empty
91
        if (sizeof($lines)) {
92
            $this->newline("/**");
93
94
            // Multi-comment with single line
95
            if (sizeof($lines) === 1) {
96
                $this->text(' '.$lines[0].' */');
97
            } else { // Iterate comments lines and if comment line is not empty
98
                foreach ($lines as $line) {
99
                    if (isset($line{0})) {
100
                        $this->newline(" * " . $line);
101
                    }
102
                }
103
104
                return $this->newline(" */");
105
            }
106
107
        }
108
109
        return $this;
110
    }
111
112
    /**
113
     * Add string value definition
114
     * @param string $value String value to add
115
     * @param string $tabs Tabs count
116
     * @param string $quote Type of quote
117
     * @return self
118
     */
119
    public function stringvalue($value, $tabs = null, $quote = self::QUOTE_SINGLE)
120
    {
121
        return $this->tabs($quote . $value . $quote, $tabs);
122
    }
123
124
    /**
125
     * Add array values definition
126
     * @param array $items Array key-value pairs collection
127
     * @return self Chaining
128
     */
129
    public function arrayvalue(array $items = array())
130
    {
131
        $this->text('array(');
132
        $this->tabs++;
133
134
        // Iterate array items
135
        foreach ($items as $key => $value) {
136
            // Start array key definition
137
            $this->newline()->stringvalue($key)->text(' => ');
138
139
            // If item value is array - recursion
140
            if (is_array($value)) {
141
                $this->arrayvalue($value)->text(',');
142
            } else {
143
                $this->stringvalue($value)->text(',');
144
            }
145
        }
146
147
        $this->newline(')');
148
        $this->tabs--;
149
150
        return $this;
151
    }
152
153
    /**
154
     * Add variable definition with array merging.
155
     *
156
     * @param string $name Variable name
157
     * @param array $value Array of key-value items for merging it to other array
158
     * @param string $arrayName Name of array to merge to, if no is specified - $name is used
159
     * @return self Chaining
160
     */
161
    public function defarraymerge($name, array $value, $arrayName = null)
162
    {
163
        // If no other array is specified - set it to current
164
        if (!isset($arrayName)) {
165
            $arrayName = $name;
166
        }
167
168
        return $this->defvar($name, $value, ' = array_merge( ' . $arrayName . ', ', '')->text(');');
0 ignored issues
show
Documentation introduced by
$value is of type array, but the function expects a string|null.

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...
169
    }
170
171
    /**
172
     * Add variable definition.
173
     *
174
     * @param string $name Variable name
175
     * @param string $value Variable default value
176
     * @param string $after String to insert after variable definition
177
     * @param string $end Closing part of variable definition
178
     * @param string $quote Type of quote
179
     * @return Generator Chaining
180
     */
181
    public function defVar($name, $value = null, $after = ' = ', $end = ';', $quote = self::QUOTE_SINGLE)
182
    {
183
        // Output variable definition
184
        $this->newline($name);
185
186
        // Get variable type
187
        switch (gettype($value)) {
188
            case 'integer':
189
            case 'boolean':
190
            case 'double':
191
                $this->text($after)->text($value)->text($end);
192
                break;
193
            case 'string':
194
                $this->text($after)->stringvalue($value, 0, $quote)->text($end);
195
                break;
196
            case 'array':
197
                $this->text($after)->arrayvalue($value)->text($end);
0 ignored issues
show
Documentation introduced by
$value is of type null, but the function expects a array.

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...
198
                break;
199
            case 'NULL':
200
            case 'object':
201
            case 'resource':
202
            default:
203
                $this->text(';');
204
        }
205
206
        return $this;
207
    }
208
209
    /**
210
     * Add class definition.
211
     *
212
     * @param string $name Class name
213
     * @param string $extends Parent class name
214
     * @param array $implements Interfaces names collection
215
     * @return self Chaining
216
     */
217
    public function defClass($name, $extends = null, array $implements = array())
218
    {
219
        // If we define another class, and we were in other class context
220
        if (isset($this->class) && ($name !== $this->class)) {
221
            // Close old class context
222
            $this->endclass();
223
        }
224
225
        // Save new class name
226
        $this->class = $name;
227
228
        // Class definition start
229
        $this->newline('class ' . $name);
230
231
        // Parent class definition
232
        if (isset($extends)) {
233
            $this->text(' extends ' . $extends);
234
        }
235
236
        // Interfaces
237
        if (sizeof($implements)) {
238
            $this->text(' implements ' . implode(',', $implements));
239
        }
240
241
        $this->newline('{');
242
243
        $this->tabs++;
244
245
        return $this;
246
    }
247
248
    /**
249
     * Close current class context.
250
     *
251
     * @return self Chaining
252
     */
253
    public function endclass()
254
    {
255
        // Close class definition
256
        $this->newline('}')
257
            // Add one empty line after class definition
258
        ->newline('');
259
260
        $this->tabs--;
261
262
        return $this;
263
    }
264
265
    /**
266
     * Add class variable definition.
267
     *
268
     * @param string $name Variable name
269
     * @param string $visibility Variable accessibility level
270
     * @param string|null $comment Variable description
271
     * @param string $value Variable default value
272
     * @return self Chaining
273
     */
274
    public function defClassVar($name, $visibility = 'public', $comment = null, $value = null)
275
    {
276
        if (isset($comment)) {
277
            $this->multicomment(array($comment));
278
        }
279
280
        return $this->defvar($visibility . ' ' . $name, $value)->newline();
281
    }
282
283
    /**
284
     * Add class constant definition.
285
     *
286
     * @param string $name Constant name
287
     * @param string $value Variable default value
288
     * @param string|null $comment Variable description
289
     * @return self Chaining
290
     */
291
    public function defClassConst($name, $value, $comment = null)
292
    {
293
        return $this->defClassVar(strtoupper($name), 'const', $comment, $value);
294
    }
295
296
    /**
297
     * Write file to disk
298
     * @param string $name Path to file
299
     * @param string $format Output file format
300
     */
301
    public function write($name, $format = 'php')
302
    {
303
        $code = $this->flush();
304
305
        if ($format === 'php') {
306
            $code = '<?php ' . $code;
307
        }
308
309
        file_put_contents($name, $code, 0775);
310
    }
311
312
    /**
313
     * Flush internal data and return it.
314
     *
315
     * @return string Current generated code
316
     */
317
    public function flush()
318
    {
319
        // We should use 4 spaces instead of tabs
320
        $code = str_replace("\t", '    ', $this->code);
321
322
        $this->tabs = 0;
323
        $this->code = '';
324
        $this->class = null;
325
326
        return $code;
327
    }
328
329
    /**
330
     * Add function definition
331
     * @param string $name Function name
332
     * @return self Chaining
333
     */
334
    public function deffunction($name)
335
    {
336
        return $this->newline('function ' . $name . '()')
337
            ->newline('{')
338
            ->tabs('', 1);
339
    }
340
341
    /**
342
     * Close current function context
343
     * @return\samson\activerecord\Generator
344
     */
345
    public function endfunction()
346
    {
347
        return $this->newline('}')->newline('');
348
    }
349
350
    /**
351
     * Constructor
352
     * @param string $namespace Code namespace
353
     */
354
    public function __construct($namespace = null)
355
    {
356
        // If namespace is defined - set it
357
        if (isset($namespace)) {
358
            $this->defnamespace($namespace);
359
        }
360
    }
361
362
    /**
363
     * Add namespace declaration
364
     * @param string $name Namespace name
365
     * @return self
366
     */
367
    private function defnamespace($name)
368
    {
369
        return $this->newline('namespace ' . $name . ';')->newline();
370
    }
371
}
372
//[PHPCOMPRESSOR(remove,end)]
373