5 use Doctrine\DBAL\Connection;
6 use Doctrine\DBAL\Driver\Exception\NoIdentityValue;
7 use Doctrine\DBAL\DriverManager;
8 use Doctrine\DBAL\Exception\DriverException;
9 use Doctrine\DBAL\Result;
16 use Elgg\Traits\Loggable;
31 const DELAYED_QUERY =
'q';
32 const DELAYED_HANDLER =
'h';
42 protected array $connections = [];
47 protected int $query_count = 0;
56 protected array $delayed_queries = [];
71 $this->resetConnections($db_config);
82 $this->closeConnections();
85 $this->table_prefix =
$config->getTablePrefix();
86 $this->query_cache->enable();
87 $this->query_cache->clear();
99 foreach ($this->connections as $connection) {
100 $connection->close();
103 $this->connections = [];
114 if (isset($this->connections[
$type])) {
115 return $this->connections[
$type];
116 }
else if (isset($this->connections[
'readwrite'])) {
117 return $this->connections[
'readwrite'];
120 $this->setupConnections();
122 return $this->getConnection(
$type);
134 if ($this->db_config->isDatabaseSplit()) {
135 $this->connect(
'read');
136 $this->connect(
'write');
138 $this->connect(
'readwrite');
153 $conf = $this->db_config->getConnectionConfig(
$type);
156 'dbname' => $conf[
'database'],
157 'user' => $conf[
'user'],
158 'password' => $conf[
'password'],
159 'host' => $conf[
'host'],
160 'port' => $conf[
'port'],
161 'charset' => $conf[
'encoding'],
162 'driver' =>
'pdo_mysql',
166 $this->connections[
$type] = DriverManager::getConnection(
$params);
169 $sub_query =
"SELECT REPLACE(@@SESSION.sql_mode, 'ONLY_FULL_GROUP_BY', '')";
170 $this->connections[
$type]->executeStatement(
"SET SESSION sql_mode=($sub_query);");
171 }
catch (\Exception $e) {
173 $this->log(LogLevel::ERROR, $e);
175 if ($e->getCode() == 1102 || $e->getCode() == 1049) {
176 $msg =
"Elgg couldn't select the database '{$conf['database']}'. Please check that the database is created and you have access to it.";
178 $msg =
"Elgg couldn't connect to the database using the given credentials. Check the settings file.";
181 throw new DatabaseException($msg);
201 return $this->getResults(
$query, $callback,
false);
217 return $this->getResults(
$query, $callback,
true);
234 $this->getLogger()->info(
"DB insert query {$sql} (params: " . print_r(
$params,
true) .
')');
236 $this->query_cache->clear();
238 $this->executeQuery(
$query);
241 return (
int)
$query->getConnection()->lastInsertId();
242 }
catch (DriverException $e) {
243 if ($e->getPrevious() instanceof NoIdentityValue) {
265 $this->getLogger()->info(
"DB update query {$sql} (params: " . print_r(
$params,
true) .
')');
267 $this->query_cache->clear();
270 if (!$get_num_rows) {
290 $this->getLogger()->info(
"DB delete query {$sql} (params: " . print_r(
$params,
true) .
')');
292 $this->query_cache->clear();
310 if (is_string($callback)) {
314 if (is_object($callback)) {
315 return spl_object_hash($callback) .
'::__invoke';
318 if (is_array($callback)) {
319 if (is_string($callback[0])) {
320 return "{$callback[0]}::{$callback[1]}";
323 return spl_object_hash($callback[0]) .
"::{$callback[1]}";
349 $extras = (int) $single .
'|';
351 if (!is_callable($callback)) {
355 $extras .= $this->fingerprintCallback($callback);
358 $hash = $this->getCacheHash($sql,
$params, $extras);
360 $cached_results = $this->query_cache->load($hash);
361 if (isset($cached_results)) {
362 return $cached_results;
365 $this->getLogger()->info(
"DB select query {$sql} (params: " . print_r(
$params,
true) .
')');
369 $stmt = $this->executeQuery(
$query);
371 while ($row = $stmt->fetchAssociative()) {
372 $row_obj = (object) $row;
374 $row_obj = call_user_func($callback, $row_obj);
381 $return[] = $row_obj;
385 $this->query_cache->save($hash, $return);
406 return $query->executeQuery();
408 return $query->executeStatement();
411 }
catch (\Exception $e) {
413 $ex->setParameters(
$query->getParameters());
414 $ex->setQuery(
$query->getSQL());
433 $query_id = $sql .
'|';
435 $query_id .= serialize(
$params) .
'|';
438 $query_id .= $extras;
441 return md5($query_id);
457 $this->query_count++;
459 $timer_key = preg_replace(
'~\\s+~',
' ', trim($sql .
'|' . serialize(
$params)));
462 $stop_timer =
function() use ($timer_key) {
463 $this->
endTimer([
'SQL', $timer_key]);
468 }
catch (\Exception $e) {
496 $stmt = $this->executeQuery(
$query);
498 if (is_callable($callback)) {
499 call_user_func($callback, $stmt);
501 }
catch (\Throwable $t) {
503 $this->getLogger()->error($t);
509 $this->delayed_queries[] = [
510 self::DELAYED_QUERY =>
$query,
511 self::DELAYED_HANDLER => $callback,
523 foreach ($this->delayed_queries as $set) {
524 $query = $set[self::DELAYED_QUERY];
525 $handler = $set[self::DELAYED_HANDLER];
528 $stmt = $this->executeQuery(
$query);
533 }
catch (\Throwable $t) {
535 $this->getLogger()->error($t);
539 $this->delayed_queries = [];
548 return $this->query_count;
559 return $this->getConnection(
$type)->getServerVersion();
570 return $this->getConnection(
$type)->getDatabasePlatform() instanceof \Doctrine\DBAL\Platforms\MariaDBPlatform;
583 return $this->getConnection(
$type)->getDatabasePlatform() instanceof \Doctrine\DBAL\Platforms\MySQLPlatform;
595 if (
$name ===
'prefix') {
596 return $this->table_prefix;
if(! $user||! $user->canDelete()) $name
$params
Saves global plugin settings.
return[ 'admin/delete_admin_notices'=>['access'=> 'admin'], 'admin/menu/save'=>['access'=> 'admin'], 'admin/plugins/activate'=>['access'=> 'admin'], 'admin/plugins/activate_all'=>['access'=> 'admin'], 'admin/plugins/deactivate'=>['access'=> 'admin'], 'admin/plugins/deactivate_all'=>['access'=> 'admin'], 'admin/plugins/set_priority'=>['access'=> 'admin'], 'admin/security/security_txt'=>['access'=> 'admin'], 'admin/security/settings'=>['access'=> 'admin'], 'admin/security/regenerate_site_secret'=>['access'=> 'admin'], 'admin/site/cache/invalidate'=>['access'=> 'admin'], 'admin/site/flush_cache'=>['access'=> 'admin'], 'admin/site/icons'=>['access'=> 'admin'], 'admin/site/set_maintenance_mode'=>['access'=> 'admin'], 'admin/site/set_robots'=>['access'=> 'admin'], 'admin/site/theme'=>['access'=> 'admin'], 'admin/site/unlock_upgrade'=>['access'=> 'admin'], 'admin/site/settings'=>['access'=> 'admin'], 'admin/upgrade'=>['access'=> 'admin'], 'admin/upgrade/reset'=>['access'=> 'admin'], 'admin/user/ban'=>['access'=> 'admin'], 'admin/user/bulk/ban'=>['access'=> 'admin'], 'admin/user/bulk/delete'=>['access'=> 'admin'], 'admin/user/bulk/unban'=>['access'=> 'admin'], 'admin/user/bulk/validate'=>['access'=> 'admin'], 'admin/user/change_email'=>['access'=> 'admin'], 'admin/user/delete'=>['access'=> 'admin'], 'admin/user/login_as'=>['access'=> 'admin'], 'admin/user/logout_as'=>[], 'admin/user/makeadmin'=>['access'=> 'admin'], 'admin/user/resetpassword'=>['access'=> 'admin'], 'admin/user/removeadmin'=>['access'=> 'admin'], 'admin/user/unban'=>['access'=> 'admin'], 'admin/user/validate'=>['access'=> 'admin'], 'annotation/delete'=>[], 'avatar/upload'=>[], 'comment/save'=>[], 'diagnostics/download'=>['access'=> 'admin'], 'entity/chooserestoredestination'=>[], 'entity/delete'=>[], 'entity/mute'=>[], 'entity/restore'=>[], 'entity/subscribe'=>[], 'entity/trash'=>[], 'entity/unmute'=>[], 'entity/unsubscribe'=>[], 'login'=>['access'=> 'logged_out'], 'logout'=>[], 'notifications/mute'=>['access'=> 'public'], 'plugins/settings/remove'=>['access'=> 'admin'], 'plugins/settings/save'=>['access'=> 'admin'], 'plugins/usersettings/save'=>[], 'register'=>['access'=> 'logged_out', 'middleware'=>[\Elgg\Router\Middleware\RegistrationAllowedGatekeeper::class,],], 'river/delete'=>[], 'settings/notifications'=>[], 'settings/notifications/subscriptions'=>[], 'user/changepassword'=>['access'=> 'public'], 'user/requestnewpassword'=>['access'=> 'public'], 'useradd'=>['access'=> 'admin'], 'usersettings/save'=>[], 'widgets/add'=>[], 'widgets/delete'=>[], 'widgets/move'=>[], 'widgets/save'=>[],]
foreach( $paths as $path)
Load, boot, and implement a front controller for an Elgg application.
Volatile cache for select queries.
Database configuration service.
Database abstraction query builder.
insertData(QueryBuilder $query)
Insert a row into the database.
getData(QueryBuilder $query, $callback=null)
Retrieve rows from the database.
executeQuery(QueryBuilder $query)
Execute a query.
connect(string $type='readwrite')
Establish a connection to the database server.
getResults(QueryBuilder $query, $callback=null, bool $single=false)
Handles queries that return results, running the results through a an optional callback function.
isMySQL(string $type=DbConfig::READ_WRITE)
Is the database MySQL.
getCacheHash(string $sql, array $params=[], string $extras='')
Returns a hashed key for storage in the cache.
registerDelayedQuery(QueryBuilder $query, $callback=null)
Queue a query for execution upon shutdown.
__set($name, $value)
Handle magic property writes.
trackQuery(QueryBuilder $query, callable $callback)
Tracks the query count and timers for a given query.
getQueryCount()
Get the number of queries made to the database.
getConnection(string $type)
Gets (if required, also creates) a DB connection.
deleteData(QueryBuilder $query)
Delete data from the database.
setupConnections()
Establish database connections.
resetConnections(DbConfig $config)
Reset the connections with new credentials.
getDataRow(QueryBuilder $query, $callback=null)
Retrieve a single row from the database.
closeConnections()
Close all database connections.
fingerprintCallback($callback)
Get a string that uniquely identifies a callback during the current request.
isMariaDB(string $type=DbConfig::READ_WRITE)
Is the database MariaDB.
__get($name)
Handle magic property reads.
updateData(QueryBuilder $query, bool $get_num_rows=false)
Update the database.
executeDelayedQueries()
Trigger all queries that were registered as "delayed" queries.
getServerVersion(string $type=DbConfig::READ_WRITE)
Get the server version number.
__construct(DbConfig $db_config, protected QueryCache $query_cache, protected Config $config)
Constructor.
A generic parent class for database exceptions.
Exception thrown if an error which can only be found on runtime occurs.
Result of a single BatchUpgrade run.
$config
Advanced site settings, debugging section.
_elgg_services()
Get the global service provider.
endTimer(array $keys)
Ends the timer (when enabled)
trait Profilable
Make an object accept a timer.
beginTimer(array $keys)
Start the timer (when enabled)
if(parse_url(elgg_get_site_url(), PHP_URL_PATH) !=='/') if(file_exists(elgg_get_root_path() . 'robots.txt'))
Set robots.txt.