lean True if the database engine supports UTF-8 character encoding. * * @since 1.0 */ public function hasUtfSupport() { return $this->utf; } /** * Inserts a row into a table based on an object's properties. * * @param string $table The name of the database table to insert into. * @param object $object A reference to an object whose public properties match the table fields. * @param string $key The name of the primary key. If provided the object property is updated. * * @return boolean * * @since 1.0 * @throws \RuntimeException */ public function insertObject($table, &$object, $key = null) { $fields = []; $values = []; $tableColumns = $this->getTableColumns($table); // Iterate over the object variables to build the query fields and values. foreach (get_object_vars($object) as $k => $v) { // Skip columns that don't exist in the table. if (!\array_key_exists($k, $tableColumns)) { continue; } // Only process non-null scalars. if (\is_array($v) || \is_object($v) || $v === null) { continue; } // Ignore any internal fields. if ($k[0] === '_') { continue; } // Prepare and sanitize the fields and values for the database query. $fields[] = $this->quoteName($k); $values[] = $this->quote($v); } // Create the base insert statement. $query = $this->createQuery() ->insert($this->quoteName($table)) ->columns($fields) ->values(implode(',', $values)); // Set the query and execute the insert. $this->setQuery($query)->execute(); // Update the primary key if it exists. $id = $this->insertid(); if ($key && $id && \is_string($key)) { $object->$key = $id; } return true; } /** * Method to check whether the installed database version is supported by the database driver * * @return boolean True if the database version is supported * * @since 1.0 */ public function isMinimumVersion() { return version_compare($this->getVersion(), $this->getMinimum()) >= 0; } /** * Method to get the first row of the result set from the database query as an associative array of ['field_name' => 'row_value']. * * @return mixed The return value or null if the query failed. * * @since 1.0 * @throws \RuntimeException */ public function loadAssoc() { $this->connect(); $ret = null; // Execute the query and get the result set cursor. $this->execute(); // Get the first row from the result set as an associative array. $array = $this->fetchAssoc(); if ($array) { $ret = $array; } // Free up system resources and return. $this->freeResult(); return $ret; } /** * Method to get an array of the result set rows from the database query where each row is an associative array * of ['field_name' => 'row_value']. The array of rows can optionally be keyed by a field name, but defaults to * a sequential numeric array. * * NOTE: Choosing to key the result array by a non-unique field name can result in unwanted * behavior and should be avoided. * * @param string $key The name of a field on which to key the result array. * @param string $column An optional column name. Instead of the whole row, only this column value will be in * the result array. * * @return mixed The return value or null if the query failed. * * @since 1.0 * @throws \RuntimeException */ public function loadAssocList($key = null, $column = null) { $this->connect(); $array = []; // Execute the query and get the result set cursor. $this->execute(); // Get all of the rows from the result set. while ($row = $this->fetchAssoc()) { $value = $column ? ($row[$column] ?? $row) : $row; if ($key) { $array[$row[$key]] = $value; } else { $array[] = $value; } } // Free up system resources and return. $this->freeResult(); return $array; } /** * Method to get an array of values from the $offset field in each row of the result set from the database query. * * @param integer $offset The row offset to use to build the result array. * * @return mixed The return value or null if the query failed. * * @since 1.0 * @throws \RuntimeException */ public function loadColumn($offset = 0) { $this->connect(); $array = []; // Execute the query and get the result set cursor. $this->execute(); // Get all of the rows from the result set as arrays. while ($row = $this->fetchArray()) { $array[] = $row[$offset]; } // Free up system resources and return. $this->freeResult(); return $array; } /** * Method to get the first row of the result set from the database query as an object. * * @param string $class The class name to use for the returned row object. * * @return mixed The return value or null if the query failed. * * @since 1.0 * @throws \RuntimeException */ public function loadObject($class = \stdClass::class) { $this->connect(); $ret = null; if ($this->statement) { $fetchMode = $class === \stdClass::class ? FetchMode::STANDARD_OBJECT : FetchMode::CUSTOM_OBJECT; // PDO doesn't allow extra arguments for \PDO::FETCH_CLASS, so only forward the class for the custom object mode if ($fetchMode === FetchMode::STANDARD_OBJECT) { $this->statement->setFetchMode($fetchMode); } else { $this->statement->setFetchMode($fetchMode, $class); } } // Execute the query and get the result set cursor. $this->execute(); // Get the first row from the result set as an object of type $class. $object = $this->fetchObject(); if ($object) { $ret = $object; } // Free up system resources and return. $this->freeResult(); return $ret; } /** * Method to get an array of the result set rows from the database query where each row is an object. The array * of objects can optionally be keyed by a field name, but defaults to a sequential numeric array. * * NOTE: Choosing to key the result array by a non-unique field name can result in unwanted behavior and should be avoided. * * @param string $key The name of a field on which to key the result array. * @param string $class The class name to use for the returned row objects. * * @return mixed The return value or null if the query failed. * * @since 1.0 * @throws \RuntimeException */ public function loadObjectList($key = '', $class = \stdClass::class) { $this->connect(); $array = []; if ($this->statement) { $fetchMode = $class === \stdClass::class ? FetchMode::STANDARD_OBJECT : FetchMode::CUSTOM_OBJECT; // PDO doesn't allow extra arguments for \PDO::FETCH_CLASS, so only forward the class for the custom object mode if ($fetchMode === FetchMode::STANDARD_OBJECT) { $this->statement->setFetchMode($fetchMode); } else { $this->statement->setFetchMode($fetchMode, $class); } } // Execute the query and get the result set cursor. $this->execute(); // Get all of the rows from the result set as objects of type $class. while ($row = $this->fetchObject()) { if ($key) { $array[$row->$key] = $row; } else { $array[] = $row; } } // Free up system resources and return. $this->freeResult(); return $array; } /** * Method to get the first field of the first row of the result set from the database query. * * @return mixed The return value or null if the query failed. * * @since 1.0 * @throws \RuntimeException */ public function loadResult() { $this->connect(); $ret = null; // Execute the query and get the result set cursor. $this->execute(); // Get the first row from the result set as an array. $row = $this->fetchArray(); if ($row) { $ret = $row[0]; } // Free up system resources and return. $this->freeResult(); return $ret; } /** * Method to get the first row of the result set from the database query as an array. * * Columns are indexed numerically so the first column in the result set would be accessible via $row[0], etc. * * @return mixed The return value or null if the query failed. * * @since 1.0 * @throws \RuntimeException */ public function loadRow() { $this->connect(); $ret = null; // Execute the query and get the result set cursor. $this->execute(); // Get the first row from the result set as an array. $row = $this->fetchArray(); if ($row) { $ret = $row; } // Free up system resources and return. $this->freeResult(); return $ret; } /** * Method to get an array of the result set rows from the database query where each row is an array. The array * of objects can optionally be keyed by a field offset, but defaults to a sequential numeric array. * * NOTE: Choosing to key the result array by a non-unique field can result in unwanted behavior and should be avoided. * * @param string $key The name of a field on which to key the result array. * * @return array An array of results. * * @since 1.0 * @throws \RuntimeException */ public function loadRowList($key = null) { $this->connect(); $array = []; // Execute the query and get the result set cursor. $this->execute(); // Get all of the rows from the result set as arrays. while ($row = $this->fetchArray()) { if ($key !== null) { $array[$row[$key]] = $row; } else { $array[] = $row; } } // Free up system resources and return. $this->freeResult(); return $array; } /** * Prepares a SQL statement for execution * * @param string $query The SQL query to be prepared. * * @return StatementInterface * * @since 2.0.0 * @throws PrepareStatementFailureException */ abstract protected function prepareStatement(string $query): StatementInterface; /** * Alias for quote method * * @param array|string $text A string or an array of strings to quote. * @param boolean $escape True (default) to escape the string, false to leave it unchanged. * * @return string The quoted input string. * * @since 1.0 */ public function q($text, $escape = true) { return $this->quote($text, $escape); } /** * Quotes and optionally escapes a string to database requirements for use in database queries. * * @param array|string $text A string or an array of strings to quote. * @param boolean $escape True (default) to escape the string, false to leave it unchanged. * * @return array|string The quoted input string. * * @since 1.0 */ public function quote($text, $escape = true) { if (\is_array($text)) { foreach ($text as $k => $v) { $text[$k] = $this->quote($v, $escape); } return $text; } return '\'' . ($escape ? $this->escape($text) : $text) . '\''; } /** * Quotes a binary string to database requirements for use in database queries. * * @param string $data A binary string to quote. * * @return string The binary quoted input string. * * @since 1.7.0 */ public function quoteBinary($data) { // SQL standard syntax for hexadecimal literals return "X'" . bin2hex($data) . "'"; } /** * Replace special placeholder representing binary field with the original string. * * @param string|resource $data Encoded string or resource. * * @return string The original string. * * @since 1.7.0 */ public function decodeBinary($data) { return $data; } /** * Alias for quoteName method * * @param array|string $name The identifier name to wrap in quotes, or an array of identifier names to wrap in quotes. * Each type supports dot-notation name. * @param array|string $as The AS query part associated to $name. It can be string or array, in latter case it has to be * same length of $name; if is null there will not be any AS part for string or array element. * * @return array|string The quote wrapped name, same type of $name. * * @since 1.0 */ public function qn($name, $as = null) { return $this->quoteName($name, $as); } /** * Wrap an SQL statement identifier name such as column, table or database names in quotes to prevent injection * risks and reserved word conflicts. * * @param array|string $name The identifier name to wrap in quotes, or an array of identifier names to wrap in quotes. * Each type supports dot-notation name. * @param array|string $as The AS query part associated to $name. It can be string or array, in latter case it has to be * same length of $name; if is null there will not be any AS part for string or array element. * * @return array|string The quote wrapped name, same type of $name. * * @since 1.0 */ public function quoteName($name, $as = null) { if (\is_string($name)) { $name = $this->quoteNameString($name); if ($as !== null) { $name .= ' AS ' . $this->quoteNameString($as, true); } return $name; } $fin = []; if ($as === null) { foreach ($name as $str) { $fin[] = $this->quoteName($str); } } elseif (\is_array($name) && (\count($name) === \count($as))) { $count = \count($name); for ($i = 0; $i < $count; $i++) { $fin[] = $this->quoteName($name[$i], $as[$i]); } } return $fin; } /** * Quote string coming from quoteName call. * * @param string $name Identifier name to be quoted. * @param boolean $asSinglePart Treat the name as a single part of the identifier. * * @return string Quoted identifier string. * * @since 1.7.0 */ protected function quoteNameString($name, $asSinglePart = false) { $q = $this->nameQuote . $this->nameQuote; // Double quote reserved keyword $name = str_replace($q[1], $q[1] . $q[1], $name); if ($asSinglePart) { return $q[0] . $name . $q[1]; } return $q[0] . str_replace('.', "$q[1].$q[0]", $name) . $q[1]; } /** * This function replaces a string identifier with the configured table prefix. * * @param string $sql The SQL statement to prepare. * @param string $prefix The table prefix. * * @return string The processed SQL statement. * * @since 1.0 */ public function replacePrefix($sql, $prefix = '#__') { $escaped = false; $startPos = 0; $quoteChar = ''; $literal = ''; $sql = trim($sql); $n = \strlen($sql); while ($startPos < $n) { $ip = strpos($sql, $prefix, $startPos); if ($ip === false) { break; } $j = strpos($sql, "'", $startPos); $k = strpos($sql, '"', $startPos); if (($k !== false) && (($k < $j) || ($j === false))) { $quoteChar = '"'; $j = $k; } else { $quoteChar = "'"; } if ($j === false) { $j = $n; } $literal .= str_replace($prefix, $this->tablePrefix, substr($sql, $startPos, $j - $startPos)); $startPos = $j; $j = $startPos + 1; if ($j >= $n) { break; } // Quote comes first, find end of quote while (true) { $k = strpos($sql, $quoteChar, $j); $escaped = false; if ($k === false) { break; } $l = $k - 1; while ($l >= 0 && $sql[$l] === '\\') { $l--; $escaped = !$escaped; } if ($escaped) { $j = $k + 1; continue; } break; } if ($k === false) { // Error in the query - no end quote; ignore it break; } $literal .= substr($sql, $startPos, $k - $startPos + 1); $startPos = $k + 1; } if ($startPos < $n) { $literal .= substr($sql, $startPos, $n - $startPos); } return $literal; } /** * Get the query monitor. * * @return QueryMonitorInterface|null The query monitor or null if not set. * * @since 2.0.0 */ public function getMonitor() { return $this->monitor; } /** * Set a query monitor. * * @param QueryMonitorInterface|null $monitor The query monitor. * * @return $this * * @since 2.0.0 */ public function setMonitor(?QueryMonitorInterface $monitor = null) { $this->monitor = $monitor; return $this; } /** * Sets the SQL statement string for later execution. * * @param string|QueryInterface $query The SQL statement to set either as a Query object or a string. * @param integer $offset The affected row offset to set. {@deprecated 3.0 Use LimitableInterface::setLimit() instead} * @param integer $limit The maximum affected rows to set. {@deprecated 3.0 Use LimitableInterface::setLimit() instead} * * @return $this * * @since 1.0 * @throws \InvalidArgumentException */ public function setQuery($query, $offset = 0, $limit = 0) { $this->connect(); $this->freeResult(); if (\is_string($query)) { // Allows taking advantage of bound variables in a direct query: $query = $this->createQuery()->setQuery($query); } elseif (!($query instanceof QueryInterface)) { throw new \InvalidArgumentException( sprintf( 'A query must be a string or a %s instance, a %s was given.', QueryInterface::class, \gettype($query) === 'object' ? (\get_class($query) . ' instance') : \gettype($query) ) ); } if ($offset > 0 || $limit > 0) { trigger_deprecation( 'joomla/database', '2.0.0', 'The "$offset" and "$limit" arguments of %s() are deprecated and will be removed in 3.0, use %s::setLimit() instead.', __METHOD__, QueryInterface::class ); } // Check for values set on the query object and use those if there is a zero value passed here if ($limit === 0 && $query->limit > 0) { $limit = $query->limit; } if ($offset === 0 && $query->offset > 0) { $offset = $query->offset; } $query->setLimit($limit, $offset); $sql = $this->replacePrefix((string) $query); $this->statement = $this->prepareStatement($sql); $this->sql = $query; $this->limit = (int) max(0, $limit); $this->offset = (int) max(0, $offset); return $this; } /** * Set the connection to use UTF-8 character encoding. * * @return boolean True on success. * * @since 1.0 */ abstract public function setUtf(); /** * Method to truncate a table. * * @param string $table The table to truncate * * @return void * * @since 1.0 * @throws \RuntimeException */ public function truncateTable($table) { $this->setQuery('TRUNCATE TABLE ' . $this->quoteName($table)) ->execute(); } /** * Updates a row in a table based on an object's properties. * * @param string $table The name of the database table to update. * @param object $object A reference to an object whose public properties match the table fields. * @param array|string $key The name of the primary key. * @param boolean $nulls True to update null fields or false to ignore them. * * @return boolean True on success. * * @since 1.0 * @throws \RuntimeException */ public function updateObject($table, &$object, $key, $nulls = false) { $fields = []; $where = []; $tableColumns = $this->getTableColumns($table); if (\is_string($key)) { $key = [$key]; } if (\is_object($key)) { $key = (array) $key; } // Create the base update statement. $statement = 'UPDATE ' . $this->quoteName($table) . ' SET %s WHERE %s'; // Iterate over the object variables to build the query fields/value pairs. foreach (get_object_vars($object) as $k => $v) { // Skip columns that don't exist in the table. if (!\array_key_exists($k, $tableColumns)) { continue; } // Only process scalars that are not internal fields. if (\is_array($v) || \is_object($v) || $k[0] === '_') { continue; } // Set the primary key to the WHERE clause instead of a field to update. if (\in_array($k, $key, true)) { $where[] = $this->quoteName($k) . ($v === null ? ' IS NULL' : ' = ' . $this->quote($v)); continue; } // Prepare and sanitize the fields and values for the database query. if ($v === null) { // If the value is null and we want to update nulls then set it. if ($nulls) { $val = 'NULL'; } else { // If the value is null and we do not want to update nulls then ignore this field. continue; } } else { // The field is not null so we prep it for update. $val = $this->quote($v); } // Add the field to be updated. $fields[] = $this->quoteName($k) . '=' . $val; } // We don't have any fields to update. if (empty($fields)) { return true; } // Set the query and execute the update. $this->setQuery(sprintf($statement, implode(',', $fields), implode(' AND ', $where)))->execute(); return true; } /** * Extract pure host name (or IP address) and port or socket from host name option. * * @param string $host Host given in options used to configure the connection. * @param integer|null $port Port given in options used to configure the connection, null if none. * @param string|null $socket Socket given in options used to configure the connection, null if none. * @param integer $defaultPort The default port number to be used if no port is given. * @param boolean $ipv6SquareBrackets True if database connector uses ipv6 address with square brackets, false if not. * * @return array Array with host, port and socket. * * @since 3.3.0 */ protected function extractHostPortSocket(string $host, ?int $port, ?string $socket, int $defaultPort, bool $ipv6SquareBrackets = true): array { $portNew = $port ?? $defaultPort; if (preg_match('/^unix:(?P[^:]+)$/', $host, $matches)) { // UNIX socket URI, e.g. 'unix:/path/to/unix/socket.sock' $host = null; $socket = $matches['socket']; $port = null; } elseif ( preg_match( '/^(?P((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?))(:(?P.+))?$/', $host, $matches ) ) { // It's an IPv4 address with or without port $host = $matches['host']; if (!empty($matches['port'])) { $portNew = $matches['port']; } } elseif (preg_match('/^(?P\[.*\])(:(?P.+))?$/', $host, $matches)) { // We assume square-bracketed IPv6 address with or without port, e.g. [fe80:102::2%eth1]:3306 $host = $ipv6SquareBrackets ? $matches['host'] : rtrim(ltrim($matches['host'], '['), ']'); if (!empty($matches['port'])) { $portNew = $matches['port']; } } elseif (preg_match('/^(?P(\w+:\/{2,3})?[a-z0-9\.\-]+)(:(?P[^:]+))?$/i', $host, $matches)) { // Named host (e.g example.com or localhost) with or without port $host = $matches['host']; if (!empty($matches['port'])) { $portNew = $matches['port']; } } elseif (preg_match('/^:(?P[^:]+)$/', $host, $matches)) { // Empty host, just port, e.g. ':3306' $host = 'localhost'; $portNew = $matches['port']; } // ... else we assume normal (naked) IPv6 address, so host and port stay as they are or default // Get the port number or socket name if (is_numeric($portNew)) { $port = (int) $portNew; } else { $socket = $portNew; } return [$host, $port, $socket]; } } An Error Occurred: Whoops, looks like something went wrong.

Sorry, there was a problem we could not recover from.

The server returned a "500 - Whoops, looks like something went wrong."

Help me resolve this