Completed
Push — master ( df6ef2...369f62 )
by joanhey
01:55
created

lib/Kumbia/ActiveRecord/ActiveRecord.php (1 issue)

Upgrade to new PHP Analysis Engine

These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more

1
<?php
2
/**
3
 * KumbiaPHP web & app Framework.
4
 *
5
 * LICENSE
6
 *
7
 * This source file is subject to the new BSD license that is bundled
8
 * with this package in the file LICENSE.txt.
9
 * It is also available through the world-wide-web at this URL:
10
 * http://wiki.kumbiaphp.com/Licencia
11
 * If you did not receive a copy of the license and are unable to
12
 * obtain it through the world-wide-web, please send an email
13
 * to [email protected] so we can send you a copy immediately.
14
 *
15
 * @category   Kumbia
16
 *
17
 * @copyright  2005 - 2016  Kumbia Team (http://www.kumbiaphp.com)
18
 * @license    http://wiki.kumbiaphp.com/Licencia     New BSD License
19
 */
20
namespace Kumbia\ActiveRecord;
21
22
/**
23
 * Implementación de patrón ActiveRecord con ayudantes de consultas sql.
24
 */
25
class ActiveRecord extends LiteRecord
26
{
27
28
    const BELONG_TO = 1;
29
    const HAS_MANY  = 2;
30
    const HAS_ONE   = 3;
31
32
    /**
33
     * Describe the relationships
34
     * @var array
35
     */
36
    static protected $rs = [];
37
38
    static public function resolver($rs, $obj){
39
        $model = $rs->model;
40
        if($rs->type === self::HAS_MANY){
41
            return $model::allBy($rs->via, $obj->pk());
42
        }
43
        return $model::first($rs->via, $obj->pk());
44
    }
45
46 View Code Duplication
    static public function hasMany($name, $class, $via = NULL){
47
        $str = strtolower($name);
48
        $name = static::getTable();
49
        static::$rs[$str] = (object)[
50
            'model' => $class,
51
            'type'  => self::HAS_MANY,
52
            'via'   => $via ? $via : "{$name}_id"
53
        ];
54
    }
55
56 View Code Duplication
    static public function hasOne($name, $class, $via = NULL){
57
        $str = strtolower($name);
58
        $name = static::getTable();
59
        static::$rs[$str] = (object)[
60
            'model' => $class,
61
            'type'  => self::HAS_ONE,
62
            'via'   => $via ? $via : "{$name}_id"
63
        ];
64
    }
65
66
    public function __get($key){
67
 
68
        if ($this->$key) {
69
            return $this->$key;
70
        }
71
        //it's a relationship
72
        if (isset(static::$rs[$key])) {
73
            $this->populate($key);
74
            return $this->values[$key];
0 ignored issues
show
The property values does not exist on object<Kumbia\ActiveRecord\ActiveRecord>. Since you implemented __get, maybe consider adding a @property annotation.

Since your code implements the magic getter _get, this function will be called for any read access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

If the property has read access only, you can use the @property-read annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
75
        }
76
        return null; //TODO: change for error
77
    }
78
79
    static protected function getRelationship($rel){
80
        if(!isset(static::$rs[$rel]))
81
            throw new \RuntimeException("Invalid relationship '$rel'", 500);
82
        return static::$rs[$rel];
83
    }
84
85
    public function populate($rel){
86
        $rs = static::getRelationship($rel);
87
        $this->$rel =  static::resolver($rs, $this);
88
    }
89
90
    /**
91
     * Pagination of Results
92
     * @param  Array  $params   [description]
93
     * @param  Array  $values   [description]
94
     * @param  integer $page     [description]
95
     * @param  integer $per_page [description]
96
     * @return Paginator            [description]
97
     */
98
    static  public function pagination($params = [], $values = [], $page = 1, $per_page = 10){
99
        $model =  get_called_class();
100
        unset($params['limit'], $params['offset']);
101
        $sql = QueryGenerator::select($model::getSource(), $model::getDriver(), $params);
102
        return new Paginator($model, $sql, $page, $per_page, $values);
103
    }
104
105
106
    /**
107
     * Actualizar registros.
108
     *
109
     * @param array  $fields
110
     * @param string $where  condiciones
111
     * @param array  $values valores para condiciones
112
     *
113
     * @return int numero de registros actualizados
114
     */
115 View Code Duplication
    public static function updateAll(array $fields, $where = null, array $values = [])
116
    {
117
        if ($values !== null && !is_array($values)) {
118
            $values = \array_slice(\func_get_args(), 2);
119
        }
120
        $sql = QueryGenerator::updateAll(\get_called_class(), $fields, $values, $where);
121
        $sth = self::prepare($sql);
122
        $sth->execute($values);
123
124
        return $sth->rowCount();
125
    }
126
127
    /**
128
     * Eliminar registro.
129
     *
130
     * @param string        $where  condiciones
131
     * @param array |string $values valores
132
     *
133
     * @return int numero de registros eliminados
134
     */
135
    public static function deleteAll($where = null, $values = null)
136
    {
137
        $source = static::getSource();
138
        $sql = QueryGenerator::deleteAll($source, $where);
139
        $sth = self::query($sql, $values);
140
141
        return $sth->rowCount();
142
    }
143
144
    /**
145
     * Elimina caracteres que podrian ayudar a ejecutar
146
     * un ataque de Inyeccion SQL.
147
     *
148
     * @param string $sqlItem
149
     *
150
     * @return string
151
     * @throw KumbiaException
152
     */
153
    public static function sqlItemSanitize($sqlItem)
154
    {
155
        $sqlItem = \trim($sqlItem);
156
        if ($sqlItem !== '' && $sqlItem !== null) {
157
            $sql_temp = \preg_replace('/\s+/', '', $sqlItem);
158
            if (!\preg_match('/^[a-zA-Z0-9_\.]+$/', $sql_temp)) {
159
                throw new \RuntimeException('Se esta tratando de ejecutar una operacion maliciosa!');
160
            }
161
        }
162
163
        return $sqlItem;
164
    }
165
166
    /**
167
     * Obtener la primera coincidencia por el campo indicado.
168
     *
169
     * @param string $field  campo
170
     * @param string $value  valor
171
     * @param array  $params parametros adicionales
172
     *                       order: criterio de ordenamiento
173
     *                       fields: lista de campos
174
     *                       join: joins de tablas
175
     *                       group: agrupar campos
176
     *                       having: condiciones de grupo
177
     *                       offset: valor offset
178
     *
179
     * @return ActiveRecord
180
     */
181 View Code Duplication
    public static function firstBy($field, $value, $params = [])
182
    {
183
        $field = self::sqlItemSanitize($field);
184
        $params['where'] = "$field = ?";
185
186
        return self::first($params, $value);
187
    }
188
189
    /**
190
     * Obtener la primera coincidencia de las condiciones indicadas.
191
     *
192
     * @param array  $params parametros de bus
193
     * @param string $field  campo
194
     * @param string $value  valor
195
     * @param array  $params parametros adicionales
196
     *                       order: criterio de ordenamiento
197
     *                       fields: lista de campos
198
     *                       group: agrupar campos
199
     *                       join: joins de tablas
200
     *                       having: condiciones de grupo
201
     *                       offset: valor offset queda
202
     * @param array  $values valores de busqueda
203
     *
204
     * @return ActiveRecord
205
     */
206
    public static function first($params = [], $values = [])
207
    {
208
        $args = func_get_args();
209
        /*Reescribe el limit*/
210
        $args[0]['limit'] = 1;
211
        $res = self::doQuery($args);
212
213
        return $res->fetch();
214
    }
215
216
    /**
217
     * Obtener todos los registros.
218
     *
219
     * @param array $params
220
     *                      where: condiciones where
221
     *                      order: criterio de ordenamiento
222
     *                      fields: lista de campos
223
     *                      join: joins de tablas
224
     *                      group: agrupar campos
225
     *                      having: condiciones de grupo
226
     *                      limit: valor limit
227
     *                      offset: valor offset
228
     * @param array $values valores de busqueda
229
     *
230
     * @return \PDOStatement
231
     */
232
    public static function all($params = [], $values = [])
233
    {
234
        $res = self::doQuery(func_get_args());
235
236
        return $res->fetchAll();
237
    }
238
239
    /**
240
     * Do a query.
241
     *
242
     * @param array $array params of query
243
     *
244
     * @return \PDOStatement|false
245
     */
246
    protected static function doQuery(array $array)
247
    {
248
        $params = self::getParam($array);
249
        $values = self::getValues($array);
250
        $sql = QueryGenerator::select(static::getSource(), static::getDriver(), $params);
251
        $sth = static::query($sql, $values);
252
253
        return $sth;
254
    }
255
256
    /**
257
     * Retorna los parametros para el doQuery.
258
     *
259
     * @param array $array
260
     *
261
     * @return array
262
     */
263
    protected static function getParam(array &$array)
264
    {
265
        $val = array_shift($array);
266
267
        return is_null($val) ?  [] : $val;
268
    }
269
270
    /**
271
     * Retorna los values para el doQuery.
272
     *
273
     * @param array $array
274
     *
275
     * @return array
276
     */
277
    protected static function getValues(array $array)
278
    {
279
        return isset($array[0]) ?
280
            is_array($array[0]) ? $array[0] : [$array[0]]: $array;
281
    }
282
283
    /**
284
     * Obtener todas las coincidencias por el campo indicado.
285
     *
286
     * @param string $field  campo
287
     * @param string $value  valor
288
     * @param array  $params
289
     *                       order: criterio de ordenamiento
290
     *                       fields: lista de campos
291
     *                       join: joins de tablas
292
     *                       group: agrupar campos
293
     *                       having: condiciones de grupo
294
     *                       limit: valor limit
295
     *                       offset: valor offset
296
     *
297
     * @return \PDOStatement
298
     */
299 View Code Duplication
    public static function allBy($field, $value, $params = [])
300
    {
301
        $field = self::sqlItemSanitize($field);
302
        $params['where'] = "$field = ?";
303
304
        return self::all($params, $value);
305
    }
306
307
    /**
308
     * Cuenta los registros que coincidan con las condiciones indicadas.
309
     *
310
     * @param string $where  condiciones
311
     * @param array  $values valores
312
     *
313
     * @return int
314
     */
315 View Code Duplication
    public static function count($where = null, $values = null)
316
    {
317
        $source = static::getSource();
318
        $sql = QueryGenerator::count($source, $where);
319
        if ($values !== null && !is_array($values)) {
320
            $values = \array_slice(\func_get_args(), 1);
321
        }
322
        $sth = static::query($sql, $values);
323
324
        return $sth->fetch()->count;
325
    }
326
327
    /**
328
     * Paginar.
329
     *
330
     * @param array $params
331
     * @param int   $page    numero de pagina
332
     * @param int   $perPage cantidad de items por pagina
333
     * @param array $values  valores
334
     *
335
     * @return Paginator
336
     */
337
    public static function paginate(array $params, $page, $perPage, $values = null)
338
    {
339
        unset($params['limit'], $params['offset']);
340
        $sql = QueryGenerator::select(static::getSource(), static::getDriver(), $params);
341
342
        // Valores para consulta
343
        if ($values !== null && !\is_array($values)) {
344
            $values = \array_slice(func_get_args(), 3);
345
        }
346
347
        return new Paginator(\get_called_class(), $sql, (int) $page, (int) $perPage, $values);
348
    }
349
350
    /**
351
     * Obtiene todos los registros de la consulta sql.
352
     *
353
     * @param string         $sql
354
     * @param string | array $values
355
     *
356
     * @return array
357
     */
358 View Code Duplication
    public static function allBySql($sql, $values = null)
359
    {
360
        if (!is_array($values)) {
361
            $values = \array_slice(\func_get_args(), 1);
362
        }
363
364
        return parent::all($sql, $values);
365
    }
366
367
    /**
368
     * Obtiene el primer registro de la consulta sql.
369
     *
370
     * @param string         $sql
371
     * @param string | array $values
372
     *
373
     * @return array
374
     */
375 View Code Duplication
    public static function firstBySql($sql, $values = null)
376
    {
377
        if (!is_array($values)) {
378
            $values = \array_slice(\func_get_args(), 1);
379
        }
380
381
        return parent::first($sql, $values);
382
    }
383
}
384