General developer forum

Best way to implement the Privacy API for a plugin/subplugin relationship

Picture of Mike Churchward
Best way to implement the Privacy API for a plugin/subplugin relationship
Core developersParticularly helpful MoodlersPlugin developersPlugins guardiansTesters

Hi -

I'm implementing the Privacy API for a plugin that has subplugins. Each of the subplugins defines a context that it stores data associated with.

The main plugin on its own, does not store any personal data, but any of the subplugins might.

Currently, I have implemented it such that the main plugin uses the "null_provider" to indicate that it does not store any personal data. Then, a subplugin that does (for example, on a user) implements the "\core_privacy\local\metadata\provider" and the "\core_privacy\local\request\plugin\provider" to indicate that it does, and provide the export and delete functions.

Other subplugins likewise implement the "null_provider" to indicate no personal data.

Is this the best/proper way? Or should the main plugin somehow indicate that it "might" store personal data, and gather that data from any subplugin that indicates it does?


Average of ratings: -
Picture of Adrian Greeve
Re: Best way to implement the Privacy API for a plugin/subplugin relationship
Core developersMoodle HQParticularly helpful MoodlersPlugin developersTesters

I see there being two possible ways to handle the situation where the main plugin stores no user information, but the subplugins do.

If the information in the subplugins is not heavily tied to the main plugin then:

1) Define the main plugin as a null provider and implement the privacy API individually for each of the subplugins.

A certain amount of contextual information may be required to make the exported information useful for the user who is asking for their data.



id   course   selectionid   userid

1    2        5             3

This table is deemed to contain user information as it has a user id, but just exporting this record leaves the end user with nothing meaningful. It needs to have some related information also included. The main thing that we need here is information related to the selectionid.

mdl_table_two (selections)

id    selectionname


5     Peanuts.


So while table two stores no user data it should be queried when returning user information to provide relevant information.

(Possible returned json information)

{1:{course: "My course", selection: "Peanuts"}}

If you can make a link between the userid in the subplugins and a context id without requiring a link to tables from the main plugin then this method would be fine.

Otherwise we need the more involved method number two.

2) The main plugin is defined as a provider, and a custom interface is created to retrieve information from the subplugins.

This is especially relevant if it is not possible to retrieve user information with just the userid and a context from the subplugin, but need to join on tables from the core plugins and so need custom information to do so. (see MDL-62535)

The interface should have different method names to retrieve entries related to users that can ultimately be linked to a context, and be able to delete user data from these records.

In the get_metadata(collection) method as there is no user data stored directly, you only need to add code to link to the subplugins.

mod_assign example:

$collection->add_plugintype_link('assignsubmission', [], 'privacy:metadata:assignsubmissionpluginsummary');

Each of the subplugins should still implement the metadataprovider as normal.

get_contexts_for_userid(userid) should make a call to each of the subplugins to retrieve information that creates a link between the user id and a context id.

export_user_data(approved_contextlist) This makes another call to each of the subplugins to write / export any relevant user data.

delete_data_for_all_users_in_context(context) Given this specific context delete all user information that can be linked to it through your plugin / subplugin system.

delete_data_for_user(approved_contextlist) For the specified contexts for this user make a call to each of the subplugins with appropriate information to delete that user's data.

mod_assign is one example of how a custom interface is created to handle subplugins. MDL-62535 is another example of how the subplugins need rely on the main plugin to link user information to a context.

Average of ratings: Useful (1)