/** * Process single type for column * * @param string $column_name * @param array $column_options * @param mixed $value * @return array */ public static function process_single_column_type($column_name, $column_options, $value, $options = []) { $result = []; // processing as per different data types if ($column_options['type'] == 'boolean') { // booleans $result[$column_name] = !empty($value) ? 1 : 0; } else { if (in_array($column_options['type'], ['smallserial', 'serial', 'bigserial'])) { if (format::read_intval($value, ['valid_check' => 1])) { $temp = format::read_intval($value); if ($temp !== 0) { $result[$column_name] = $temp; } } else { $result[$column_name . '_is_serial_error'] = true; } $result[$column_name . '_is_serial'] = true; } else { if (in_array($column_options['type'], ['smallint', 'integer', 'bigint'])) { // integers // if we got empty string we say its null if (is_string($value) && $value === '') { $value = null; } if (is_null($value)) { if (!empty($column_options['null']) || !empty($options['ignore_defaults'])) { $result[$column_name] = null; } else { $result[$column_name] = $column_options['default'] ?? 0; } } else { $result[$column_name] = format::read_intval($value); } } else { if (in_array($column_options['type'], ['numeric', 'bcnumeric'])) { // numerics as floats or strings // if we got empty string we say its null if (is_string($value) && $value == '') { $value = null; } if (is_null($value)) { if (!empty($column_options['null']) || !empty($options['ignore_defaults'])) { $result[$column_name] = null; } else { $result[$column_name] = $column_options['default'] ?? ($column_options['type'] == 'bcnumeric' ? '0' : 0); } } else { $result[$column_name] = format::read_floatval($value, ['bcnumeric' => $column_options['type'] == 'bcnumeric']); } } else { if (in_array($column_options['type'], ['date', 'time', 'datetime', 'timestamp'])) { $result[$column_name] = format::read_date($value, $column_options['type']); // for datetime we do additional processing if (!empty($options['process_datetime'])) { $result[$column_name . '_strtotime_value'] = 0; if (!empty($value)) { $result[$column_name . '_strtotime_value'] = strtotime($result[$column_name]); } } } else { if ($column_options['type'] == 'json') { if (is_null($value)) { $result[$column_name] = null; } else { if (is_array($value)) { $result[$column_name] = json_encode($value); } else { $result[$column_name] = (string) $value; } } } else { if (is_null($value)) { $result[$column_name] = null; } else { $result[$column_name] = (string) $value; } } } } } } } return $result; }
/** * Validate data type for single value * * @param string $k * @param array $v * @param mixed $in_value * @param string $error_field */ public final function validate_data_types_single_value($k, $v, $in_value, $error_field = null) { // we set error field as main key if (empty($error_field)) { $error_field = $k; } // perform validation $data = object_table_columns::process_single_column_type($k, $v['options'], $in_value, ['process_datetime' => true]); if (array_key_exists($k, $data)) { // validations $error = false; $value = $in_value; // perform validation if ($v['options']['type'] == 'boolean') { if (!empty($value) && $value . '' != $data[$k] . '') { $this->error('danger', 'Wrong boolean value!', $error_field); $error = true; } } else { if (in_array($v['options']['type'], ['date', 'time', 'datetime', 'timestamp'])) { // dates first if (!empty($value) && empty($data[$k . '_strtotime_value'])) { $this->error('danger', 'Invalid date, time or datetime!', $error_field); $error = true; } } else { if ($v['options']['php_type'] == 'integer') { if ($value . '' !== '' && !format::read_intval($value, ['valid_check' => 1])) { $this->error('danger', 'Wrong integer value!', $error_field); $error = true; } // null processing if (!$error) { if (empty($data[$k]) && !empty($v['options']['null'])) { $data[$k] = null; } } } else { if ($v['options']['php_type'] == 'bcnumeric') { // accounting numbers if ($value . '' !== '' && !format::read_bcnumeric($value, ['valid_check' => 1])) { $this->error('danger', 'Wrong numeric value!', $error_field); $error = true; } // precision & scale validations if (!$error) { // validate scale $digits = explode('.', $data[$k] . ''); if (!empty($v['options']['scale'])) { if (!empty($digits[1]) && strlen($digits[1]) > $v['options']['scale']) { $this->error('danger', 'Only [digits] fraction digits allowed!', $error_field, ['replace' => ['[digits]' => i18n(null, $v['options']['scale'])]]); $error = true; } } // validate precision if (!empty($v['options']['precision'])) { $precision = $v['options']['precision'] - $v['options']['scale'] ?? 0; if (strlen($digits[0]) > $precision) { $this->error('danger', 'Only [digits] digits allowed!', $error_field, ['replace' => ['[digits]' => i18n(null, $precision)]]); $error = true; } } } } else { if ($v['options']['php_type'] == 'float') { // regular floats if ($value . '' !== '' && !format::read_floatval($value, ['valid_check' => 1])) { $this->error('danger', 'Wrong float value!', $error_field); $error = true; } // null processing if (!$error) { if (empty($data[$k]) && !empty($v['options']['null'])) { $data[$k] = null; } } } else { if ($v['options']['php_type'] == 'string') { // we need to convert empty string to null if ($data[$k] . '' === '' && !empty($v['options']['null'])) { $data[$k] = null; } // validate string length if ($data[$k] . '' !== '') { // validate length if (!empty($v['options']['type']) && $v['options']['type'] == 'char' && strlen($data[$k]) != $v['options']['length']) { // char $this->error('danger', 'The length must be [length] characters!', $error_field, ['replace' => ['[length]' => i18n(null, $v['options']['length'])]]); $error = true; } else { if (!empty($v['options']['length']) && strlen($data[$k]) > $v['options']['length']) { // varchar $this->error('danger', 'String is too long, should be no longer than [length]!', $error_field, ['replace' => ['[length]' => i18n(null, $v['options']['length'])]]); $error = true; } } } } } } } } } $data['flag_error'] = $error; } else { if (!empty($data[$k . '_is_serial'])) { if ($in_value . '' !== '' && !empty($data[$k . '_is_serial_error'])) { $this->error('danger', 'Wrong sequence value!', $error_field); $data['flag_error'] = true; } } else { $this->error('danger', object_content_messages::unknown_value, $error_field); $data['flag_error'] = true; } } return $data; }