J3.x

Integreer de privacy-component in extensies

From Joomla! Documentation

This page is a translated version of the page J3.x:Integrate Extensions with the Privacy Component and the translation is 100% complete.

Other languages:
Deutsch • ‎English • ‎français • ‎italiano • ‎Nederlands

Onderstaande informatie is beschikbaar voor extensie ontwikkelaars om integratie met de Privacy Tool Suite te realiseren.

Privacy gerelateerde extensie mogelijkheden

De nieuwe privacy component heeft een mogelijkheden sectie die extensies de kans biedt privacy gerelateerde mogelijkheden te rapporteren. Het doel van deze sectie is gebruikers te helpen te begrijpen wat een extensie doet in verband met persooonlijke gegevens van gebruikers en zo website eigenaren overeenkomstig te laten regelen. Kijk, voor details over deze sectie, inclusief hoe een plugin zou moeten integreren op de Rapport extensie mogelijheden in privacy component pagina.

Controleer op een gepubliceerd privacy beleid

De gezondheidscontrole van de privacy component bericht gebruikers of er een privacy beleid gepubliceerd is op dd website. Deze controle wordt uitgevoerd door het onPrivacyCheckPrivacyPolicyPublished event wat kan worden subscribed door plugins in de privacy, systeem end user plugin groepen. Het event ontvangt een gekoppelde 'array by reference' met twee sleutels als argument:

  • "gepubliceerd" - Een boolean waarde die aangeeft dat er een gepubliceerd beleid is
  • "editLink" - De URL om het policy item te bewerken, dit wordt getoond als er een privacy beleid gepubliceerd is
  • "articlePublished" - De artikel status als het in de database staat

Als best-practice, wordt aanbevolen dat plugins eerst controleren of de "gepubliceerd" flag al op true staat en geen veranderingen aanbrengt in de data array als dat zo is. Let op dat de Systeem - Privacy toestemming core plugin dit event zal uitvoeren.

public function onPrivacyCheckPrivacyPolicyPublished(&$policy)
{
	// If another plugin has already indicated a policy is published, we won't change anything here
	if ($policy['published'])
	{
		return;
	}

	// Do stuff to find the privacy policy data

	// For core, we check if the article exists in the database and is published or not
	$query = $this->db->getQuery(true)
		->select($this->db->quoteName(array('id', 'state')))
		->from($this->db->quoteName('#__content'))
		->where($this->db->quoteName('id') . ' = ' . (int) $articleId);
	$this->db->setQuery($query);

	$article = $this->db->loadObject();

	// Check if the article exists
	if (!$article)
	{
		return;
	}

	// Check if the article is published
	if ($article->state == 1)
	{
		$policy['articlePublished'] = true;
	}

	$policy['published'] = true;
	$policy['editLink']  = ''; // The link to the item's edit page, processed through JRoute, i.e. JRoute::_('index.php?option=com_content&task=article.edit&id=1');
}


Gegevens aan exportverzoeken toekennen

Voor het gemak zitten er diverse helper methodes in de PrivacyPlugin class en er wordt aanbevolen dat privacy plugins deze class uitbreiden om deze helpers te overerven (dit is bijvoorbeeld gelijk aan de FinderIndexerAdapter class van Slimzoeken plugins).

JLoader::register('PrivacyPlugin', JPATH_ADMINISTRATOR . '/components/com_privacy/helpers/plugin.php');

class PlgPrivacyContent extends PrivacyPlugin {}

Om gegevens aan een export-verzoek toe te voegen, moet een plugin in de privacy of systeem plugin groep zich abonneren op het onPrivacyExportRequest event.

Het event ontvangt twee argumenten:

  • $request - Een PrivacyTableRequest object bevat het informatie verzoekt record vanuit de database
  • $user - Als er een account is voor het e-mailadres van het informatieverzoek, wordt er een Joomla\CMS\User\User object teruggegeven met de gebruikersaccount gegevens

Het event moet een array met PrivacyExportDomain objecten teruggeven welke de gegevens bevat die geëxporteerd moeten worden voor een bepaald domein. Als de plugin geen gegevens bevat, moet het een lege array teruggeven.

Een PrivacyExportDomain gegevens-object levert de gevonden gegevens uit een tabel in de database en heeft drie elementen:

  • Domeinnaam - Een naam om het domein te identificeren
  • Domein beschrijving - Een korte beschrijving van de gegevens die in het domein zitten
  • Domein items - Een array met PrivacyExportItem gegevens objecten die alle items binnen het domein bevatten

