Skip to content

Commit

Permalink
Merge pull request #14216 from jdalsem/activity-last-action
Browse files Browse the repository at this point in the history
feat(plugins): it is now allowed to set arrays as private settings
  • Loading branch information
jeabakker committed Nov 21, 2022
2 parents be384e5 + 432b4da commit d42a67a
Show file tree
Hide file tree
Showing 21 changed files with 64 additions and 53 deletions.
2 changes: 1 addition & 1 deletion actions/register.php
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@
try {
// allow plugins to respond to self registration
// note: To catch all new users, even those created by an admin,
// register for the create, user event instead.
// register for the create:after, user event instead.
// only passing vars that aren't in ElggUser.
$params = $request->getParams();
$params['user'] = $new_user;
Expand Down
1 change: 1 addition & 0 deletions docs/appendix/upgrade-notes/4.x-to-5.0.rst
Original file line number Diff line number Diff line change
Expand Up @@ -382,6 +382,7 @@ Removed events

* ``access:collections:addcollection, collection`` use the ``create, access_collection`` sequence
* ``access:collections:deletecollection, collection`` use the ``delete, access_collection`` sequence
* ``create, <object|group|user|site>`` use the ``create:before, <type>`` or ``create:after, <type>`` event
* ``prepare, breadcrumbs`` use ``register, menu:breadcrumbs``
* ``widget_settings, <widget_handler>``

Expand Down
2 changes: 1 addition & 1 deletion docs/design/events.rst
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ Example:
// Register the function myPlugin_handle_create_object() to handle the
// create object event with priority 400.
elgg_register_event_handler('create', 'object', 'myPlugin_handle_create_object', 400);
elgg_register_event_handler('create:after', 'object', 'myPlugin_handle_create_object', 400);
.. warning::

Expand Down
7 changes: 5 additions & 2 deletions docs/guides/events-list.rst
Original file line number Diff line number Diff line change
Expand Up @@ -360,9 +360,12 @@ Entity events

**comments:count, <entity_type>** |results|
Return the number of comments on ``$params['entity']``.

**create:after, <entity type>**
Triggered for user, group, object, and site entities after creation.

**create, <entity type>**
Triggered for user, group, object, and site entities after creation. Return false to delete entity.
**create:before, <entity type>**
Triggered for user, group, object, and site entities before creation. Return false to prevent creating the entity.

**delete, <entity type>**
Triggered before entity deletion.
Expand Down
2 changes: 1 addition & 1 deletion docs/guides/plugins/bootstrap.rst
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ Returns Elgg's public DI container. This can be helpfull if you wish to register
.. code-block:: php
$events = $this->elgg()->events;
$events->registerHandler('create', 'object', MyCustomObjectHandler::class);
$events->registerHandler('create:after', 'object', MyCustomObjectHandler::class);
->plugin()
----------
Expand Down
3 changes: 0 additions & 3 deletions docs/guides/settings.rst
Original file line number Diff line number Diff line change
Expand Up @@ -122,9 +122,6 @@ or for group settings:

The ``$plugin_id`` needs to be provided when setting plugin (user)settings.

.. warning::

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
2 changes: 1 addition & 1 deletion docs/guides/widgets.rst
Original file line number Diff line number Diff line change
Expand Up @@ -226,6 +226,6 @@ To have widgets be created you need to register the following event:

.. code-block:: php
elgg_register_event_handler('create', 'object', 'Elgg\Widgets\CreateDefaultWidgetsHandler');
elgg_register_event_handler('create:after', 'object', 'Elgg\Widgets\CreateDefaultWidgetsHandler');
When an object triggers an event that matches the event, entity\_type, and entity\_subtype parameters passed, Elgg core will look for default widgets that match the widget\_context and will copy them to that object's owner\_guid and container\_guid. All widget settings will also be copied.
2 changes: 1 addition & 1 deletion engine/classes/Elgg/Comments/AutoSubscribeHandler.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ class AutoSubscribeHandler {
/**
* Subscribe the user to the comment container
*
* @param \Elgg\Event $event 'create', 'object'
* @param \Elgg\Event $event 'create:after', 'object'
*
* @return void
*/
Expand Down
2 changes: 1 addition & 1 deletion engine/classes/Elgg/Friends/CreateAclHandler.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ class CreateAclHandler {
/**
* Creates a Friends ACL for a user
*
* @param \Elgg\Event $event 'create', 'user'
* @param \Elgg\Event $event 'create:after', 'user'
*
* @return void
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ class CreateContentEventHandler {
/**
* Subscribe to content you just created in order to receive notifications
*
* @param \Elgg\Event $event 'create', 'object'|'group'
* @param \Elgg\Event $event 'create:after', 'object'|'group'
*
* @return void
*/
Expand Down
7 changes: 1 addition & 6 deletions engine/classes/Elgg/Traits/Entity/PluginSettings.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ trait PluginSettings {
*
* @param string $plugin_id plugin ID
* @param string $name setting name
* @param mixed $value setting value (needs to be a scalar)
* @param mixed $value setting value
*
* @return bool
*/
Expand All @@ -26,11 +26,6 @@ public function setPluginSetting(string $plugin_id, string $name, $value): bool
'value' => $value,
], $value);

if (isset($value) && !is_scalar($value)) {
elgg_log("Invalid value type provided to save plugin setting '{$name}' for plugin '{$plugin_id}' only scalars are allowed", 'ERROR');
return false;
}

$name = $this->getNamespacedPluginSettingName($plugin_id, $name);

return $this->setMetadata($name, $value);
Expand Down
2 changes: 1 addition & 1 deletion engine/classes/Elgg/Upgrade/CreateAdminNoticeHandler.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ class CreateAdminNoticeHandler {
/**
* Add an admin notice when a new \ElggUpgrade object is created.
*
* @param \Elgg\Event $event 'create', 'object'
* @param \Elgg\Event $event 'create:after', 'object'
*
* @return void
*/
Expand Down
25 changes: 8 additions & 17 deletions engine/classes/ElggEntity.php
Original file line number Diff line number Diff line change
Expand Up @@ -1233,25 +1233,10 @@ public function getIconURL(string|array $params = []): string {
* {@inheritDoc}
*/
public function save(): bool {
$result = false;

if ($this->guid > 0) {
$result = $this->update();
} else {
$guid = $this->create();
if ($guid === false) {
return false;
}

if (!_elgg_services()->events->trigger('create', $this->type, $this)) {
// plugins that return false to event don't need to override the access system
elgg_call(ELGG_IGNORE_ACCESS, function() {
return $this->delete();
});
return false;
}

$result = true;
$result = $this->create() !== false;
}

if ($result) {
Expand Down Expand Up @@ -1282,7 +1267,7 @@ protected function create() {

$subtype = $this->attributes['subtype'];
if (!$subtype) {
throw new ElggInvalidArgumentException("All entities must have a subtype");
throw new ElggInvalidArgumentException('All entities must have a subtype');
}

$owner_guid = (int) $this->attributes['owner_guid'];
Expand Down Expand Up @@ -1340,6 +1325,10 @@ protected function create() {
return false;
}
}

if (!_elgg_services()->events->triggerBefore('create', $this->type, $this)) {
return false;
}

// Create primary table row
$guid = _elgg_services()->entityTable->insertRow((object) [
Expand Down Expand Up @@ -1392,6 +1381,8 @@ protected function create() {
// users have their own logic for setting last action
$container->updateLastAction();
}

_elgg_services()->events->triggerAfter('create', $this->type, $this);

return $guid;
}
Expand Down
2 changes: 1 addition & 1 deletion engine/classes/ElggInstaller.php
Original file line number Diff line number Diff line change
Expand Up @@ -1494,7 +1494,7 @@ protected function saveSiteSettings($submissionVars) {
}

// Wo don't need to run upgrades on new installations
$app->internal_services->events->unregisterHandler('create', 'object', \Elgg\Upgrade\CreateAdminNoticeHandler::class);
$app->internal_services->events->unregisterHandler('create:after', 'object', \Elgg\Upgrade\CreateAdminNoticeHandler::class);
$upgrades = $app->internal_services->upgradeLocator->locate();
foreach ($upgrades as $upgrade) {
$upgrade->setCompleted();
Expand Down
16 changes: 8 additions & 8 deletions engine/events.php
Original file line number Diff line number Diff line change
Expand Up @@ -80,23 +80,23 @@
],
],
'create' => [
'object' => [
\Elgg\Comments\AutoSubscribeHandler::class => [],
\Elgg\Notifications\CreateContentEventHandler::class => [],
\Elgg\Upgrade\CreateAdminNoticeHandler::class => [],
],
'relationship' => [
\Elgg\Friends\AddToAclHandler::class => [],
],
'user' => [
\Elgg\Friends\CreateAclHandler::class => [],
],
],
'create:after' => [
'object' => [
\Elgg\Comments\AutoSubscribeHandler::class => [],
\Elgg\Notifications\CreateContentEventHandler::class => [],
\Elgg\Upgrade\CreateAdminNoticeHandler::class => [],
],
'river' => [
\Elgg\Comments\UpdateRiverLastActionHandler::class => [],
\Elgg\River\UpdateLastActionHandler::class => [],
],
'user' => [
\Elgg\Friends\CreateAclHandler::class => [],
],
],
'cron' => [
'daily' => [
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -464,6 +464,28 @@ public function testNewGroupLoadedFromCacheDuringSaveOperations() {
$this->assertTrue($annotation_called);
}

/**
* Checks if you can return false from a create:before event to prevent entity being saved to the database
*/
public function testBeforeEventCanStopEntityCreation() {

$object = new \ElggObject();
$object->setSubtype('elgg_entity_test_subtype_prevent');

$prevent_create = function(\Elgg\Event $event) {
$entity = $event->getObject();
if ($entity->subtype === 'elgg_entity_test_subtype_prevent') {
return false;
}
};

elgg_register_event_handler('create:before', 'object', $prevent_create);

$this->assertFalse($object->save());

elgg_unregister_event_handler('create:before', 'object', $prevent_create);
}

/**
* @see https://github.com/Elgg/Elgg/pull/11998
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -83,8 +83,8 @@ public function testCanSetUserSetting() {
$this->assertTrue($user->setPluginSetting('test_plugin', 'foo1', 'bar1'));
$this->assertEquals('bar1', $user->getPluginSetting('test_plugin', 'foo1'));

$this->assertFalse($user->setPluginSetting('test_plugin', 'foo2', ['bar1', 'bar2']));
$this->assertEmpty($user->getPluginSetting('test_plugin', 'foo2'));
$this->assertTrue($user->setPluginSetting('test_plugin', 'foo2', ['bar1', 'bar2']));
$this->assertEquals(['bar1', 'bar2'], $user->getPluginSetting('test_plugin', 'foo2'));

$this->assertTrue($user->setPluginSetting('test_plugin', 'foo3', 'bar3'));

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@ public function setPluginSettingProvider() {
['test_plugin', 'foo', 1.23],
['test_plugin', 'foo', false],
['test_plugin', 'foo', true],
['test_plugin', 'multiple', ['a', 'b']],
];
}

Expand Down Expand Up @@ -110,7 +111,6 @@ public function testUseEventToConvertInvalidPluginSettingValue($invalid_value) {
public function invalidPluginSettingValueProvider() {
return [
[new \stdClass()],
[['a', 'b']],
];
}
}
8 changes: 5 additions & 3 deletions mod/groups/elgg-plugin.php
Original file line number Diff line number Diff line change
Expand Up @@ -167,13 +167,15 @@
],
],
'create' => [
'relationship' => [
'Elgg\Groups\Relationships::applyGroupNotificationSettings' => [],
],
],
'create:after' => [
'group' => [
'Elgg\Groups\Group::createAccessCollection' => [],
\Elgg\Notifications\CreateContentEventHandler::class => [],
],
'relationship' => [
'Elgg\Groups\Relationships::applyGroupNotificationSettings' => [],
],
],
'default' => [
'access' => [
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ class Users {
/**
* Enable site notifications when a user is created
*
* @param \Elgg\Event $event 'create', 'user'
* @param \Elgg\Event $event 'create:after', 'user'
*
* @return void
*/
Expand Down
2 changes: 1 addition & 1 deletion mod/site_notifications/elgg-plugin.php
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@
],
],
'events' => [
'create' => [
'create:after' => [
'user' => [
'Elgg\SiteNotifications\Users::enableSiteNotifications' => [
'priority' => 400, // simple way to prevent priority issues with other developers
Expand Down

0 comments on commit d42a67a

Please sign in to comment.