Passed
Push — master ( 1c101f...c673c5 )
by Matthew
11:42
created

GridSourceGenerator::__construct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 5
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 5
c 0
b 0
f 0
rs 9.4285
cc 1
eloc 3
nc 1
nop 2
1
<?php
2
3
namespace Dtc\GridBundle\Generator;
4
5
use Doctrine\ODM\MongoDB\Mapping\ClassMetadata;
6
use Dtc\GridBundle\Util\CamelCaseTrait;
7
use Symfony\Component\DependencyInjection\ContainerInterface;
8
use Symfony\Component\HttpKernel\Bundle\BundleInterface;
9
use Symfony\Component\Yaml\Yaml;
10
use Doctrine\ORM\Mapping\ClassMetadataInfo;
11
12
/**
13
 * @deprecated
14
 * Class GridSourceGenerator
15
 */
16
class GridSourceGenerator extends Generator
17
{
18
    use CamelCaseTrait;
19
20
    private $saveCache;
21
    private $skeletonDir;
22
23
    public function __construct($skeletonDir, ContainerInterface $container)
24
    {
25
        $this->skeletonDir = $skeletonDir;
26
        $this->container = $container;
0 ignored issues
show
Bug introduced by
The property container does not exist. Did you maybe forget to declare it?

In PHP it is possible to write to properties without declaring them. For example, the following is perfectly valid PHP code:

class MyClass { }

$x = new MyClass();
$x->foo = true;

Generally, it is a good practice to explictly declare properties to avoid accidental typos and provide IDE auto-completion:

class MyClass {
    public $foo;
}

$x = new MyClass();
$x->foo = true;
Loading history...
27
    }
28
29
    protected function generateColumns(BundleInterface $bundle, $entity, $metadata)
30
    {
31
        $parts = explode('\\', $entity);
32
        $entityClass = array_pop($parts);
33
        $entityNamespace = implode('\\', $parts);
34
35
        $gridColumnsNamespace = $bundle->getNamespace().'\\Grid\\Columns';
36
        $gridColumnsNamespace .= ($entityNamespace) ? '\\'.$entityNamespace : '';
37
38
        $gridColumnClass = $entityClass.'GridColumn';
39
        $dirPath = $bundle->getPath().'/Grid/Columns';
40
        $gridColumnPath = $dirPath.'/'.str_replace('\\', '/', $entity).'GridColumn.php';
41
        $templatePath = $bundle->getPath().'/Resources/views/'.str_replace('\\', '/', $entity).'/_grid.html.twig';
42
43
        $fields = array();
44
        foreach ($this->getFieldsFromMetadata($metadata) as $field) {
0 ignored issues
show
Bug introduced by
The expression $this->getFieldsFromMetadata($metadata) of type array|null is not guaranteed to be traversable. How about adding an additional type check?

There are different options of fixing this problem.

  1. If you want to be on the safe side, you can add an additional type-check:

    $collection = json_decode($data, true);
    if ( ! is_array($collection)) {
        throw new \RuntimeException('$collection must be an array.');
    }
    
    foreach ($collection as $item) { /** ... */ }
    
  2. If you are sure that the expression is traversable, you might want to add a doc comment cast to improve IDE auto-completion and static analysis:

    /** @var array $collection */
    $collection = json_decode($data, true);
    
    foreach ($collection as $item) { /** .. */ }
    
  3. Mark the issue as a false-positive: Just hover the remove button, in the top-right corner of this issue for more options.

Loading history...
45
            $fields[$field] = $this->fromCamelCase($field);
46
        }
47
48
        $params = array(
49
                'fields' => $fields,
50
                'namespace' => $gridColumnsNamespace,
51
                'class' => $gridColumnClass,
52
                'template_name' => "{$bundle->getName()}:{$entity}:_grid.html.twig",
53
        );
54
55
        $this->saveCache[$templatePath] = $this->render($this->skeletonDir, 'grid_template.html.twig', $params);
56
        $this->saveCache[$gridColumnPath] = $this->render($this->skeletonDir, 'GridColumns.php.twig', $params);
57
58
        return array($gridColumnClass, $gridColumnsNamespace, $gridColumnPath, $templatePath);
59
    }
60
61
    public function generate(BundleInterface $bundle, $entityDocument, $metadata, $columns = false)
62
    {
63
        if ($metadata instanceof ClassMetadataInfo) {
64
            $manager = '@doctrine.orm.default_entity_manager';
65
            $class = 'Dtc\GridBundle\Grid\Source\EntityGridSource';
66
        } elseif ($metadata instanceof \Doctrine\ODM\MongoDB\Mapping\ClassMetadataInfo) {
67
            $manager = '@doctrine_mongodb.odm.default_document_manager';
68
            $class = 'Dtc\GridBundle\Grid\Source\DocumentGridSource';
69
        } else {
70
            throw new \Exception(__METHOD__.' - Unknown class for metadata: '.get_class($metadata));
71
        }
72
        $entityDocumentClassPath = $metadata->getReflectionClass()->getName();
73
74
        $parts = explode('\\', $entityDocument);
75
        $entityDocumentClass = array_pop($parts);
76
        $files = [];
77
78
        if ($columns) {
79
            list($gridColumnClass, $gridColumnsNamespace, $gridColumnPath, $templatePath) =
80
                $this->generateColumns($bundle, $entityDocument, $metadata);
81
82
            $files = array(
83
                'grid_columns' => $gridColumnPath,
84
                'grid_template' => $templatePath,
85
            );
86
        }
87
88
        // Check to see if the files exists
89
        if ($this->saveCache) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $this->saveCache of type array<string,string> 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...
90
            foreach ($this->saveCache as $file => $output) {
91
                $this->saveFile($file, $output);
92
            }
93
        }
94
95
        $config = array();
96
        $serviceName = 'grid.source.'.strtolower($entityDocumentClass);
97
        $config[$serviceName] = array(
98
                'class' => $class,
99
                'arguments' => array($manager, $entityDocumentClassPath),
100
                'tags' => array(array('name' => 'dtc_grid.source')),
101
                'calls' => array(
102
                    array('autoDiscoverColumns'),
103
        ), );
104
105
        if ($columns && isset($gridColumnsNamespace) && isset($gridColumnClass)) {
106
            $config[$serviceName]['calls'] = array(
107
                array('setColumns', array(
108
                    '@'.$serviceName.'.columns',
109
                ),
110
                ),
111
            );
112
113
            $config[$serviceName.'.columns'] = array(
114
                'class' => $gridColumnsNamespace.'\\'.$gridColumnClass,
115
                'arguments' => array('@twig'),
116
            );
117
        }
118
119
        $configFile = $bundle->getPath().'/Resources/config/grid.yml';
120
        $services = array();
121
        if (file_exists($configFile)) {
122
            $services = Yaml::parse($contents = file_get_contents($configFile));
123
            if (isset($services['services'])) {
124
                $services['services'] = array_merge($services['services'], $config);
125
            } else {
126
                $services['services'] = $config;
127
            }
128
        } else {
129
            $services['services'] = $config;
130
        }
131
132
        $this->saveFile($configFile, Yaml::dump($services, 3));
133
134
        $params = array(
135
            'gridsource_id' => $serviceName,
136
            'files' => $files,
137
        );
138
139
        $output = $this->render($this->skeletonDir, 'controller.php.twig', $params);
140
        echo $output;
141
        exit();
0 ignored issues
show
Coding Style Compatibility introduced by
The method generate() contains an exit expression.

An exit expression should only be used in rare cases. For example, if you write a short command line script.

In most cases however, using an exit expression makes the code untestable and often causes incompatibilities with other libraries. Thus, unless you are absolutely sure it is required here, we recommend to refactor your code to avoid its usage.

Loading history...
142
    }
