Completed
Pull Request — 4.0 (#55)
by Huberty
03:08
created

BeanDescriptor::generateFindByDaoCode()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 14
Code Lines 9

Duplication

Lines 0
Ratio 0 %

Importance

Changes 3
Bugs 0 Features 0
Metric Value
c 3
b 0
f 0
dl 0
loc 14
rs 9.4285
cc 3
eloc 9
nc 3
nop 2
1
<?php
2
3
namespace Mouf\Database\TDBM\Utils;
4
5
use Doctrine\DBAL\Schema\Column;
6
use Doctrine\DBAL\Schema\Index;
7
use Doctrine\DBAL\Schema\Schema;
8
use Doctrine\DBAL\Schema\Table;
9
use Doctrine\DBAL\Schema\ForeignKeyConstraint;
10
use Mouf\Database\SchemaAnalyzer\SchemaAnalyzer;
11
use Mouf\Database\TDBM\TDBMException;
12
use Mouf\Database\TDBM\TDBMSchemaAnalyzer;
13
14
/**
15
 * This class represents a bean.
16
 */
17
class BeanDescriptor
18
{
19
    /**
20
     * @var Table
21
     */
22
    private $table;
23
24
    /**
25
     * @var SchemaAnalyzer
26
     */
27
    private $schemaAnalyzer;
28
29
    /**
30
     * @var Schema
31
     */
32
    private $schema;
33
34
    /**
35
     * @var AbstractBeanPropertyDescriptor[]
36
     */
37
    private $beanPropertyDescriptors = [];
38
39
    /**
40
     * @var TDBMSchemaAnalyzer
41
     */
42
    private $tdbmSchemaAnalyzer;
43
44
    public function __construct(Table $table, SchemaAnalyzer $schemaAnalyzer, Schema $schema, TDBMSchemaAnalyzer $tdbmSchemaAnalyzer)
45
    {
46
        $this->table = $table;
47
        $this->schemaAnalyzer = $schemaAnalyzer;
48
        $this->schema = $schema;
49
        $this->tdbmSchemaAnalyzer = $tdbmSchemaAnalyzer;
50
        $this->initBeanPropertyDescriptors();
51
    }
52
53
    private function initBeanPropertyDescriptors()
54
    {
55
        $this->beanPropertyDescriptors = $this->getProperties($this->table);
56
    }
57
58
    /**
59
     * Returns the foreign-key the column is part of, if any. null otherwise.
60
     *
61
     * @param Table  $table
62
     * @param Column $column
63
     *
64
     * @return ForeignKeyConstraint|null
65
     */
66
    private function isPartOfForeignKey(Table $table, Column $column)
67
    {
68
        $localColumnName = $column->getName();
69
        foreach ($table->getForeignKeys() as $foreignKey) {
70
            foreach ($foreignKey->getColumns() as $columnName) {
71
                if ($columnName === $localColumnName) {
0 ignored issues
show
Unused Code Bug introduced by
The strict comparison === seems to always evaluate to false as the types of $columnName (integer) and $localColumnName (string) can never be identical. Maybe you want to use a loose comparison == instead?
Loading history...
72
                    return $foreignKey;
73
                }
74
            }
75
        }
76
77
        return;
78
    }
79
80
    /**
81
     * @return AbstractBeanPropertyDescriptor[]
82
     */
83
    public function getBeanPropertyDescriptors()
84
    {
85
        return $this->beanPropertyDescriptors;
86
    }
87
88
    /**
89
     * Returns the list of columns that are not nullable and not autogenerated for a given table and its parent.
90
     *
91
     * @return AbstractBeanPropertyDescriptor[]
92
     */
93
    public function getConstructorProperties()
94
    {
95
        $constructorProperties = array_filter($this->beanPropertyDescriptors, function (AbstractBeanPropertyDescriptor $property) {
96
           return $property->isCompulsory();
97
        });
98
99
        return $constructorProperties;
100
    }
101
102
    /**
103
     * Returns the list of properties exposed as getters and setters in this class.
104
     *
105
     * @return AbstractBeanPropertyDescriptor[]
106
     */
107
    public function getExposedProperties()
108
    {
109
        $exposedProperties = array_filter($this->beanPropertyDescriptors, function (AbstractBeanPropertyDescriptor $property) {
110
            return $property->getTable()->getName() == $this->table->getName();
111
        });
112
113
        return $exposedProperties;
114
    }
115
116
    /**
117
     * Returns the list of properties for this table (including parent tables).
118
     *
119
     * @param Table $table
120
     *
121
     * @return AbstractBeanPropertyDescriptor[]
122
     */
123
    private function getProperties(Table $table)
124
    {
125
        $parentRelationship = $this->schemaAnalyzer->getParentRelationship($table->getName());
126
        if ($parentRelationship) {
127
            $parentTable = $this->schema->getTable($parentRelationship->getForeignTableName());
128
            $properties = $this->getProperties($parentTable);
129
            // we merge properties by overriding property names.
130
            $localProperties = $this->getPropertiesForTable($table);
131
            foreach ($localProperties as $name => $property) {
132
                // We do not override properties if this is a primary key!
133
                if ($property->isPrimaryKey()) {
134
                    continue;
135
                }
136
                $properties[$name] = $property;
137
            }
138
        } else {
139
            $properties = $this->getPropertiesForTable($table);
140
        }
141
142
        return $properties;
143
    }
144
145
    /**
146
     * Returns the list of properties for this table (ignoring parent tables).
147
     *
148
     * @param Table $table
149
     *
150
     * @return AbstractBeanPropertyDescriptor[]
151
     */
152
    private function getPropertiesForTable(Table $table)
153
    {
154
        $parentRelationship = $this->schemaAnalyzer->getParentRelationship($table->getName());
155
        if ($parentRelationship) {
156
            $ignoreColumns = $parentRelationship->getLocalColumns();
157
        } else {
158
            $ignoreColumns = [];
159
        }
160
161
        $beanPropertyDescriptors = [];
162
163
        foreach ($table->getColumns() as $column) {
164
            if (array_search($column->getName(), $ignoreColumns) !== false) {
165
                continue;
166
            }
167
168
            $fk = $this->isPartOfForeignKey($table, $column);
169
            if ($fk !== null) {
170
                // Check that previously added descriptors are not added on same FK (can happen with multi key FK).
171
                foreach ($beanPropertyDescriptors as $beanDescriptor) {
172
                    if ($beanDescriptor instanceof ObjectBeanPropertyDescriptor && $beanDescriptor->getForeignKey() === $fk) {
173
                        continue 2;
174
                    }
175
                }
176
                // Check that this property is not an inheritance relationship
177
                $parentRelationship = $this->schemaAnalyzer->getParentRelationship($table->getName());
178
                if ($parentRelationship === $fk) {
179
                    continue;
180
                }
181
182
                $beanPropertyDescriptors[] = new ObjectBeanPropertyDescriptor($table, $fk, $this->schemaAnalyzer);
183
            } else {
184
                $beanPropertyDescriptors[] = new ScalarBeanPropertyDescriptor($table, $column);
185
            }
186
        }
187
188
        // Now, let's get the name of all properties and let's check there is no duplicate.
189
        /** @var $names AbstractBeanPropertyDescriptor[] */
190
        $names = [];
191
        foreach ($beanPropertyDescriptors as $beanDescriptor) {
192
            $name = $beanDescriptor->getUpperCamelCaseName();
193
            if (isset($names[$name])) {
194
                $names[$name]->useAlternativeName();
195
                $beanDescriptor->useAlternativeName();
196
            } else {
197
                $names[$name] = $beanDescriptor;
198
            }
199
        }
200
201
        // Final check (throw exceptions if problem arises)
202
        $names = [];
203
        foreach ($beanPropertyDescriptors as $beanDescriptor) {
204
            $name = $beanDescriptor->getUpperCamelCaseName();
205
            if (isset($names[$name])) {
206
                throw new TDBMException('Unsolvable name conflict while generating method name');
207
            } else {
208
                $names[$name] = $beanDescriptor;
209
            }
210
        }
211
212
        // Last step, let's rebuild the list with a map:
213
        $beanPropertyDescriptorsMap = [];
214
        foreach ($beanPropertyDescriptors as $beanDescriptor) {
215
            $beanPropertyDescriptorsMap[$beanDescriptor->getLowerCamelCaseName()] = $beanDescriptor;
216
        }
217
218
        return $beanPropertyDescriptorsMap;
219
    }
220
221
    public function generateBeanConstructor()
222
    {
223
        $constructorProperties = $this->getConstructorProperties();
224
225
        $constructorCode = '    /**
226
     * The constructor takes all compulsory arguments.
227
     *
228
%s
229
     */
230
    public function __construct(%s) {
231
%s%s
232
    }
233
    ';
234
235
        $paramAnnotations = [];
236
        $arguments = [];
237
        $assigns = [];
238
        $parentConstructorArguments = [];
239
240
        foreach ($constructorProperties as $property) {
241
            $className = $property->getClassName();
242
            if ($className) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $className of type null|string is loosely compared to true; this is ambiguous if the string can be empty. You might want to explicitly use !== null instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For string values, the empty string '' is a special case, in particular the following results might be unexpected:

''   == false // true
''   == null  // true
'ab' == false // false
'ab' == null  // false

// It is often better to use strict comparison
'' === false // false
'' === null  // false
Loading history...
243
                $arguments[] = $className.' '.$property->getVariableName();
244
            } else {
245
                $arguments[] = $property->getVariableName();
246
            }
247
            $paramAnnotations[] = $property->getParamAnnotation();
248
            if ($property->getTable()->getName() === $this->table->getName()) {
249
                $assigns[] = $property->getConstructorAssignCode();
250
            } else {
251
                $parentConstructorArguments[] = $property->getVariableName();
252
            }
253
        }
254
255
        $parentConstrutorCode = sprintf("        parent::__construct(%s);\n", implode(', ', $parentConstructorArguments));
256
257
        return sprintf($constructorCode, implode("\n", $paramAnnotations), implode(', ', $arguments), $parentConstrutorCode, implode("\n", $assigns));
258
    }
259
260
    public function generateDirectForeignKeysCode()
261
    {
262
        $fks = $this->tdbmSchemaAnalyzer->getIncomingForeignKeys($this->table->getName());
263
264
        $fksByTable = [];
265
266
        foreach ($fks as $fk) {
267
            $fksByTable[$fk->getLocalTableName()][] = $fk;
268
        }
269
270
        /* @var $fksByMethodName ForeignKeyConstraint[] */
271
        $fksByMethodName = [];
272
273
        foreach ($fksByTable as $tableName => $fksForTable) {
274
            if (count($fksForTable) > 1) {
275
                foreach ($fksForTable as $fk) {
276
                    $methodName = 'get'.TDBMDaoGenerator::toCamelCase($fk->getLocalTableName()).'By';
277
278
                    $camelizedColumns = array_map(['Mouf\\Database\\TDBM\\Utils\\TDBMDaoGenerator', 'toCamelCase'], $fk->getLocalColumns());
279
280
                    $methodName .= implode('And', $camelizedColumns);
281
282
                    $fksByMethodName[$methodName] = $fk;
283
                }
284
            } else {
285
                $methodName = 'get'.TDBMDaoGenerator::toCamelCase($fksForTable[0]->getLocalTableName());
286
                $fksByMethodName[$methodName] = $fksForTable[0];
287
            }
288
        }
289
290
        $code = '';
291
292
        foreach ($fksByMethodName as $methodName => $fk) {
293
            $getterCode = '    /**
294
     * Returns the list of %s pointing to this bean via the %s column.
295
     *
296
     * @return %s[]|ResultIterator
297
     */
298
    public function %s()
299
    {
300
        return $this->tdbmService->findObjects(%s, %s, %s);
301
    }
302
303
';
304
305
            list($sql, $parametersCode) = $this->getFilters($fk);
306
307
            $beanClass = TDBMDaoGenerator::getBeanNameFromTableName($fk->getLocalTableName());
308
            $code .= sprintf($getterCode,
309
                $beanClass,
310
                implode(', ', $fk->getColumns()),
311
                $beanClass,
312
                $methodName,
313
                var_export($fk->getLocalTableName(), true),
314
                $sql,
315
                $parametersCode
316
            );
317
        }
318
319
        return $code;
320
    }
321
322
    private function getFilters(ForeignKeyConstraint $fk)
323
    {
324
        $sqlParts = [];
325
        $counter = 0;
326
        $parameters = [];
327
328
        $pkColumns = $this->table->getPrimaryKeyColumns();
329
330
        foreach ($fk->getLocalColumns() as $columnName) {
331
            $paramName = 'tdbmparam'.$counter;
332
            $sqlParts[] = $fk->getLocalTableName().'.'.$columnName.' = :'.$paramName;
333
334
            $pkColumn = $pkColumns[$counter];
335
            $parameters[] = sprintf('%s => $this->get(%s, %s)', var_export($paramName, true), var_export($pkColumn, true), var_export($this->table->getName(), true));
336
            ++$counter;
337
        }
338
        $sql = "'".implode(' AND ', $sqlParts)."'";
339
        $parametersCode = '[ '.implode(', ', $parameters).' ]';
340
341
        return [$sql, $parametersCode];
342
    }
343
344
    /**
345
     * Generate code section about pivot tables.
346
     *
347
     * @return string
348
     */
349
    public function generatePivotTableCode()
350
    {
351
        $finalDescs = $this->getPivotTableDescriptors();
352
353
        $code = '';
354
355
        foreach ($finalDescs as $desc) {
356
            $code .= $this->getPivotTableCode($desc['name'], $desc['table'], $desc['localFK'], $desc['remoteFK']);
357
        }
358
359
        return $code;
360
    }
361
362
    private function getPivotTableDescriptors()
363
    {
364
        $descs = [];
365
        foreach ($this->schemaAnalyzer->detectJunctionTables() as $table) {
366
            // There are exactly 2 FKs since this is a pivot table.
367
            $fks = array_values($table->getForeignKeys());
368
369
            if ($fks[0]->getForeignTableName() === $this->table->getName()) {
370
                $localFK = $fks[0];
371
                $remoteFK = $fks[1];
372
            } elseif ($fks[1]->getForeignTableName() === $this->table->getName()) {
373
                $localFK = $fks[1];
374
                $remoteFK = $fks[0];
375
            } else {
376
                continue;
377
            }
378
379
            $descs[$remoteFK->getForeignTableName()][] = [
380
                'table' => $table,
381
                'localFK' => $localFK,
382
                'remoteFK' => $remoteFK,
383
            ];
384
        }
385
386
        $finalDescs = [];
387
        foreach ($descs as $descArray) {
388
            if (count($descArray) > 1) {
389
                foreach ($descArray as $desc) {
390
                    $desc['name'] = TDBMDaoGenerator::toCamelCase($desc['remoteFK']->getForeignTableName()).'By'.TDBMDaoGenerator::toCamelCase($desc['table']->getName());
391
                    $finalDescs[] = $desc;
392
                }
393
            } else {
394
                $desc = $descArray[0];
395
                $desc['name'] = TDBMDaoGenerator::toCamelCase($desc['remoteFK']->getForeignTableName());
396
                $finalDescs[] = $desc;
397
            }
398
        }
399
400
        return $finalDescs;
401
    }
402
403
    public function getPivotTableCode($name, Table $table, ForeignKeyConstraint $localFK, ForeignKeyConstraint $remoteFK)
0 ignored issues
show
Unused Code introduced by
The parameter $localFK is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
404
    {
405
        $singularName = TDBMDaoGenerator::toSingular($name);
406
        $remoteBeanName = TDBMDaoGenerator::getBeanNameFromTableName($remoteFK->getForeignTableName());
407
        $variableName = '$'.TDBMDaoGenerator::toVariableName($remoteBeanName);
408
409
        $str = '    /**
410
     * Returns the list of %s associated to this bean via the %s pivot table.
411
     *
412
     * @return %s[]
413
     */
414
    public function get%s() {
415
        return $this->_getRelationships(%s);
416
    }
417
';
418
419
        $getterCode = sprintf($str, $remoteBeanName, $table->getName(), $remoteBeanName, $name, var_export($remoteFK->getLocalTableName(), true));
420
421
        $str = '    /**
422
     * Adds a relationship with %s associated to this bean via the %s pivot table.
423
     *
424
     * @param %s %s
425
     */
426
    public function add%s(%s %s) {
427
        return $this->addRelationship(%s, %s);
428
    }
429
';
430
431
        $adderCode = sprintf($str, $remoteBeanName, $table->getName(), $remoteBeanName, $variableName, $singularName, $remoteBeanName, $variableName, var_export($remoteFK->getLocalTableName(), true), $variableName);
432
433
        $str = '    /**
434
     * Deletes the relationship with %s associated to this bean via the %s pivot table.
435
     *
436
     * @param %s %s
437
     */
438
    public function remove%s(%s %s) {
439
        return $this->_removeRelationship(%s, %s);
440
    }
441
';
442
443
        $removerCode = sprintf($str, $remoteBeanName, $table->getName(), $remoteBeanName, $variableName, $singularName, $remoteBeanName, $variableName, var_export($remoteFK->getLocalTableName(), true), $variableName);
444
445
        $str = '    /**
446
     * Returns whether this bean is associated with %s via the %s pivot table.
447
     *
448
     * @param %s %s
449
     * @return bool
450
     */
451
    public function has%s(%s %s) {
452
        return $this->hasRelationship(%s, %s);
453
    }
454
';
455
456
        $hasCode = sprintf($str, $remoteBeanName, $table->getName(), $remoteBeanName, $variableName, $singularName, $remoteBeanName, $variableName, var_export($remoteFK->getLocalTableName(), true), $variableName);
457
458
        $code = $getterCode.$adderCode.$removerCode.$hasCode;
459
460
        return $code;
461
    }
462
463
    public function generateJsonSerialize()
464
    {
465
        $tableName = $this->table->getName();
466
        $parentFk = $this->schemaAnalyzer->getParentRelationship($tableName);
467
        if ($parentFk !== null) {
468
            $initializer = '$array = parent::jsonSerialize();';
469
        } else {
470
            $initializer = '$array = [];';
471
        }
472
473
        $str = '
474
    /**
475
     * Serializes the object for JSON encoding
476
     *
477
     * @param bool $stopRecursion Parameter used internally by TDBM to stop embedded objects from embedding other objects.
478
     * @return array
479
     */
480
    public function jsonSerialize($stopRecursion = false)
481
    {
482
        %s
483
%s
484
%s
485
        return $array;
486
    }
487
';
488
489
        $propertiesCode = '';
490
        foreach ($this->beanPropertyDescriptors as $beanPropertyDescriptor) {
491
            $propertiesCode .= $beanPropertyDescriptor->getJsonSerializeCode();
492
        }
493
494
        // Many to many relationships:
495
496
        $descs = $this->getPivotTableDescriptors();
497
498
        $many2manyCode = '';
499
500
        foreach ($descs as $desc) {
501
            $remoteFK = $desc['remoteFK'];
502
            $remoteBeanName = TDBMDaoGenerator::getBeanNameFromTableName($remoteFK->getForeignTableName());
503
            $variableName = '$'.TDBMDaoGenerator::toVariableName($remoteBeanName);
504
505
            $many2manyCode .= '        if (!$stopRecursion) {
506
            $array[\''.lcfirst($desc['name']).'\'] = array_map(function('.$remoteBeanName.' '.$variableName.') {
507
                return '.$variableName.'->jsonSerialize(true);
508
            }, $this->get'.$desc['name'].'());
509
        }
510
        ';
511
        }
