first commit

This commit is contained in:
2025-06-17 11:53:18 +02:00
commit 9f0f7ba12b
8804 changed files with 1369176 additions and 0 deletions

View File

@ -0,0 +1,21 @@
<?xml version="1.0" encoding="UTF-8"?>
<extension type="plugin" group="privacy" method="upgrade">
<name>plg_privacy_actionlogs</name>
<author>Joomla! Project</author>
<creationDate>2018-07</creationDate>
<copyright>(C) 2018 Open Source Matters, Inc.</copyright>
<license>GNU General Public License version 2 or later; see LICENSE.txt</license>
<authorEmail>admin@joomla.org</authorEmail>
<authorUrl>www.joomla.org</authorUrl>
<version>3.9.0</version>
<description>PLG_PRIVACY_ACTIONLOGS_XML_DESCRIPTION</description>
<namespace path="src">Joomla\Plugin\Privacy\Actionlogs</namespace>
<files>
<folder plugin="actionlogs">services</folder>
<folder>src</folder>
</files>
<languages>
<language tag="en-GB">language/en-GB/plg_privacy_actionlogs.ini</language>
<language tag="en-GB">language/en-GB/plg_privacy_actionlogs.sys.ini</language>
</languages>
</extension>

View File

@ -0,0 +1,48 @@
<?php
/**
* @package Joomla.Plugin
* @subpackage Privacy.actionlogs
*
* @copyright (C) 2023 Open Source Matters, Inc. <https://www.joomla.org>
* @license GNU General Public License version 2 or later; see LICENSE.txt
*/
\defined('_JEXEC') or die;
use Joomla\CMS\Extension\PluginInterface;
use Joomla\CMS\Factory;
use Joomla\CMS\Plugin\PluginHelper;
use Joomla\Database\DatabaseInterface;
use Joomla\DI\Container;
use Joomla\DI\ServiceProviderInterface;
use Joomla\Event\DispatcherInterface;
use Joomla\Plugin\Privacy\Actionlogs\Extension\Actionlogs;
return new class () implements ServiceProviderInterface {
/**
* Registers the service provider with a DI container.
*
* @param Container $container The DI container.
*
* @return void
*
* @since 4.4.0
*/
public function register(Container $container): void
{
$container->set(
PluginInterface::class,
function (Container $container) {
$plugin = new Actionlogs(
$container->get(DispatcherInterface::class),
(array) PluginHelper::getPlugin('privacy', 'actionlogs')
);
$plugin->setApplication(Factory::getApplication());
$plugin->setDatabase($container->get(DatabaseInterface::class));
return $plugin;
}
);
}
};

View File

@ -0,0 +1,96 @@
<?php
/**
* @package Joomla.Plugin
* @subpackage Privacy.actionlogs
*
* @copyright (C) 2018 Open Source Matters, Inc. <https://www.joomla.org>
* @license GNU General Public License version 2 or later; see LICENSE.txt
*/
namespace Joomla\Plugin\Privacy\Actionlogs\Extension;
use Joomla\CMS\Event\Privacy\ExportRequestEvent;
use Joomla\Component\Actionlogs\Administrator\Helper\ActionlogsHelper;
use Joomla\Component\Privacy\Administrator\Plugin\PrivacyPlugin;
use Joomla\Database\ParameterType;
use Joomla\Event\SubscriberInterface;
// phpcs:disable PSR1.Files.SideEffects
\defined('_JEXEC') or die;
// phpcs:enable PSR1.Files.SideEffects
/**
* Privacy plugin managing Joomla actionlogs data
*
* @since 3.9.0
*/
final class Actionlogs extends PrivacyPlugin implements SubscriberInterface
{
/**
* Returns an array of events this subscriber will listen to.
*
* @return array
*
* @since 5.0.0
*/
public static function getSubscribedEvents(): array
{
return [
'onPrivacyExportRequest' => 'onPrivacyExportRequest',
];
}
/**
* Processes an export request for Joomla core actionlog data
*
* @param ExportRequestEvent $event The request event
*
* @return void
*
* @since 3.9.0
*/
public function onPrivacyExportRequest(ExportRequestEvent $event)
{
$user = $event->getUser();
// RequestTable $request, User $user = null
if (!$user) {
return;
}
$domain = $this->createDomain('user_action_logs', 'joomla_user_action_logs_data');
$db = $this->getDatabase();
$userId = (int) $user->id;
$query = $db->getQuery(true)
->select(['a.*', $db->quoteName('u.name')])
->from($db->quoteName('#__action_logs', 'a'))
->join('INNER', $db->quoteName('#__users', 'u'), $db->quoteName('a.user_id') . ' = ' . $db->quoteName('u.id'))
->where($db->quoteName('a.user_id') . ' = :id')
->bind(':id', $userId, ParameterType::INTEGER);
$db->setQuery($query);
$data = $db->loadObjectList();
if (!\count($data)) {
return;
}
$data = ActionlogsHelper::getCsvData($data);
$isFirst = true;
foreach ($data as $item) {
if ($isFirst) {
$isFirst = false;
continue;
}
$domain->addItem($this->createItemFromArray($item));
}
$event->addResult([$domain]);
}
}