143
144
    private function getFieldsFromMetadata($metadata)
145
    {
146
        if ($metadata instanceof ClassMetadataInfo) {
147
            $fields = $metadata->getFieldNames();
148
149
            // Remove the primary key field if it's not managed manually
150
            if (!$metadata->isIdentifierNatural()) {
151
                $fields = array_diff($fields, $metadata->getIdentifier());
152
            }
153
154
            foreach ($metadata->associationMappings as $fieldName => $relation) {
155
                if (ClassMetadataInfo::ONE_TO_MANY !== $relation['type']) {
156
                    $fields[] = $fieldName;
157
                }
158
            }
159
160
            return $fields;
161
        } elseif ($metadata instanceof ClassMetadata) {
162
            $fields = $metadata->getFieldNames();
163
            $retFields = [];
164
            $identifier = $metadata->getIdentifier();
165
            $identifier = isset($identifier[0]) ? $identifier[0] : null;
166
            foreach ($fields as $field) {
167
                if ($identifier === $field) {
168
                    $mapping = $metadata->getFieldMapping($field);
169
                    if (isset($mapping['strategy']) && 'auto' == $mapping['strategy']) {
170
                        continue;
171
                    }
172
                }
173
                $retFields[] = $field;
174
            }
175
176
            return $retFields;
177
        }
178
    }
179
}
180