Completed
Push — master ( b70b78...814e9e )
by Filipe
03:21
created

EntityDescriptor::className()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 4
ccs 0
cts 2
cp 0
rs 10
cc 1
eloc 2
nc 1
nop 0
crap 2
1
<?php
2
3
/**
4
 * This file is part of slick/orm package
5
 *
6
 * For the full copyright and license information, please view the LICENSE
7
 * file that was distributed with this source code.
8
 */
9
10
namespace Slick\Orm\Descriptor;
11
12
use Slick\Common\Inspector;
13
use Slick\Common\Utils\Text;
14
use Slick\Orm\Annotations\Column;
15
use Slick\Orm\Descriptor\Field\FieldDescriptor;
16
use Slick\Orm\Descriptor\Field\FieldsCollection;
17
18
/**
19
 * Entity Descriptor
20
 *
21
 * @package Slick\Orm\Descriptor
22
 * @author  Filipe Silva <[email protected]>
23
 */
24
class EntityDescriptor implements EntityDescriptorInterface
25
{
26
27
    /**
28
     * @var string Entity class name
29
     */
30
    protected $entity;
31
32
    /**
33
     * @var string
34
     */
35
    protected $tableName;
36
37
    /**
38
     * @var Inspector
39
     */
40
    protected $inspector;
41
42
    /**
43
     * @var FieldsCollection
44
     */
45
    protected $fields;
46
47
    /**
48
     * @var FieldDescriptor
49
     */
50
    protected $primaryKey;
51
52
    /**
53
     * @var string
54
     */
55
    protected $adapterAlias = '__undefined__';
56
57
    /**
58
     * EntityDescriptor need an entity FQ class name.
59
     *
60
     * @param string $entity
61
     */
62 10
    public function __construct($entity)
63
    {
64 10
        $this->entity = $entity;
65 10
        $this->inspector = Inspector::forClass($entity);
66 10
    }
67
68
    /**
69
     * Gets entity table name
70
     *
71
     * @return string
72
     */
73 6
    public function getTableName()
74
    {
75 6
        if (null == $this->tableName) {
76 4
            $this->tableName = $this->determineTableName();
77 2
        }
78 6
        return $this->tableName;
79
    }
80
81
    /**
82
     * Returns entity fields
83
     *
84
     * @return FieldsCollection|FieldDescriptor[]
85
     */
86 8
    public function getFields()
87
    {
88 8
        if (null == $this->fields) {
89 6
            $properties = $this->inspector->getClassProperties();
90 6
            $this->fields = new FieldsCollection();
91 6
            foreach ($properties as $property) {
92 6
                $this->addDescriptor($property);
93 3
            }
94 3
        }
95 8
        return $this->fields;
96
    }
97
98
    /**
99
     * Returns the primary key field
100
     *
101
     * @return FieldDescriptor|null
102
     */
103 6
    public function getPrimaryKey()
104
    {
105 6
        if (null == $this->primaryKey) {
106 4
            foreach ($this->getFields() as $field) {
107 4
                if ($field->isPrimaryKey()) {
108 4
                    $this->primaryKey = $field;
109 4
                    break;
110
                }
111 2
            }
112 2
        }
113 6
        return $this->primaryKey;
114
    }
115
116
    /**
117
     * Determines the table name for current entity
118
     *
119
     * If there is an annotation @table present it will be used
120
     * otherwise the name will be parsed by convention using the
121
     * EntityDescriptor::parseTableName() method.
122
     *
123
     * @return string
124
     */
125 4
    private function determineTableName()
126
    {
127 4
        $annotations = $this->inspector->getClassAnnotations();
128 4
        $name = self::parseTableName($this->entity);
129 4
        if ($annotations->hasAnnotation('@table')) {
130 4
            $name = $annotations->getAnnotation('@table')->getValue();
131 2
        }
132 4
        return $name;
133
    }
134
135
    /**
136
     * Creates the descriptor if provided property has annotation @column
137
     *
138
     * @param $property
139
     *
140
     * @return self|$this|EntityDescriptor
141
     */
142 6
    private function addDescriptor($property)
143
    {
144 6
        $annotations = $this->inspector
145 6
            ->getPropertyAnnotations($property);
146 6
        if ($annotations->hasAnnotation('@column')) {
147
            /** @var Column $annotation */
148 6
            $annotation = $annotations->getAnnotation('@column');
149 6
            $descriptor = new FieldDescriptor($annotation->getParameters());
150 6
            $this->fields[] = $descriptor->setName($property);
151 3
        }
152 6
        return $this;
153
    }
154
155
    /**
156
     * Parses the table name from the class name
157
     *
158
     * @param string $className
159
     *
160
     * @return string
161
     */
162 10
    public static function parseTableName($className)
163
    {
164 10
        $parts = explode('\\', $className);
165 10
        $name = end($parts);
166 10
        $tableName = null;
167
168 10
        $words = explode('#', Text::camelCaseToSeparator($name, "#"));
169 10
        $last = array_pop($words);
170 10
        $last = Text::plural(strtolower($last));
171 10
        array_push($words, $last);
172 10
        foreach ($words as $word) {
173 10
            $tableName .= ucfirst($word);
174 5
        }
175 10
        return lcfirst($tableName);
176
    }
177
178
    /**
179
     * Returns the adapter alias name to use with this entity
180
     *
181
     * @return string
182
     */
183 2
    public function getAdapterAlias()
184
    {
185 2
        if ('__undefined__' == $this->adapterAlias) {
186 2
            $this->adapterAlias = null;
187 2
            $annotations = $this->inspector->getClassAnnotations();
188 2
            if ($annotations->hasAnnotation('@adapter')) {
189 2
                $this->adapterAlias = $annotations
190 2
                    ->getAnnotation('@adapter')
191 2
                    ->getValue();
192 1
            }
193 1
        }
194 2
        return $this->adapterAlias;
195
    }
196
197
    /**
198
     * Gets entity class name
199
     *
200
     * @return string
201
     */
202
    public function className()
203
    {
204
        return $this->entity;
205
    }
206
}