X-Git-Url: https://git.mxchange.org/?a=blobdiff_plain;f=src%2FModule%2FSettings%2FUserExport.php;h=431cbfe106180517392bb63d20aea40956cc784c;hb=561aba18e3a230c0912ad9483c6df43cc40e09d6;hp=a1ea50353dc630798d6798d8072c6a12ae907321;hpb=0406fe7adeb48775bd5a25638042f61c8d2b4fd1;p=friendica.git diff --git a/src/Module/Settings/UserExport.php b/src/Module/Settings/UserExport.php index a1ea50353d..431cbfe106 100644 --- a/src/Module/Settings/UserExport.php +++ b/src/Module/Settings/UserExport.php @@ -1,17 +1,35 @@ . + * */ namespace Friendica\Module\Settings; -use Friendica\App; use Friendica\Core\Hook; use Friendica\Core\Renderer; use Friendica\Database\DBA; use Friendica\Database\DBStructure; use Friendica\DI; +use Friendica\Model\Item; +use Friendica\Model\Post; use Friendica\Module\BaseSettings; +use Friendica\Network\HTTPException; /** * Module to export user data @@ -28,10 +46,18 @@ class UserExport extends BaseSettings * * If there is an action required through the URL / path, react * accordingly and export the requested data. - **/ - public static function content(array $parameters = []) + * + * @return string + * @throws HTTPException\ForbiddenException + * @throws HTTPException\InternalServerErrorException + */ + protected function content(array $request = []): string { - parent::content($parameters); + if (!local_user()) { + throw new HTTPException\ForbiddenException(DI::l10n()->t('Permission denied.')); + } + + parent::content(); /** * options shown on "Export personal data" page @@ -50,43 +76,52 @@ class UserExport extends BaseSettings '$options' => $options ]); } + /** * raw content generated for the different choices made * by the user. At the moment this returns a JSON file * to the browser which then offers a save / open dialog * to the user. - **/ - public static function rawContent(array $parameters = []) + * + * @throws HTTPException\ForbiddenException + */ + protected function rawContent(array $request = []) { + if (!DI::app()->isLoggedIn()) { + throw new HTTPException\ForbiddenException(DI::l10n()->t('Permission denied.')); + } + $args = DI::args(); if ($args->getArgc() == 3) { // @TODO Replace with router-provided arguments $action = $args->get(2); - $user = DI::app()->user; switch ($action) { case "backup": header("Content-type: application/json"); - header('Content-Disposition: attachment; filename="' . $user['nickname'] . '.' . $action . '"'); - self::exportAll(DI::app()); - exit(); + header('Content-Disposition: attachment; filename="' . DI::app()->getLoggedInUserNickname() . '.' . $action . '"'); + self::exportAll(local_user()); break; case "account": header("Content-type: application/json"); - header('Content-Disposition: attachment; filename="' . $user['nickname'] . '.' . $action . '"'); - self::exportAccount(DI::app()); - exit(); + header('Content-Disposition: attachment; filename="' . DI::app()->getLoggedInUserNickname() . '.' . $action . '"'); + self::exportAccount(local_user()); break; case "contact": header("Content-type: application/csv"); - header('Content-Disposition: attachment; filename="' . $user['nickname'] . '-contacts.csv'. '"'); - self::exportContactsAsCSV(); - exit(); + header('Content-Disposition: attachment; filename="' . DI::app()->getLoggedInUserNickname() . '-contacts.csv' . '"'); + self::exportContactsAsCSV(local_user()); break; - default: - exit(); } + + exit(); } } + + /** + * @param string $query + * @return array + * @throws \Exception + */ private static function exportMultiRow(string $query) { $dbStructure = DBStructure::definition(DI::app()->getBasePath(), false); @@ -98,14 +133,14 @@ class UserExport extends BaseSettings $rows = DBA::p($query); while ($row = DBA::fetch($rows)) { $p = []; - foreach ($row as $k => $v) { - switch ($dbStructure[$table]['fields'][$k]['type']) { - case 'datetime': - $p[$k] = $v ?? DBA::NULL_DATETIME; - break; - default: - $p[$k] = $v; - break; + foreach ($dbStructure[$table]['fields'] as $column => $field) { + if (!isset($row[$column])) { + continue; + } + if ($field['type'] == 'datetime') { + $p[$column] = $row[$column] ?? DBA::NULL_DATETIME; + } else { + $p[$column] = $row[$column]; } } $result[] = $p; @@ -114,6 +149,11 @@ class UserExport extends BaseSettings return $result; } + /** + * @param string $query + * @return array + * @throws \Exception + */ private static function exportRow(string $query) { $dbStructure = DBStructure::definition(DI::app()->getBasePath(), false); @@ -122,75 +162,94 @@ class UserExport extends BaseSettings $table = $match[1]; $result = []; - $r = q($query); - if (DBA::isResult($r)) { - - foreach ($r as $rr) { - foreach ($rr as $k => $v) { - switch ($dbStructure[$table]['fields'][$k]['type']) { - case 'datetime': - $result[$k] = $v ?? DBA::NULL_DATETIME; - break; - default: - $result[$k] = $v; - break; - } + $rows = DBA::p($query); + while ($row = DBA::fetch($rows)) { + foreach ($row as $k => $v) { + if (empty($dbStructure[$table]['fields'][$k])) { + continue; + } + + switch ($dbStructure[$table]['fields'][$k]['type']) { + case 'datetime': + $result[$k] = $v ?? DBA::NULL_DATETIME; + break; + default: + $result[$k] = $v; + break; } } } + DBA::close($rows); + return $result; } /** * Export a list of the contacts as CSV file as e.g. Mastodon and Pleroma are doing. - **/ - private static function exportContactsAsCSV() + * + * @param int $user_id + * @throws \Exception + */ + private static function exportContactsAsCSV(int $user_id) { + if (!$user_id) { + throw new \RuntimeException(DI::l10n()->t('Permission denied.')); + } + // write the table header (like Mastodon) echo "Account address, Show boosts\n"; // get all the contacts - $contacts = DBA::select('contact', ['addr'], ['uid' => $_SESSION['uid'], 'self' => false, 'rel' => [1,3], 'deleted' => false]); + $contacts = DBA::select('contact', ['addr', 'url'], ['uid' => $user_id, 'self' => false, 'rel' => [1, 3], 'deleted' => false]); while ($contact = DBA::fetch($contacts)) { - echo $contact['addr'] . ", true\n"; + echo ($contact['addr'] ?: $contact['url']) . ", true\n"; } DBA::close($contacts); } - private static function exportAccount(App $a) + + /** + * @param int $user_id + * @throws \Exception + */ + private static function exportAccount(int $user_id) { + if (!$user_id) { + throw new \RuntimeException(DI::l10n()->t('Permission denied.')); + } + $user = self::exportRow( - sprintf("SELECT * FROM `user` WHERE `uid` = %d LIMIT 1", intval(local_user())) + sprintf("SELECT * FROM `user` WHERE `uid` = %d LIMIT 1", $user_id) ); $contact = self::exportMultiRow( - sprintf("SELECT * FROM `contact` WHERE `uid` = %d ", intval(local_user())) + sprintf("SELECT * FROM `contact` WHERE `uid` = %d ", $user_id) ); $profile = self::exportMultiRow( - sprintf("SELECT *, 'default' AS `profile_name`, 1 AS `is-default` FROM `profile` WHERE `uid` = %d ", intval(local_user())) + sprintf("SELECT *, 'default' AS `profile_name`, 1 AS `is-default` FROM `profile` WHERE `uid` = %d ", $user_id) ); $profile_fields = self::exportMultiRow( - sprintf("SELECT * FROM `profile_field` WHERE `uid` = %d ", intval(local_user())) + sprintf("SELECT * FROM `profile_field` WHERE `uid` = %d ", $user_id) ); $photo = self::exportMultiRow( - sprintf("SELECT * FROM `photo` WHERE uid = %d AND profile = 1", intval(local_user())) + sprintf("SELECT * FROM `photo` WHERE uid = %d AND profile = 1", $user_id) ); foreach ($photo as &$p) { $p['data'] = bin2hex($p['data']); } $pconfig = self::exportMultiRow( - sprintf("SELECT * FROM `pconfig` WHERE uid = %d", intval(local_user())) + sprintf("SELECT * FROM `pconfig` WHERE uid = %d", $user_id) ); $group = self::exportMultiRow( - sprintf("SELECT * FROM `group` WHERE uid = %d", intval(local_user())) + sprintf("SELECT * FROM `group` WHERE uid = %d", $user_id) ); $group_member = self::exportMultiRow( - sprintf("SELECT `group_member`.`gid`, `group_member`.`contact-id` FROM `group_member` INNER JOIN `group` ON `group`.`id` = `group_member`.`gid` WHERE `group`.`uid` = %d", intval(local_user())) + sprintf("SELECT `group_member`.`gid`, `group_member`.`contact-id` FROM `group_member` INNER JOIN `group` ON `group`.`id` = `group_member`.`gid` WHERE `group`.`uid` = %d", $user_id) ); $output = [ @@ -213,26 +272,25 @@ class UserExport extends BaseSettings /** * echoes account data and items as separated json, one per line * - * @param App $a + * @param int $user_id * @throws \Exception */ - private static function exportAll(App $a) + private static function exportAll(int $user_id) { - self::exportAccount($a); + if (!$user_id) { + throw new \RuntimeException(DI::l10n()->t('Permission denied.')); + } + + self::exportAccount($user_id); echo "\n"; - $total = DBA::count('item', ['uid' => local_user()]); + $total = Post::count(['uid' => $user_id]); // chunk the output to avoid exhausting memory for ($x = 0; $x < $total; $x += 500) { - $r = q("SELECT * FROM `item` WHERE `uid` = %d LIMIT %d, %d", - intval(local_user()), - intval($x), - intval(500) - ); - - $output = ['item' => $r]; - echo json_encode($output, JSON_PARTIAL_OUTPUT_ON_ERROR). "\n"; + $items = Post::selectToArray(Item::ITEM_FIELDLIST, ['uid' => $user_id], ['limit' => [$x, 500]]); + $output = ['item' => $items]; + echo json_encode($output, JSON_PARTIAL_OUTPUT_ON_ERROR) . "\n"; } } }