Completed
Push — master ( 646730...43a697 )
by Vitaly
05:45
created

Generator   A

Complexity

Total Complexity 14

Size/Duplication

Total Lines 234
Duplicated Lines 40.17 %

Coupling/Cohesion

Components 1
Dependencies 1

Importance

Changes 2
Bugs 1 Features 2
Metric Value
wmc 14
c 2
b 1
f 2
lcom 1
cbo 1
dl 94
loc 234
rs 10

8 Methods

Rating   Name   Duplication   Size   Complexity  
A transliterated() 0 51 1
A constantNameByValue() 0 11 2
A createEntityClass() 47 47 3
A createQueryClass() 47 47 3
A entityHash() 0 9 1
A entityStructures() 0 7 1
A createEntityClasses() 0 13 2
A __construct() 0 4 1

How to fix   Duplicated Code   

Duplicated Code

Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.

Common duplication problems, and corresponding solutions are:

1
<?php
2
/**
3
 * Created by PhpStorm.
4
 * User: VITALYIEGOROV
5
 * Date: 09.12.15
6
 * Time: 14:34
7
 */
8
namespace samsoncms\api;
9
10
use samsonframework\orm\DatabaseInterface;
11
12
/**
13
 * Entity classes generator.
14
 * @package samsoncms\api
15
 */
