-
Notifications
You must be signed in to change notification settings - Fork 8
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #77 from humhub/enh/167-user-data-export-rest
User data export
- Loading branch information
Showing
13 changed files
with
604 additions
and
20 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,74 @@ | ||
<?php | ||
/** | ||
* @link https://www.humhub.org/ | ||
* @copyright Copyright (c) HumHub GmbH & Co. KG | ||
* @license https://www.humhub.com/licences | ||
*/ | ||
|
||
namespace humhub\modules\legal\controllers; | ||
|
||
use humhub\modules\legal\Module; | ||
use humhub\modules\legal\services\ExportService; | ||
use humhub\modules\user\components\BaseAccountController; | ||
use Yii; | ||
use yii\web\BadRequestHttpException; | ||
use yii\web\NotFoundHttpException; | ||
|
||
/* @property Module $module */ | ||
class ExportController extends BaseAccountController | ||
{ | ||
/** | ||
* @inheritdoc | ||
*/ | ||
protected function getAccessRules() | ||
{ | ||
return array_merge(parent::getAccessRules(), [ | ||
['checkEnabledExportUserData'], | ||
]); | ||
} | ||
|
||
public function checkEnabledExportUserData($rule, $access) | ||
{ | ||
return $this->module->isEnabledExportUserData(); | ||
} | ||
|
||
public function actionIndex() | ||
{ | ||
return $this->render('index', [ | ||
'service' => ExportService::instance(), | ||
]); | ||
} | ||
|
||
public function actionRequest() | ||
{ | ||
if (ExportService::instance()->requestPackage()) { | ||
$this->view->success(Yii::t('LegalModule.base', 'The exporting of your data has been started, please wait some time.')); | ||
} else { | ||
$this->view->error('Cannot start the exporting of your data, please try again.'); | ||
} | ||
|
||
return $this->redirect(['index']); | ||
} | ||
|
||
public function actionDownload() | ||
{ | ||
$package = ExportService::instance()->downloadPackage(); | ||
|
||
if ($package === null) { | ||
throw new NotFoundHttpException(); | ||
} | ||
|
||
return $package; | ||
} | ||
|
||
public function actionDelete() | ||
{ | ||
if (ExportService::instance()->deletePackage()) { | ||
$this->view->success(Yii::t('LegalModule.base', 'The package has been deleted.')); | ||
} else { | ||
$this->view->error('Cannot delete the package, please try again.'); | ||
} | ||
|
||
return $this->redirect(['index']); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
# Development вocumentation | ||
|
||
## Export user data | ||
|
||
Please note that this feature will only work if the [RESTful API](https://github.com/humhub/rest) module is enabled. | ||
|
||
To append user data from another module: | ||
|
||
1) Add the following line to the `events` section of your module's `config.php` file: | ||
|
||
```php | ||
['class' => 'humhub\modules\legal\services\ExportService', 'event' => 'collectUserData', 'callback' => ['humhub\modules\your_module\Events', 'onLegalModuleUserDataExport']], | ||
``` | ||
|
||
2) Implement the `humhub\modules\your_module\Events::onLegalModuleUserDataExport` method in your `Events` class like this: | ||
|
||
```php | ||
public static function onLegalModuleUserDataExport(\humhub\modules\legal\events\UserDataCollectionEvent $event) | ||
{ | ||
$event->addExportData('wiki', array_map(function ($page) { | ||
return \humhub\modules\wiki\helpers\RestDefinitions::getWikiPage($page); | ||
}, \humhub\modules\wiki\models\WikiPage::find() | ||
->joinWith('content') | ||
->andWhere(['content.created_by' => $event->user->id]) | ||
->all())); | ||
|
||
$files = File::findAll(['created_by' => $event->user->id]); | ||
foreach ($files as $file) { | ||
$event->addExportFile($file->file_name, $file->store->get()); | ||
} | ||
} | ||
``` | ||
|
||
To test it, go to edit your profile, and run "Export your data". You should find the file `/files/wiki.json` in the ZIP archive, along with all the user's uploaded files in the `/uploads/` folder. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
# Manual | ||
|
||
## Modules that support user data export | ||
|
||
- [Calendar](https://github.com/humhub/calendar) | ||
- [Files](https://github.com/humhub/cfiles) | ||
- [Messenger](https://github.com/humhub/mail) | ||
- [Polls](https://github.com/humhub/polls) | ||
- [Tasks](https://github.com/humhub/tasks) | ||
- [Wiki](https://github.com/humhub/wiki) | ||
|
||
Please note that the "Export your data" feature only works if the [RESTful API](https://github.com/humhub/rest) module is enabled. By default, it exports the following data from the database: | ||
- User data | ||
- Posts | ||
- Comments | ||
- Likes | ||
- Files (physical files are also attached to the ZIP archive in the `/uploads/` folder) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,130 @@ | ||
<?php | ||
/** | ||
* @link https://www.humhub.org/ | ||
* @copyright Copyright (c) HumHub GmbH & Co. KG | ||
* @license https://www.humhub.com/licences | ||
*/ | ||
|
||
namespace humhub\modules\legal\events; | ||
|
||
use humhub\modules\file\libs\FileHelper; | ||
use humhub\modules\legal\services\ExportService; | ||
use humhub\modules\user\events\UserEvent; | ||
use Yii; | ||
use yii\base\Exception; | ||
use ZipArchive; | ||
|
||
class UserDataCollectionEvent extends UserEvent | ||
{ | ||
/** | ||
* Array with export data: | ||
* - Key is a category name which will be used to name JSON file in ZIP archive | ||
* - Value is an array with any data | ||
* @var array $exportData | ||
*/ | ||
public array $exportData = []; | ||
|
||
/** | ||
* Array with export files: | ||
* - Key is a file name which will be used in ZIP archive | ||
* - Value is a file path where it is really located on the server disk | ||
* @var array $exportFiles | ||
*/ | ||
public array $exportFiles = []; | ||
|
||
/** | ||
* Add data to export | ||
* | ||
* @param string $category Category name which will be used to name JSON file in ZIP archive | ||
* @param array $data Array with any data | ||
*/ | ||
public function addExportData(string $category, array $data) | ||
{ | ||
$index = $this->getUniqueArrayIndex($this->exportData, $category); | ||
$this->exportData[$index] = $data; | ||
} | ||
|
||
/** | ||
* Add a file to export | ||
* | ||
* @param string $fileName File name which will be used in ZIP archive | ||
* @param string $sourceFilePath File path where it is really located on the server disk | ||
*/ | ||
public function addExportFile(string $fileName, string $sourceFilePath) | ||
{ | ||
$index = $this->getUniqueArrayIndex($this->exportFiles, $fileName); | ||
$this->exportFiles[$index] = $sourceFilePath; | ||
} | ||
|
||
private function getUniqueArrayIndex(array $array, string $index): string | ||
{ | ||
$origIndex = $index; | ||
$i = 1; | ||
while (isset($array[$index])) { | ||
$index = preg_replace('/(^.+?)(\.[a-z0-9]+)?$/i', '$1-' . (++$i) . '$2', $origIndex); | ||
} | ||
|
||
return $index; | ||
} | ||
|
||
/** | ||
* @inheritdoc | ||
* @throws Exception | ||
* @throws \Throwable | ||
*/ | ||
public static function trigger($class, $name, $event = null) | ||
{ | ||
parent::trigger($class, $name, $event); | ||
|
||
if ($event instanceof self) { | ||
$event->createPackage(); | ||
} | ||
} | ||
|
||
/** | ||
* Create a package with data json files and with uploaded files | ||
* | ||
* @throws Exception | ||
* @throws \Throwable | ||
* @throws \yii\web\ForbiddenHttpException | ||
*/ | ||
private function createPackage() | ||
{ | ||
if (!Yii::$app->getModule('legal')->isEnabledExportUserData()) { | ||
return; | ||
} | ||
|
||
$packagePath = ExportService::instance($this->user)->getPackagePath(); | ||
|
||
$exportDirPath = dirname($packagePath); | ||
if (!is_dir($exportDirPath)) { | ||
try { | ||
if (!FileHelper::createDirectory($exportDirPath)) { | ||
return; | ||
} | ||
} catch (Exception $e) { | ||
Yii::error('Cannot create a folder for legal module user export data! ' . $e->getMessage(), 'legal'); | ||
return; | ||
} | ||
} | ||
|
||
if (file_exists($packagePath)) { | ||
unlink($packagePath); | ||
} | ||
|
||
$archive = new ZipArchive(); | ||
if (!$archive->open($packagePath, ZipArchive::CREATE)) { | ||
throw new Exception('Error on creating of ZIP archive!'); | ||
} | ||
|
||
foreach ($this->exportData as $category => $data) { | ||
$archive->addFromString('files/' . $category . '.json', json_encode($data)); | ||
} | ||
|
||
foreach ($this->exportFiles as $fileName => $sourceFilePath) { | ||
$archive->addFile($sourceFilePath, 'uploads/' . $fileName); | ||
} | ||
|
||
$archive->close(); | ||
} | ||
} |
Oops, something went wrong.