View File

@ -0,0 +1,21 @@
<?xml version="1.0" encoding="UTF-8"?>
<extension type="plugin" group="privacy" method="upgrade">
<name>plg_privacy_consents</name>
<author>Joomla! Project</author>
<creationDate>2018-07</creationDate>
<copyright>(C) 2018 Open Source Matters, Inc.</copyright>
<license>GNU General Public License version 2 or later; see LICENSE.txt</license>
<authorEmail>admin@joomla.org</authorEmail>
<authorUrl>www.joomla.org</authorUrl>
<version>3.9.0</version>
<description>PLG_PRIVACY_CONSENTS_XML_DESCRIPTION</description>
<namespace path="src">Joomla\Plugin\Privacy\Consents</namespace>
<files>
<folder plugin="consents">services</folder>
<folder>src</folder>
</files>
<languages>
<language tag="en-GB">language/en-GB/plg_privacy_consents.ini</language>
<language tag="en-GB">language/en-GB/plg_privacy_consents.sys.ini</language>
</languages>
</extension>

View File

@ -0,0 +1,48 @@
<?php
/**
* @package Joomla.Plugin
* @subpackage Privacy.consents
*
* @copyright (C) 2023 Open Source Matters, Inc. <https://www.joomla.org>
* @license GNU General Public License version 2 or later; see LICENSE.txt
*/
\defined('_JEXEC') or die;
use Joomla\CMS\Extension\PluginInterface;
use Joomla\CMS\Factory;
use Joomla\CMS\Plugin\PluginHelper;
use Joomla\Database\DatabaseInterface;
use Joomla\DI\Container;
use Joomla\DI\ServiceProviderInterface;
use Joomla\Event\DispatcherInterface;
use Joomla\Plugin\Privacy\Consents\Extension\Consents;
return new class () implements ServiceProviderInterface {
/**
* Registers the service provider with a DI container.
*
* @param Container $container The DI container.
*
* @return void
*
* @since 4.4.0
*/
public function register(Container $container): void
{
$container->set(
PluginInterface::class,
function (Container $container) {
$plugin = new Consents(
$container->get(DispatcherInterface::class),
(array) PluginHelper::getPlugin('privacy', 'consents')
);
$plugin->setApplication(Factory::getApplication());
$plugin->setDatabase($container->get(DatabaseInterface::class));
return $plugin;
}
);
}
};

View File

