Passed
Push — sudav3 ( b29c56...468d62 )
by 世昌
02:20
created

TableStructBuilder::getTableFieldName()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 2
nc 1
nop 2
dl 0
loc 3
rs 10
c 0
b 0
f 0
1
<?php
2
namespace suda\orm\struct;
3
4
use ReflectionClass;
5
use ReflectionProperty;
6
use suda\orm\TableStruct;
7
use suda\orm\struct\Field;
8
9
class TableStructBuilder
10
{
11
    /**
12
     * 解析对象
13
     *
14
     * @var string
15
     */
16
    protected $object;
17
18
19
    /**
20
     * 反射对象
21
     *
22
     * @var ReflectionClass
23
     */
24
    protected $reflectObject;
25
26
    public function __construct(string $object)
27
    {
28
        $this->object = $object;
29
        $this->reflectObject = new ReflectionClass($object);
30
    }
31
32
33
    /**
34
     * 创建表结构
35
     *
36
     * @return TableStruct
37
     */
38
    public function createStruct():TableStruct
39
    {
40
        $name = $this->getName();
41
        $struct = new TableStruct($name);
42
        foreach ($this->reflectObject->getProperties(ReflectionProperty::IS_PUBLIC | ReflectionProperty::IS_PROTECTED | ReflectionProperty::IS_PRIVATE) as $property) {
43
            if ($this->isTableField($property)) {
44
                $field = $this->createField($name, $property);
45
                $struct->addField($field);
46
            }
47
        }
48
        return $struct;
49
    }
50
51
    /**
52
     * 获取表名
53
     *
54
     * @return string
55
     */
56
    protected function getName()
57
    {
58
        if ($doc = $this->reflectObject->getDocComment()) {
59
            if (is_string($doc) && \preg_match('/\@table\s+(\w+)/', $doc, $match)) {
60
                return $match[1];
61
            }
62
        }
63
        return static::createName($this->reflectObject->getShortName());
64
    }
65
66
    /**
67
     * 创建字段
68
     *
69
     * @param string $tableName
70
     * @param \ReflectionProperty $property
71
     * @return \suda\orm\struct\Field
72
     */
73
    protected function createField(string $tableName, ReflectionProperty $property): Field
74
    {
75
        $name = static::getFieldName($property);
76
        list($type, $length, $modifier) = static::getFieldType($property);
77
        $field = new Field($tableName, $name, $type, $length);
78
        $parser = new FieldModifierParser;
79
        $parser->parse($modifier)->modify($field);
80
        return $field;
81
    }
82
83
    /**
84
     * 转换名称
85
     *
86
     * @param string $name
87
     * @return string
88
     */
89
    public static function createName(string $name):string
90
    {
91
        $name = preg_replace('/([A-Z]+)/', '_$1', $name);
92
        $name = \preg_replace('/_+/', '_', $name);
93
        $name = trim($name, '_');
94
        return \strtolower($name);
95
    }
96
97
    /**
98
     * 获取表字段名
99
     *
100
     * @param string $object
101
     * @param string $name
102
     * @return string
103
     */
104
    public static function getTableFieldName(string $object, string $name) {
105
        $property = new ReflectionProperty($object, $name);
106
        return static::getFieldName($property);
107
    }
108
109
    /**
110
     * 获取字段名
111
     *
112
     * @param \ReflectionProperty $property
113
     * @return string
114
     */
115
    public static function getFieldName(ReflectionProperty $property)
116
    {
117
        if ($doc = $property->getDocComment()) {
118
            if (is_string($doc) && preg_match('/@field-?name\s+(\w+)/i', $doc, $match)) {
119
                return $match[1];
120
            }
121
        }
122
        return $property->getName();
123
    }
124
125
    /**
126
     * 获取字段类型
127
     *
128
     * @param \ReflectionProperty $property
129
     * @return array|null
130
     */
131
    public static function getFieldType(ReflectionProperty $property)
132
    {
133
        if ($doc = $property->getDocComment()) {
134
            if (is_string($doc) && preg_match('/@field\s+(\w+)(?:\((.+?)\))?\s+(.+)?$/im', $doc, $match)) {
135
                $type = strtoupper($match[1]);
136
                $length = $match[2] ?? '';
137
                if (strlen($length)) {
138
                    $length = \explode(',', $length);
139
                    if (count($length) === 1) {
140
                        $length = $length[0];
141
                    }
142
                } else {
143
                    $length = null;
144
                }
145
                return [$type, $length , trim($match[3] ?? '')];
146
            }
147
        }
148
        return ['text', null, ''];
149
    }
150
151
    /**
152
     * 检查是否为数据库字段
153
     *
154
     * @param \ReflectionProperty $property
155
     * @return boolean
156
     */
157
    public static function isTableField(ReflectionProperty $property) {
158
        if ($doc = $property->getDocComment()) {
159
            if (is_string($doc) && stripos($doc, '@field')) {
160
                return true;
161
            }
162
        }
163
        return false;
164
    }
165
}
166