Een PrivacyExportItem gegevens object vertegenwoordigt één enkel item in het gegevens domein en bestaat uit twee elementen:

  • Item-ID - De primaire identificator van dit item binnen het domein, dit is de primaire sleutel van het record in de database
  • Item velden - Een array met PrivacyExportField gegevensobjecten die elk veld van het item bevatten

Een PrivacyExportField gegevens object vertegenwoordigt één enkel item in het gegevens domein en bestaat uit twee elementen:

  • Veldnaam - De naam van het veld
  • Veldwaarde - De waarde van het veld

De standaard werkflow voor het exportproces is als volgt:

  • Valideer de plugin die de gegevens verwerkt
  • Verwerk de gegevens uit de database
  • Maak een domein aan voor de resultaten (de createDomain methode overerft van de PrivacyPlugin class kan hierbij helpen)
  • Voeg items toe voor iedere rij
    • De createItemFromArray methode overerft van de PrivacyPlugin class kan gebruikt worden om een PrivacyExportItem object aan te maken vanuit een array (dit moet gebruikt worden in samenhang met de loadAssocList methode van de database)
    • De createItemForTable methode overerft van de PrivacyPlugin class kan gebruikt worden om een PrivacyExportItem object aan te maken vanuit een Joomla\CMS\Table\Table object
  • Geef het domein terug

Hieronder staat een voorbeeld van het exporteren van artikelen gemaakt door een gebruiker, inclusief gegevens van extra velden.

use Joomla\CMS\User\User;

JLoader::register('FieldsHelper', JPATH_ADMINISTRATOR . '/components/com_fields/helpers/fields.php');
JLoader::register('PrivacyPlugin', JPATH_ADMINISTRATOR . '/components/com_privacy/helpers/plugin.php');

class PlgPrivacyContent extends PrivacyPlugin
{
	/**
	 * @var  JDatabaseDriver
	 */
	protected $db;

	/**
	 * @var  array
	 */
	protected $contents = array();

	public function onPrivacyExportRequest(PrivacyTableRequest $request, User $user = null)
	{
		// This plugin only processes data for registered user accounts
		if (!$user)
		{
			return array();
		}

		$domains   = array();
		$domains[] = $this->createContentDomain($user);

		// Create domains for each article's custom fields
		foreach ($this->contents as $content)
		{
			$domains[] = $this->createContentCustomFieldsDomain($content);
		}

		return $domains;
	}

	private function createContentDomain(User $user)
	{
		$domain = $this->createDomain('user_content', 'joomla_user_content_data');

		$query = $this->db->getQuery(true)
			->select('*')
			->from($this->db->quoteName('#__content'))
			->where($this->db->quoteName('created_by') . ' = ' . (int) $user->id)
			->order($this->db->quoteName('ordering') . ' ASC');

		$items = $this->db->setQuery($query)->loadAssocList();

		// Add each article to the domain
		foreach ($items as $item)
		{
			$domain->addItem($this->createItemFromArray($item));

			// Store the article for use in the custom fields processing
			$this->contents[] = (object) $item;
		}

		return $domain;
	}

	private function createContentCustomFieldsDomain($content)
	{
		$domain = $this->createDomain('content_custom_fields', 'joomla_content_custom_fields_data');

		// Get item's fields, also preparing their value property for manual display
		$fields = FieldsHelper::getFields('com_content.article', $content);

		foreach ($fields as $field)
		{
			$fieldValue = is_array($field->value) ? implode(', ', $field->value) : $field->value;

			$data = array(
				'content_id'  => $content->id,
				'field_name'  => $field->name,
				'field_title' => $field->title,
				'field_value' => $fieldValue,
			);

			$domain->addItem($this->createItemFromArray($data));
		}

		return $domain;
	}
}


Verwerk verwijderverzoeken

Het verwerken van een verwijderverzoek vereist twee stappen: Valideren dat de gegevens van het onderwerp verwijderd kunnen worden en het effectief verwijderen. Opnieuw wordt geadviseerd dat plugins de PrivacyPlugin class uitbreiden, dit is echter geen strenge eis.

JLoader::register('PrivacyPlugin', JPATH_ADMINISTRATOR . '/components/com_privacy/helpers/plugin.php');

class PlgPrivacyUser extends PrivacyPlugin {}

Valideer dat gegevens kunnen worden verwijderd

Als de plugin het verwijderen van gegevens van het onderwerp moet kunnen blokkeren, moet het het onPrivacyCanRemoveData event subscriben. In het algemeen moet een verwijdering worden geweigerd als er een valide legale reden is om de gegevens te behouden of als het verwijderen permanente schade aan de site veroorzaakt (bijvoorbeeld, dat de core Privacy - Gebruikersaccounts het verbiedt dat een Supergebruiker wordt verwijderd).

