Skip to content

Commit

Permalink
Merge branch 'b-7.2.x-extral-all-user-data-OXDEV-805' into b-7.2.x
Browse files Browse the repository at this point in the history
  • Loading branch information
NikolaIvanovski committed Oct 10, 2024
2 parents 1d145a8 + 46c9aa3 commit 1cae215
Show file tree
Hide file tree
Showing 54 changed files with 2,039 additions and 4 deletions.
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@ and this project adheres to [Semantic Versioning](http://semver.org/).

## [v4.1.0] - Unreleased

### Added
- User Data Export Feature**: Administrators can now export a user's personal data as a ZIP file, encompassing all available information related to that user.

### Removed
- Support of PHP 8.1

Expand Down
7 changes: 5 additions & 2 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,12 @@
"proprietary"
],
"minimum-stability": "dev",
"prefer-stable": true,
"prefer-dist": true,
"require": {
"php": ">=8.2",
"symfony/filesystem": "*"
"symfony/filesystem": "*",
"ext-zip": "*"
},
"require-dev": {
"phpstan/phpstan": "^1.8.11",
Expand Down Expand Up @@ -69,7 +72,7 @@

"codeception": [
"Composer\\Config::disableProcessTimeout",
"THEME_ID=apex MODULE_IDS=oegdproptin vendor/bin/codecept run Acceptance -c tests/codeception.yml --no-redirect"
"THEME_ID=apex MODULE_IDS=oegdproptin /var/www/vendor/bin/codecept run Acceptance -c /var/www/vendor/oxid-esales/gdpr-optin-module/tests/codeception.yml --no-redirect"
]
},
"config": {
Expand Down
3 changes: 3 additions & 0 deletions metadata.php
Original file line number Diff line number Diff line change
Expand Up @@ -96,4 +96,7 @@
'onActivate' => 'OxidEsales\GdprOptinModule\Core\GdprOptinModule::onActivate',
'onDeactivate' => 'OxidEsales\GdprOptinModule\Core\GdprOptinModule::onDeactivate',
],
'controllers' => [
'oegdproptin_user_data_export' => \OxidEsales\GdprOptinModule\UserData\Controller\UserDataExportController::class,
],
];
3 changes: 3 additions & 0 deletions services.yaml
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
imports:
- { resource: src/UserData/services.yaml }

services:

_defaults:
Expand Down
23 changes: 23 additions & 0 deletions src/UserData/Controller/UserDataExportController.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
<?php

/**
* Copyright © OXID eSales AG. All rights reserved.
* See LICENSE file for license details.
*/

declare(strict_types=1);

namespace OxidEsales\GdprOptinModule\UserData\Controller;

use OxidEsales\Eshop\Application\Controller\Admin\AdminController;
use OxidEsales\GdprOptinModule\UserData\Service\UserDataExportServiceInterface;

class UserDataExportController extends AdminController
{
public function exportUserData(): void
{
$userId = $this->getEditObjectId();
$userDataExportService = $this->getService(UserDataExportServiceInterface::class);
$userDataExportService->exportUserData(userId: $userId);
}
}
29 changes: 29 additions & 0 deletions src/UserData/DataType/ResultFile.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
<?php

/**
* Copyright © OXID eSales AG. All rights reserved.
* See LICENSE file for license details.
*/

declare(strict_types=1);

namespace OxidEsales\GdprOptinModule\UserData\DataType;

class ResultFile implements ResultFileInterface
{
public function __construct(
private readonly string $fileName,
private readonly string $content
) {
}

public function getFileName(): string
{
return $this->fileName;
}

public function getContent(): string
{
return $this->content;
}
}
15 changes: 15 additions & 0 deletions src/UserData/DataType/ResultFileInterface.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<?php

/**
* Copyright © OXID eSales AG. All rights reserved.
* See LICENSE file for license details.
*/

namespace OxidEsales\GdprOptinModule\UserData\DataType;

interface ResultFileInterface
{
public function getFileName(): string;

public function getContent(): string;
}
32 changes: 32 additions & 0 deletions src/UserData/DataType/TableDataCollection.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
<?php

/**
* Copyright © OXID eSales AG. All rights reserved.
* See LICENSE file for license details.
*/

declare(strict_types=1);

namespace OxidEsales\GdprOptinModule\UserData\DataType;

class TableDataCollection implements TableDataCollectionInterface
{
/**
* @param array<string, array<array<string, string>>> $dataCollection
*/
public function __construct(
protected string $collectionName,
protected array $dataCollection
) {
}

public function getCollectionName(): string
{
return $this->collectionName;
}

public function getCollection(): array
{
return $this->dataCollection;
}
}
18 changes: 18 additions & 0 deletions src/UserData/DataType/TableDataCollectionInterface.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<?php

/**
* Copyright © OXID eSales AG. All rights reserved.
* See LICENSE file for license details.
*/

namespace OxidEsales\GdprOptinModule\UserData\DataType;

interface TableDataCollectionInterface
{
public function getCollectionName(): string;

/**
* @return array<string, array<array<string, string>>>
*/
public function getCollection(): array;
}
25 changes: 25 additions & 0 deletions src/UserData/Event/UserDataExportCleanupEvent.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
<?php

