Test Failed
Push — master ( 4fec67...e6f5ff )
by Carlos
08:10
created

CodeModel::all()   B

Complexity

Conditions 10
Paths 46

Size

Total Lines 45
Code Lines 25

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 10
eloc 25
c 1
b 0
f 0
nc 46
nop 5
dl 0
loc 45
rs 7.6666

How to fix   Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
/**
3
 * This file is part of FacturaScripts
4
 * Copyright (C) 2017-2024 Carlos Garcia Gomez <[email protected]>
5
 *
6
 * This program is free software: you can redistribute it and/or modify
7
 * it under the terms of the GNU Lesser General Public License as
8
 * published by the Free Software Foundation, either version 3 of the
9
 * License, or (at your option) any later version.
10
 *
11
 * This program is distributed in the hope that it will be useful,
12
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
 * GNU Lesser General Public License for more details.
15
 *
16
 * You should have received a copy of the GNU Lesser General Public License
17
 * along with this program. If not, see <http://www.gnu.org/licenses/>.
18
 */
19
20
namespace FacturaScripts\Core\Model;
21
22
use FacturaScripts\Core\Base\DataBase;
23
use FacturaScripts\Core\Base\DataBase\DataBaseWhere;
24
use FacturaScripts\Core\Cache;
25
use FacturaScripts\Core\Tools;
26
27
/**
28
 * Auxiliary model to load a list of codes and their descriptions
29
 *
30
 * @author Jose Antonio Cuello Principal <[email protected]>
31
 * @author Carlos García Gómez           <[email protected]>
32
 */
