diff --git a/www/admin/class_test.admin.backend.php b/www/admin/class_test.admin.backend.php index de776a25..c117aec1 100644 --- a/www/admin/class_test.admin.backend.php +++ b/www/admin/class_test.admin.backend.php @@ -55,7 +55,25 @@ print '

' . $PAGE_NAME . '

'; print "SETACL[]:
"; $backend->setACL(['EMPTY' => 'EMPTY']); print "ADBEDITLOG:
"; -$backend->adbEditLog('CLASSTEST-ADMIN', 'Some info string'); +$backend->adbEditLog('CLASSTEST-ADMIN-BINARY', 'Some info string', 'BINARY'); +$backend->adbEditLog('CLASSTEST-ADMIN-ZLIB', 'Some info string', 'ZLIB'); +$backend->adbEditLog('CLASSTEST-ADMIN-SERIAL', 'Some info string', 'SERIAL'); +$backend->adbEditLog('CLASSTEST-ADMIN-INVALID', 'Some info string', 'INVALID'); +// test with various +$backend->action = 'TEST ACTION'; +$backend->action_id = 'TEST ACTION ID'; +$backend->action_yes = 'TEST ACTION YES'; +$backend->action_flag = 'TEST ACTION FLAG'; +$backend->action_menu = 'TEST ACTION MENU'; +$backend->action_loaded = 'TEST ACTION LOADED'; +$backend->action_value = 'TEST ACTION VALUE'; +$backend->action_type = 'TEST ACTION TYPE'; +$backend->action_error = 'TEST ACTION ERROR'; +$backend->adbEditLog('CLASSTEST-ADMIN-JSON', [ + "_GET" => $_GET, + "_POST" => $_POST, +], 'JSON'); + print "ADBTOPMENU(0): " . Support::printAr($backend->adbTopMenu(CONTENT_PATH)) . "
"; print "ADBMSG:
"; $backend->adbMsg('info', 'Message: %1$d', [1]); diff --git a/www/lib/CoreLibs/Admin/Backend.php b/www/lib/CoreLibs/Admin/Backend.php index e6606631..044930a5 100644 --- a/www/lib/CoreLibs/Admin/Backend.php +++ b/www/lib/CoreLibs/Admin/Backend.php @@ -31,6 +31,8 @@ declare(strict_types=1); namespace CoreLibs\Admin; +use CoreLibs\Convert\Json; + class Backend { // page name @@ -42,7 +44,7 @@ class Backend /** @var array */ public array $action_list = [ 'action', 'action_id', 'action_sub_id', 'action_yes', 'action_flag', - 'action_menu', 'action_value', 'action_error', 'action_loaded' + 'action_menu', 'action_value', 'action_type', 'action_error', 'action_loaded' ]; /** @var string */ public string $action; @@ -61,20 +63,31 @@ class Backend /** @var string */ public string $action_value; /** @var string */ + public string $action_type; + /** @var string */ public string $action_error; + // ACL array variable if we want to set acl data from outisde /** @var array */ public array $acl = []; /** @var int */ public int $default_acl; + // queue key /** @var string */ public string $queue_key; + + /** @var array list of allowed types for edit log write */ + private const WRITE_TYPES = ['BINARY', 'BZIP2', 'LZIP', 'STRING', 'SERIAL', 'JSON']; + /** @var array list of available write types for log */ + private array $write_types_available = []; + // the current active edit access id /** @var int|null */ public int|null $edit_access_id; /** @var string */ public string $page_name; + // error/warning/info messages /** @var array */ public array $messages = []; @@ -84,6 +97,7 @@ class Backend public bool $warning = false; /** @var bool */ public bool $info = false; + // internal lang & encoding vars /** @var string */ public string $lang_dir = ''; @@ -95,6 +109,7 @@ class Backend public string $domain; /** @var string */ public string $encoding; + /** @var \CoreLibs\Logging\Logging logger */ public \CoreLibs\Logging\Logging $log; /** @var \CoreLibs\DB\IO database */ @@ -103,6 +118,7 @@ class Backend public \CoreLibs\Language\L10n $l; /** @var \CoreLibs\Create\Session session class */ public \CoreLibs\Create\Session $session; + // smarty publics [end processing in smarty class] /** @var array */ public array $DATA = []; @@ -175,6 +191,9 @@ class Backend if (preg_match("/^(add|save|delete|remove|move|up|down|push_live)$/", $this->action ?? '')) { $this->queue_key = \CoreLibs\Create\RandomKey::randomKeyGen(3); } + + // check what edit log data write types are allowed + $this->adbSetEditLogWriteTypeAvailable(); } /** @@ -185,7 +204,26 @@ class Backend // NO OP } - // PUBLIC METHODS |=================================================> + // MARK: PRIVATE METHODS + + /** + * set the write types that are allowed + * + * @return void + */ + private function adbSetEditLogWriteTypeAvailable() + { + // check what edit log data write types are allowed + $this->write_types_available = self::WRITE_TYPES; + if (!function_exists('bzcompress')) { + $this->write_types_available = array_diff($this->write_types_available, ['BINARY', 'BZIP']); + } + if (!function_exists('gzcompress')) { + $this->write_types_available = array_diff($this->write_types_available, ['LZIP']); + } + } + + // MARK: PUBLIC METHODS |=================================================> /** * set internal ACL from login ACL @@ -223,27 +261,57 @@ class Backend /** * writes all action vars plus other info into edit_log table * - * @param string $event any kind of event description, - * @param string|array $data any kind of data related to that event - * @param string $write_type write type can bei STRING or BINARY - * @param string|null $db_schema override target schema + * @param string $event [default=''] any kind of event description, + * @param string|array $data [default=''] any kind of data related to that event + * @param string $write_type [default=JSON] write type can be + * JSON, STRING/SERIEAL, BINARY/BZIP or ZLIB + * @param string|null $db_schema [default=null] override target schema * @return void */ public function adbEditLog( string $event = '', string|array $data = '', - string $write_type = 'STRING', + string $write_type = 'JSON', ?string $db_schema = null ): void { $data_binary = ''; $data_write = ''; - if ($write_type == 'BINARY') { - $data_binary = $this->db->dbEscapeBytea((string)bzcompress(serialize($data))); - $data_write = 'see bzip compressed data_binary field'; + // check if write type is valid, if not fallback to JSON + if (!in_array($write_type, $this->write_types_available)) { + $this->log->warning('Write type not in allowed array, fallback to JSON', context:[ + "write_type" => $write_type, + "write_list" => $this->write_types_available, + ]); + $write_type = 'JSON'; } - if ($write_type == 'STRING') { - $data_binary = ''; - $data_write = $this->db->dbEscapeString(serialize($data)); + switch ($write_type) { + case 'BINARY': + case 'BZIP': + $data_binary = $this->db->dbEscapeBytea((string)bzcompress(serialize($data))); + $data_write = 'see bzip compressed data_binary field'; + break; + case 'ZLIB': + $data_binary = $this->db->dbEscapeBytea((string)gzcompress(serialize($data))); + $data_write = 'see zlib compressed data_binary field'; + break; + case 'STRING': + case 'SERIAL': + $data_binary = ''; + $data_write = serialize($data); + break; + case 'JSON': + $data_binary = ''; + // must be converted to array + if (!is_array($data)) { + $data = ["data" => $data]; + } + $data_write = Json::jsonConvertArrayTo($data); + break; + default: + $this->log->alert('Invalid type for data compression was set', context:[ + "write_type" => $write_type + ]); + break; } /** @var string $DB_SCHEMA check schema */ @@ -253,44 +321,62 @@ class Backend } elseif (!empty($this->db->dbGetSchema())) { $DB_SCHEMA = $this->db->dbGetSchema(); } - $q = "INSERT INTO " . $DB_SCHEMA . ".edit_log " - . "(euid, event_date, event, data, data_binary, page, " - . "ip, user_agent, referer, script_name, query_string, server_name, http_host, " - . "http_accept, http_accept_charset, http_accept_encoding, session_id, " - . "action, action_id, action_yes, action_flag, action_menu, action_loaded, action_value, action_error) " - . "VALUES " - . "(" . $this->db->dbEscapeString(isset($_SESSION['EUID']) && is_numeric($_SESSION['EUID']) ? - $_SESSION['EUID'] : - 'NULL') - . ", " - . "NOW(), " - . "'" . $this->db->dbEscapeString((string)$event) . "', " - . "'" . $data_write . "', " - . "'" . $data_binary . "', " - . "'" . $this->db->dbEscapeString((string)$this->page_name) . "', " - . "'" . ($_SERVER["REMOTE_ADDR"] ?? '') . "', " - . "'" . $this->db->dbEscapeString($_SERVER['HTTP_USER_AGENT'] ?? '') . "', " - . "'" . $this->db->dbEscapeString($_SERVER['HTTP_REFERER'] ?? '') . "', " - . "'" . $this->db->dbEscapeString($_SERVER['SCRIPT_FILENAME'] ?? '') . "', " - . "'" . $this->db->dbEscapeString($_SERVER['QUERY_STRING'] ?? '') . "', " - . "'" . $this->db->dbEscapeString($_SERVER['SERVER_NAME'] ?? '') . "', " - . "'" . $this->db->dbEscapeString($_SERVER['HTTP_HOST'] ?? '') . "', " - . "'" . $this->db->dbEscapeString($_SERVER['HTTP_ACCEPT'] ?? '') . "', " - . "'" . $this->db->dbEscapeString($_SERVER['HTTP_ACCEPT_CHARSET'] ?? '') . "', " - . "'" . $this->db->dbEscapeString($_SERVER['HTTP_ACCEPT_ENCODING'] ?? '') . "', " - . ($this->session->getSessionId() === false ? - "NULL" : - "'" . $this->session->getSessionId() . "'") - . ", " - . "'" . $this->db->dbEscapeString($this->action ?? '') . "', " - . "'" . $this->db->dbEscapeString($this->action_id ?? '') . "', " - . "'" . $this->db->dbEscapeString($this->action_yes ?? '') . "', " - . "'" . $this->db->dbEscapeString($this->action_flag ?? '') . "', " - . "'" . $this->db->dbEscapeString($this->action_menu ?? '') . "', " - . "'" . $this->db->dbEscapeString($this->action_loaded ?? '') . "', " - . "'" . $this->db->dbEscapeString($this->action_value ?? '') . "', " - . "'" . $this->db->dbEscapeString($this->action_error ?? '') . "')"; - $this->db->dbExec($q, 'NULL'); + $q = <<db->dbExecParams( + str_replace( + ['{DB_SCHEMA}'], + [$DB_SCHEMA], + $q + ), + [ + // row 1 + isset($_SESSION['EUID']) && is_numeric($_SESSION['EUID']) ? + $_SESSION['EUID'] : null, + (string)$event, + $data_write, + $data_binary, + (string)$this->page_name, + // row 2 + $_SERVER["REMOTE_ADDR"] ?? '', + $_SERVER['HTTP_USER_AGENT'] ?? '', + $_SERVER['HTTP_REFERER'] ?? '', + $_SERVER['SCRIPT_FILENAME'] ?? '', + $_SERVER['QUERY_STRING'] ?? '', + $_SERVER['SERVER_NAME'] ?? '', + $_SERVER['HTTP_HOST'] ?? '', + // row 3 + $_SERVER['HTTP_ACCEPT'] ?? '', + $_SERVER['HTTP_ACCEPT_CHARSET'] ?? '', + $_SERVER['HTTP_ACCEPT_ENCODING'] ?? '', + $this->session->getSessionId() !== false ? + $this->session->getSessionId() : null, + // row 4 + $this->action ?? '', + $this->action_id ?? '', + $this->action_yes ?? '', + $this->action_flag ?? '', + $this->action_menu ?? '', + $this->action_loaded ?? '', + $this->action_value ?? '', + $this->action_type ?? '', + $this->action_error ?? '', + ], + 'NULL' + ); } /** @@ -540,16 +626,30 @@ class Backend } elseif (!empty($this->db->dbGetSchema())) { $DB_SCHEMA = $this->db->dbGetSchema(); } - $q = "INSERT INTO " . $DB_SCHEMA . ".live_queue (" - . "queue_key, key_value, key_name, type, target, data, group_key, action, associate, file" - . ") VALUES (" - . "'" . $this->db->dbEscapeString($queue_key) . "', '" . $this->db->dbEscapeString($key_value) . "', " - . "'" . $this->db->dbEscapeString($key_name) . "', '" . $this->db->dbEscapeString($type) . "', " - . "'" . $this->db->dbEscapeString($target) . "', '" . $this->db->dbEscapeString($data) . "', " - . "'" . $this->queue_key . "', '" . $this->action . "', " - . "'" . $this->db->dbEscapeString((string)$associate) . "', " - . "'" . $this->db->dbEscapeString((string)$file) . "')"; - $this->db->dbExec($q); + $q = <<db->dbExec($q); + $this->db->dbExecParams( + str_replace( + ['{DB_SCHEMA}'], + [$DB_SCHEMA], + $q + ), + [ + $queue_key, $key_value, + $key_name, $type, + $target, $data, + $this->queue_key, $this->action, + (string)$associate, (string)$file + ] + ); } /**