The TryingToScale PHP framework.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 

299 lines
8.5 KiB

<?php
declare(strict_types=1);
namespace tts\database;
final class help_save {
use run_sql;
use validation;
const successful_save = 1;
const duplicate_found = 2;
const validation_error = 3;
const pre_save_failed = 4;
const post_save_failed = 5;
private $table;
private $members = [];
private $validation_members = [];
private $missing = [];
private $error_message;
private $pdo;
private $primary_key = 'id';
public function __construct($pdo, $table) {
$this->pdo = $pdo;
$this->table = $table;
}
public function saved(bool $worked = true): bool {
if (headers_sent()) {
return false;
}
header("Content-Type: application/json; charset=UTF-8");
$time = \tts\time_zones::convert_time_zone(array('format' => 'g:i a'));
echo json_encode(['time' => $time, 'saved' => $worked]);
return true;
}
/**
* JSON API inform AJAX that save failed
*/
public function save_failed($msg = 'Save Failed!'): void {
\tts\api::error(array('code' => 500, 'success' => false, 'error' => $msg, 'responce' => \tts\api::INTERNAL_ERROR));
}
public function dump_table_fields(string $table) {
$fields = $this->get_fields($table);
$this->do_dump($fields);
}
public function dump_diff(): bool {
$fields = $this->get_fields($this->table);
$diff = array_diff($fields, array_keys($this->members));
if (($key = array_search('id', $diff)) !== false) {
unset($diff[$key]); // Who cares about IDs
}
if (count($diff)) {
echo "Diff on fields:<br>" . PHP_EOL;
$this->do_dump($diff);
return true;
}
return false;
}
private function do_dump(array $data) {
echo "<pre style=\"border: 1px solid #000; overflow: auto; margin: 0.5em;\">";
print_r($data);
echo '</pre>';
}
public function set_primary_key_name(string $key): void {
$this->primary_key = $key;
}
/**
* @param array $data [fields=[key=>value]]
*/
public function set_members_by_array(array $data): bool {
$error_count = (isset($data['errors'])) ? count($data['errors']) : 0;
if ($error_count) {
return false;
}
if (count($data['meta']['missing'])) {
$this->missing = $data['meta']['missing'];
}
if (count($data['fields'])) {
foreach($data['fields'] as $key => $value) {
$meta = $data['meta'][$key] ?? false;
if ($meta !== false) {
$skip_db = $meta['skip_db'] ?? false;
if ($skip_db === true) {
continue; // Skip Field
}
}
$this->members[$key] = $value;
}
}
return true;
}
public function auto_set_members(array $post = [], array $skip = ['route', 'm'], array $only_these = []): void {
if (isset($post['json'])) {
$globals = \tts\safer_io::get_json_post_data();
} else {
$json_post = count($post);
$globals = ($json_post) ? $post : filter_input_array(INPUT_POST) ?? [];
}
foreach ($globals as $key => $data) {
if (count($skip) && in_array($key, $skip)) {
continue;
}
if (in_array($key, $only_these) || !count($only_these)) {
$this->members[$key] = (\tts\request::is_not_empty($data)) ? $data : "";
}
}
}
public function get_missing() {
return $this->missing;
}
/* From old Model code: */
public function get_member(string $member) {
return $this->members[$member] ?? null;
}
public function get_members(string $member) {
return $this->members;
}
public function set_member(string $member, string $data): void {
$this->members[$member] = $data;
}
public function has_member($member): bool {
return isset($this->members[$member]);
}
public function get_last_error(): string {
return $this->error_message;
}
/**
* Set Member for Validation
* @param string $key
* @param array $a
*/
public function set_member_for_validation(string $key, array $a): void {
$this->validation_members[$key] = $a;
}
/**
* Get Validation Member
* @param string $key
* @return array
*/
public function get_vaildation_member(string $key): array {
return $this->validation_members[$key] ?? array();
}
/**
* Unset Validation Member
* @param string $key
*/
public function clear_validation_member(string $key): void {
unset($this->validation_members[$key]);
}
private function cleanup($bind) {
if (!is_array($bind)) {
if (!empty($bind)) {
$bind = array($bind);
} else {
$bind = array();
}
}
return $bind;
}
public function insert($table, $info) {
$fields = $this->filter($table, $info);
if (strrpos($table, "`") === false) {
$table = "`{$table}`";
}
$sql = "INSERT INTO {$table} (" . implode(", ", $fields) . ") VALUES (:" . implode(", :", $fields) . ");";
$bind = array();
foreach ($fields as $field) {
$bind[":$field"] = $info[$field];
}
return $this->run($sql, $bind);
}
public function update($table, $info, $where, $bind = "") {
$bind = $this->cleanup($bind);
$fields = $this->filter($table, $info);
if (strrpos($table, "`") === false) {
$table = "`{$table}`";
}
$sql = "UPDATE {$table} SET ";
$f = 0;
foreach ($fields as $key => $value) {
if ($f > 0) {
$sql .= ", ";
}
$f++;
$value = trim($value);
if (strrpos($value, "`") === false) {
$cf = '`' . $value . '`';
} else {
$cf = $value;
}
$sql .= $cf . " = :update_" . $value;
$bind[":update_$value"] = $info[$value];
}
$sql .= " WHERE " . $where . ";";
return $this->run($sql, $bind);
}
public static function make_db_time_stamp(): string {
return \tts\time_zones::convert_time_zone(['format' => 'database', 'timezone' => 'UTC']);
}
/**
* Save
*
* @param object $lcoal_model Should be $this from the Model
*
* Insert if primary key not set
* Update if primary key set
*/
public function save(object $local_model=null, bool $validate = true): int {
if (method_exists($local_model, 'pre_save')) {
$pre_was_successfull = $local_model->pre_save();
if (! $pre_was_successfull) {
return self::pre_save_failed;
}
}
$name = $this->pdo->getAttribute(\PDO::ATTR_DRIVER_NAME); // Get DB Driver
if ($name === 'mysql' && $validate) {
if (!$this->validate_mysql()) {
return self::validation_error;
}
}
if ($this->has_member('modified')) {
$this->set_member('modified', self::make_db_time_stamp());
}
if (empty($this->members[$this->primary_key])) {
if (method_exists($local_model, 'duplicate_check')) {
$dup = $local_model->duplicate_check();
if ($dup) {
return self::duplicate_found;
}
}
if ($this->has_member('created')) {
$this->set_member('created', self::make_db_time_stamp());
}
$this->members[$this->primary_key] = $this->insert($this->table, $this->members);
} else {
$this->set_member("row_count", $this->update($this->table, $this->members,
"`{$this->primary_key}` = :search_key",
array(':search_key' => $this->members[$this->primary_key])
));
}
if (method_exists($local_model, 'post_save')) {
$post_save_successfull = $local_model->post_save();
if (! $post_save_successfull) {
return self::post_save_failed;
}
}
return self::successful_save;
}
/* End Model */
}