Passed
Branch main (d2dd60)
by Sammy
07:24 queued 47s
created

TableModel::getId()   A

Complexity

Conditions 4
Paths 4

Size

Total Lines 8
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 4
eloc 4
nc 4
nop 1
dl 0
loc 8
rs 10
c 0
b 0
f 0
1
<?php
2
3
namespace HexMakina\TightORM;
4
5
use HexMakina\Crudites\Crudites;
6
use HexMakina\Crudites\CruditesException;
7
use HexMakina\BlackBox\Database\TableManipulationInterface;
8
use HexMakina\BlackBox\Database\SelectInterface;
9
10
abstract class TableModel extends Crudites
11
{
12
13
    //check all primary keys are set (FIXME that doesn't work unles AIPK.. nice try)
14
    public function isNew(): bool
15
    {
16
        $match = static::table()->primaryKeysMatch(get_object_vars($this));
17
        return empty($match);
18
    }
19
20
    public function getId($mode = null)
21
    {
22
        $primary_key = static::table()->autoIncrementedPrimaryKey();
23
        if (is_null($primary_key) && count($pks = static::table()->primaryKeys()) == 1) {
24
            $primary_key = current($pks);
25
        }
26
27
        return $mode === 'name' ? $primary_key->name() : $this->get($primary_key->name());
28
    }
29
30
    public function get($prop_name)
31
    {
32
        if (property_exists($this, $prop_name) === true) {
33
            return $this->$prop_name;
34
        }
35
36
        return null;
37
    }
38
39
    public function set($prop_name, $value)
40
    {
41
        $this->$prop_name = $value;
42
    }
43
44
    public function import($assoc_data)
45
    {
46
        if (!is_array($assoc_data)) {
47
            throw new \Exception(__FUNCTION__ . '(assoc_data) parm is not an array');
48
        }
49
50
        // shove it all up in model, god will sort them out
51
        foreach ($assoc_data as $field => $value) {
52
            $this->set($field, $value);
53
        }
54
55
        return $this;
56
    }
57
58
    public static function table(): TableManipulationInterface
59
    {
60
        $table = static::relationalMappingName();
61
        $table = self::inspect($table);
62
63
        return $table;
64
    }
65
66
    public static function relationalMappingName(): string
67
    {
68
        $reflect = new \ReflectionClass(get_called_class());
69
70
        $table_name = $reflect->getConstant('TABLE_NAME');
71
72
        if ($table_name === false) {
73
            $calling_class = $reflect->getShortName();
74
            if (defined($const_name = 'TABLE_' . strtoupper($calling_class))) {
75
                $table_name = constant($const_name);
76
            } else {
77
                $table_name = strtolower($calling_class);
78
            }
79
        }
80
81
        return $table_name;
82
    }
83
84
85
    public function to_table_row($operator_id = null)
86
    {
87
        if (!is_null($operator_id) && $this->isNew() && is_null($this->get('created_by'))) {
88
            $this->set('created_by', $operator_id);
89
        }
90
91
        $model_data = get_object_vars($this);
92
93
        // 1. Produce OR restore a row
94
        if ($this->isNew()) {
95
            $table_row = static::table()->produce($model_data);
96
        } else {
97
            $table_row = static::table()->restore($model_data);
98
        }
99
100
        // 2. Apply alterations from form_model data
101
        $table_row->alter($model_data);
102
103
        return $table_row;
104
    }
105
106
    //------------------------------------------------------------  Data Retrieval
107
    // DEPRECATED, only exist for unit testing vis-a-vis TightModelSelector
108
    public static function query_retrieve($filters = [], $options = []): SelectInterface
109
    {
110
        $class = get_called_class();
111
        $query = (new TableModelSelector(new $class()))->select($filters, $options);
112
        return $query;
113
    }
114
115
    // success: return PK-indexed array of results (associative array or object)
116
    public static function retrieve(SelectInterface $Query): array
117
    {
118
        $ret = [];
119
        $pk_name = implode('_', array_keys($Query->table()->primaryKeys()));
120
121
        if (count($pks = $Query->table()->primaryKeys()) > 1) {
122
            $concat_pk = sprintf('CONCAT(%s) as %s', implode(',', $pks), $pk_name);
123
            $Query->selectAlso([$concat_pk]);
124
        }
125
126
        try {
127
            $Query->run();
128
        } catch (CruditesException $e) {
129
            return [];
130
        }
131
132
        if ($Query->isSuccess()) {
133
            foreach ($Query->retObj(get_called_class()) as $rec) {
134
                  $ret[$rec->get($pk_name)] = $rec;
135
            }
136
        }
137
138
        return $ret;
139
    }
140
141
    /* USAGE
142
    * one($primary_key_value)
143
    * one($unique_column, $value)
144
    */
145
    public static function one($arg1, $arg2 = null)
146
    {
147
        $mixed_info = is_null($arg2) ? $arg1 : [$arg1 => $arg2];
148
149
        $unique_identifiers = get_called_class()::table()->matchUniqueness($mixed_info);
150
151
        if (empty($unique_identifiers)) {
152
            throw new CruditesException('UNIQUE_IDENTIFIER_NOT_FOUND');
153
        }
154
155
        $Query = static::query_retrieve([], ['eager' => true])->whereFieldsEQ($unique_identifiers);
156
        switch (count($res = static::retrieve($Query))) {
157
            case 0:
158
                throw new CruditesException('INSTANCE_NOT_FOUND');
159
            case 1:
160
                return current($res);
161
            default:
162
                throw new CruditesException('SINGULAR_INSTANCE_ERROR');
163
        }
164
    }
165
166
    public static function exists($arg1, $arg2 = null)
167
    {
168
        try {
169
            return self::one($arg1, $arg2);
170
        } catch (CruditesException $e) {
171
            return null;
172
        }
173
    }
174
175
176
    public static function any($field_exact_values, $options = [])
177
    {
178
        $Query = static::query_retrieve([], $options)->whereFieldsEQ($field_exact_values);
179
        return static::retrieve($Query);
180
    }
181
182
    public static function filter($filters = [], $options = []): array
183
    {
184
        return static::retrieve(static::query_retrieve($filters, $options));
185
    }
186
187
    public static function listing($filters = [], $options = []): array
188
    {
189
        return static::retrieve(static::query_retrieve($filters, $options)); // listing as arrays for templates
190
    }
191
192
193
194
    public static function get_many_by_AIPK($aipk_values)
195
    {
196
        if (!empty($aipk_values) && !is_null($AIPK = static::table()->autoIncrementedPrimaryKey())) {
197
            return static::retrieve(static::table()->select()->whereNumericIn($AIPK, $aipk_values));
198
        }
199
200
        return null;
201
    }
202
}
203