@ -0,0 +1,65 @@
<?php
/**
* @package Joomla.Plugin
* @subpackage Privacy.consents
*
* @copyright (C) 2018 Open Source Matters, Inc. <https://www.joomla.org>
* @license GNU General Public License version 2 or later; see LICENSE.txt
*/
namespace Joomla\Plugin\Privacy\Consents\Extension;
use Joomla\CMS\User\User;
use Joomla\Component\Privacy\Administrator\Plugin\PrivacyPlugin;
use Joomla\Component\Privacy\Administrator\Table\RequestTable;
use Joomla\Database\ParameterType;
// phpcs:disable PSR1.Files.SideEffects
\defined('_JEXEC') or die;
// phpcs:enable PSR1.Files.SideEffects
/**
* Privacy plugin managing Joomla user consent data
*
* @since 3.9.0
*/
final class Consents extends PrivacyPlugin
{
/**
* Processes an export request for Joomla core user consent data
*
* This event will collect data for the core `#__privacy_consents` table
*
* @param RequestTable $request The request record being processed
* @param User $user The user account associated with this request if available
*
* @return \Joomla\Component\Privacy\Administrator\Export\Domain[]
*
* @since 3.9.0
*/
public function onPrivacyExportRequest(RequestTable $request, User $user = null)
{
if (!$user) {
return [];
}
$domain = $this->createDomain('consents', 'joomla_consent_data');
$db = $this->getDatabase();
$query = $db->getQuery(true)
->select('*')
->from($db->quoteName('#__privacy_consents'))
->where($db->quoteName('user_id') . ' = :id')
->order($db->quoteName('created') . ' ASC')
->bind(':id', $user->id, ParameterType::INTEGER);
$items = $db->setQuery($query)->loadAssocList();
foreach ($items as $item) {
$domain->addItem($this->createItemFromArray($item));
}
return [$domain];
}
}

View File

@ -0,0 +1,21 @@
<?xml version="1.0" encoding="UTF-8"?>
<extension type="plugin" group="privacy" method="upgrade">
<name>plg_privacy_contact</name>
<author>Joomla! Project</author>
<creationDate>2018-07</creationDate>
<copyright>(C) 2018 Open Source Matters, Inc.</copyright>
<license>GNU General Public License version 2 or later; see LICENSE.txt</license>
<authorEmail>admin@joomla.org</authorEmail>
<authorUrl>www.joomla.org</authorUrl>
<version>3.9.0</version>
<description>PLG_PRIVACY_CONTACT_XML_DESCRIPTION</description>
<namespace path="src">Joomla\Plugin\Privacy\Contact</namespace>
<files>
<folder plugin="contact">services</folder>
<folder>src</folder>
</files>
<languages>
<language tag="en-GB">language/en-GB/plg_privacy_contact.ini</language>
<language tag="en-GB">language/en-GB/plg_privacy_contact.sys.ini</language>
</languages>
</extension>

View File

@ -0,0 +1,48 @@
<?php
/**
* @package Joomla.Plugin
* @subpackage Privacy.contact
*
* @copyright (C) 2023 Open Source Matters, Inc. <https://www.joomla.org>
* @license GNU General Public License version 2 or later; see LICENSE.txt
*/
\defined('_JEXEC') or die;
use Joomla\CMS\Extension\PluginInterface;
use Joomla\CMS\Factory;
use Joomla\CMS\Plugin\PluginHelper;
use Joomla\Database\DatabaseInterface;
use Joomla\DI\Container;
use Joomla\DI\ServiceProviderInterface;
use Joomla\Event\DispatcherInterface;
use Joomla\Plugin\Privacy\Contact\Extension\Contact;
return new class () implements ServiceProviderInterface {
/**
* Registers the service provider with a DI container.
*
* @param Container $container The DI container.
*
* @return void
*
* @since 4.4.0
*/
public function register(Container $container): void
{
$container->set(
PluginInterface::class,
function (Container $container) {
$plugin = new Contact(
$container->get(DispatcherInterface::class),
(array) PluginHelper::getPlugin('privacy', 'contact')
);
$plugin->setApplication(Factory::getApplication());
$plugin->setDatabase($container->get(DatabaseInterface::class));
return $plugin;
}
);
}
};

View File

