Skip to content

Commit

Permalink
feat(db): private settings are merged into metadata
Browse files Browse the repository at this point in the history
fixes #13881
  • Loading branch information
Jeroen Dalsem authored and Jeroen Dalsem committed Aug 30, 2022
1 parent 04265e2 commit cb9951a
Show file tree
Hide file tree
Showing 94 changed files with 233 additions and 3,099 deletions.
2 changes: 1 addition & 1 deletion actions/admin/site/set_maintenance_mode.php
Expand Up @@ -10,7 +10,7 @@

$result = elgg_save_config('elgg_maintenance_mode', $mode);

$result = $result && $site->setPrivateSetting('elgg_maintenance_message', $message);
$result = $result && $site->setMetadata('elgg_maintenance_message', $message);

if (!$result) {
return elgg_error_response(elgg_echo('save:fail'));
Expand Down
2 changes: 1 addition & 1 deletion actions/admin/site/set_robots.php
Expand Up @@ -7,7 +7,7 @@

$site = elgg_get_site_entity();

if (!$site->setPrivateSetting('robots.txt', $content)) {
if (!$site->setMetadata('robots.txt', $content)) {
return elgg_error_response(elgg_echo('save:fail'));
}

Expand Down
12 changes: 6 additions & 6 deletions actions/settings/notifications.php
Expand Up @@ -32,9 +32,9 @@
// delayed email interval
if ((bool) elgg_get_config('enable_delayed_email')) {
$delayed_email_interval = get_input('delayed_email_interval');
if ($user->getPrivateSetting('delayed_email_interval') !== $delayed_email_interval) {
if ($user->delayed_email_interval !== $delayed_email_interval) {
// save new setting
$user->setPrivateSetting('delayed_email_interval', $delayed_email_interval);
$user->delayed_email_interval = $delayed_email_interval;

// update all queued notifications to the new interval
_elgg_services()->delayedEmailQueueTable->updateRecipientInterval($user->guid, $delayed_email_interval);
Expand All @@ -50,11 +50,11 @@
$end_date->setTime(23, 59, 59);
$end = $end_date->getTimestamp();

$user->setPrivateSetting('timed_muting_start', $start);
$user->setPrivateSetting('timed_muting_end', $end);
$user->timed_muting_start = $start;
$user->timed_muting_end = $end;
} else {
$user->removePrivateSetting('timed_muting_start');
$user->removePrivateSetting('timed_muting_end');
unset($user->timed_muting_start);
unset($user->timed_muting_end);
}

return elgg_ok_response('', elgg_echo('usersettings:notifications:save:ok'));
5 changes: 5 additions & 0 deletions docs/appendix/upgrade-notes/4.x-to-5.0.rst
Expand Up @@ -18,6 +18,11 @@ Faker

The faker library is no longer maintained by fzaninotto so we switched to a fork which is maintained by FakerPHP.

Private Settings
----------------

The concept of private settings has been removed from the system. All private settings have been copied to metadata. All related functions have been removed.

Javascript
----------

Expand Down
2 changes: 1 addition & 1 deletion docs/guides/database.rst
Expand Up @@ -116,7 +116,7 @@ By properties
~~~~~~~~~~~~~

You can fetch entities by their properties using ``elgg_get_entities``. Using specific parameters passed to ``$options``
array, you can retrieve entities by their attributes, metadata, annotations, private settings and relationships.
array, you can retrieve entities by their attributes, metadata, annotations and relationships.


Displaying entities
Expand Down
1 change: 0 additions & 1 deletion docs/guides/hooks-list.rst
Expand Up @@ -779,7 +779,6 @@ Search
'attributes' => [],
'metadata' => ['title', 'description'],
'annotations' => ['revision'],
'private_settings' => ['internal_notes'],
];
**search:fields, <entity_type>:<entity_subtype>**
Expand Down
5 changes: 2 additions & 3 deletions docs/guides/settings.rst
Expand Up @@ -11,7 +11,7 @@ You need to perform some extra steps if your plugin needs settings to be saved a
name of your plugin’s directory in the ``mod`` hierarchy
- Fill this file with the form elements you want to display together with :doc:`internationalised <i18n>` text labels
- Set the name attribute in your form components to ``params[`varname`]`` where ``varname`` is the name of the variable. These will be
saved as private settings attached to a plugin entity. So, if your variable is called ``params[myparameter]`` your plugin (which is also
saved as metadata attached to a plugin entity. So, if your variable is called ``params[myparameter]`` your plugin (which is also
passed to this view as ``$vars['entity']``) will be called ``$vars['entity']->myparameter``

An example ``settings.php`` would look like:
Expand Down Expand Up @@ -124,8 +124,7 @@ or for group settings:

.. warning::

Since plugin settings are saved as private settings only `scalar <https://www.php.net/manual/en/function.is-scalar.php>`_ values
are allowed, so no objects or arrays.
Plugin settings only supports `scalar <https://www.php.net/manual/en/function.is-scalar.php>`_ values, so no objects or arrays.

Default plugin (group|user) settings
------------------------------------
Expand Down
10 changes: 0 additions & 10 deletions elgg-config/settings.example.php
Expand Up @@ -228,16 +228,6 @@
*/
//$CONFIG->assetroot = "";

/**
* Plugins with more than the configured number of plugin settings won't be loaded into
* bootdata cache. This is done to prevent memory issues.
*
* If set to < 1 all plugins will be loaded into the bootdata cache
*
* Default: 40
*/
//$CONFIG->bootdata_plugin_settings_limit = 0;

/**
* Enable SendFile file serving
*
Expand Down
50 changes: 1 addition & 49 deletions engine/classes/Elgg/BootData.php
Expand Up @@ -25,11 +25,6 @@ class BootData {
*/
private $active_plugins;

/**
* @var array
*/
private $plugin_settings = [];

/**
* @var array
*/
Expand Down Expand Up @@ -63,7 +58,7 @@ public function populate(Config $config, Database $db, EntityTable $entities, Pl
return;
}

// find GUIDs with not too many private settings
// find GUIDs with not too many settings
$guids = array_map(function (\ElggPlugin $plugin) {
return $plugin->guid;
}, $this->active_plugins);
Expand All @@ -73,40 +68,6 @@ public function populate(Config $config, Database $db, EntityTable $entities, Pl
foreach ($guids as $guid) {
$this->plugin_metadata[$guid] = _elgg_services()->metadataCache->getEntityMetadata($guid);
}

// find plugin GUIDs with not too many settings
$limit = $config->bootdata_plugin_settings_limit;
if ($limit > 0) {
$qb = Select::fromTable('private_settings');
$qb->select('entity_guid')
->where($qb->compare('entity_guid', 'in', $guids, ELGG_VALUE_GUID))
->andWhere($qb->compare('name', 'not like', 'plugin:user_setting:%', ELGG_VALUE_STRING))
->groupBy('entity_guid')
->having("count(*) > {$limit}");

$unsuitable_guids = $db->getData($qb, function ($row) {
return (int) $row->entity_guid;
});

$guids = array_values($guids);
$guids = array_diff($guids, $unsuitable_guids);
}

if (!empty($guids)) {
// get the settings
$qb = Select::fromTable('private_settings');
$qb->select('entity_guid', 'name', 'value')
->where($qb->compare('entity_guid', 'in', $guids, ELGG_VALUE_GUID))
->andWhere($qb->compare('name', 'not like', 'plugin:user_setting:%', ELGG_VALUE_STRING));

$rows = $db->getData($qb);

// make sure we show all entities as loaded
$this->plugin_settings = array_fill_keys($guids, []);
foreach ($rows as $row) {
$this->plugin_settings[$row->entity_guid][$row->name] = $row->value;
}
}
}

/**
Expand All @@ -127,15 +88,6 @@ public function getActivePlugins() {
return $this->active_plugins;
}

/**
* Get the plugin settings (may not include all active plugins)
*
* @return array
*/
public function getPluginSettings() {
return $this->plugin_settings;
}

/**
* Get plugin metadata
*
Expand Down
4 changes: 0 additions & 4 deletions engine/classes/Elgg/BootService.php
Expand Up @@ -68,10 +68,6 @@ public function boot(InternalContainer $services) {
}
}

foreach ($data->getPluginSettings() as $guid => $entity_settings) {
$services->privateSettingsCache->save($guid, $entity_settings);
}

foreach ($data->getPluginMetadata() as $guid => $metadata) {
$services->dataCache->metadata->save($guid, $metadata);
}
Expand Down
3 changes: 1 addition & 2 deletions engine/classes/Elgg/Cache/DataCache.php
Expand Up @@ -4,10 +4,9 @@

/**
* Persistent data cache
* Used for caching entities, metadata and private settings
* Used for caching metadata
*
* @property-read CompositeCache $metadata
* @property-read CompositeCache $private_settings
*/
class DataCache extends CacheCollection {

Expand Down
97 changes: 0 additions & 97 deletions engine/classes/Elgg/Cache/PrivateSettingsCache.php

This file was deleted.

2 changes: 0 additions & 2 deletions engine/classes/Elgg/Config.php
Expand Up @@ -22,7 +22,6 @@
* @property int $authentication_failures_limit Number of allowed authentication failures
* @property bool $auto_disable_plugins Are unbootable plugins automatically disabled
* @property int $batch_run_time_in_secs Max time for a single upgrade loop
* @property int $bootdata_plugin_settings_limit Max amount of plugin settings to determine if plugin will be cached
* @property int $boot_cache_ttl Time to live for boot cache in seconds
* @property array $breadcrumbs
* @property string $cacheroot Path of cache storage with trailing "/"
Expand Down Expand Up @@ -191,7 +190,6 @@ class Config {
'auto_disable_plugins' => true,
'batch_run_time_in_secs' => 4,
'boot_cache_ttl' => 3600,
'bootdata_plugin_settings_limit' => 40,
'can_change_username' => false,
'class_loader_verify_file_existence' => true,
'comment_box_collapses' => true,
Expand Down
34 changes: 1 addition & 33 deletions engine/classes/Elgg/Database/Annotations.php
Expand Up @@ -6,7 +6,6 @@
use Elgg\Database\Clauses\AnnotationWhereClause;
use Elgg\Database\Clauses\EntityWhereClause;
use Elgg\Database\Clauses\MetadataWhereClause;
use Elgg\Database\Clauses\PrivateSettingWhereClause;
use Elgg\Database\Clauses\RelationshipWhereClause;
use Elgg\Exceptions\InvalidArgumentException;
use Elgg\Exceptions\InvalidParameterException;
Expand Down Expand Up @@ -45,7 +44,7 @@ public function count() {
*
* @param string $function Valid numeric function
* @param string $property Property name
* @param string $property_type 'attribute'|'metadata'|'annotation'|'private_setting'
* @param string $property_type 'attribute'|'metadata'|'annotation'
*
* @return int|float
* @throws InvalidParameterException
Expand Down Expand Up @@ -84,11 +83,6 @@ public function calculate($function, $property, $property_type = null) {
$alias = $qb->joinMetadataTable('n_table', 'entity_guid', $property);
$qb->select("{$function}({$alias}.value) AS calculation");
break;

case 'private_setting' :
$alias = $qb->joinPrivateSettingsTable('n_table', 'entity_guid', $property);
$qb->select("{$function}({$alias}.value) AS calculation");
break;
}

$qb = $this->buildQuery($qb);
Expand Down Expand Up @@ -207,7 +201,6 @@ protected function buildQuery(QueryBuilder $qb) {
$ands[] = $this->buildEntityWhereClause($qb);
$ands[] = $this->buildPairedMetadataClause($qb, $this->options->metadata_name_value_pairs, $this->options->metadata_name_value_pairs_operator);
$ands[] = $this->buildPairedMetadataClause($qb, $this->options->search_name_value_pairs, 'OR');
$ands[] = $this->buildPairedPrivateSettingsClause($qb, $this->options->private_setting_name_value_pairs, $this->options->private_setting_name_value_pairs_operator);
$ands[] = $this->buildPairedRelationshipClause($qb, $this->options->relationship_pairs);

$ands = $qb->merge($ands);
Expand Down Expand Up @@ -282,31 +275,6 @@ protected function buildPairedMetadataClause(QueryBuilder $qb, $clauses, $boolea
return $qb->merge($parts, $boolean);
}

/**
* Process private settings name value pairs
* Joins private settings table on entity_guid in the annotations table and applies where clauses
*
* @param QueryBuilder $qb Query builder
* @param PrivateSettingWhereClause[] $clauses Where clauses
* @param string $boolean Merge boolean
*
* @return CompositeExpression|string
*/
protected function buildPairedPrivateSettingsClause(QueryBuilder $qb, $clauses, $boolean = 'AND') {
$parts = [];

foreach ($clauses as $clause) {
if (strtoupper($boolean) === 'OR' || count($clauses) > 1) {
$joined_alias = $qb->joinPrivateSettingsTable('n_table', 'entity_guid');
} else {
$joined_alias = $qb->joinPrivateSettingsTable('n_table', 'entity_guid', $clause->names);
}
$parts[] = $clause->prepare($qb, $joined_alias);
}

return $qb->merge($parts, $boolean);
}

/**
* Process relationship name value pairs
* Joins relationship table on entity_guid in the annotations table and applies where clauses
Expand Down

0 comments on commit cb9951a

Please sign in to comment.