/**
* Copyright © OXID eSales AG. All rights reserved.
* See LICENSE file for license details.
*/

declare(strict_types=1);

namespace OxidEsales\GdprOptinModule\UserData\Event;

use Symfony\Contracts\EventDispatcher\Event;

class UserDataExportCleanupEvent extends Event implements UserDataExportCleanupEventInterface
{
public function __construct(
private readonly string $filePath
) {
}

public function getFilePath(): string
{
return $this->filePath;
}
}
15 changes: 15 additions & 0 deletions src/UserData/Event/UserDataExportCleanupEventInterface.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<?php

/**
* Copyright © OXID eSales AG. All rights reserved.
* See LICENSE file for license details.
*/

declare(strict_types=1);

namespace OxidEsales\GdprOptinModule\UserData\Event;

interface UserDataExportCleanupEventInterface
{
public function getFilePath(): string;
}
35 changes: 35 additions & 0 deletions src/UserData/Event/UserDataExportCleanupSubscriber.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
<?php

/**
* Copyright © OXID eSales AG. All rights reserved.
* See LICENSE file for license details.
*/

declare(strict_types=1);

namespace OxidEsales\GdprOptinModule\UserData\Event;

use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Contracts\EventDispatcher\Event;

class UserDataExportCleanupSubscriber implements EventSubscriberInterface
{
/**
* @inheritDoc
*/
public static function getSubscribedEvents(): array
{
return [
UserDataExportCleanupEvent::class => 'onUserDataExportCleanup',
];
}

public function onUserDataExportCleanup(UserDataExportCleanupEventInterface&Event $event): void
{
$filePath = $event->getFilePath();

if (file_exists($filePath)) {
unlink($filePath);
}
}
}
14 changes: 14 additions & 0 deletions src/UserData/Exception/AggregationTypeException.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<?php

/**
* Copyright © OXID eSales AG. All rights reserved.
* See LICENSE file for license details.
*/

declare(strict_types=1);

namespace OxidEsales\GdprOptinModule\UserData\Exception;

class AggregationTypeException extends \Exception
{
}
14 changes: 14 additions & 0 deletions src/UserData/Exception/JsonSerializationException.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<?php

/**
* Copyright © OXID eSales AG. All rights reserved.
* See LICENSE file for license details.
*/

declare(strict_types=1);

namespace OxidEsales\GdprOptinModule\UserData\Exception;

class JsonSerializationException extends \Exception
{
}
14 changes: 14 additions & 0 deletions src/UserData/Exception/UserDataFileDownloadException.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<?php

/**
* Copyright © OXID eSales AG. All rights reserved.
* See LICENSE file for license details.
*/

declare(strict_types=1);

namespace OxidEsales\GdprOptinModule\UserData\Exception;

class UserDataFileDownloadException extends \Exception
{
}
16 changes: 16 additions & 0 deletions src/UserData/Exception/ZipCreationException.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
<?php

/**
* Copyright © OXID eSales AG. All rights reserved.
* See LICENSE file for license details.
*/

declare(strict_types=1);

namespace OxidEsales\GdprOptinModule\UserData\Exception;

use RuntimeException;

class ZipCreationException extends RuntimeException
{
}
20 changes: 20 additions & 0 deletions src/UserData/Infrastructure/DataSelectorInterface.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
<?php

/**
* Copyright © OXID eSales AG. All rights reserved.
* See LICENSE file for license details.
*/

namespace OxidEsales\GdprOptinModule\UserData\Infrastructure;

interface DataSelectorInterface
{
public function getCollection(): string;

public function getSelectionTable(): string;

/**
* @return array<array<string, string>>
*/
public function getDataForColumnValue(string $columnValue): array;
}
61 changes: 61 additions & 0 deletions src/UserData/Infrastructure/GeneralTableDataSelector.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
<?php

/**
* Copyright © OXID eSales AG. All rights reserved.
* See LICENSE file for license details.
*/

declare(strict_types=1);

namespace OxidEsales\GdprOptinModule\UserData\Infrastructure;

use Doctrine\DBAL\ForwardCompatibility\Result;
use OxidEsales\EshopCommunity\Internal\Framework\Database\QueryBuilderFactoryInterface;

class GeneralTableDataSelector implements DataSelectorInterface
{
/**
* @SuppressWarnings(PHPMD.BooleanArgumentFlag) Not different behaviour, just protection from explosion
*/
public function __construct(
private string $collection,
private string $selectionTable,
private string $filterColumn,
private QueryBuilderFactoryInterface $queryBuilderFactory,
private bool $optional = false,
) {
}

public function getCollection(): string
{
return $this->collection;
}

public function getSelectionTable(): string
{
return $this->selectionTable;
}

public function getDataForColumnValue(string $columnValue): array
{
$queryBuilder = $this->queryBuilderFactory->create();

try {
$queryBuilder->select('*')
->from($this->selectionTable)
->where($this->filterColumn . ' = :filterValue')
->setParameter('filterValue', $columnValue);

/** @var Result $result */
$result = $queryBuilder->execute(); /** @phpstan-ignore missingType.iterableValue */

return $result->fetchAllAssociative();
} catch (\Exception $e) {
if (!$this->optional) {
throw $e;
}
}

return [];
}
}
Loading

0 comments on commit 1cae215

Please sign in to comment.