Het event ontvangt twee argumenten:

  • $request - Een PrivacyTableRequest object bevat het informatie verzoekt record vanuit de database
  • $user - Als er een account is voor het e-mailadres van het informatieverzoek, wordt er een Joomla\CMS\User\User object teruggegeven met de gebruikersaccount gegevens

Het event moet een PrivacyRemovalStatus gegevens-object teruggeven dat aangeeft dat de gegevens niet kunnen worden verwijderd en een reden voor het niet kunnen verwijderen van de gegevens.

use Joomla\CMS\Language\Text;
use Joomla\CMS\User\User;

JLoader::register('PrivacyPlugin', JPATH_ADMINISTRATOR . '/components/com_privacy/helpers/plugin.php');
JLoader::register('PrivacyRemovalStatus', JPATH_ADMINISTRATOR . '/components/com_privacy/helpers/removal/status.php');

class PlgPrivacyUser extends PrivacyPlugin
{
	public function onPrivacyCanRemoveData(PrivacyTableRequest $request, User $user = null)
	{
		$status = new PrivacyRemovalStatus;

		// We only need to check if there is an associated user account
		if (!$user)
		{
			return $status;
		}

		// We will not remove a super user account from the site
		if ($user->authorise('core.admin'))
		{
			$status->canRemove = false;
			$status->reason    = Text::_('PLG_PRIVACY_USER_ERROR_CANNOT_REMOVE_SUPER_USER');
		}

		return $status;
	}
}

Verwijder of anonimiseer de gegevens

Als de plugin het verwijderen of anonimiseren van gegevens verwerkt, moet het zich aanmelden bij het onPrivacyRemoveData event.

Het event ontvangt twee argumenten:

  • $request - Een PrivacyTableRequest object bevat het informatie verzoekt record vanuit de database
  • $user - Als er een account is voor het e-mailadres van het informatieverzoek, wordt er een Joomla\CMS\User\User object teruggegeven met de gebruikersaccount gegevens

Afwijkend van de andere events in deze component, wordt van de plugins niet verwacht gegevens terug te geven.

Afhankelijk van de onderliggende gegevenseisen, moeten de plugins informatie anonimiseren die wordt behouden en gegevens verwijderen die niet meer nodig is. Indien noodzakelijk kan de plugin andere acties uitvoeren gerelateerd aan het verzoek en/of het gebruikersaccount.

Onderstaande voorbeeld toont hoe Joomla gegevens anonimiseert en verwijdert gerelateerd aan het core gebruikersaccount.

use Joomla\CMS\Factory;
use Joomla\CMS\User\User;

JLoader::register('PrivacyPlugin', JPATH_ADMINISTRATOR . '/components/com_privacy/helpers/plugin.php');

class PlgPrivacyUser extends PrivacyPlugin
{
	/**
	 * @var  JDatabaseDriver
	 */
	protected $db;

	public function onPrivacyRemoveData(PrivacyTableRequest $request, User $user = null)
	{
		// This plugin only processes data for registered user accounts
		if (!$user)
		{
			return;
		}

		$pseudoanonymisedData = array(
			'name'      => 'User ID ' . $user->id,
			'username'  => bin2hex(random_bytes(12)), // Generates a random username
			'email'     => 'UserID' . $user->id . 'removed@email.invalid',
			'block'     => true,
		);

		$user->bind($pseudoanonymisedData);

		$user->save();

		// Destroy all sessions for the user account
		$sessionIds = $this->db->setQuery(
			$this->db->getQuery(true)
				->select($this->db->quoteName('session_id'))
				->from($this->db->quoteName('#__session'))
				->where($this->db->quoteName('userid') . ' = ' . (int) $user->id)
		)->loadColumn();

		// If there aren't any active sessions then there's nothing to do here
		if (empty($sessionIds))
		{
			return;
		}

		$storeName = Factory::getConfig()->get('session_handler', 'none');
		$store     = JSessionStorage::getInstance($storeName);
		$quotedIds = array();

		// Destroy the sessions and quote the IDs to purge the session table
		foreach ($sessionIds as $sessionId)
		{
			$store->destroy($sessionId);
			$quotedIds[] = $this->db->quote($sessionId);
		}

		$this->db->setQuery(
			$this->db->getQuery(true)
				->delete($this->db->quoteName('#__session'))
				->where($this->db->quoteName('session_id') . ' IN (' . implode(', ', $quotedIds) . ')')
		)->execute();
	}
}