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])) {
116 return $this->connections[
$type];
117 }
elseif (isset($this->connections[DbConfig::READ_WRITE])) {
119 return $this->connections[DbConfig::READ_WRITE];
120 }
elseif (isset($this->connections[DbConfig::READ])) {
122 return $this->connections[DbConfig::READ];
125 $this->setupConnections();
127 return $this->getConnection(
$type);
139 if ($this->db_config->isDatabaseSplit()) {
140 $this->connect(DbConfig::READ);
141 $this->connect(DbConfig::WRITE);
143 $this->connect(DbConfig::READ_WRITE);
158 $conf = $this->db_config->getConnectionConfig(
$type);
161 'dbname' => $conf[
'database'],
162 'user' => $conf[
'user'],
163 'password' => $conf[
'password'],
164 'host' => $conf[
'host'],
165 'port' => $conf[
'port'],
166 'charset' => $conf[
'encoding'],
167 'driver' =>
'pdo_mysql',
171 $this->connections[
$type] = DriverManager::getConnection(
$params);
174 $sub_query =
"SELECT REPLACE(@@SESSION.sql_mode, 'ONLY_FULL_GROUP_BY', '')";
175 $this->connections[
$type]->executeStatement(
"SET SESSION sql_mode=($sub_query);");
176 }
catch (\Exception $e) {
178 $this->log(LogLevel::ERROR, $e);
180 if ($e->getCode() == 1102 || $e->getCode() == 1049) {
181 $msg =
"Elgg couldn't select the database '{$conf['database']}'. Please check that the database is created and you have access to it.";
183 $msg =
"Elgg couldn't connect to the database using the given credentials. Check the settings file.";
186 throw new DatabaseException($msg);
206 return $this->getResults(
$query, $callback,
false);
222 return $this->getResults(
$query, $callback,
true);
239 $this->getLogger()->info(
"DB insert query {$sql} (params: " . print_r(
$params,
true) .
')');
241 $this->query_cache->clear();
243 $this->executeQuery(
$query);
246 return (
int)
$query->getConnection()->lastInsertId();
247 }
catch (DriverException $e) {
248 if ($e->getPrevious() instanceof NoIdentityValue) {
270 $this->getLogger()->info(
"DB update query {$sql} (params: " . print_r(
$params,
true) .
')');
272 $this->query_cache->clear();
275 if (!$get_num_rows) {
295 $this->getLogger()->info(
"DB delete query {$sql} (params: " . print_r(
$params,
true) .
')');
297 $this->query_cache->clear();
315 if (is_string($callback)) {
319 if (is_object($callback)) {
320 return spl_object_hash($callback) .
'::__invoke';
323 if (is_array($callback)) {
324 if (is_string($callback[0])) {
325 return "{$callback[0]}::{$callback[1]}";
328 return spl_object_hash($callback[0]) .
"::{$callback[1]}";
354 $extras = (int) $single .
'|';
356 if (!is_callable($callback)) {
360 $extras .= $this->fingerprintCallback($callback);
363 $hash = $this->getCacheHash($sql,
$params, $extras);
365 $cached_results = $this->query_cache->load($hash);
366 if (isset($cached_results)) {
367 return $cached_results;
370 $this->getLogger()->info(
"DB select query {$sql} (params: " . print_r(
$params,
true) .
')');
374 $stmt = $this->executeQuery(
$query);
376 while ($row = $stmt->fetchAssociative()) {
377 $row_obj = (object) $row;
379 $row_obj = call_user_func($callback, $row_obj);
386 $return[] = $row_obj;
390 $this->query_cache->save($hash, $return);
411 return $query->executeQuery();
413 return $query->executeStatement();
416 }
catch (\Exception $e) {
418 $ex->setParameters(
$query->getParameters());
419 $ex->setQuery(
$query->getSQL());
438 $query_id = $sql .
'|';
440 $query_id .= serialize(
$params) .
'|';
443 $query_id .= $extras;
446 return md5($query_id);
461 if ($this->config->db_enable_query_logging) {
462 $this->getLogger()->notice($sql, [
'params' =>
$params]);
465 $this->query_count++;
467 $timer_key = preg_replace(
'~\\s+~',
' ', trim($sql .
'|' . serialize(
$params)));
470 $stop_timer =
function() use ($timer_key) {
471 $this->
endTimer([
'SQL', $timer_key]);
476 }
catch (\Exception $e) {
504 $stmt = $this->executeQuery(
$query);
506 if (is_callable($callback)) {
507 call_user_func($callback, $stmt);
509 }
catch (\Throwable $t) {
511 $this->getLogger()->error($t);
517 $this->delayed_queries[] = [
518 self::DELAYED_QUERY =>
$query,
519 self::DELAYED_HANDLER => $callback,
531 foreach ($this->delayed_queries as $set) {
532 $query = $set[self::DELAYED_QUERY];
533 $handler = $set[self::DELAYED_HANDLER];
536 $stmt = $this->executeQuery(
$query);
541 }
catch (\Throwable $t) {
543 $this->getLogger()->error($t);
547 $this->delayed_queries = [];
556 return $this->query_count;
567 return $this->getConnection(
$type)->getServerVersion();
578 return $this->getConnection(
$type)->getDatabasePlatform() instanceof \Doctrine\DBAL\Platforms\MariaDBPlatform;
591 return $this->getConnection(
$type)->getDatabasePlatform() instanceof \Doctrine\DBAL\Platforms\MySQLPlatform;
603 if (
$name ===
'prefix') {
604 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.
isMySQL(string $type=DbConfig::READ)
Is the database MySQL.
insertData(QueryBuilder $query)
Insert a row into the database.
getData(QueryBuilder $query, $callback=null)
Retrieve rows from the database.
getServerVersion(string $type=DbConfig::READ)
Get the server version number.
executeQuery(QueryBuilder $query)
Execute a query.
getResults(QueryBuilder $query, $callback=null, bool $single=false)
Handles queries that return results, running the results through an optional callback function.
getCacheHash(string $sql, array $params=[], string $extras='')
Returns a hashed key for storage in the cache.
isMariaDB(string $type=DbConfig::READ)
Is the database MariaDB.
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.
connect(string $type=DbConfig::READ_WRITE)
Establish a connection to the database server.
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.
__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.
__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.
if($item instanceof \ElggEntity) elseif($item instanceof \ElggRiverItem) elseif($item instanceof \ElggRelationship) elseif(is_callable([ $item, 'getType']))
_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.