Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions modules/gdpr_fields/config/schema/gdpr_field.schema.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
field.field.*.*.*.third_party.gdpr_fields:
type: mapping
label: 'GDPR field'
mapping:
gdpr_fields_rta:
type: string
label: 'Whether this field is user sensitive or not.'
gdpr_fields_rtf:
type: string
label: 'Whether this field is user sensitive or not.'
9 changes: 9 additions & 0 deletions modules/gdpr_fields/gdpr_fields.info.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
name: General Data Protection Regulation (GDPR) - Fields
description: Allow tracking and removing of user data in all fields.
core: 8.x
type: module
package: General Data Protection Regulation

dependencies:
- gdpr:gdpr
- ctools:ctools (>=8.x-3.0-beta1)
4 changes: 4 additions & 0 deletions modules/gdpr_fields/gdpr_fields.links.task.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
gdpr_fields.fields_list:
route_name: gdpr_fields.fields_list
title: 'Used in GDPR'
base_route: entity.field_storage_config.collection
100 changes: 100 additions & 0 deletions modules/gdpr_fields/gdpr_fields.module
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
<?php

/**
* @file
* Module file for the GDPR Fields module.
*/

use Drupal\Core\Form\FormStateInterface;

/**
* Implements hook_form_FORM_ID_alter().
*
* @todo Find a better way of editing field GDPR settings as lots of fields are not UI configurable.
* @todo Check user edit permission for GDPR fields.
*/
function gdpr_fields_form_field_config_edit_form_alter(&$form, FormStateInterface $form_state, $form_id) {
/* @var \Drupal\Core\Field\FieldConfigInterface $field */
$field = $form_state->getFormObject()->getEntity();
// @todo Check that target entity is a content entity.

$enabled = $field->getThirdPartySetting('gdpr_fields', 'gdpr_fields_enabled', FALSE);
$form['field']['gdpr_fields'] = [
'#type' => 'details',
'#title' => t('GDPR field settings'),
'#open' => $enabled,
];

$form['field']['gdpr_fields']['gdpr_fields_enabled'] = [
'#type' => 'checkbox',
'#title' => t('This is a GDPR field'),
'#default_value' => $enabled,
];

$form['field']['gdpr_fields']['gdpr_fields_rta'] = [
'#type' => 'select',
'#title' => t('Right to access'),
'#options' => [
'inc' => 'Included',
'maybe' => 'Maybe',
'no' => 'Not',
],
'#default_value' => $field->getThirdPartySetting('gdpr_fields', 'gdpr_fields_rta', 'no'),
'#states' => array(
'visible' => array(
':input[name="gdpr_fields_enabled"]' => array(
'checked' => TRUE,
),
),
),
];

$form['field']['gdpr_fields']['gdpr_fields_rtf'] = [
'#type' => 'select',
'#title' => t('Right to be forgotten'),
'#options' => [
'obfuscate' => 'Obfuscate',
'remove' => 'Remove',
'maybe' => 'Maybe',
'no' => 'Not',
],
'#default_value' => $field->getThirdPartySetting('gdpr_fields', 'gdpr_fields_rtf', 'no'),
'#states' => array(
'visible' => array(
':input[name="gdpr_fields_enabled"]' => array(
'checked' => TRUE,
),
),
),
];
$form['actions']['submit']['#submit'][] = 'gdpr_fields_form_field_config_edit_form_submit';
}

/**
* Form submission handler for gdpr_fields_form_field_config_edit_form_alter.
*
* @param array $form
* The form array.
* @param \Drupal\Core\Form\FormStateInterface $form_state
* The form state.
*/
function gdpr_fields_form_field_config_edit_form_submit(array $form, FormStateInterface $form_state) {
/* @var \Drupal\Core\Field\FieldConfigInterface $field */
$field = $form_state->getFormObject()->getEntity();
$form_fields = &$form_state->getValues();

// If the private option is checked, update settings.
if ($form_fields['gdpr_fields_enabled']) {
$field->setThirdPartySetting('gdpr_fields', 'gdpr_fields_enabled', TRUE);
$field->setThirdPartySetting('gdpr_fields', 'gdpr_fields_rta', $form_fields['gdpr_fields_rta']);
$field->setThirdPartySetting('gdpr_fields', 'gdpr_fields_rtf', $form_fields['gdpr_fields_rtf']);
$field->save();
}
else {
$field->unsetThirdPartySetting('gdpr_fields', 'gdpr_fields_enabled');
$field->unsetThirdPartySetting('gdpr_fields', 'gdpr_fields_rta');
$field->unsetThirdPartySetting('gdpr_fields', 'gdpr_fields_rtf');
$field->save();
}

}
5 changes: 5 additions & 0 deletions modules/gdpr_fields/gdpr_fields.permissions.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
view gdpr fields:
title: 'View GDPR fields'

