mirror of
https://github.com/friendica/friendica
synced 2025-04-22 11:10:11 +00:00
Merge branch 'develop' into show_image_upload_limit
# Conflicts: # src/Util/Strings.php # view/lang/C/messages.po
This commit is contained in:
commit
a01872a117
72 changed files with 1605 additions and 1038 deletions
|
@ -325,8 +325,8 @@ class Site extends BaseAdmin
|
|||
/* Installed langs */
|
||||
$lang_choices = DI::l10n()->getAvailableLanguages();
|
||||
|
||||
if (strlen(DI::config()->get('system', 'directory_submit_url')) &&
|
||||
!strlen(DI::config()->get('system', 'directory'))) {
|
||||
if (DI::config()->get('system', 'directory_submit_url') &&
|
||||
!DI::config()->get('system', 'directory')) {
|
||||
DI::config()->set('system', 'directory', dirname(DI::config()->get('system', 'directory_submit_url')));
|
||||
DI::config()->delete('system', 'directory_submit_url');
|
||||
}
|
||||
|
|
|
@ -21,8 +21,12 @@
|
|||
|
||||
namespace Friendica\Module\Api\Mastodon\Accounts;
|
||||
|
||||
use Friendica\App\Router;
|
||||
use Friendica\Core\Logger;
|
||||
use Friendica\DI;
|
||||
use Friendica\Model\Contact;
|
||||
use Friendica\Model\Photo;
|
||||
use Friendica\Model\Profile;
|
||||
use Friendica\Model\User;
|
||||
use Friendica\Module\BaseApi;
|
||||
|
||||
/**
|
||||
|
@ -35,8 +39,72 @@ class UpdateCredentials extends BaseApi
|
|||
self::checkAllowedScope(self::SCOPE_WRITE);
|
||||
$uid = self::getCurrentUserID();
|
||||
|
||||
Logger::info('Patch data', ['data' => $request]);
|
||||
$owner = User::getOwnerDataById($uid);
|
||||
|
||||
$this->response->unsupported(Router::PATCH, $request);
|
||||
$request = $this->getRequest([
|
||||
'bot' => ($owner['contact-type'] == Contact::TYPE_NEWS),
|
||||
'discoverable' => $owner['net-publish'],
|
||||
'display_name' => $owner['name'],
|
||||
'fields_attributes' => [],
|
||||
'locked' => $owner['manually-approve'],
|
||||
'note' => $owner['about'],
|
||||
'avatar' => [],
|
||||
'header' => [],
|
||||
], $request);
|
||||
|
||||
$user = [];
|
||||
$profile = [];
|
||||
|
||||
if ($request['bot']) {
|
||||
$user['account-type'] = Contact::TYPE_NEWS;
|
||||
$user['page-flags'] = User::PAGE_FLAGS_SOAPBOX;
|
||||
} elseif ($owner['contact-type'] == Contact::TYPE_NEWS) {
|
||||
$user['account-type'] = Contact::TYPE_PERSON;
|
||||
} else {
|
||||
$user['account-type'] = $owner['contact-type'];
|
||||
}
|
||||
|
||||
$profile['net-publish'] = $request['discoverable'];
|
||||
|
||||
if (!empty($request['display_name'])) {
|
||||
$user['username'] = $request['display_name'];
|
||||
}
|
||||
|
||||
if ($user['account-type'] == Contact::TYPE_COMMUNITY) {
|
||||
$user['page-flags'] = $request['locked'] ? User::PAGE_FLAGS_PRVGROUP : User::PAGE_FLAGS_COMMUNITY;
|
||||
} elseif ($user['account-type'] == Contact::TYPE_PERSON) {
|
||||
if ($request['locked']) {
|
||||
$user['page-flags'] = User::PAGE_FLAGS_NORMAL;
|
||||
} elseif ($owner['page-flags'] == User::PAGE_FLAGS_NORMAL) {
|
||||
$user['page-flags'] = User::PAGE_FLAGS_SOAPBOX;
|
||||
}
|
||||
}
|
||||
|
||||
if (!empty($request['note'])) {
|
||||
$profile['about'] = $request['note'];
|
||||
}
|
||||
|
||||
Logger::debug('Patch data', ['data' => $request, 'files' => $_FILES]);
|
||||
|
||||
Logger::info('Update profile and user', ['uid' => $uid, 'user' => $user, 'profile' => $profile]);
|
||||
|
||||
if (!empty($request['avatar'])) {
|
||||
Photo::uploadAvatar(1, $request['avatar']);
|
||||
}
|
||||
|
||||
if (!empty($request['header'])) {
|
||||
Photo::uploadBanner(1, $request['header']);
|
||||
}
|
||||
|
||||
User::update($user, $uid);
|
||||
Profile::update($profile, $uid);
|
||||
|
||||
$cdata = Contact::getPublicAndUserContactID($owner['id'], $uid);
|
||||
if (empty($cdata)) {
|
||||
DI::mstdnError()->InternalError();
|
||||
}
|
||||
|
||||
$account = DI::mstdnAccount()->createFromContactId($cdata['user'], $uid);
|
||||
$this->response->exitWithJson($account->toArray());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -26,6 +26,7 @@ use Friendica\Core\System;
|
|||
use Friendica\Database\DBA;
|
||||
use Friendica\DI;
|
||||
use Friendica\Model\Contact;
|
||||
use Friendica\Model\Item;
|
||||
use Friendica\Model\Post;
|
||||
use Friendica\Model\Tag;
|
||||
use Friendica\Module\BaseApi;
|
||||
|
@ -67,10 +68,24 @@ class Search extends BaseApi
|
|||
|
||||
if (empty($request['type']) || ($request['type'] == 'accounts')) {
|
||||
$result['accounts'] = self::searchAccounts($uid, $request['q'], $request['resolve'], $limit, $request['offset'], $request['following']);
|
||||
|
||||
if (!is_array($result['accounts'])) {
|
||||
// Curbing the search if we got an exact result
|
||||
$request['type'] = 'accounts';
|
||||
$result['accounts'] = [$result['accounts']];
|
||||
}
|
||||
}
|
||||
|
||||
if ((empty($request['type']) || ($request['type'] == 'statuses')) && (strpos($request['q'], '@') == false)) {
|
||||
$result['statuses'] = self::searchStatuses($uid, $request['q'], $request['account_id'], $request['max_id'], $request['min_id'], $limit, $request['offset']);
|
||||
|
||||
if (!is_array($result['statuses'])) {
|
||||
// Curbing the search if we got an exact result
|
||||
$request['type'] = 'statuses';
|
||||
$result['statuses'] = [$result['statuses']];
|
||||
}
|
||||
}
|
||||
|
||||
if ((empty($request['type']) || ($request['type'] == 'hashtags')) && (strpos($request['q'], '@') == false)) {
|
||||
$result['hashtags'] = self::searchHashtags($request['q'], $request['exclude_unreviewed'], $limit, $request['offset'], $this->parameters['version']);
|
||||
}
|
||||
|
@ -78,31 +93,59 @@ class Search extends BaseApi
|
|||
System::jsonExit($result);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $uid
|
||||
* @param string $q
|
||||
* @param bool $resolve
|
||||
* @param int $limit
|
||||
* @param int $offset
|
||||
* @param bool $following
|
||||
* @return array|\Friendica\Object\Api\Mastodon\Account Object if result is absolute (exact account match), list if not
|
||||
* @throws \Friendica\Network\HTTPException\InternalServerErrorException
|
||||
* @throws \Friendica\Network\HTTPException\NotFoundException
|
||||
* @throws \ImagickException
|
||||
*/
|
||||
private static function searchAccounts(int $uid, string $q, bool $resolve, int $limit, int $offset, bool $following)
|
||||
{
|
||||
$accounts = [];
|
||||
|
||||
if ((strrpos($q, '@') > 0) || Network::isValidHttpUrl($q)) {
|
||||
$id = Contact::getIdForURL($q, 0, $resolve ? null : false);
|
||||
|
||||
if (!empty($id)) {
|
||||
$accounts[] = DI::mstdnAccount()->createFromContactId($id, $uid);
|
||||
}
|
||||
if (
|
||||
(strrpos($q, '@') > 0 || Network::isValidHttpUrl($q))
|
||||
&& $id = Contact::getIdForURL($q, 0, $resolve ? null : false)
|
||||
) {
|
||||
return DI::mstdnAccount()->createFromContactId($id, $uid);
|
||||
}
|
||||
|
||||
if (empty($accounts)) {
|
||||
$contacts = Contact::searchByName($q, '', $following ? $uid : 0, $limit, $offset);
|
||||
foreach ($contacts as $contact) {
|
||||
$accounts[] = DI::mstdnAccount()->createFromContactId($contact['id'], $uid);
|
||||
}
|
||||
DBA::close($contacts);
|
||||
$accounts = [];
|
||||
foreach (Contact::searchByName($q, '', $following ? $uid : 0, $limit, $offset) as $contact) {
|
||||
$accounts[] = DI::mstdnAccount()->createFromContactId($contact['id'], $uid);
|
||||
}
|
||||
|
||||
return $accounts;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $uid
|
||||
* @param string $q
|
||||
* @param string $account_id
|
||||
* @param int $max_id
|
||||
* @param int $min_id
|
||||
* @param int $limit
|
||||
* @param int $offset
|
||||
* @return array|\Friendica\Object\Api\Mastodon\Status Object is result is absolute (exact post match), list if not
|
||||
* @throws \Friendica\Network\HTTPException\InternalServerErrorException
|
||||
* @throws \Friendica\Network\HTTPException\NotFoundException
|
||||
* @throws \ImagickException
|
||||
*/
|
||||
private static function searchStatuses(int $uid, string $q, string $account_id, int $max_id, int $min_id, int $limit, int $offset)
|
||||
{
|
||||
if (Network::isValidHttpUrl($q)) {
|
||||
$q = Network::convertToIdn($q);
|
||||
// If the user-specific search failed, we search and probe a public post
|
||||
$item_id = Item::fetchByLink($q, $uid) ?: Item::fetchByLink($q);
|
||||
if ($item_id && $item = Post::selectFirst(['uri-id'], ['id' => $item_id])) {
|
||||
return DI::mstdnStatus()->createFromUriId($item['uri-id'], $uid);
|
||||
}
|
||||
}
|
||||
|
||||
$params = ['order' => ['uri-id' => true], 'limit' => [$offset, $limit]];
|
||||
|
||||
if (substr($q, 0, 1) == '#') {
|
||||
|
@ -148,7 +191,7 @@ class Search extends BaseApi
|
|||
return $statuses;
|
||||
}
|
||||
|
||||
private static function searchHashtags(string $q, bool $exclude_unreviewed, int $limit, int $offset, int $version)
|
||||
private static function searchHashtags(string $q, bool $exclude_unreviewed, int $limit, int $offset, int $version): array
|
||||
{
|
||||
$q = ltrim($q, '#');
|
||||
|
||||
|
|
|
@ -21,7 +21,6 @@
|
|||
|
||||
namespace Friendica\Module\Api\Mastodon;
|
||||
|
||||
use Friendica\App\Router;
|
||||
use Friendica\Content\Text\Markdown;
|
||||
use Friendica\Core\Protocol;
|
||||
use Friendica\Core\System;
|
||||
|
@ -35,6 +34,7 @@ use Friendica\Model\Photo;
|
|||
use Friendica\Model\Post;
|
||||
use Friendica\Model\User;
|
||||
use Friendica\Module\BaseApi;
|
||||
use Friendica\Network\HTTPException;
|
||||
use Friendica\Protocol\Activity;
|
||||
use Friendica\Util\Images;
|
||||
|
||||
|
@ -48,7 +48,47 @@ class Statuses extends BaseApi
|
|||
self::checkAllowedScope(self::SCOPE_WRITE);
|
||||
$uid = self::getCurrentUserID();
|
||||
|
||||
$this->response->unsupported(Router::PUT, $request);
|
||||
$request = $this->getRequest([
|
||||
'status' => '', // Text content of the status. If media_ids is provided, this becomes optional. Attaching a poll is optional while status is provided.
|
||||
'in_reply_to_id' => 0, // ID of the status being replied to, if status is a reply
|
||||
'spoiler_text' => '', // Text to be shown as a warning or subject before the actual content. Statuses are generally collapsed behind this field.
|
||||
'language' => '', // ISO 639 language code for this status.
|
||||
], $request);
|
||||
|
||||
$owner = User::getOwnerDataById($uid);
|
||||
|
||||
$condition = [
|
||||
'uid' => $uid,
|
||||
'uri-id' => $this->parameters['id'],
|
||||
'contact-id' => $owner['id'],
|
||||
'author-id' => Contact::getPublicIdByUserId($uid),
|
||||
'origin' => true,
|
||||
];
|
||||
|
||||
$post = Post::selectFirst(['uri-id', 'id'], $condition);
|
||||
if (empty($post['id'])) {
|
||||
throw new HTTPException\NotFoundException('Item with URI ID ' . $this->parameters['id'] . ' not found for user ' . $uid . '.');
|
||||
}
|
||||
|
||||
// The imput is defined as text. So we can use Markdown for some enhancements
|
||||
$item = ['body' => Markdown::toBBCode($request['status']), 'app' => $this->getApp()];
|
||||
|
||||
if (!empty($request['language'])) {
|
||||
$item['language'] = json_encode([$request['language'] => 1]);
|
||||
}
|
||||
|
||||
if (!empty($request['spoiler_text'])) {
|
||||
if ($request['in_reply_to_id'] != $post['uri-id']) {
|
||||
$item['body'] = '[abstract=' . Protocol::ACTIVITYPUB . ']' . $request['spoiler_text'] . "[/abstract]\n" . $item['body'];
|
||||
} else {
|
||||
$item['title'] = $request['spoiler_text'];
|
||||
}
|
||||
}
|
||||
|
||||
Item::update($item, ['id' => $post['id']]);
|
||||
Item::updateDisplayCache($post['uri-id']);
|
||||
|
||||
System::jsonExit(DI::mstdnStatus()->createFromUriId($post['uri-id'], $uid));
|
||||
}
|
||||
|
||||
protected function post(array $request = [])
|
||||
|
@ -80,14 +120,7 @@ class Statuses extends BaseApi
|
|||
$item['contact-id'] = $owner['id'];
|
||||
$item['author-id'] = $item['owner-id'] = Contact::getPublicIdByUserId($uid);
|
||||
$item['body'] = $body;
|
||||
|
||||
if (!empty(self::getCurrentApplication()['name'])) {
|
||||
$item['app'] = self::getCurrentApplication()['name'];
|
||||
}
|
||||
|
||||
if (empty($item['app'])) {
|
||||
$item['app'] = 'API';
|
||||
}
|
||||
$item['app'] = $this->getApp();
|
||||
|
||||
switch ($request['visibility']) {
|
||||
case 'public':
|
||||
|
@ -257,4 +290,13 @@ class Statuses extends BaseApi
|
|||
|
||||
System::jsonExit(DI::mstdnStatus()->createFromUriId($this->parameters['id'], $uid));
|
||||
}
|
||||
|
||||
private function getApp(): string
|
||||
{
|
||||
if (!empty(self::getCurrentApplication()['name'])) {
|
||||
return self::getCurrentApplication()['name'];
|
||||
} else {
|
||||
return 'API';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
57
src/Module/Api/Mastodon/Statuses/Source.php
Normal file
57
src/Module/Api/Mastodon/Statuses/Source.php
Normal file
|
@ -0,0 +1,57 @@
|
|||
<?php
|
||||
/**
|
||||
* @copyright Copyright (C) 2010-2022, the Friendica project
|
||||
*
|
||||
* @license GNU AGPL version 3 or any later version
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
namespace Friendica\Module\Api\Mastodon\Statuses;
|
||||
|
||||
use Friendica\Core\System;
|
||||
use Friendica\DI;
|
||||
use Friendica\Model\Post;
|
||||
use Friendica\Module\BaseApi;
|
||||
use Friendica\Network\HTTPException;
|
||||
|
||||
/**
|
||||
* @see https://docs.joinmastodon.org/methods/statuses/#source
|
||||
*/
|
||||
class Source extends BaseApi
|
||||
{
|
||||
/**
|
||||
* @throws \Friendica\Network\HTTPException\InternalServerErrorException
|
||||
*/
|
||||
protected function rawContent(array $request = [])
|
||||
{
|
||||
self::checkAllowedScope(self::SCOPE_READ);
|
||||
$uid = self::getCurrentUserID();
|
||||
|
||||
if (empty($this->parameters['id'])) {
|
||||
DI::mstdnError()->UnprocessableEntity();
|
||||
}
|
||||
|
||||
$id = $this->parameters['id'];
|
||||
|
||||
if (!Post::exists(['uri-id' => $id, 'uid' => [0, $uid]])) {
|
||||
throw new HTTPException\NotFoundException('Item with URI ID ' . $id . ' not found' . ($uid ? ' for user ' . $uid : '.'));
|
||||
}
|
||||
|
||||
$source = DI::mstdnStatusSource()->createFromUriId($id, $uid);
|
||||
|
||||
System::jsonExit($source->toArray());
|
||||
}
|
||||
}
|
|
@ -48,7 +48,10 @@ class Suggestions extends BaseApi
|
|||
$accounts = [];
|
||||
|
||||
foreach ($suggestions as $suggestion) {
|
||||
$accounts[] = DI::mstdnAccount()->createFromContactId($suggestion['id'], $uid);
|
||||
$accounts[] = [
|
||||
'source' => 'past_interactions',
|
||||
'account' => DI::mstdnAccount()->createFromContactId($suggestion['id'], $uid)
|
||||
];
|
||||
}
|
||||
|
||||
System::jsonExit($accounts);
|
||||
|
|
|
@ -37,7 +37,6 @@ class Attach extends BaseModule
|
|||
*/
|
||||
protected function rawContent(array $request = [])
|
||||
{
|
||||
$a = DI::app();
|
||||
if (empty($this->parameters['item'])) {
|
||||
throw new \Friendica\Network\HTTPException\BadRequestException();
|
||||
}
|
||||
|
|
|
@ -327,7 +327,7 @@ class Profile extends BaseModule
|
|||
'$submit' => $this->t('Submit'),
|
||||
'$lbl_info1' => $lbl_info1,
|
||||
'$lbl_info2' => $this->t('Their personal note'),
|
||||
'$reason' => trim($contact['reason']),
|
||||
'$reason' => trim($contact['reason'] ?? ''),
|
||||
'$infedit' => $this->t('Edit contact notes'),
|
||||
'$common_link' => 'contact/' . $contact['id'] . '/contacts/common',
|
||||
'$relation_text' => $relation_text,
|
||||
|
|
100
src/Module/Media/Attachment/Browser.php
Normal file
100
src/Module/Media/Attachment/Browser.php
Normal file
|
@ -0,0 +1,100 @@
|
|||
<?php
|
||||
/**
|
||||
* @copyright Copyright (C) 2010-2022, the Friendica project
|
||||
*
|
||||
* @license GNU AGPL version 3 or any later version
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
namespace Friendica\Module\Media\Attachment;
|
||||
|
||||
use Friendica\App;
|
||||
use Friendica\BaseModule;
|
||||
use Friendica\Core\L10n;
|
||||
use Friendica\Core\Renderer;
|
||||
use Friendica\Core\Session\Capability\IHandleUserSessions;
|
||||
use Friendica\Core\System;
|
||||
use Friendica\Model\Attach;
|
||||
use Friendica\Module\Response;
|
||||
use Friendica\Network\HTTPException\UnauthorizedException;
|
||||
use Friendica\Util\Profiler;
|
||||
use Friendica\Util\Strings;
|
||||
use Psr\Log\LoggerInterface;
|
||||
|
||||
/**
|
||||
* Browser for Attachments
|
||||
*/
|
||||
class Browser extends BaseModule
|
||||
{
|
||||
/** @var IHandleUserSessions */
|
||||
protected $session;
|
||||
/** @var App */
|
||||
protected $app;
|
||||
|
||||
public function __construct(L10n $l10n, App\BaseURL $baseUrl, App\Arguments $args, LoggerInterface $logger, Profiler $profiler, Response $response, IHandleUserSessions $session, App $app, array $server, array $parameters = [])
|
||||
{
|
||||
parent::__construct($l10n, $baseUrl, $args, $logger, $profiler, $response, $server, $parameters);
|
||||
|
||||
$this->session = $session;
|
||||
$this->app = $app;
|
||||
}
|
||||
|
||||
protected function content(array $request = []): string
|
||||
{
|
||||
if (!$this->session->getLocalUserId()) {
|
||||
throw new UnauthorizedException($this->t('You need to be logged in to access this page.'));
|
||||
}
|
||||
|
||||
// Needed to match the correct template in a module that uses a different theme than the user/site/default
|
||||
$theme = Strings::sanitizeFilePathItem($request['theme'] ?? '');
|
||||
if ($theme && is_file("view/theme/$theme/config.php")) {
|
||||
$this->app->setCurrentTheme($theme);
|
||||
}
|
||||
|
||||
$files = Attach::selectToArray(['id', 'filename', 'filetype'], ['uid' => $this->session->getLocalUserId()]);
|
||||
|
||||
$fileArray = array_map([$this, 'map_files'], $files);
|
||||
|
||||
$tpl = Renderer::getMarkupTemplate('media/browser.tpl');
|
||||
$output = Renderer::replaceMacros($tpl, [
|
||||
'$type' => 'attachment',
|
||||
'$path' => ['' => $this->t('Files')],
|
||||
'$folders' => false,
|
||||
'$files' => $fileArray,
|
||||
'$cancel' => $this->t('Cancel'),
|
||||
'$nickname' => $this->app->getLoggedInUserNickname(),
|
||||
'$upload' => $this->t('Upload'),
|
||||
]);
|
||||
|
||||
if (empty($request['mode'])) {
|
||||
System::httpExit($output);
|
||||
}
|
||||
|
||||
return $output;
|
||||
}
|
||||
|
||||
protected function map_files(array $record): array
|
||||
{
|
||||
list($m1, $m2) = explode('/', $record['filetype']);
|
||||
$filetype = file_exists(sprintf('images/icons/%s.png', $m1) ? $m1 : 'text');
|
||||
|
||||
return [
|
||||
sprintf('%s/attach/%s', $this->baseUrl, $record['id']),
|
||||
$record['filename'],
|
||||
sprintf('%s/images/icon/16/%s.png', $this->baseUrl, $filetype),
|
||||
];
|
||||
}
|
||||
}
|
|
@ -19,7 +19,7 @@
|
|||
*
|
||||
*/
|
||||
|
||||
namespace Friendica\Module\Profile\Attachment;
|
||||
namespace Friendica\Module\Media\Attachment;
|
||||
|
||||
use Friendica\App;
|
||||
use Friendica\Core\Config\Capability\IManageConfigValues;
|
||||
|
@ -73,30 +73,12 @@ class Upload extends \Friendica\BaseModule
|
|||
$this->response->setType(Response::TYPE_JSON, 'application/json');
|
||||
}
|
||||
|
||||
$nick = $this->parameters['nickname'];
|
||||
$owner = User::getOwnerDataByNick($nick);
|
||||
$owner = User::getOwnerDataById($this->userSession->getLocalUserId());
|
||||
if (!$owner) {
|
||||
$this->logger->warning('owner is not a valid record:', ['owner' => $owner, 'nick' => $nick]);
|
||||
$this->logger->warning('Owner not found.', ['uid' => $this->userSession->getLocalUserId()]);
|
||||
return $this->return(401, $this->t('Invalid request.'));
|
||||
}
|
||||
|
||||
$can_post = false;
|
||||
$contact_id = 0;
|
||||
$page_owner_uid = $owner['uid'];
|
||||
$community_page = $owner['page-flags'] == User::PAGE_FLAGS_COMMUNITY;
|
||||
|
||||
if ($this->userSession->getLocalUserId() && $this->userSession->getLocalUserId() == $page_owner_uid) {
|
||||
$can_post = true;
|
||||
} elseif ($community_page && !empty($this->userSession->getRemoteContactID($page_owner_uid))) {
|
||||
$contact_id = $this->userSession->getRemoteContactID($page_owner_uid);
|
||||
$can_post = $this->database->exists('contact', ['blocked' => false, 'pending' => false, 'id' => $contact_id, 'uid' => $page_owner_uid]);
|
||||
}
|
||||
|
||||
if (!$can_post) {
|
||||
$this->logger->warning('User does not have required permissions', ['contact_id' => $contact_id, 'page_owner_uid' => $page_owner_uid]);
|
||||
return $this->return(403, $this->t('Permission denied.'), true);
|
||||
}
|
||||
|
||||
if (empty($_FILES['userfile'])) {
|
||||
$this->logger->warning('No file uploaded (empty userfile)');
|
||||
return $this->return(401, $this->t('Invalid request.'), true);
|
||||
|
@ -126,7 +108,7 @@ class Upload extends \Friendica\BaseModule
|
|||
return $this->return(401, $msg);
|
||||
}
|
||||
|
||||
$newid = Attach::storeFile($tempFileName, $page_owner_uid, $fileName, '<' . $owner['id'] . '>');
|
||||
$newid = Attach::storeFile($tempFileName, $owner['uid'], $fileName, '<' . $owner['id'] . '>');
|
||||
|
||||
@unlink($tempFileName);
|
||||
|
125
src/Module/Media/Photo/Browser.php
Normal file
125
src/Module/Media/Photo/Browser.php
Normal file
|
@ -0,0 +1,125 @@
|
|||
<?php
|
||||
/**
|
||||
* @copyright Copyright (C) 2010-2022, the Friendica project
|
||||
*
|
||||
* @license GNU AGPL version 3 or any later version
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
namespace Friendica\Module\Media\Photo;
|
||||
|
||||
use Friendica\App;
|
||||
use Friendica\BaseModule;
|
||||
use Friendica\Core\L10n;
|
||||
use Friendica\Core\Renderer;
|
||||
use Friendica\Core\Session\Capability\IHandleUserSessions;
|
||||
use Friendica\Core\System;
|
||||
use Friendica\Model\Photo;
|
||||
use Friendica\Module\Response;
|
||||
use Friendica\Network\HTTPException\UnauthorizedException;
|
||||
use Friendica\Util\Images;
|
||||
use Friendica\Util\Profiler;
|
||||
use Friendica\Util\Strings;
|
||||
use Psr\Log\LoggerInterface;
|
||||
|
||||
/**
|
||||
* Browser for Photos
|
||||
*/
|
||||
class Browser extends BaseModule
|
||||
{
|
||||
/** @var IHandleUserSessions */
|
||||
protected $session;
|
||||
/** @var App */
|
||||
protected $app;
|
||||
|
||||
public function __construct(L10n $l10n, App\BaseURL $baseUrl, App\Arguments $args, LoggerInterface $logger, Profiler $profiler, Response $response, IHandleUserSessions $session, App $app, array $server, array $parameters = [])
|
||||
{
|
||||
parent::__construct($l10n, $baseUrl, $args, $logger, $profiler, $response, $server, $parameters);
|
||||
|
||||
$this->session = $session;
|
||||
$this->app = $app;
|
||||
}
|
||||
|
||||
protected function content(array $request = []): string
|
||||
{
|
||||
if (!$this->session->getLocalUserId()) {
|
||||
throw new UnauthorizedException($this->t('You need to be logged in to access this page.'));
|
||||
}
|
||||
|
||||
// Needed to match the correct template in a module that uses a different theme than the user/site/default
|
||||
$theme = Strings::sanitizeFilePathItem($request['theme'] ?? '');
|
||||
if ($theme && is_file("view/theme/$theme/config.php")) {
|
||||
$this->app->setCurrentTheme($theme);
|
||||
}
|
||||
|
||||
$album = $this->parameters['album'] ?? null;
|
||||
|
||||
$photos = Photo::getBrowsablePhotosForUser($this->session->getLocalUserId(), $album);
|
||||
$albums = $album ? false : Photo::getBrowsableAlbumsForUser($this->session->getLocalUserId());
|
||||
|
||||
$path = [
|
||||
'' => $this->t('Photos'),
|
||||
];
|
||||
if (!empty($album)) {
|
||||
$path[$album] = $album;
|
||||
}
|
||||
|
||||
$photosArray = array_map([$this, 'map_files'], $photos);
|
||||
|
||||
$tpl = Renderer::getMarkupTemplate('media/browser.tpl');
|
||||
$output = Renderer::replaceMacros($tpl, [
|
||||
'$type' => 'photo',
|
||||
'$path' => $path,
|
||||
'$folders' => $albums,
|
||||
'$files' => $photosArray,
|
||||
'$cancel' => $this->t('Cancel'),
|
||||
'$nickname' => $this->app->getLoggedInUserNickname(),
|
||||
'$upload' => $this->t('Upload'),
|
||||
]);
|
||||
|
||||
if (empty($request['mode'])) {
|
||||
System::httpExit($output);
|
||||
}
|
||||
|
||||
return $output;
|
||||
}
|
||||
|
||||
protected function map_files(array $record): array
|
||||
{
|
||||
$types = Images::supportedTypes();
|
||||
$ext = $types[$record['type']];
|
||||
$filename_e = $record['filename'];
|
||||
|
||||
// Take the largest picture that is smaller or equal 640 pixels
|
||||
$photo = Photo::selectFirst(
|
||||
['scale'],
|
||||
[
|
||||
"`resource-id` = ? AND `height` <= ? AND `width` <= ?",
|
||||
$record['resource-id'],
|
||||
640,
|
||||
640
|
||||
],
|
||||
['order' => ['scale']]);
|
||||
$scale = $photo['scale'] ?? $record['loq'];
|
||||
|
||||
return [
|
||||
sprintf('%s/photos/%s/image/%s', $this->baseUrl, $this->app->getLoggedInUserNickname(), $record['resource-id']),
|
||||
$filename_e,
|
||||
sprintf('%s/photo/%s-%s.%s', $this->baseUrl, $record['resource-id'], $scale, $ext),
|
||||
$record['desc'],
|
||||
];
|
||||
}
|
||||
}
|
|
@ -19,7 +19,7 @@
|
|||
*
|
||||
*/
|
||||
|
||||
namespace Friendica\Module\Profile\Photos;
|
||||
namespace Friendica\Module\Media\Photo;
|
||||
|
||||
use Friendica\App;
|
||||
use Friendica\Core\Config\Capability\IManageConfigValues;
|
||||
|
@ -76,36 +76,11 @@ class Upload extends \Friendica\BaseModule
|
|||
|
||||
$album = trim($request['album'] ?? '');
|
||||
|
||||
if (empty($_FILES['media'])) {
|
||||
$user = $this->database->selectFirst('owner-view', ['id', 'uid', 'nickname', 'page-flags'], ['nickname' => $this->parameters['nickname'], 'blocked' => false]);
|
||||
} else {
|
||||
$user = $this->database->selectFirst('owner-view', ['id', 'uid', 'nickname', 'page-flags'], ['uid' => BaseApi::getCurrentUserID() ?: null, 'blocked' => false]);
|
||||
}
|
||||
$owner = User::getOwnerDataById($this->userSession->getLocalUserId());
|
||||
|
||||
if (!$this->database->isResult($user)) {
|
||||
$this->logger->warning('User is not valid', ['nickname' => $this->parameters['nickname'], 'user' => $user]);
|
||||
return $this->return(404, $this->t('User not found.'));
|
||||
}
|
||||
|
||||
/*
|
||||
* Setup permissions structures
|
||||
*/
|
||||
$can_post = false;
|
||||
$visitor = 0;
|
||||
$contact_id = 0;
|
||||
$page_owner_uid = $user['uid'];
|
||||
|
||||
if ($this->userSession->getLocalUserId() && $this->userSession->getLocalUserId() == $page_owner_uid) {
|
||||
$can_post = true;
|
||||
} elseif ($user['page-flags'] == User::PAGE_FLAGS_COMMUNITY && !$this->userSession->getRemoteContactID($page_owner_uid)) {
|
||||
$contact_id = $this->userSession->getRemoteContactID($page_owner_uid);
|
||||
$can_post = $this->database->exists('contact', ['blocked' => false, 'pending' => false, 'id' => $contact_id, 'uid' => $page_owner_uid]);
|
||||
$visitor = $contact_id;
|
||||
}
|
||||
|
||||
if (!$can_post) {
|
||||
$this->logger->warning('No permission to upload files', ['contact_id' => $contact_id, 'page_owner_uid' => $page_owner_uid]);
|
||||
return $this->return(403, $this->t('Permission denied.'), true);
|
||||
if (!$owner) {
|
||||
$this->logger->warning('Owner not found.', ['uid' => $this->userSession->getLocalUserId()]);
|
||||
return $this->return(401, $this->t('Invalid request.'));
|
||||
}
|
||||
|
||||
if (empty($_FILES['userfile']) && empty($_FILES['media'])) {
|
||||
|
@ -223,9 +198,9 @@ class Upload extends \Friendica\BaseModule
|
|||
$album = $this->t('Wall Photos');
|
||||
}
|
||||
|
||||
$allow_cid = '<' . $user['id'] . '>';
|
||||
$allow_cid = '<' . $owner['id'] . '>';
|
||||
|
||||
$result = Photo::store($image, $page_owner_uid, $visitor, $resource_id, $filename, $album, 0, Photo::DEFAULT, $allow_cid);
|
||||
$result = Photo::store($image, $owner['uid'], 0, $resource_id, $filename, $album, 0, Photo::DEFAULT, $allow_cid);
|
||||
if (!$result) {
|
||||
$this->logger->warning('Photo::store() failed', ['result' => $result]);
|
||||
return $this->return(401, $this->t('Image upload failed.'));
|
||||
|
@ -233,7 +208,7 @@ class Upload extends \Friendica\BaseModule
|
|||
|
||||
if ($width > 640 || $height > 640) {
|
||||
$image->scaleDown(640);
|
||||
$result = Photo::store($image, $page_owner_uid, $visitor, $resource_id, $filename, $album, 1, Photo::DEFAULT, $allow_cid);
|
||||
$result = Photo::store($image, $owner['uid'], 0, $resource_id, $filename, $album, 1, Photo::DEFAULT, $allow_cid);
|
||||
if ($result) {
|
||||
$smallest = 1;
|
||||
}
|
||||
|
@ -241,14 +216,14 @@ class Upload extends \Friendica\BaseModule
|
|||
|
||||
if ($width > 320 || $height > 320) {
|
||||
$image->scaleDown(320);
|
||||
$result = Photo::store($image, $page_owner_uid, $visitor, $resource_id, $filename, $album, 2, Photo::DEFAULT, $allow_cid);
|
||||
$result = Photo::store($image, $owner['uid'], 0, $resource_id, $filename, $album, 2, Photo::DEFAULT, $allow_cid);
|
||||
if ($result && ($smallest == 0)) {
|
||||
$smallest = 2;
|
||||
}
|
||||
}
|
||||
|
||||
$this->logger->info('upload done');
|
||||
return $this->return(200, "\n\n" . '[url=' . $this->baseUrl . '/photos/' . $user['nickname'] . '/image/' . $resource_id . '][img]' . $this->baseUrl . "/photo/$resource_id-$smallest." . $image->getExt() . "[/img][/url]\n\n");
|
||||
return $this->return(200, "\n\n" . '[url=' . $this->baseUrl . '/photos/' . $owner['nickname'] . '/image/' . $resource_id . '][img]' . $this->baseUrl . "/photo/$resource_id-$smallest." . $image->getExt() . "[/img][/url]\n\n");
|
||||
}
|
||||
|
||||
/**
|
|
@ -142,14 +142,9 @@ class Salmon extends \Friendica\BaseModule
|
|||
throw new HTTPException\BadRequestException();
|
||||
}
|
||||
|
||||
$key_info = explode('.', $key);
|
||||
$this->logger->info('Key details', ['info' => $key]);
|
||||
|
||||
$m = Strings::base64UrlDecode($key_info[1]);
|
||||
$e = Strings::base64UrlDecode($key_info[2]);
|
||||
|
||||
$this->logger->info('Key details', ['info' => $key_info]);
|
||||
|
||||
$pubkey = Crypto::meToPem($m, $e);
|
||||
$pubkey = SalmonProtocol::magicKeyToPem($key);
|
||||
|
||||
// We should have everything we need now. Let's see if it verifies.
|
||||
|
||||
|
|
|
@ -19,7 +19,7 @@
|
|||
*
|
||||
*/
|
||||
|
||||
namespace Friendica\Module\Profile\Photos;
|
||||
namespace Friendica\Module\Profile;
|
||||
|
||||
use Friendica\App;
|
||||
use Friendica\Content\Pager;
|
||||
|
@ -40,7 +40,7 @@ use Friendica\Util\Images;
|
|||
use Friendica\Util\Profiler;
|
||||
use Psr\Log\LoggerInterface;
|
||||
|
||||
class Index extends \Friendica\Module\BaseProfile
|
||||
class Photos extends \Friendica\Module\BaseProfile
|
||||
{
|
||||
/** @var IHandleUserSessions */
|
||||
private $session;
|
|
@ -23,11 +23,9 @@ namespace Friendica\Module;
|
|||
|
||||
use Friendica\BaseModule;
|
||||
use Friendica\Core\System;
|
||||
use Friendica\DI;
|
||||
use Friendica\Model\User;
|
||||
use Friendica\Network\HTTPException\BadRequestException;
|
||||
use Friendica\Util\Crypto;
|
||||
use Friendica\Util\Strings;
|
||||
use Friendica\Protocol\Salmon;
|
||||
|
||||
/**
|
||||
* prints the public RSA key of a user
|
||||
|
@ -47,9 +45,10 @@ class PublicRSAKey extends BaseModule
|
|||
throw new BadRequestException();
|
||||
}
|
||||
|
||||
Crypto::pemToMe($user['spubkey'], $modulus, $exponent);
|
||||
|
||||
$content = 'RSA' . '.' . Strings::base64UrlEncode($modulus, true) . '.' . Strings::base64UrlEncode($exponent, true);
|
||||
System::httpExit($content, Response::TYPE_BLANK, 'application/magic-public-key');
|
||||
System::httpExit(
|
||||
Salmon::salmonKey($user['spubkey']),
|
||||
Response::TYPE_BLANK,
|
||||
'application/magic-public-key'
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -233,7 +233,7 @@ class PortableContacts extends BaseModule
|
|||
}
|
||||
|
||||
if ($selectedFields['tags']) {
|
||||
$tags = str_replace(',', ' ', $contact['keywords']);
|
||||
$tags = str_replace(',', ' ', $contact['keywords'] ?? '');
|
||||
$tags = explode(' ', $tags);
|
||||
|
||||
$cleaned = [];
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue