diff --git a/src/bootstrap/safer_io.php b/src/bootstrap/safer_io.php
index f8a93d9..30cf92e 100644
--- a/src/bootstrap/safer_io.php
+++ b/src/bootstrap/safer_io.php
@@ -322,111 +322,210 @@ final class safer_io {
return $data;
}
+ /**
+ * Initialize JSON post data into static array, if used....
+ * @param int $levels_deep are JSON Levels to use
+ */
+
+ public static function init_json(int $levels_deep = 512): void {
+ self::$JSON_POST_DATA = self::get_json_post_data(true, $levels_deep);
+ }
+
/**
* Sanitize the inputs based on the rules an optionally trim the string
- * @param array $inputs [input, field, html, rule, message, skip_db]
* @param FIELD_FILTER $default_filter FILTER_SANITIZE_STRING
* @param bool $trim
* @return array [meta, fields, html, errors]
*/
- public static function sanitize(
- array $inputs,
+ private static function sanitize_helper(
+ string $from,
+ string $input_field_name,
+ array $a,
FIELD_FILTER $default_filter = FIELD_FILTER::raw_string,
bool $trim = true,
- int $levels_deep = 512 // JSON Levels
) : array {
-
- self::$JSON_POST_DATA = self::get_json_post_data(true, $levels_deep);
$meta = [];
$meta['missing'] = [];
- $safer_data = [];
- $safer_db_data = [];
- $safer_html_data = [];
+ $safer_data = "";
$rules = [];
$messages = [];
- foreach ($inputs as $input_field_name => $a) {
- if (isset($a['field']) && $a['field'] instanceof \UnitEnum) {
- $field_type = $a['field'];
- } else {
- $field_type = $default_filter;
- }
- if (isset($a['input']) && $a['input'] instanceof \UnitEnum) {
- $user_text = self::get_input_by_type($input_field_name, $a['input'], $field_type);
- } else {
- $meta['missing'][] = $input_field_name;
- continue;
- }
-
- $safer_data[$input_field_name] = false; // needs to be false to fail the validator
- $safer_html_data[$input_field_name] = null; // should be null for ?? operator to work with it....
-
- if (isset($a['rule'])) {
- $rules[$input_field_name] = $a['rule'];
- }
-
- if (isset($a['message']) && isset($a['rule'])) {
- $messages[$input_field_name] = $a['message'];
- }
+ if (isset($a['field']) && $a['field'] instanceof \UnitEnum) {
+ $field_type = $a['field'];
+ } else {
+ $field_type = $default_filter;
+ }
- $db = (isset($a['skip_db'])) ? $a['skip_db'] : false;
- $meta[$input_field_name]['type'] = $field_type->name;
- $meta[$input_field_name]['skip_db'] = $db;
-
- if ($user_text === null) {
- continue;
- }
-
+ if (isset($a['input']) && $a['input'] instanceof \UnitEnum) {
+ $user_text = self::get_input_by_type($input_field_name, $a['input'], $field_type);
+ } else {
+ $ret['name'] = $input_field_name;
+ $ret['meta']['missing'][] = $input_field_name;
+ $ret['errors'][$input_field_name] = "Missing Field $input_field_name";
+ $ret['html'] = null;
+ $ret['db'] = false;
+ $ret['logic'] = false;
+ return $ret;
+ }
+
+ $safer_data = false; // needs to be false to fail the validator
+ $safer_html_data = null; // should be null for ?? operator to work with it....
+
+ if (isset($a['rule'])) {
+ $rules[$input_field_name] = $a['rule'];
+ }
+
+ if (isset($a['message']) && isset($a['rule'])) {
+ $messages[$input_field_name] = $a['message'];
+ }
+
+ $db = (isset($a['skip_db'])) ? $a['skip_db'] : false;
+ $meta[$input_field_name]['type'] = $field_type->name;
+ $meta[$input_field_name]['skip_db'] = $db;
+
+ if ($user_text === null) {
+ $safer_data = null;
+ $safer_db_data = null;
+ $safer_html_data = null;
+ } else {
$field_filter_resolved = $field_type->resolve();
- $safer_data[$input_field_name] = $user_text;
+ $safer_data = $user_text;
if ($field_type == FIELD_FILTER::email) {
- $safer_data[$input_field_name] = substr($safer_data[$input_field_name], 0, 254);
+ $safer_data = substr($safer_data, 0, 254);
}
- $safer_data[$input_field_name] = filter_var($safer_data[$input_field_name], FILTER_DEFAULT, $field_filter_resolved);
+ $safer_data = filter_var($safer_data, FILTER_DEFAULT, $field_filter_resolved);
// FallBack: These field types should never allow arrays anyways
if ($field_type == FIELD_FILTER::raw_string ||
$field_type == FIELD_FILTER::raw
) {
- if (\tts\common::get_count($safer_data[$input_field_name])) {
- $safer_data[$input_field_name] = $safer_data[$input_field_name][0];
+ if (\tts\common::get_count($safer_data)) {
+ $safer_data = $safer_data[0];
}
}
- $safer_html = self::get_safer_html($safer_data[$input_field_name], $a);
- if ($safer_html !== false) {
- $safer_html_data[$input_field_name] = $safer_html;
- }
+ if ($from === "html") {
+ $safer_html = self::get_safer_html($safer_data, $a);
+ if ($safer_html !== false) {
+ $safer_html_data = $safer_html;
+ }
- $safer_data[$input_field_name] = self::t($safer_data[$input_field_name], $trim);
- if (isset($safer_html_data[$input_field_name])) {
- $safer_html_data[$input_field_name] = self::t($safer_html_data[$input_field_name], $trim);
+ if (isset($safer_html_data)) {
+ $safer_html_data = self::t($safer_html_data, $trim);
+ }
+ } else {
+ $safer_data = self::t($safer_data, $trim);
}
-
+
if ($field_type == FIELD_FILTER::integer_number) {
- $safer_data[$input_field_name] = intval($safer_data[$input_field_name]);
+ $safer_data = intval($safer_data);
}
if ($field_type == FIELD_FILTER::floating_point) {
- $safer_data[$input_field_name] = floatval($safer_data[$input_field_name]);
+ $safer_data = floatval($safer_data);
}
- if ($field_type == FIELD_FILTER::integer_number || $field_type == FIELD_FILTER::floating_point) {
- $safer_db_data[$input_field_name] = $safer_data[$input_field_name];
- } else {
- if (isset($a['db']) && $a['db'] == DB_FILTER::ON) {
- $safe_for_db = \tts\safer_sql::get_safer_sql_text($safer_data[$input_field_name]);
- $text = $safe_for_db["text"];
+ if ($from === "db") {
+ if ($field_type == FIELD_FILTER::integer_number || $field_type == FIELD_FILTER::floating_point) {
+ $safer_db_data = $safer_data;
} else {
- $text = $safer_data[$input_field_name];
+ if (isset($a['db']) && $a['db'] == DB_FILTER::ON) {
+ $safe_for_db = \tts\safer_sql::get_safer_sql_text($safer_data);
+ $text = $safe_for_db["text"];
+ } else {
+ $text = $safer_data;
+ }
+ $safer_db_data = $text;
}
- $safer_db_data[$input_field_name] = $text;
}
-
+ }
+ $ret['name'] = $input_field_name;
+ $ret['meta'] = $meta;
+ if ($from === "db") {
+ $ret['db'] = $safer_db_data;
+ $data[$input_field_name] = $safer_db_data;
+ } elseif ($from === "logic") {
+ $ret['logic'] = $safer_data;
+ $data[$input_field_name] = $safer_data;
+ } elseif ($from === "html") {
+ $ret['html'] = $safer_html_data;
+ $data[$input_field_name] = $safer_html_data;
}
- $errors = (count($rules)) ? \tts\validator::validate($safer_data, $rules, $messages) : [];
+ $ret['errors'] = (count($rules)) ? \tts\validator::validate($data, $rules, $messages) : [];
+ return $ret;
+ }
+
- return ['meta' => $meta, 'fields' => $safer_data, 'db'=>$safer_db_data, 'html' => $safer_html_data, 'errors' => $errors];
+ /**
+ * Sanitize the inputs based on the rules an optionally trim the string
+ * @param array $inputs [input, field, html, rule, message, skip_db, db]
+ * @param FIELD_FILTER $default_filter FILTER_SANITIZE_STRING
+ * @param bool $trim
+ * @return Generator
+ */
+ public static function db_sanitize(
+ array $inputs,
+ FIELD_FILTER $default_filter = FIELD_FILTER::raw_string,
+ bool $trim = true,
+ ) : \Generator {
+ foreach ($inputs as $input_field_name => $a) {
+ $yield = static::sanitize_helper(
+ "db",
+ $input_field_name,
+ $a,
+ $default_filter,
+ $trim
+ );
+ yield $yield;
+ }
+ }
+
+ /**
+ * Sanitize the inputs based on the rules an optionally trim the string
+ * @param array $inputs [input, field, html, rule, message, skip_db, db]
+ * @param FIELD_FILTER $default_filter FILTER_SANITIZE_STRING
+ * @param bool $trim
+ * @return Generator
+ */
+ public static function logic_sanitize(
+ array $inputs,
+ FIELD_FILTER $default_filter = FIELD_FILTER::raw_string,
+ bool $trim = true,
+ ) : \Generator {
+ foreach ($inputs as $input_field_name => $a) {
+ $yield = static::sanitize_helper(
+ "logic",
+ $input_field_name,
+ $a,
+ $default_filter,
+ $trim
+ );
+ yield $yield;
+ }
+ }
+
+ /**
+ * Sanitize the inputs based on the rules an optionally trim the string
+ * @param array $inputs [input, field, html, rule, message, skip_db, db]
+ * @param FIELD_FILTER $default_filter FILTER_SANITIZE_STRING
+ * @param bool $trim
+ * @return Generator
+ */
+ public static function html_sanitize(
+ array $inputs,
+ FIELD_FILTER $default_filter = FIELD_FILTER::raw_string,
+ bool $trim = true,
+ ) : \Generator {
+ foreach ($inputs as $input_field_name => $a) {
+ $yield = static::sanitize_helper(
+ "html",
+ $input_field_name,
+ $a,
+ $default_filter,
+ $trim
+ );
+ yield $yield;
+ }
}
-}
\ No newline at end of file
+}
diff --git a/src/classes/database/help_load.php b/src/classes/database/help_load.php
index 0b1d7ae..c20611f 100644
--- a/src/classes/database/help_load.php
+++ b/src/classes/database/help_load.php
@@ -16,7 +16,7 @@ class help_load {
* @param \PDOStatement $stmt
* @return \Generator
*/
- public static function fetch_lazy(\PDOStatement $stmt): \Generator {
+ public static function pdo_fetch_lazy(\PDOStatement $stmt): \Generator {
foreach($stmt as $record) {
yield $record;
}
diff --git a/src/classes/database/help_save.php b/src/classes/database/help_save.php
index db72a9e..687b5e0 100644
--- a/src/classes/database/help_save.php
+++ b/src/classes/database/help_save.php
@@ -4,6 +4,8 @@ declare(strict_types=1);
namespace tts\database;
+use \tts\safer_io as SafeIO;
+
final class help_save {
use \tts\traits\database\run_sql;
@@ -22,6 +24,7 @@ final class help_save {
private $error_message;
private $pdo;
private $primary_key = 'id';
+ private $db_skiped = [];
public function __construct($pdo, $table) {
$this->pdo = $pdo;
@@ -59,6 +62,10 @@ final class help_save {
unset($diff[$key]); // Who cares about IDs
}
+ foreach($this->db_skiped as $skip) {
+ unset($diff[$skip]);
+ }
+
if (count($diff)) {
echo "Diff on fields:
" . PHP_EOL;
$this->do_dump($diff);
@@ -77,35 +84,45 @@ final class help_save {
$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['db'])) {
- foreach($data['db'] as $key => $value) {
- $meta = $data['meta'][$key] ?? false;
- if ($meta !== false) {
- $skip_db = $meta['skip_db'] ?? false;
- if ($skip_db === true) {
- continue; // Skip Field
- }
+ public function set_members_by_generator(array $input): bool {
+ $good = true;
+ foreach(SafeIO::db_sanitize($input) as $data) {
+ $key = $data['name'] ?? false;
+ $value = $data['db'] ?? null;
+ $error_count = (isset($data['errors'])) ? \tts\common::get_count($data['errors']) : 0;
+ if ($error_count) {
+ return false;
+ }
+
+ if (isset($data['meta']['missing']) && \tts\common::get_count($data['meta']['missing'])) {
+ $this->missing = $data['meta']['missing'];
+ }
+
+ $meta = $data['meta'][$key] ?? false;
+ if ($meta !== false) {
+ $skip_db = $meta['skip_db'] ?? false;
+ if ($skip_db === true) {
+ $this->db_skiped[$key] = true;
+ continue; // Skip Field
}
+ }
+ if ($key !== false) {
$this->members[$key] = $value;
+ } else {
+ $good = false;
}
}
- return true;
+ return $good;
}
+ /**
+ * Do not use this one in production! AS anyone can override
+ * the DB security and Inject stuff into the DB via POST, etc...
+ */
public function auto_set_members(array $post = [], array $skip = ['route', 'm'], array $only_these = []): void {
+ if (\tts\main\configure::get('tts', 'live') === true) {
+ return; // Bail if LIVE
+ }
if (isset($post['json'])) {
$globals = \tts\safer_io::get_json_post_data();
} else {
diff --git a/src/classes/html.php b/src/classes/html.php
index ee5216f..5ddfe0a 100644
--- a/src/classes/html.php
+++ b/src/classes/html.php
@@ -90,7 +90,6 @@ final class html {
*/
public static function show_table_from_generator(
array $header_fields,
- array $db_field_names,
\Iterator $records,
bool $escape = true
): void {
@@ -102,11 +101,14 @@ final class html {
echo "\t\t