Passed
Push — main ( 4f9f31...df1d09 )
by Sammy
01:43
created

TableModel::retrieve()   A

Complexity

Conditions 5
Paths 6

Size

Total Lines 23
Code Lines 13

Duplication

Lines 0
Ratio 0 %

Importance

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