Completed
Push — master ( 7f60e8...0bb0d8 )
by Jared
01:31
created

DefinitionBuilder::get()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 9

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 9
rs 9.9666
c 0
b 0
f 0
cc 2
nc 2
nop 1
1
<?php
2
3
namespace Pulsar;
4
5
use Pulsar\Relation\BelongsToMany;
6
use Pulsar\Relation\RelationFactory;
7
8
class DefinitionBuilder
9
{
10
    const DEFAULT_ID_PROPERTY = [
11
        'type' => Type::INTEGER,
12
        'mutable' => Property::IMMUTABLE,
13
    ];
14
15
    const AUTO_TIMESTAMPS = [
16
        'created_at' => [
17
            'type' => Type::DATE,
18
            'validate' => 'timestamp|db_timestamp',
19
        ],
20
        'updated_at' => [
21
            'type' => Type::DATE,
22
            'validate' => 'timestamp|db_timestamp',
23
        ],
24
    ];
25
26
    const SOFT_DELETE_TIMESTAMPS = [
27
        'deleted_at' => [
28
            'type' => Type::DATE,
29
            'validate' => 'timestamp|db_timestamp',
30
            'null' => true,
31
        ],
32
    ];
33
34
    /** @var Definition[] */
35
    private static $definitions;
36
37
    /**
38
     * Gets the definition for a model. If needed the
39
     * definition will be generated. It will only be
40
     * generated once.
41
     */
42
    public static function get(string $modelClass): Definition
43
    {
44
        /** @var Model $modelClass */
45
        if (!isset(self::$definitions[$modelClass])) {
46
            self::$definitions[$modelClass] = $modelClass::buildDefinition();
47
        }
48
49
        return self::$definitions[$modelClass];
50
    }
51
52
    /**
53
     * Builds a model definition given certain parameters.
54
     */
55
    public static function build(array $properties, string $modelClass, bool $autoTimestamps, bool $softDelete): Definition
56
    {
57
        /** @var Model $modelClass */
58
        // add in the default ID property
59
        if (!isset($properties[Model::DEFAULT_ID_NAME]) && $modelClass::getIDProperties() == [Model::DEFAULT_ID_NAME]) {
60
            $properties[Model::DEFAULT_ID_NAME] = self::DEFAULT_ID_PROPERTY;
61
        }
62
63
        // generates created_at and updated_at timestamps
64
        if ($autoTimestamps) {
65
            $properties = array_replace(self::AUTO_TIMESTAMPS, $properties);
66
        }
67
68
        // generates deleted_at timestamps
69
        if ($softDelete) {
70
            $properties = array_replace(self::SOFT_DELETE_TIMESTAMPS, $properties);
71
        }
72
73
        $result = [];
74
        foreach ($properties as $k => $property) {
75
            // populate relationship property settings
76
            if (isset($property['relation'])) {
77
                // this is added for BC with older versions of pulsar
78
                // that only supported belongs to relationships
79
                if (!isset($property['relation_type'])) {
80
                    $property['relation_type'] = Model::RELATIONSHIP_BELONGS_TO;
81
                    $property['local_key'] = $k;
82
                } elseif (!isset($property['persisted'])) {
83
                    $property['persisted'] = false;
84
                }
85
86
                $tempProperty = new Property($property);
87
                $relation = RelationFactory::make(new $modelClass(), $k, $tempProperty);
88
                if (!isset($property['foreign_key'])) {
89
                    $property['foreign_key'] = $relation->getForeignKey();
90
                }
91
92
                if (!isset($property['local_key'])) {
93
                    $property['local_key'] = $relation->getLocalKey();
94
                }
95
96
                if (!isset($property['pivot_tablename']) && $relation instanceof BelongsToMany) {
97
                    $property['pivot_tablename'] = $relation->getTablename();
98
                }
99
100
                // when a belongs_to relationship is used then we automatically add a
101
                // new property for the ID field which gets persisted to the DB
102
                if (Model::RELATIONSHIP_BELONGS_TO == $property['relation_type'] && !isset($result[$property['local_key']])) {
103
                    $result[$property['local_key']] = new Property([
104
                        'type' => Type::INTEGER,
105
                    ]);
106
                }
107
            }
108
109
            $result[$k] = new Property($property);
110
        }
111
112
        // order the properties array by name for consistency
113
        // since it is constructed in a random order
114
        ksort($result);
115
116
        return new Definition($result);
117
    }
118
}
119