diff --git a/lang/en/tag.php b/lang/en/tag.php index 83d3b5f7ee0..311829ecdbe 100644 --- a/lang/en/tag.php +++ b/lang/en/tag.php @@ -92,6 +92,19 @@ $string['noresultsfor'] = 'No results for "{$a}"'; $string['nothingtoupdate'] = 'Nothing to update'; $string['owner'] = 'Owner'; $string['prevpage'] = 'Back'; +$string['privacy:metadata:tag'] = 'The details of each unique tag are stored alongside their description and other related information'; +$string['privacy:metadataetag:name'] = 'The name of the tag - this is the normalised version of the name.'; +$string['privacy:metadata:tag:rawname'] = 'The name of the tag - this is the display name.'; +$string['privacy:metadata:tag:description'] = 'The description of the tag.'; +$string['privacy:metadata:tag:flag'] = 'Whether a tag has been flagged as inappropriate.'; +$string['privacy:metadata:tag:timemodified'] = 'The last time that the tag was last modified.'; +$string['privacy:metadata:tag:userid'] = 'The user who first created the tag.'; +$string['privacy:metadata:taginstance'] = 'The link between each tag and where it is used.'; +$string['privacy:metadata:taginstance:tagid'] = 'The link to the tag.'; +$string['privacy:metadata:taginstance:ordering'] = 'The relative order of this tag.'; +$string['privacy:metadata:taginstance:timecreated'] = 'The time that this tag was linked to the target.'; +$string['privacy:metadata:taginstance:timemodified'] = 'The time that this tag was last modified for the target.'; +$string['privacy:metadata:taginstance:tiuserid'] = 'Where shared content can be individually tagged by users, tThe owner of the tag instance is stored.'; $string['ptags'] = 'User defined tags (Comma separated)'; $string['relatedblogs'] = 'Most recent blog entries'; $string['relatedtags'] = 'Related tags'; diff --git a/tag/classes/privacy/provider.php b/tag/classes/privacy/provider.php new file mode 100644 index 00000000000..0bd437f12a3 --- /dev/null +++ b/tag/classes/privacy/provider.php @@ -0,0 +1,149 @@ +. + +/** + * Privacy Subsystem implementation for core_tag. + * + * @package core_tag + * @copyright 2018 Zig Tan + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ + +namespace core_tag\privacy; + +defined('MOODLE_INTERNAL') || die(); + +use \core_privacy\local\metadata\collection; + +/** + * Privacy Subsystem implementation for core_tag. + * + * @copyright 2018 Zig Tan + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ +class provider implements + // Tags store user data. + \core_privacy\local\metadata\provider, + + // The tag subsystem provides data to other components. + \core_privacy\local\request\subsystem\plugin_provider { + + /** + * Returns meta data about this system. + * + * @param collection $collection The initialised collection to add items to. + * @return collection A listing of user data stored through this system. + */ + public static function get_metadata(collection $collection) : collection { + // The table 'tag' contains data that a user has entered. + // It is currently linked with a userid, but this field will hopefulyl go away. + // Note: The userid is not necessarily 100% accurate. See MDL-61555. + $collection->add_database_table('tag', [ + 'name' => 'privacy:metadata:tag:name', + 'rawname' => 'privacy:metadata:tag:rawname', + 'description' => 'privacy:metadata:tag:description', + 'flag' => 'privacy:metadata:tag:flag', + 'timemodified' => 'privacy:metadata:tag:timemodified', + 'userid' => 'privacy:metadata:tag:userid', + ], 'privacy:metadata:tag'); + + // The table 'tag_instance' contains user data. + // It links the user of a specific tag, to the item which is tagged. + // In some cases the userid who 'owns' the tag is also stored. + $collection->add_database_table('tag_instance', [ + 'tagid' => 'privacy:metadata:taginstance:tagid', + 'ordering' => 'privacy:metadata:taginstance:ordering', + 'timecreated' => 'privacy:metadata:taginstance:timecreated', + 'timemodified' => 'privacy:metadata:taginstance:timemodified', + 'tiuserid' => 'privacy:metadata:taginstance:tiuserid', + ], 'privacy:metadata:taginstance'); + + // The table 'tag_area' does not contain any specific user data. + // It links components and item types to collections and describes how they can be associated. + + // The table 'tag_coll' does not contain any specific user data. + // It describes a list of tag collections configured by the administrator. + + // The table 'tag_correlation' does not contain any user data. + // It is a cache for other data already stored. + + return $collection; + } + + /** + * Store all tags which match the specified component, itemtype, and itemid. + * + * In most situations you will want to specify $onlyuser as false. + * This will fetch only tags where the user themselves set the tag, or where tags are a shared resource. + * + * If you specify $onlyuser as true, only the tags created by that user will be included. + * + * @param int $userid The user whose information is to be exported + * @param \context $context The context to export for + * @param array $subcontext The subcontext within the context to export this information + * @param string $component The component to fetch data from + * @param string $itemtype The itemtype that the data was exported in within the component + * @param int $itemid The itemid within that tag + * @param bool $onlyuser Whether to only export ratings that the current user has made, or all tags + */ + public static function export_item_tags( + int $userid, + \context $context, + array $subcontext, + string $component, + string $itemtype, + int $itemid, + bool $onlyuser = false + ) { + global $DB; + + // Do not include the mdl_tag userid data because of bug with re-using existing tags by other users. + $sql = "SELECT + t.id, + t.tagcollid, + t.name, + t.rawname, + t.isstandard, + t.description, + t.descriptionformat, + t.flag, + t.timemodified + FROM {tag} t + INNER JOIN {tag_instance} ti ON ti.tagid = t.id + WHERE ti.component = :component + AND ti.itemtype = :itemtype + AND ti.itemid = :itemid + "; + + if ($onlyuser) { + $sql .= "AND ti.tiuserid = :userid"; + } else { + $sql .= "AND (ti.tiuserid = 0 OR ti.tiuserid = :userid)"; + } + + $params = [ + 'component' => $component, + 'itemtype' => $itemtype, + 'itemid' => $itemid, + 'userid' => $userid, + ]; + + if ($tags = $DB->get_records_sql($sql, $params)) { + $writer = \core_privacy\local\request\writer::with_context($context) + ->export_related_data($subcontext, 'tags', $tags); + } + } +}