@ -0,0 +1,77 @@
<?php
/**
* @package Joomla.Plugin
* @subpackage Privacy.contact
*
* @copyright (C) 2018 Open Source Matters, Inc. <https://www.joomla.org>
* @license GNU General Public License version 2 or later; see LICENSE.txt
*/
namespace Joomla\Plugin\Privacy\Contact\Extension;
use Joomla\CMS\User\User;
use Joomla\Component\Privacy\Administrator\Plugin\PrivacyPlugin;
use Joomla\Component\Privacy\Administrator\Table\RequestTable;
use Joomla\Database\ParameterType;
// phpcs:disable PSR1.Files.SideEffects
\defined('_JEXEC') or die;
// phpcs:enable PSR1.Files.SideEffects
/**
* Privacy plugin managing Joomla user contact data
*
* @since 3.9.0
*/
final class Contact extends PrivacyPlugin
{
/**
* Processes an export request for Joomla core user contact data
*
* This event will collect data for the contact core tables:
*
* - Contact custom fields
*
* @param RequestTable $request The request record being processed
* @param User $user The user account associated with this request if available
*
* @return \Joomla\Component\Privacy\Administrator\Export\Domain[]
*
* @since 3.9.0
*/
public function onPrivacyExportRequest(RequestTable $request, User $user = null)
{
if (!$user && !$request->email) {
return [];
}
$domains = [];
$domain = $this->createDomain('user_contact', 'joomla_user_contact_data');
$domains[] = $domain;
$db = $this->getDatabase();
$query = $db->getQuery(true)
->select('*')
->from($db->quoteName('#__contact_details'))
->order($db->quoteName('ordering') . ' ASC');
if ($user) {
$query->where($db->quoteName('user_id') . ' = :id')
->bind(':id', $user->id, ParameterType::INTEGER);
} else {
$query->where($db->quoteName('email_to') . ' = :email')
->bind(':email', $request->email);
}
$items = $db->setQuery($query)->loadObjectList();
foreach ($items as $item) {
$domain->addItem($this->createItemFromArray((array) $item));
}
$domains[] = $this->createCustomFieldsDomain('com_contact.contact', $items);
return $domains;
}
}

View File

@ -0,0 +1,21 @@
<?xml version="1.0" encoding="UTF-8"?>
<extension type="plugin" group="privacy" method="upgrade">
<name>plg_privacy_content</name>
<author>Joomla! Project</author>
<creationDate>2018-07</creationDate>
<copyright>(C) 2018 Open Source Matters, Inc.</copyright>
<license>GNU General Public License version 2 or later; see LICENSE.txt</license>
<authorEmail>admin@joomla.org</authorEmail>
<authorUrl>www.joomla.org</authorUrl>
<version>3.9.0</version>
<description>PLG_PRIVACY_CONTENT_XML_DESCRIPTION</description>
<namespace path="src">Joomla\Plugin\Privacy\Content</namespace>
<files>
<folder plugin="content">services</folder>
<folder>src</folder>
</files>
<languages>
<language tag="en-GB">language/en-GB/plg_privacy_content.ini</language>
<language tag="en-GB">language/en-GB/plg_privacy_content.sys.ini</language>
</languages>
</extension>

View File

@ -0,0 +1,48 @@
<?php
/**
* @package Joomla.Plugin
* @subpackage Privacy.content
*
* @copyright (C) 2023 Open Source Matters, Inc. <https://www.joomla.org>
* @license GNU General Public License version 2 or later; see LICENSE.txt
*/
\defined('_JEXEC') or die;
use Joomla\CMS\Extension\PluginInterface;
use Joomla\CMS\Factory;
use Joomla\CMS\Plugin\PluginHelper;
use Joomla\Database\DatabaseInterface;
use Joomla\DI\Container;
use Joomla\DI\ServiceProviderInterface;
use Joomla\Event\DispatcherInterface;
use Joomla\Plugin\Privacy\Content\Extension\Content;
return new class () implements ServiceProviderInterface {
/**
* Registers the service provider with a DI container.
*
* @param Container $container The DI container.
*
* @return void
*
* @since 4.4.0
*/
public function register(Container $container): void
{
$container->set(
PluginInterface::class,
function (Container $container) {
$plugin = new Content(
$container->get(DispatcherInterface::class),
(array) PluginHelper::getPlugin('privacy', 'content')
);
$plugin->setApplication(Factory::getApplication());
$plugin->setDatabase($container->get(DatabaseInterface::class));
return $plugin;
}
);
}
};

