EntityManager::getEntity()   D
last analyzed

Complexity

Conditions 21
Paths 86

Size

Total Lines 59
Code Lines 44

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 36
CRAP Score 22.2868

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 21
eloc 44
c 1
b 0
f 0
nc 86
nop 1
dl 0
loc 59
ccs 36
cts 42
cp 0.8571
crap 22.2868
rs 4.1666

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
namespace WebStream\Database;
4
5
use WebStream\DI\Injector;
0 ignored issues
show
Bug introduced by
The type WebStream\DI\Injector was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
6
7
/**
8
 * EntityManager
9
 * @author Ryuichi TANAKA.
10
 * @since 2015/01/11
11
 * @version 0.7
12
 */
13
class EntityManager
14
{
15
    use Injector;
16
17
    /**
18
     * @var string エンティティクラスパス
19
     */
20
    private string $classpath;
21
22
    /**
23
     * @var array<string> カラムメタ情報
24
     */
25
    private array $columnMeta;
26
27
    /**
28
     * コンストラクタ
29
     * @param string エンティティクラスパス
0 ignored issues
show
Documentation Bug introduced by
The doc comment エンティティクラスパス at position 0 could not be parsed: Unknown type name 'エンティティクラスパス' at position 0 in エンティティクラスパス.
Loading history...
30
     */
31 16
    public function __construct($classpath)
32
    {
33 16
        $this->classpath = $classpath;
34 16
    }
35
36
    /**
37
     * カラムメタ情報を設定する
38
     * @param array $columnMeta カラムメタ情報
39
     */
40 16
    public function setColumnMeta(array $columnMeta)
41
    {
42 16
        $this->columnMeta = $columnMeta;
43 16
    }
44
45
    /**
46
     * 列データをエンティティに変換して返却する
47
     * @param array $row 列データ
48
     * @return object 列データエンティティ
49
     * @throws \ReflectionException
50
     */
51 16
    public function getEntity(array $row)
52
    {
53 16
        $instance = new $this->classpath();
54 16
        $propertyMap = null;
55
56
        // EntityPropertyを使っている場合はリフレクションを使用しない
57 16
        if (!array_key_exists(EntityProperty::class, class_uses($instance))) {
58 8
            $propertyMap = [];
59 8
            $refClass = new \ReflectionClass($instance);
60 8
            $properties = $refClass->getProperties();
61 8
            foreach ($properties as $property) {
62 8
                if ($property->isPrivate() || $property->isProtected()) {
63 8
                    $property->setAccessible(true);
64
                }
65 8
                $propertyMap[strtolower($property->getName())] = $property;
66
            }
67
        }
68
69 16
        foreach ($row as $col => $value) {
70 16
            switch ($this->columnMeta[$col]) {
71 16
                case 'LONG':      // mysql:int
72 16
                case 'SHORT':     // mysql:smallint
73 16
                case 'int4':      // postgres:int
74 16
                case 'int2':      // postgres:smallint
75 16
                case 'integer':   // sqlite:int
76 16
                case 'smallint':  // sqlite:smallint
77 16
                    $value = intval($value);
78 16
                    break;
79 16
                case 'LONGLONG':  // mysql:bigint
80 16
                case 'int8':      // postgres:bigint
81 16
                case 'bigint':    // sqlite:bigint
82
                    $value = doubleval($value);
83
                    break;
84 16
                case 'DATETIME':  // mysql:datetime
85 16
                case 'DATE':      // mysql:date
86 16
                case 'timestamp': // postgres:timestamp, sqlite:timestamp
87 16
                case 'date':      // postgres:date, sqlite:date
88
                    $value = new \DateTime($value);
89
                    break;
90
                default: // string
91 16
                    break;
92
            }
93
94 16
            $col = strtolower(preg_replace_callback('/_([a-zA-Z])/', function ($matches) {
95
                return ucfirst($matches[1]);
96 16
            }, $col));
97
98 16
            if ($propertyMap === null) {
99 8
                $instance->{$col} = $value;
100
            } else {
101 8
                if (array_key_exists($col, $propertyMap)) {
102 8
                    $propertyMap[$col]->setValue($instance, $value);
103
                } else {
104
                    $this->logger->error("Column '$col' is failed mapping in " . $this->classpath);
105
                }
106
            }
107
        }
108
109 16
        return $instance;
110
    }
111
}
112