diff --git a/src/core/Model.php b/src/core/Model.php index dc4c410..e6221a5 100644 --- a/src/core/Model.php +++ b/src/core/Model.php @@ -8,6 +8,9 @@ use PDO; use PDOException; use Exception; +/** + * Class Model. + */ class Model { /** @@ -77,7 +80,7 @@ class Model $properties = $refClass->getProperties(ReflectionProperty::IS_PRIVATE); foreach ($properties as $property) { $propertyTags = $app->parseTagsFromComment($property->getDocComment(), - 'ColumnName|ColumnOption|ColumnType'); + 'ColumnName|ColumnOption|ColumnType|PDOType'); if ($propertyTags) { if (array_key_exists('ColumnName', $propertyTags)) { @@ -151,11 +154,24 @@ class Model $where_sql = ''; $mode_sql = ''; - if (is_null($where)) { - if (is_null($records) || !count($records)) { - throw new Exception('$records unspecified.'); - } + if (is_null($where) && (is_null($records) || !count($records))) { + throw new Exception('$records unspecified.'); + } + + if ($where) { + $where_sql .= str_replace( + array_map(function ($item) { + return "{{$item}}"; + }, array_keys($internal_table_map['fields'])), + array_map(function ($item) { + return "`{$item}`"; + }, array_values($internal_table_map['fields'])), + $where + ); + } + + if (is_array($records) && count($records)) { if (is_null($column)) { $column_name = "`{$internal_table_map['id']}`"; } else { @@ -178,11 +194,12 @@ class Model if (empty($mode_sql)) { throw new Exception('Bad $mode'); } - $query = $model->app->db->prepare("SELECT $select_fields FROM `{$internal_table_map['name']}` WHERE $mode_sql $order_sql $limit_sql;"); - } else { - $query = $model->app->db->prepare("SELECT $select_fields FROM `{$internal_table_map['name']}` ;"); + + $where_sql = $mode_sql.($where ? " AND ($where_sql)" : ''); } + $query = $model->app->db->prepare("SELECT $select_fields FROM `{$internal_table_map['name']}` WHERE $where_sql $order_sql $limit_sql;"); + $num = 0; $params = []; @@ -202,6 +219,14 @@ class Model } } + if (count($bind) && $where) { + foreach ($bind as $parameter => $variable) { + $params[$num] = $variable; + $query->bindParam($parameter, $params[$num]); + ++$num; + } + } + $query->execute(); $data = $query->fetchAll(PDO::FETCH_ASSOC); @@ -228,6 +253,88 @@ class Model return null; } + /** + * Save models + * + * @param Model[] $models + * + * @return bool + * + * @throws Exception + */ + public static function save(array $models): bool + { + if (count($models)) { + if ($models[0] instanceof Model) { + if ('db' !== $models[0]->getModelType()) { + throw new Exception('Item 0 is not Model of a db type'); + } + $db = $models[0]->app->db; + $db->beginTransaction(); + foreach ($models as $number => $model) { + if ($model instanceof Model) { + if ('db' !== $model->getModelType()) { + $db->rollBack(); + throw new Exception("Item $number is not Model of a db type"); + } + + $table_map = $model->getInternalTableMap(); + + $operation = 'INSERT INTO'; + $suffix = ''; + + $data_model = []; + (function () use (&$data_model, $table_map) { + foreach ($table_map['fields'] as $name => $db_field) { + $data_model[$name] = $this->{$name}; + } + })->call($model); + + $update_mode = !is_null($data_model[$table_map['id']]); + if ($update_mode) { + $operation = 'UPDATE'; + $suffix = ' WHERE `'.$table_map['fields'][$table_map['id']].'` = :param_'.$table_map['id']; + } + + $pairs = []; + foreach ($table_map['fields'] as $param_name => $column_name) { + if ($table_map['id'] !== $param_name) { + $pairs[] = "`{$column_name}` = :param_{$param_name}"; + } + } + $pairs_string = 'SET ' . implode(', ', $pairs); + $query = $db->prepare($operation." `{$table_map['name']}` $pairs_string $suffix;"); + + $bind_params = []; + $num = 0; + foreach ($data_model as $item => $value) { + if ($table_map['id'] !== $item) { + $bind_params[$num] = $value; + $query->bindParam(':param_' . $item, + $bind_params[$num]); + ++$num; + } + } + if ($update_mode) { + $bind_params[$num] = $data_model[$table_map['id']]; + $query->bindParam(':param_' . $table_map['id'], + $bind_params[$num]); + } + + $query->execute(); + } + } + $db->commit(); + + return true; + } else { + throw new Exception('Item 0 is not Model of a db type'); + } + } + + return false; + } + /** * @return array */