View File

@ -0,0 +1,69 @@
<?php
/**
* @package Joomla.Plugin
* @subpackage Privacy.content
*
* @copyright (C) 2018 Open Source Matters, Inc. <https://www.joomla.org>
* @license GNU General Public License version 2 or later; see LICENSE.txt
*/
namespace Joomla\Plugin\Privacy\Content\Extension;
use Joomla\CMS\User\User;
use Joomla\Component\Privacy\Administrator\Plugin\PrivacyPlugin;
use Joomla\Component\Privacy\Administrator\Table\RequestTable;
// phpcs:disable PSR1.Files.SideEffects
\defined('_JEXEC') or die;
// phpcs:enable PSR1.Files.SideEffects
/**
* Privacy plugin managing Joomla user content data
*
* @since 3.9.0
*/
final class Content extends PrivacyPlugin
{
/**
* Processes an export request for Joomla core user content data
*
* This event will collect data for the content core table
*
* - Content custom fields
*
* @param RequestTable $request The request record being processed
* @param User $user The user account associated with this request if available
*
* @return \Joomla\Component\Privacy\Administrator\Export\Domain[]
*
* @since 3.9.0
*/
public function onPrivacyExportRequest(RequestTable $request, User $user = null)
{
if (!$user) {
return [];
}
$domains = [];
$domain = $this->createDomain('user_content', 'joomla_user_content_data');
$domains[] = $domain;
$db = $this->getDatabase();
$query = $db->getQuery(true)
->select('*')
->from($db->quoteName('#__content'))
->where($db->quoteName('created_by') . ' = ' . (int) $user->id)
->order($db->quoteName('ordering') . ' ASC');
$items = $db->setQuery($query)->loadObjectList();
foreach ($items as $item) {
$domain->addItem($this->createItemFromArray((array) $item));
}
$domains[] = $this->createCustomFieldsDomain('com_content.article', $items);
return $domains;
}
}

View File

@ -0,0 +1,21 @@
<?xml version="1.0" encoding="UTF-8"?>
<extension type="plugin" group="privacy" method="upgrade">
<name>plg_privacy_message</name>
<author>Joomla! Project</author>
<creationDate>2018-07</creationDate>
<copyright>(C) 2018 Open Source Matters, Inc.</copyright>
<license>GNU General Public License version 2 or later; see LICENSE.txt</license>
<authorEmail>admin@joomla.org</authorEmail>
<authorUrl>www.joomla.org</authorUrl>
<version>3.9.0</version>
<description>PLG_PRIVACY_MESSAGE_XML_DESCRIPTION</description>
<namespace path="src">Joomla\Plugin\Privacy\Message</namespace>
<files>
<folder plugin="message">services</folder>
<folder>src</folder>
</files>
<languages>
<language tag="en-GB">language/en-GB/plg_privacy_message.ini</language>
<language tag="en-GB">language/en-GB/plg_privacy_message.sys.ini</language>
</languages>
</extension>

View File