16
class Generator
17
{
18
    /** @var DatabaseInterface */
19
    protected $database;
20
21
    /**
22
     * Transliterate string to english.
23
     *
24
     * @param string $string Source string
25
     * @return string Transliterated string
26
     */
27
    protected function transliterated($string)
28
    {
29
        return str_replace(
30
            ' ',
31
            '',
32
            ucwords(iconv("UTF-8", "UTF-8//IGNORE", strtr($string, array(
33
                            "'" => "",
34
                            "`" => "",
35
                            "-" => " ",
36
                            "_" => " ",
37
                            "а" => "a", "А" => "a",
38
                            "б" => "b", "Б" => "b",
39
                            "в" => "v", "В" => "v",
40
                            "г" => "g", "Г" => "g",
41
                            "д" => "d", "Д" => "d",
42
                            "е" => "e", "Е" => "e",
43
                            "ж" => "zh", "Ж" => "zh",
44
                            "з" => "z", "З" => "z",
45
                            "и" => "i", "И" => "i",
46
                            "й" => "y", "Й" => "y",
47
                            "к" => "k", "К" => "k",
48
                            "л" => "l", "Л" => "l",
49
                            "м" => "m", "М" => "m",
50
                            "н" => "n", "Н" => "n",
51
                            "о" => "o", "О" => "o",
52
                            "п" => "p", "П" => "p",
53
                            "р" => "r", "Р" => "r",
54
                            "с" => "s", "С" => "s",
55
                            "т" => "t", "Т" => "t",
56
                            "у" => "u", "У" => "u",
57
                            "ф" => "f", "Ф" => "f",
58
                            "х" => "h", "Х" => "h",
59
                            "ц" => "c", "Ц" => "c",
60
                            "ч" => "ch", "Ч" => "ch",
61
                            "ш" => "sh", "Ш" => "sh",
62
                            "щ" => "sch", "Щ" => "sch",
63
                            "ъ" => "", "Ъ" => "",
64
                            "ы" => "y", "Ы" => "y",
65
                            "ь" => "", "Ь" => "",
66
                            "э" => "e", "Э" => "e",
67
                            "ю" => "yu", "Ю" => "yu",
68
                            "я" => "ya", "Я" => "ya",
69
                            "і" => "i", "І" => "i",
70
                            "ї" => "yi", "Ї" => "yi",
71
                            "є" => "e", "Є" => "e"
72
                        )
73
                    )
74
                )
75
            )
76
        );
77
    }
78
79
    /**
80
     * Get class constant name by its value.
81
     *
82
     * @param string $value Constant value
83
     * @param string $className Class name
84
     * @return string Full constant name
85
     */
86
    protected function constantNameByValue($value, $className = Field::ENTITY)
87
    {
88
        // Get array where class constants are values and their values are keys
89
        $nameByValue = array_flip((new \ReflectionClass($className))->getConstants());
90
91
        // Try to find constant by its value
92
        if (isset($nameByValue[$value])) {
93
            // Return constant name
94
            return '\\' . $className . '::' . $nameByValue[$value];
95
        }
96
    }
97
98
    /**
99
     * Create entity PHP class code.
100
     *
101
     * @param array $structureRow Collection of structure info
102
     * @return string Generated entitiy class code
103
     */
104 View Code Duplication
    protected function createEntityClass($structureRow)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
105
    {
106
        $structureKey = ucfirst($this->transliterated($structureRow['Name']));
107
108
        $class = "\n" . 'class ' . $structureKey . ' extends Entity';
109
        $class .= "\n" . '{';
110
        $class .= "\n\t" . '/** @var string Not transliterated entity name */';
111
        $class .= "\n\t" . 'protected $identifier = "' . $structureRow['Name'] . '";';
112
113
        // Get structure fields
114
        //$fieldMap = array();
115
        $fields = array();
116
        $fieldIDs = array();
117
118
        // TODO: Optimize queries
119
        foreach ($this->database->fetch('SELECT * FROM `structurefield` WHERE `StructureID` = "' . $structureRow['StructureID'] . '" AND `Active` = "1"') as $fieldStructureRow) {
120
            foreach ($this->database->fetch('SELECT * FROM `field` WHERE `FieldID` = "' . $fieldStructureRow['FieldID'] . '"') as $fieldRow) {
121
                $type = str_replace(
0 ignored issues
show
Unused Code introduced by
$type is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
122
                    '\samsoncms\api\Field',
123
                    'Field',
124
                    $this->constantNameByValue($fieldRow['Type'])
125
                );
126
                $commentType = Field::$PHP_TYPE[$fieldRow['Type']];
127
                $fieldName = lcfirst($this->transliterated($fieldRow['Name']));
128
129
                $class .= "\n\t" . '/** @var ' . $commentType . ' Field #' . $fieldRow['FieldID'] . '*/';
130
                $class .= "\n\t" . 'protected $' . $fieldName . ';';
131
132
                // Store field metadata
133
                $fields[$fieldName][] = $fieldRow;
134
                $fieldIDs[] = $fieldRow['FieldID'];
135
                //$fieldMap[] = '"'.$fieldName.'" => array("Id" => "'.$fieldRow['FieldID'].'", "Type" => ' . $type . ', "Name" => "' . $fieldRow['Name'] . '")';
136
            }
137
        }
138
139
        //$class .= "\n\t" . '/** @var array Entity additional fields metadata */';
140
        //$class .= "\n\t" .'protected $fieldsData = array('."\n\t\t".implode(','."\n\t\t", $fieldMap)."\n\t".');';
141
        $class .= "\n\t";
142
        $class .= "\n\t" . '/** @var array Collection of additional fields identifiers */';
143
        $class .= "\n\t" . 'protected static $fieldIDs = array(' . implode(',', $fieldIDs) . ');';
144
        $class .= "\n\t" . '/** @var array Collection of navigation identifiers */';
145
        $class .= "\n\t" . 'protected static $navigationIDs = array(' . $structureRow['StructureID'] . ');';
146
        $class .= "\n" . '}';
147
148
        // Replace tabs with spaces
149
        return str_replace("\t", '    ', $class);
150
    }
151
152
    /**
153
     * Create entity PHP class code.
154
     *
155
     * @param array $structureRow Collection of structure info
156
     * @return string Generated entitiy class code
157
     */
158 View Code Duplication
    protected function createQueryClass($structureRow)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
159
    {
160
        $structureKey = ucfirst($this->transliterated($structureRow['Name']));
161
162
        $class = "\n" . 'class ' . $structureKey . ' extends Base';
163
        $class .= "\n" . '{';
164
        $class .= "\n\t" . '/** @var string Not transliterated entity name */';
165
        $class .= "\n\t" . 'protected $identifier = "' . $structureRow['Name'] . '";';
166
167
        // Get structure fields
168
        //$fieldMap = array();
169
        $fields = array();
170
        $fieldIDs = array();
171
172
        // TODO: Optimize queries
173
        foreach ($this->database->fetch('SELECT * FROM `structurefield` WHERE `StructureID` = "' . $structureRow['StructureID'] . '" AND `Active` = "1"') as $fieldStructureRow) {
174
            foreach ($this->database->fetch('SELECT * FROM `field` WHERE `FieldID` = "' . $fieldStructureRow['FieldID'] . '"') as $fieldRow) {
175
                $type = str_replace(
0 ignored issues
show
Unused Code introduced by
$type is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
176
                    '\samsoncms\api\Field',
177
                    'Field',
178
                    $this->constantNameByValue($fieldRow['Type'])
179
                );
180
                $commentType = Field::$PHP_TYPE[$fieldRow['Type']];
181
                $fieldName = lcfirst($this->transliterated($fieldRow['Name']));
182
183
                $class .= "\n\t" . '/** @var ' . $commentType . ' Field #' . $fieldRow['FieldID'] . '*/';
184
                $class .= "\n\t" . 'protected $' . $fieldName . ';';
185
186
                // Store field metadata
187
                $fields[$fieldName][] = $fieldRow;
188
                $fieldIDs[] = $fieldRow['FieldID'];
189
                //$fieldMap[] = '"'.$fieldName.'" => array("Id" => "'.$fieldRow['FieldID'].'", "Type" => ' . $type . ', "Name" => "' . $fieldRow['Name'] . '")';
190
            }
191
        }
192
193
        //$class .= "\n\t" . '/** @var array Entity additional fields metadata */';
194
        //$class .= "\n\t" .'protected $fieldsData = array('."\n\t\t".implode(','."\n\t\t", $fieldMap)."\n\t".');';
195
        $class .= "\n\t";
196
        $class .= "\n\t" . '/** @var array Collection of additional fields identifiers */';
197
        $class .= "\n\t" . 'protected static $fieldIDs = array(' . implode(',', $fieldIDs) . ');';
198
        $class .= "\n\t" . '/** @var array Collection of navigation identifiers */';
199
        $class .= "\n\t" . 'protected static $navigationIDs = array(' . $structureRow['StructureID'] . ');';
200
        $class .= "\n" . '}';
201
202
        // Replace tabs with spaces
203
        return str_replace("\t", '    ', $class);
204
    }
205
206
    /** @return string Entity state hash */
207
    public function entityHash()
208
    {
209
        // Получим информацию о всех таблицах из БД
210
        return md5($this->database->fetch(
211
            'SELECT `TABLES`.`TABLE_NAME` as `TABLE_NAME`
212
              FROM `information_schema`.`TABLES` as `TABLES`
213
              WHERE `TABLES`.`TABLE_SCHEMA`="' . $this->database->database() . '";'
214
        ));
215
    }
216
217
    /** @return mixed Get collection of structures object */
218
    protected function entityStructures()
219
    {
220
        return $this->database->fetch('
221
        SELECT * FROM `structure`
222
        WHERE `Active` = "1" AND `Type` = "0"'
223
        );
224
    }
225
226
    /** @return string Generate entity classes */
227
    public function createEntityClasses()
228
    {
229
        $classes = "\n" . 'namespace ' . __NAMESPACE__ . ';';
230
        $classes .= "\n";
231
        $classes .= "\n" . 'use \samsoncms\api\Field;';
232
        $classes .= "\n";
233
        // Iterate all structures
234
        foreach ($this->entityStructures() as $structureRow) {
235
            $classes .= $this->createEntityClass($structureRow);
236
        }
237
238
        return $classes;
239
    }
240
241
    /**
242
     * Generator constructor.
243
     * @param DatabaseInterface $database Database instance
244
     */
245
    public function __construct(DatabaseInterface $database)
246
    {
247
        $this->database = $database;
248
    }
249
}
250