edit gdpr fields:
title: 'Edit GDPR fields'
7 changes: 7 additions & 0 deletions modules/gdpr_fields/gdpr_fields.routing.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
gdpr_fields.fields_list:
path: '/admin/reports/fields/gdpr-fields'
defaults:
_controller: '\Drupal\gdpr_fields\Controller\GDPRController::fieldsList'
_title: 'Used in GDPR'
requirements:
_permission: 'view gdpr fields'
4 changes: 4 additions & 0 deletions modules/gdpr_fields/gdpr_fields.services.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
services:
gdpr_fields.collector:
class: Drupal\gdpr_fields\GDPRCollector
arguments: ['@entity_type.manager', '@plugin.manager.ctools.relationship']
110 changes: 110 additions & 0 deletions modules/gdpr_fields/src/Controller/GDPRController.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
<?php

namespace Drupal\gdpr_fields\Controller;

use Drupal\Core\Controller\ControllerBase;
use Drupal\Core\Link;
use Drupal\Core\Url;
use Drupal\gdpr_fields\GDPRCollector;
use Symfony\Component\DependencyInjection\ContainerInterface;

/**
* Returns responses for GDPR Field routes.
*/
class GDPRController extends ControllerBase {

/**
* Stores the Views data cache object.
*
* @var \Drupal\gdpr_fields\GDPRCollector
*/
protected $collector;

/**
* Constructs a new GDPRController.
*
* @param \Drupal\gdpr_fields\GDPRCollector $collector
* The GDPR collector service.
*/
public function __construct(GDPRCollector $collector) {
$this->collector = $collector;
}

/**
* {@inheritdoc}
*/
public static function create(ContainerInterface $container) {
return new static(
$container->get('gdpr_fields.collector')
);
}

/**
* Lists all fields with GDPR sensitivity.
*
* @return array
* The Views plugins report page.
*/
public function fieldsList() {
$output = [];
$entities = [];
$this->collector->getEntities($entities);

foreach ($entities as $entity_type => $bundles) {
$output[$entity_type] = array(
'#type' => 'details',
'#title' => t($entity_type),
'#description' => t('@configure entity @entity_type for GDPR.', [
// @todo Create ability to exclude entity type from GDPR in configuration.
'@configure' => Link::fromTextAndUrl('Configure', Url::fromUri('internal:/'))->toString(),
'@entity_type' => ucfirst($entity_type),
]),
'#open' => TRUE,
);

if (count($bundles) > 1) {
foreach ($bundles as $bundle_id) {
$output[$entity_type][$bundle_id] = array(
'#type' => 'details',
'#title' => t($bundle_id),
'#open' => TRUE,
);
$output[$entity_type][$bundle_id]['fields'] = $this->buildFieldTable($entity_type, $bundle_id);
}
}
else {
// Don't add another collapsible wrapper around single bundle entities.
$bundle_id = reset($bundles);
$output[$entity_type][$bundle_id]['fields'] = $this->buildFieldTable($entity_type, $bundle_id);
}
}

return $output;
}

/**
* Build a table for entity field list.
*
* @param string $entity_type
* The entity type id.
* @param string $bundle_id
* The entity bundle id.
*
* @return array
* Renderable array for field list table.
*/
protected function buildFieldTable($entity_type, $bundle_id) {
$rows = $this->collector->listFields($entity_type, $bundle_id);
// Sort rows by field name.
ksort($rows);

return [
'#type' => 'table',
'#header' => [t('Name'), t('Type'), t('Right to access'), t('Right to be forgotten'), ''],
'#rows' => $rows,
'#sticky' => TRUE,
'#empty' => t('There are no GDPR fields for this entity.'),
];
}

}
Loading