/** * Prepares a ShoppDatabaseObject for entry into the database * * Iterates the properties of a ShoppDatabaseObject and formats the data * according to the datatype meta available for the property to create * an array of key/value pairs that are easy concatenate into a valid * SQL query * * @author Jonathan Davis * @since 1.0 * * @param ShoppDatabaseObject $Object The object to be prepared * @return array Data structure ready for query building **/ public static function prepare($Object, array $mapping = array()) { $data = array(); // Go through each data property of the object $properties = get_object_vars($Object); foreach ($properties as $var => $value) { $property = isset($mapping[$var]) ? $mapping[$var] : $var; if (!isset($Object->_datatypes[$property])) { continue; } // If the property is has a _datatype // it belongs in the database and needs // to be prepared // Process the data switch ($Object->_datatypes[$property]) { case 'string': // Escape characters in strings as needed if (is_array($value) || is_object($value)) { $data[$property] = "'" . addslashes(serialize($value)) . "'"; } else { $data[$property] = "'" . sDB::escape($value) . "'"; } break; case 'list': // If value is empty, skip setting the field // so it inherits the default value in the db if (!empty($value)) { $data[$property] = "'{$value}'"; } break; case 'date': // If it's an empty date, set it to the current time if (is_null($value)) { $value = current_time('mysql'); // If the date is an integer, convert it to an // sql YYYY-MM-DD HH:MM:SS format } elseif (!empty($value) && (is_int($value) || intval($value) > 86400)) { $value = sDB::mkdatetime(intval($value)); } $data[$property] = "'{$value}'"; break; case 'float': // Sanitize without rounding to protect precision if (is_string($value) && method_exists('ShoppCore', 'floatval')) { $value = ShoppCore::floatval($value, false); } else { $value = floatval($value); } case 'int': // Normalize for MySQL float representations (@see bug #853) // Force formating with full stop (.) decimals // Trim excess 0's followed by trimming (.) when there is no fractional value $value = rtrim(rtrim(number_format((double) $value, 6, '.', ''), '0'), '.'); $data[$property] = "'{$value}'"; if (empty($value)) { $data[$property] = "'0'"; } // Special exception for id fields if ('id' == $property && empty($value)) { $data[$property] = "NULL"; } break; default: // Anything not needing processing // passes through into the structure $data[$property] = "'{$value}'"; } } return $data; }