33
class CodeModel
34
{
35
    const ALL_LIMIT = 1000;
36
    const MODEL_NAMESPACE = '\\FacturaScripts\\Dinamic\\Model\\';
37
    const SEARCH_LIMIT = 50;
38
39
    /** @var DataBase */
40
    protected static $dataBase;
41
42
    /** @var int */
43
    protected static $limit;
44
45
    /** @var string */
46
    public $code;
47
48
    /** @var string */
49
    public $description;
50
51
    public function __construct(array $data = [])
52
    {
53
        if (empty($data)) {
54
            $this->code = '';
55
            $this->description = '';
56
        } else {
57
            $this->code = $data['code'];
58
            $this->description = $data['description'];
59
        }
60
    }
61
62
    /**
63
     * Load a CodeModel list (code and description) for the indicated table.
64
     *
65
     * @param string $tableName
66
     * @param string $fieldCode
67
     * @param string $fieldDescription
68
     * @param bool $addEmpty
69
     * @param array $where
70
     *
71
     * @return static[]
72
     */
73
    public static function all(string $tableName, string $fieldCode, string $fieldDescription, bool $addEmpty = true, array $where = []): array
74
    {
75
        // check cache
76
        $cacheKey = $addEmpty ?
77
            'table-' . $tableName . '-code-model-' . $fieldCode . '-' . $fieldDescription . '-empty' :
78
            'table-' . $tableName . '-code-model-' . $fieldCode . '-' . $fieldDescription;
79
        $result = Cache::get($cacheKey);
80
        if (empty($where) && is_array($result)) {
81
            return $result;
82
        }
83
84
        // initialize
85
        $result = [];
86
        if ($addEmpty) {
87
            $result[] = new static(['code' => null, 'description' => '------']);
88
        }
89
90
        // is a table or a model?
91
        $modelClass = self::MODEL_NAMESPACE . $tableName;
92
        if (class_exists($modelClass)) {
93
            $model = new $modelClass();
94
            if ($model->modelClassName() === $tableName) {
95
                return array_merge($result, $model->codeModelAll($fieldCode));
96
            }
97
        }
98
99
        // check table
100
        self::initDataBase();
101
        if (!self::$dataBase->tableExists($tableName)) {
102
            Tools::log()->error('table-not-found', ['%tableName%' => $tableName]);
103
            return $result;
104
        }
105
106
        $sql = 'SELECT DISTINCT ' . $fieldCode . ' AS code, ' . $fieldDescription . ' AS description '
107
            . 'FROM ' . $tableName . DataBaseWhere::getSQLWhere($where) . ' ORDER BY 2 ASC';
108
        foreach (self::$dataBase->selectLimit($sql, self::getLimit()) as $row) {
109
            $result[] = new static($row);
110
        }
111
112
        // save cache
113
        if (empty($where)) {
114
            Cache::set($cacheKey, $result);
115
        }
116
117
        return $result;
118
    }
119
120
    /**
121
     * Convert an associative array (code and value) into a CodeModel array.
122
     *
123
     * @param array $data
124
     * @param bool $addEmpty
125
     *
126
     * @return static[]
127
     */
128
    public static function array2codeModel(array $data, bool $addEmpty = true): array
129
    {
130
        $result = [];
131
        if ($addEmpty) {
132
            $result[] = new static(['code' => null, 'description' => '------']);
133
        }
134
135
        foreach ($data as $key => $value) {
136
            $row = ['code' => $key, 'description' => $value];
137
            $result[] = new static($row);
138
        }
139
140
        return $result;
141
    }
142
143
    /**
144
     * Returns a codemodel with the selected data.
145
     *
146
     * @param string $tableName
147
     * @param string $fieldCode
148
     * @param string $code
149
     * @param string $fieldDescription
150
     *
151
     * @return static
152
     */
153
    public function get(string $tableName, string $fieldCode, $code, $fieldDescription)
154
    {
155
        // is a table or a model?
156
        $modelClass = self::MODEL_NAMESPACE . $tableName;
157
        if ($tableName && class_exists($modelClass)) {
158
            $model = new $modelClass();
159
            $where = [new DataBaseWhere($fieldCode, $code)];
160
            if ($model->loadFromCode('', $where)) {
161
                return new static(['code' => $model->{$fieldCode}, 'description' => $model->primaryDescription()]);
162
            }
163
164
            return new static();
165
        }
166
167
        self::initDataBase();
168
        if ($tableName && self::$dataBase->tableExists($tableName)) {
169
            $sql = 'SELECT ' . $fieldCode . ' AS code, ' . $fieldDescription . ' AS description FROM '
170
                . $tableName . ' WHERE ' . $fieldCode . ' = ' . self::$dataBase->var2str($code);
171
            $data = self::$dataBase->selectLimit($sql, 1);
172
            return empty($data) ? new static() : new static($data[0]);
173
        }
174
175
        return new static();
176
    }
177
178
    /**
179
     * Returns a description with the selected data.
180
     *
181
     * @param string $tableName
182
     * @param string $fieldCode
183
     * @param string $code
184
     * @param string $fieldDescription
185
     *
186
     * @return string
187
     */
188
    public function getDescription(string $tableName, string $fieldCode, $code, $fieldDescription): string
189
    {
190
        $model = $this->get($tableName, $fieldCode, $code, $fieldDescription);
191
        return empty($model->description) ? (string)$code : $model->description;
192
    }
193
194
    public static function getLimit(): int
195
    {
196
        return self::$limit ?? self::ALL_LIMIT;
197
    }
198
199
    /**
200
     * Load a CodeModel list (code and description) for the indicated table and search.
201
     *
202
     * @param string $tableName
203
     * @param string $fieldCode
204
     * @param string $fieldDescription
205
     * @param string $query
206
     * @param DataBaseWhere[] $where
207
     *
208
     * @return static[]
209
     */
210
    public static function search(string $tableName, string $fieldCode, string $fieldDescription, string $query, array $where = []): array
211
    {
212
        // is a table or a model?
213
        $modelClass = self::MODEL_NAMESPACE . $tableName;
214
        if (class_exists($modelClass)) {
215
            $model = new $modelClass();
216
            return $model->codeModelSearch($query, $fieldCode, $where);
217
        }
218
219
        $fields = $fieldCode . '|' . $fieldDescription;
220
        $where[] = new DataBaseWhere($fields, mb_strtolower($query, 'UTF8'), 'LIKE');
221
        return self::all($tableName, $fieldCode, $fieldDescription, false, $where);
222
    }
223
224
    public static function setLimit(int $newLimit): void
225
    {
226
        self::$limit = $newLimit;
227
    }
228
229
    /**
230
     * Inits database connection.
231
     */
232
    protected static function initDataBase(): void
233
    {
234
        if (self::$dataBase === null) {
235
            self::$dataBase = new DataBase();
236
        }
237
    }
238
}
239