KumbiaPHP/ActiveRecord

View on GitHub
ActiveRecord.php

Summary

Maintainability
A
3 hrs
Test Coverage
<?php
/**
* KumbiaPHP web & app Framework.
*
* LICENSE
*
* This source file is subject to the new BSD license that is bundled
* with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://wiki.kumbiaphp.com/Licencia
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@kumbiaphp.com so we can send you a copy immediately.
*
* @category Kumbia
*
* @copyright 2005 - 2020 Kumbia Team (http://www.kumbiaphp.com)
* @license http://wiki.kumbiaphp.com/Licencia New BSD License
*/
 
namespace Kumbia\ActiveRecord;
 
/**
* Implementación de patrón ActiveRecord con ayudantes de consultas sql.
*/
`ActiveRecord` has 22 functions (exceeds 20 allowed). Consider refactoring.
class ActiveRecord extends LiteRecord implements \JsonSerializable
{
const BELONG_TO = 1;
const HAS_MANY = 2;
const HAS_ONE = 3;
 
/**
* Describe the relationships.
*
* @var array
*/
protected static $relations = [];
 
public static function resolver($relations, $obj)
{
$model = $relations->model;
if ($relations->type === self::HAS_MANY) {
return $model::allBy($relations->via, $obj->pk());
}
 
return $model::first($relations->via, $obj->pk());
}
 
Similar blocks of code found in 2 locations. Consider refactoring.
public static function hasMany($name, $class, $via = null)
{
$str = strtolower($name);
$name = static::getTable();
static::$relations[$str] = (object) [
'model' => $class,
'type' => self::HAS_MANY,
'via' => $via ? $via : "{$name}_id",
];
}
 
Similar blocks of code found in 2 locations. Consider refactoring.
public static function hasOne($name, $class, $via = null)
{
$str = strtolower($name);
$name = static::getTable();
static::$relations[$str] = (object) [
'model' => $class,
'type' => self::HAS_ONE,
'via' => $via ? $via : "{$name}_id",
];
}
 
/**
* json_encode() method.
*/
public function jsonSerialize()
{
return $this; //TODO: populate relations before
}
 
public function __get($key)
{
if (property_exists($this, $key)) {
return $this->$key;
}
//it's a relationship
if (isset(static::$relations[$key])) {
$this->populate($key);
 
return $this->$key;
}
 
return null; //TODO: change for error
}
 
protected static function getRelationship($rel)
{
if (!isset(static::$relations[$rel])) {
throw new \RuntimeException("Invalid relationship '$rel'", 500);
}
 
return static::$relations[$rel];
}
 
public function populate($rel)
{
$relations = static::getRelationship($rel);
$this->$rel = static::resolver($relations, $this);
}
 
/**
* Pagination of Results.
*
* @param array $params [description]
* @param array $values [description]
* @param int $page [description]
* @param int $per_page [description]
*
* @return Paginator [description]
*/
public static function pagination($params = [], $values = [], $page = 1, $per_page = 10)
{
$model = static::class;
unset($params['limit'], $params['offset']);
$sql = QueryGenerator::select($model::getSource(), $model::getDriver(), $params);
 
return new Paginator($model, $sql, $page, $per_page, $values);
}
 
/**
* Actualizar registros.
*
* @param array $fields
* @param string $where condiciones
* @param array $values valores para condiciones
*
* @return int numero de registros actualizados
*/
public static function updateAll(array $fields, string $where = '', array $values = [])
{
$sql = QueryGenerator::updateAll(static::class, $fields, $values, $where);
$sth = self::prepare($sql);
$sth->execute($values);
 
return $sth->rowCount();
}
 
/**
* Eliminar registro.
*
* @param string $where condiciones
* @param array |string $values valores
*
* @return int numero de registros eliminados
*/
public static function deleteAll($where = null, $values = null)
{
$source = static::getSource();
$sql = QueryGenerator::deleteAll($source, $where);
$sth = self::query($sql, $values);
 
return $sth->rowCount();
}
 
/**
* Elimina caracteres que podrian ayudar a ejecutar
* un ataque de Inyeccion SQL.
*
* @param string $sqlItem
*
* @return string
* @throws \RuntimeException
*/
public static function sqlItemSanitize($sqlItem)
{
$sqlItem = \trim($sqlItem);
if ($sqlItem !== '' && $sqlItem !== null) {
$sql_temp = \preg_replace('/\s+/', '', $sqlItem);
if (!\preg_match('/^[a-zA-Z0-9_\.]+$/', $sql_temp)) {
throw new \RuntimeException('Se está tratando de ejecutar un SQL peligroso!');
}
}
 
return $sqlItem;
}
 
/**
* Obtener la primera coincidencia por el campo indicado.
*
* @param string $field campo
* @param string $value valor
* @param array $params parametros adicionales
* order: criterio de ordenamiento
* fields: lista de campos
* join: joins de tablas
* group: agrupar campos
* having: condiciones de grupo
* offset: valor offset
*
* @return ActiveRecord
*/
public static function firstBy($field, $value, $params = [])
{
$field = self::sqlItemSanitize($field);
$params['where'] = "$field = ?";
 
return self::first($params, $value);
}
 
/**
* Obtener la primera coincidencia de las condiciones indicadas.
*
* @param array $params parametros adicionales
* order: criterio de ordenamiento
* fields: lista de campos
* group: agrupar campos
* join: joins de tablas
* having: condiciones de grupo
* offset: valor offset queda
* @param array $values valores de busqueda
*
* @return ActiveRecord
*/
public static function first($params = [], $values = [])
{
$args = func_get_args();
/*Reescribe el limit*/
$args[0]['limit'] = 1;
$res = self::doQuery($args);
 
return $res->fetch();
}
 
/**
* Obtener todos los registros.
*
* @param array $params
* where: condiciones where
* order: criterio de ordenamiento
* fields: lista de campos
* join: joins de tablas
* group: agrupar campos
* having: condiciones de grupo
* limit: valor limit
* offset: valor offset
* @param array $values valores de busqueda
*
* @return \PDOStatement
*/
public static function all($params = [], $values = [])
{
$res = self::doQuery(func_get_args());
 
return $res->fetchAll();
}
 
/**
* Do a query.
*
* @param array $array params of query
*
* @return \PDOStatement|false
*/
protected static function doQuery(array $array)
{
$params = self::getParam($array);
$values = self::getValues($array);
$sql = QueryGenerator::select(static::getSource(), static::getDriver(), $params);
$sth = static::query($sql, $values);
 
return $sth;
}
 
/**
* Retorna los parametros para el doQuery.
*
* @param array $array
*
* @return array
*/
protected static function getParam(array &$array)
{
$val = array_shift($array);
 
return is_null($val) ? [] : $val;
}
 
/**
* Retorna los values para el doQuery.
*
* @param array $array
*
* @return array
*/
protected static function getValues(array $array)
{
return isset($array[0]) ?
(is_array($array[0]) ? $array[0] : [$array[0]]) : $array;
}
 
/**
* Obtener todas las coincidencias por el campo indicado.
*
* @param string $field campo
* @param string $value valor
* @param array $params
* order: criterio de ordenamiento
* fields: lista de campos
* join: joins de tablas
* group: agrupar campos
* having: condiciones de grupo
* limit: valor limit
* offset: valor offset
*
* @return \PDOStatement
*/
public static function allBy($field, $value, $params = [])
{
$field = self::sqlItemSanitize($field);
$params['where'] = "$field = ?";
 
return self::all($params, $value);
}
 
/**
* Cuenta los registros que coincidan con las condiciones indicadas.
*
* @param string $where condiciones
* @param array $values valores
*
* @return int
*/
public static function count(string $where = '', array $values = [])
{
$source = static::getSource();
$sql = QueryGenerator::count($source, $where);
 
$sth = static::query($sql, $values);
 
return $sth->fetch()->count;
}
 
/**
* Paginar.
*
* @param array $params
* @param int $page numero de pagina
* @param int $perPage cantidad de items por pagina
* @param array $values valores
*
* @return Paginator
*/
public static function paginate(array $params, int $page, int $perPage, $values = null)
{
unset($params['limit'], $params['offset']);
$sql = QueryGenerator::select(static::getSource(), static::getDriver(), $params);
 
// Valores para consulta
if ($values !== null && !\is_array($values)) {
$values = \array_slice(func_get_args(), 3);
}
 
return new Paginator(static::class, $sql, $page, $perPage, $values);
}
 
/**
* Obtiene todos los registros de la consulta sql.
*
* @param string $sql
* @param string | array $values
*
* @return array
*/
public static function allBySql($sql, $values = null)
{
if (!is_array($values)) {
$values = \array_slice(\func_get_args(), 1);
}
 
return parent::all($sql, $values);
}
 
/**
* Obtiene el primer registro de la consulta sql.
*
* @param string $sql
* @param string | array $values
*
* @return array
*/
public static function firstBySql($sql, $values = null)
{
if (!is_array($values)) {
$values = \array_slice(\func_get_args(), 1);
}
 
return parent::first($sql, $values);
}
}