@ -0,0 +1,48 @@
<?php
/**
* @package Joomla.Plugin
* @subpackage Privacy.message
*
* @copyright (C) 2023 Open Source Matters, Inc. <https://www.joomla.org>
* @license GNU General Public License version 2 or later; see LICENSE.txt
*/
\defined('_JEXEC') or die;
use Joomla\CMS\Extension\PluginInterface;
use Joomla\CMS\Factory;
use Joomla\CMS\Plugin\PluginHelper;
use Joomla\Database\DatabaseInterface;
use Joomla\DI\Container;
use Joomla\DI\ServiceProviderInterface;
use Joomla\Event\DispatcherInterface;
use Joomla\Plugin\Privacy\Message\Extension\Message;
return new class () implements ServiceProviderInterface {
/**
* Registers the service provider with a DI container.
*
* @param Container $container The DI container.
*
* @return void
*
* @since 4.4.0
*/
public function register(Container $container): void
{
$container->set(
PluginInterface::class,
function (Container $container) {
$plugin = new Message(
$container->get(DispatcherInterface::class),
(array) PluginHelper::getPlugin('privacy', 'message')
);
$plugin->setApplication(Factory::getApplication());
$plugin->setDatabase($container->get(DatabaseInterface::class));
return $plugin;
}
);
}
};

View File

@ -0,0 +1,66 @@
<?php
/**
* @package Joomla.Plugin
* @subpackage Privacy.message
*
* @copyright (C) 2018 Open Source Matters, Inc. <https://www.joomla.org>
* @license GNU General Public License version 2 or later; see LICENSE.txt
*/
namespace Joomla\Plugin\Privacy\Message\Extension;
use Joomla\CMS\User\User;
use Joomla\Component\Privacy\Administrator\Plugin\PrivacyPlugin;
use Joomla\Component\Privacy\Administrator\Table\RequestTable;
use Joomla\Database\ParameterType;
// phpcs:disable PSR1.Files.SideEffects
\defined('_JEXEC') or die;
// phpcs:enable PSR1.Files.SideEffects
/**
* Privacy plugin managing Joomla user messages
*
* @since 3.9.0
*/
final class Message extends PrivacyPlugin
{
/**
* Processes an export request for Joomla core user message
*
* This event will collect data for the message table
*
* @param RequestTable $request The request record being processed
* @param User $user The user account associated with this request if available
*
* @return \Joomla\Component\Privacy\Administrator\Export\Domain[]
*
* @since 3.9.0
*/
public function onPrivacyExportRequest(RequestTable $request, User $user = null)
{
if (!$user) {
return [];
}
$domain = $this->createDomain('user_messages', 'joomla_user_messages_data');
$db = $this->getDatabase();
$query = $db->getQuery(true)
->select('*')
->from($db->quoteName('#__messages'))
->where($db->quoteName('user_id_from') . ' = :useridfrom')
->extendWhere('OR', $db->quoteName('user_id_to') . ' = :useridto')
->order($db->quoteName('date_time') . ' ASC')
->bind([':useridfrom', ':useridto'], $user->id, ParameterType::INTEGER);
$items = $db->setQuery($query)->loadAssocList();
foreach ($items as $item) {
$domain->addItem($this->createItemFromArray($item));
}
return [$domain];
}
}

View File

@ -0,0 +1,48 @@
<?php
/**
* @package Joomla.Plugin
* @subpackage Privacy.user
*
* @copyright (C) 2023 Open Source Matters, Inc. <https://www.joomla.org>
* @license GNU General Public License version 2 or later; see LICENSE.txt
*/
\defined('_JEXEC') or die;
use Joomla\CMS\Extension\PluginInterface;
use Joomla\CMS\Factory;
use Joomla\CMS\Plugin\PluginHelper;
use Joomla\Database\DatabaseInterface;
use Joomla\DI\Container;
use Joomla\DI\ServiceProviderInterface;
use Joomla\Event\DispatcherInterface;
use Joomla\Plugin\Privacy\User\Extension\UserPlugin;
return new class () implements ServiceProviderInterface {
/**
* Registers the service provider with a DI container.
*
* @param Container $container The DI container.
*
* @return void
*
* @since 4.4.0
*/
public function register(Container $container): void
{
$container->set(
PluginInterface::class,
function (Container $container) {
$plugin = new UserPlugin(
$container->get(DispatcherInterface::class),
(array) PluginHelper::getPlugin('privacy', 'user')
);
$plugin->setApplication(Factory::getApplication());
$plugin->setDatabase($container->get(DatabaseInterface::class));
return $plugin;
}
);
}
};