512
513
        return sprintf($str, $initializer, $propertiesCode, $many2manyCode);
514
    }
515
516
    /**
517
     * Writes the PHP bean file with all getters and setters from the table passed in parameter.
518
     *
519
     * @param string $beannamespace The namespace of the bean
520
     */
521
    public function generatePhpCode($beannamespace)
522
    {
523
        $baseClassName = TDBMDaoGenerator::getBaseBeanNameFromTableName($this->table->getName());
524
        $className = TDBMDaoGenerator::getBeanNameFromTableName($this->table->getName());
525
        $tableName = $this->table->getName();
526
527
        $parentFk = $this->schemaAnalyzer->getParentRelationship($tableName);
528
        if ($parentFk !== null) {
529
            $extends = TDBMDaoGenerator::getBeanNameFromTableName($parentFk->getForeignTableName());
530
            $use = '';
531
        } else {
532
            $extends = 'AbstractTDBMObject';
533
            $use = "use Mouf\\Database\\TDBM\\AbstractTDBMObject;\n\n";
534
        }
535
536
        $str = "<?php
537
namespace {$beannamespace};
538
539
use Mouf\\Database\\TDBM\\ResultIterator;
540
$use
541
/*
542
 * This file has been automatically generated by TDBM.
543
 * DO NOT edit this file, as it might be overwritten.
544
 * If you need to perform changes, edit the $className class instead!
545
 */
546
547
/**
548
 * The $baseClassName class maps the '$tableName' table in database.
549
 */
550
class $baseClassName extends $extends implements \\JsonSerializable
551
{
552
";
553
554
        $str .= $this->generateBeanConstructor();
555
556
        foreach ($this->getExposedProperties() as $property) {
557
            $str .= $property->getGetterSetterCode();
558
        }
559
560
        $str .= $this->generateDirectForeignKeysCode();
561
        $str .= $this->generatePivotTableCode();
562
        $str .= $this->generateJsonSerialize();
563
564
        $str .= '}
565
';
566
567
        return $str;
568
    }
569
570
    /**
571
     * @param string $beanNamespace
572
     * @param string $beanClassName
573
     *
574
     * @return array first element: list of used beans, second item: PHP code as a string
575
     */
576
    public function generateFindByDaoCode($beanNamespace, $beanClassName)
577
    {
578
        $code = '';
579
        $usedBeans = [];
580
        foreach ($this->table->getIndexes() as $index) {
581
            if (!$index->isPrimary()) {
582
                list($usedBeansForIndex, $codeForIndex) = $this->generateFindByDaoCodeForIndex($index, $beanNamespace, $beanClassName);
583
                $code .= $codeForIndex;
584
                $usedBeans = array_merge($usedBeans, $usedBeansForIndex);
585
            }
586
        }
587
588
        return [$usedBeans, $code];
589
    }
590
591
    /**
592
     * @param Index  $index
593
     * @param string $beanNamespace
594
     * @param string $beanClassName
595
     *
596
     * @return array first element: list of used beans, second item: PHP code as a string
597
     */
598
    private function generateFindByDaoCodeForIndex(Index $index, $beanNamespace, $beanClassName)
599
    {
600
        $columns = $index->getColumns();
601
        $usedBeans = [];
602
603
        /*
604
         * The list of elements building this index (expressed as columns or foreign keys)
605
         * @var AbstractBeanPropertyDescriptor[]
606
         */
607
        $elements = [];
608
609
        foreach ($columns as $column) {
610
            $fk = $this->isPartOfForeignKey($this->table, $this->table->getColumn($column));
611
            if ($fk !== null) {
612
                if (!in_array($fk, $elements)) {
613
                    $elements[] = new ObjectBeanPropertyDescriptor($this->table, $fk, $this->schemaAnalyzer);
614
                }
615
            } else {
616
                $elements[] = new ScalarBeanPropertyDescriptor($this->table, $this->table->getColumn($column));
617
            }
618
        }
619
620
        // If the index is actually only a foreign key, let's bypass it entirely.
621
        if (count($elements) === 1 && $elements[0] instanceof ObjectBeanPropertyDescriptor) {
622
            return [[], ''];
623
        }
624
625
        $methodNameComponent = [];
626
        $functionParameters = [];
627
        $first = true;
628
        foreach ($elements as $element) {
629
            $methodNameComponent[] = $element->getUpperCamelCaseName();
630
            $functionParameter = $element->getClassName();
631
            if ($functionParameter) {
632
                $usedBeans[] = $beanNamespace.'\\'.$functionParameter;
633
                $functionParameter .= ' ';
634
            }
635
            $functionParameter .= $element->getVariableName();
636
            if ($first) {
637
                $first = false;
638
            } else {
639
                $functionParameter .= ' = null';
640
            }
641
            $functionParameters[] = $functionParameter;
642
        }
643
        if ($index->isUnique()) {
644
            $methodName = 'findOneBy'.implode('And', $methodNameComponent);
645
            $calledMethod = 'findOne';
646
        } else {
647
            $methodName = 'findBy'.implode('And', $methodNameComponent);
648
            $calledMethod = 'find';
649
        }
650
        $functionParametersString = implode(', ', $functionParameters);
651
652
        $count = 0;
653
654
        $params = [];
655
        $filterArrayCode = '';
656
        $commentArguments = [];
657
        foreach ($elements as $element) {
658
            $params[] = $element->getParamAnnotation();
659
            if ($element instanceof ScalarBeanPropertyDescriptor) {
660
                $filterArrayCode .= '            '.var_export($element->getColumnName(), true).' => '.$element->getVariableName().",\n";
661
            } else {
662
                ++$count;
663
                $filterArrayCode .= '            '.$count.' => '.$element->getVariableName().",\n";
664
            }
665
            $commentArguments[] = substr($element->getVariableName(), 1);
666
        }
667
        $paramsString = implode("\n", $params);
668
669
        $code = "
670
    /**
671
     * Get a list of $beanClassName filtered by ".implode(', ', $commentArguments).".
672
     *
673
$paramsString
674
     * @param mixed \$orderBy The order string
675
     * @param array \$additionalTablesFetch A list of additional tables to fetch (for performance improvement)
676
     * @param string \$mode Either TDBMService::MODE_ARRAY or TDBMService::MODE_CURSOR (for large datasets). Defaults to TDBMService::MODE_ARRAY.
677
     * @return {$beanClassName}[]|ResultIterator|ResultArray
678
     */
679
    public function $methodName($functionParametersString, \$orderBy = null, array \$additionalTablesFetch = array(), \$mode = null)
680
    {
681
        \$filter = [
682
".$filterArrayCode."        ];
683
        return \$this->$calledMethod(\$filter, [], \$orderBy, \$additionalTablesFetch, \$mode);
684
    }
685
";
686
687
        return [$usedBeans, $code];
688
    }
689
}
690