View File

@ -0,0 +1,257 @@
<?php
/**
* @package Joomla.Plugin
* @subpackage Privacy.user
*
* @copyright (C) 2018 Open Source Matters, Inc. <https://www.joomla.org>
* @license GNU General Public License version 2 or later; see LICENSE.txt
*/
namespace Joomla\Plugin\Privacy\User\Extension;
use Joomla\CMS\Event\Privacy\CanRemoveDataEvent;
use Joomla\CMS\Event\Privacy\ExportRequestEvent;
use Joomla\CMS\Event\Privacy\RemoveDataEvent;
use Joomla\CMS\Language\Text;
use Joomla\CMS\Table\User as TableUser;
use Joomla\CMS\User\User;
use Joomla\CMS\User\UserHelper;
use Joomla\Component\Privacy\Administrator\Plugin\PrivacyPlugin;
use Joomla\Component\Privacy\Administrator\Removal\Status;
use Joomla\Database\ParameterType;
use Joomla\Event\SubscriberInterface;
use Joomla\Utilities\ArrayHelper;
// phpcs:disable PSR1.Files.SideEffects
\defined('_JEXEC') or die;
// phpcs:enable PSR1.Files.SideEffects
/**
* Privacy plugin managing Joomla user data
*
* @since 3.9.0
*/
final class UserPlugin extends PrivacyPlugin implements SubscriberInterface
{
/**
* Returns an array of events this subscriber will listen to.
*
* @return array
*
* @since 5.0.0
*/
public static function getSubscribedEvents(): array
{
return [
'onPrivacyCanRemoveData' => 'onPrivacyCanRemoveData',
'onPrivacyRemoveData' => 'onPrivacyRemoveData',
'onPrivacyExportRequest' => 'onPrivacyExportRequest',
];
}
/**
* Performs validation to determine if the data associated with a remove information request can be processed
*
* This event will not allow a super user account to be removed
*
* @param CanRemoveDataEvent $event The request event
*
* @return void
*
* @since 3.9.0
*/
public function onPrivacyCanRemoveData(CanRemoveDataEvent $event)
{
$user = $event->getUser();
$status = new Status();
if (!$user) {
$event->addResult($status);
return;
}
if ($user->authorise('core.admin')) {
$status->canRemove = false;
$status->reason = Text::_('PLG_PRIVACY_USER_ERROR_CANNOT_REMOVE_SUPER_USER');
}
$event->addResult($status);
}
/**
* Processes an export request for Joomla core user data
*
* This event will collect data for the following core tables:
*
* - #__users (excluding the password, otpKey, and otep columns)
* - #__user_notes
* - #__user_profiles
* - User custom fields
*
* @param ExportRequestEvent $event The request event
*
* @return void
*
* @since 3.9.0
*/
public function onPrivacyExportRequest(ExportRequestEvent $event)
{
$user = $event->getUser();
if (!$user) {
return;
}
/** @var TableUser $userTable */
$userTable = User::getTable();
$userTable->load($user->id);
$domains = [];
$domains[] = $this->createUserDomain($userTable);
$domains[] = $this->createNotesDomain($userTable);
$domains[] = $this->createProfileDomain($userTable);
$domains[] = $this->createCustomFieldsDomain('com_users.user', [$userTable]);
$event->addResult($domains);
}
/**
* Removes the data associated with a remove information request
*
* This event will pseudoanonymise the user account
*
* @param RemoveDataEvent $event The remove data event
*
* @return void
*
* @since 3.9.0
*/
public function onPrivacyRemoveData(RemoveDataEvent $event)
{
$user = $event->getUser();
// This plugin only processes data for registered user accounts
if (!$user) {
return;
}
$pseudoanonymisedData = [
'name' => 'User ID ' . $user->id,
'username' => bin2hex(random_bytes(12)),
'email' => 'UserID' . $user->id . 'removed@email.invalid',
'block' => true,
];
$user->bind($pseudoanonymisedData);
$user->save();
// Destroy all sessions for the user account
UserHelper::destroyUserSessions($user->id);
}
/**
* Create the domain for the user notes data
*
* @param TableUser $user The TableUser object to process
*
* @return \Joomla\Component\Privacy\Administrator\Export\Domain
*
* @since 3.9.0
*/
private function createNotesDomain(TableUser $user)
{
$domain = $this->createDomain('user_notes', 'joomla_user_notes_data');
$db = $this->getDatabase();
$query = $db->getQuery(true)
->select('*')
->from($db->quoteName('#__user_notes'))
->where($db->quoteName('user_id') . ' = :userid')
->bind(':userid', $user->id, ParameterType::INTEGER);
$items = $db->setQuery($query)->loadAssocList();
// Remove user ID columns
foreach (['user_id', 'created_user_id', 'modified_user_id'] as $column) {
$items = ArrayHelper::dropColumn($items, $column);
}
foreach ($items as $item) {
$domain->addItem($this->createItemFromArray($item, $item['id']));
}
return $domain;
}
/**
* Create the domain for the user profile data
*
* @param TableUser $user The TableUser object to process
*
* @return \Joomla\Component\Privacy\Administrator\Export\Domain
*
* @since 3.9.0
*/
private function createProfileDomain(TableUser $user)
{
$domain = $this->createDomain('user_profile', 'joomla_user_profile_data');
$db = $this->getDatabase();
$query = $db->getQuery(true)
->select('*')
->from($db->quoteName('#__user_profiles'))
->where($db->quoteName('user_id') . ' = :userid')
->order($db->quoteName('ordering') . ' ASC')
->bind(':userid', $user->id, ParameterType::INTEGER);
$items = $db->setQuery($query)->loadAssocList();
foreach ($items as $item) {
$domain->addItem($this->createItemFromArray($item));
}
return $domain;
}
/**
* Create the domain for the user record
*
* @param TableUser $user The TableUser object to process
*
* @return \Joomla\Component\Privacy\Administrator\Export\Domain
*
* @since 3.9.0
*/
private function createUserDomain(TableUser $user)
{
$domain = $this->createDomain('users', 'joomla_users_data');
$domain->addItem($this->createItemForUserTable($user));
return $domain;
}
/**
* Create an item object for a TableUser object
*
* @param TableUser $user The TableUser object to convert
*
* @return \Joomla\Component\Privacy\Administrator\Export\Item
*
* @since 3.9.0
*/
private function createItemForUserTable(TableUser $user)
{
$data = [];
$exclude = ['password', 'otpKey', 'otep'];
foreach (array_keys($user->getFields()) as $fieldName) {
if (!\in_array($fieldName, $exclude)) {
$data[$fieldName] = $user->$fieldName;
}
}
return $this->createItemFromArray($data, $user->id);
}
}

View File

@ -0,0 +1,21 @@
<?xml version="1.0" encoding="UTF-8"?>
<extension type="plugin" group="privacy" method="upgrade">
<name>plg_privacy_user</name>
<author>Joomla! Project</author>
<creationDate>2018-05</creationDate>
<copyright>(C) 2018 Open Source Matters, Inc.</copyright>
<license>GNU General Public License version 2 or later; see LICENSE.txt</license>
<authorEmail>admin@joomla.org</authorEmail>
<authorUrl>www.joomla.org</authorUrl>
<version>3.9.0</version>
<description>PLG_PRIVACY_USER_XML_DESCRIPTION</description>
<namespace path="src">Joomla\Plugin\Privacy\User</namespace>
<files>
<folder plugin="user">services</folder>
<folder>src</folder>
</files>
<languages>
<language tag="en-GB">language/en-GB/plg_privacy_user.ini</language>
<language tag="en-GB">language/en-GB/plg_privacy_user.sys.ini</language>
</languages>
</extension>