Merge remote-tracking branch 'upstream/develop' into logging

This commit is contained in:
Michael 2021-10-22 06:06:39 +00:00
commit a497bd3a3d
36 changed files with 1144 additions and 754 deletions

View File

@ -1,6 +1,6 @@
-- ------------------------------------------ -- ------------------------------------------
-- Friendica 2021.12-dev (Siberian Iris) -- Friendica 2021.12-dev (Siberian Iris)
-- DB_UPDATE_VERSION 1441 -- DB_UPDATE_VERSION 1442
-- ------------------------------------------ -- ------------------------------------------
@ -715,11 +715,11 @@ CREATE TABLE IF NOT EXISTS `intro` (
`contact-id` int unsigned NOT NULL DEFAULT 0 COMMENT '', `contact-id` int unsigned NOT NULL DEFAULT 0 COMMENT '',
`suggest-cid` int unsigned COMMENT 'Suggested contact', `suggest-cid` int unsigned COMMENT 'Suggested contact',
`knowyou` boolean NOT NULL DEFAULT '0' COMMENT '', `knowyou` boolean NOT NULL DEFAULT '0' COMMENT '',
`duplex` boolean NOT NULL DEFAULT '0' COMMENT '', `duplex` boolean NOT NULL DEFAULT '0' COMMENT 'deprecated',
`note` text COMMENT '', `note` text COMMENT '',
`hash` varchar(255) NOT NULL DEFAULT '' COMMENT '', `hash` varchar(255) NOT NULL DEFAULT '' COMMENT '',
`datetime` datetime NOT NULL DEFAULT '0001-01-01 00:00:00' COMMENT '', `datetime` datetime NOT NULL DEFAULT '0001-01-01 00:00:00' COMMENT '',
`blocked` boolean NOT NULL DEFAULT '1' COMMENT '', `blocked` boolean NOT NULL DEFAULT '0' COMMENT 'deprecated',
`ignore` boolean NOT NULL DEFAULT '0' COMMENT '', `ignore` boolean NOT NULL DEFAULT '0' COMMENT '',
PRIMARY KEY(`id`), PRIMARY KEY(`id`),
INDEX `contact-id` (`contact-id`), INDEX `contact-id` (`contact-id`),

View File

@ -36,17 +36,18 @@ doSomething($intros);
``` ```
After: After:
```php ```php
function doSomething(\Friendica\Collection\Introductions $intros) function doSomething(\Friendica\Contact\Introductions\Collection\Introductions $intros)
{ {
foreach ($intros as $intro) { foreach ($intros as $intro) {
/** @var $intro \Friendica\Model\Introduction */ /** @var $intro \Friendica\Contact\Introductions\Entity\Introduction */
$introId = $intro->id; $introId = $intro->id;
} }
} }
/** @var $intros \Friendica\Collection\Introductions */ /** @var $intros \Friendica\Contact\Introductions\Collection\Introductions */
$intros = \Friendica\DI::intro()->select(['uid' => local_user()]); $intros = \Friendica\DI::intro()->selecForUser(local_user());
doSomething($intros); doSomething($intros);
``` ```

View File

@ -14,11 +14,11 @@ Fields
| contact-id | | int unsigned | NO | | 0 | | | contact-id | | int unsigned | NO | | 0 | |
| suggest-cid | Suggested contact | int unsigned | YES | | NULL | | | suggest-cid | Suggested contact | int unsigned | YES | | NULL | |
| knowyou | | boolean | NO | | 0 | | | knowyou | | boolean | NO | | 0 | |
| duplex | | boolean | NO | | 0 | | | duplex | deprecated | boolean | NO | | 0 | |
| note | | text | YES | | NULL | | | note | | text | YES | | NULL | |
| hash | | varchar(255) | NO | | | | | hash | | varchar(255) | NO | | | |
| datetime | | datetime | NO | | 0001-01-01 00:00:00 | | | datetime | | datetime | NO | | 0001-01-01 00:00:00 | |
| blocked | | boolean | NO | | 1 | | | blocked | deprecated | boolean | NO | | 0 | |
| ignore | | boolean | NO | | 0 | | | ignore | | boolean | NO | | 0 | |
Indexes Indexes

View File

@ -1,29 +0,0 @@
<?php
/**
* @copyright Copyright (C) 2010-2021, 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\Collection;
use Friendica\BaseCollection;
class Introductions extends BaseCollection
{
}

View File

@ -0,0 +1,9 @@
<?php
namespace Friendica\Contact\Introduction\Collection;
use Friendica\BaseCollection;
class Introductions extends BaseCollection
{
}

View File

@ -0,0 +1,209 @@
<?php
/**
* @copyright Copyright (C) 2010-2021, 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\Contact\Introduction\Depository;
use Friendica\BaseDepository;
use Friendica\Contact\Introduction\Exception\IntroductionNotFoundException;
use Friendica\Contact\Introduction\Exception\IntroductionPersistenceException;
use Friendica\Contact\Introduction\Collection;
use Friendica\Contact\Introduction\Entity;
use Friendica\Contact\Introduction\Factory;
use Friendica\Database\Database;
use Friendica\Network\HTTPException\NotFoundException;
use Friendica\Util\DateTimeFormat;
use Psr\Log\LoggerInterface;
class Introduction extends BaseDepository
{
/** @var Factory\Introduction */
protected $factory;
protected static $table_name = 'intro';
public function __construct(Database $database, LoggerInterface $logger, Factory\Introduction $factory)
{
parent::__construct($database, $logger, $factory);
}
/**
* @param array $condition
* @param array $params
*
* @return Entity\Introduction
*
* @throws NotFoundException the underlying exception if there's no Introduction with the given conditions
*/
private function selectOne(array $condition, array $params = []): Entity\Introduction
{
return parent::_selectOne($condition, $params);
}
/**
* Converts a given Introduction into a DB compatible row array
*
* @param Entity\Introduction $introduction
*
* @return array
*/
protected function convertToTableRow(Entity\Introduction $introduction): array
{
return [
'uid' => $introduction->uid,
'contact-id' => $introduction->cid,
'suggest-cid' => $introduction->sid,
'knowyou' => $introduction->knowyou ? 1 : 0,
'note' => $introduction->note,
'hash' => $introduction->hash,
'ignore' => $introduction->ignore ? 1 : 0,
'datetime' => $introduction->datetime->format(DateTimeFormat::MYSQL),
];
}
/**
* @param int $id
* @param int $uid
*
* @return Entity\Introduction
*
* @throws IntroductionNotFoundException in case there is no Introduction with this id
*/
public function selectOneById(int $id, int $uid): Entity\Introduction
{
try {
return $this->selectOne(['id' => $id, 'uid' => $uid]);
} catch (NotFoundException $exception) {
throw new IntroductionNotFoundException(sprintf('There is no Introduction with the ID %d for the user %d', $id, $uid), $exception);
}
}
/**
* Selects introductions for a given user
*
* @param int $uid
* @param int|null $min_id
* @param int|null $max_id
* @param int $limit
*
* @return Collection\Introductions
*/
public function selectForUser(int $uid, int $min_id = null, int $max_id = null, int $limit = self::LIMIT): Collection\Introductions
{
try {
$BaseCollection = parent::_selectByBoundaries(
['`uid = ?` AND NOT `ignore`',$uid],
['order' => ['id' => 'DESC']],
$min_id, $max_id, $limit);
} catch (\Exception $e) {
throw new IntroductionPersistenceException(sprintf('Cannot select Introductions for used %d', $uid), $e);
}
return new Collection\Introductions($BaseCollection->getArrayCopy(), $BaseCollection->getTotalCount());
}
/**
* Selects the introduction for a given contact
*
* @param int $cid
*
* @return Entity\Introduction
*
* @throws IntroductionNotFoundException in case there is not Introduction for this contact
*/
public function selectForContact(int $cid): Entity\Introduction
{
try {
return $this->selectOne(['contact-id' => $cid]);
} catch (NotFoundException $exception) {
throw new IntroductionNotFoundException(sprintf('There is no Introduction for the contact %d', $cid), $exception);
}
}
public function countActiveForUser($uid, array $params = []): int
{
try {
return $this->count(['ignore' => false, 'uid' => $uid], $params);
} catch (\Exception $e) {
throw new IntroductionPersistenceException(sprintf('Cannot count Introductions for used %d', $uid), $e);
}
}
/**
* Checks, if the suggested contact already exists for the user
*
* @param int $sid
* @param int $uid
*
* @return bool
*/
public function suggestionExistsForUser(int $sid, int $uid): bool
{
try {
return $this->exists(['uid' => $uid, 'suggest-cid' => $sid]);
} catch (\Exception $e) {
throw new IntroductionPersistenceException(sprintf('Cannot check suggested Introduction for contact %d and user %d', $sid, $uid), $e);
}
}
/**
* @param Entity\Introduction $introduction
*
* @return bool
*
* @throws IntroductionPersistenceException in case the underlying storage cannot delete the Introduction
*/
public function delete(Entity\Introduction $introduction): bool
{
if (!$introduction->id) {
return false;
}
try {
return $this->db->delete(self::$table_name, ['id' => $introduction->id]);
} catch (\Exception $e) {
throw new IntroductionPersistenceException(sprintf('Cannot delete Introduction with id %d', $introduction->id), $e);
}
}
/**
* @param Entity\Introduction $introduction
*
* @return Entity\Introduction
*
* @throws IntroductionPersistenceException In case the underlying storage cannot save the Introduction
*/
public function save(Entity\Introduction $introduction): Entity\Introduction
{
try {
$fields = $this->convertToTableRow($introduction);
if ($introduction->id) {
$this->db->update(self::$table_name, $fields, ['id' => $introduction->id]);
return $this->factory->createFromTableRow($fields);
} else {
$this->db->insert(self::$table_name, $fields);
return $this->selectOneById($this->db->lastInsertId(), $introduction->uid);
}
} catch (\Exception $exception) {
throw new IntroductionPersistenceException(sprintf('Cannot insert/update the Introduction %d for user %d', $introduction->id, $introduction->uid), $exception);
}
}
}

View File

@ -0,0 +1,89 @@
<?php
/**
* @copyright Copyright (C) 2010-2021, 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\Contact\Introduction\Entity;
use Friendica\BaseEntity;
/**
* @property-read int $uid
* @property-read int $cid
* @property-read int|null $sid
* @property-read bool $knowyou
* @property-read string $note
* @property-read string $hash
* @property-read \DateTime $datetime
* @property-read bool $ignore
* @property-read int|null $id
*/
class Introduction extends BaseEntity
{
/** @var int */
protected $uid;
/** @var int */
protected $cid;
/** @var int|null */
protected $sid;
/** @var bool */
protected $knowyou;
/** @var string */
protected $note;
/** @var string */
protected $hash;
/** @var \DateTime */
protected $datetime;
/** @var bool */
protected $ignore;
/** @var int|null */
protected $id;
/**
* @param int $uid
* @param int $cid
* @param int|null $sid
* @param bool $knowyou
* @param string $note
* @param string $hash
* @param \DateTime $datetime
* @param bool $ignore
* @param int|null $id
*/
public function __construct(int $uid, int $cid, ?int $sid, bool $knowyou, string $note, string $hash, \DateTime $datetime, bool $ignore, ?int $id)
{
$this->uid = $uid;
$this->cid = $cid;
$this->sid = $sid;
$this->knowyou = $knowyou;
$this->note = $note;
$this->hash = $hash;
$this->datetime = $datetime;
$this->ignore = $ignore;
$this->id = $id;
}
/**
* Ignore the current Introduction
*/
public function ignore()
{
$this->ignore = true;
}
}

View File

@ -0,0 +1,11 @@
<?php
namespace Friendica\Contact\Introduction\Exception;
class IntroductionNotFoundException extends \OutOfBoundsException
{
public function __construct($message = "", \Throwable $previous = null)
{
parent::__construct($message, 404, $previous);
}
}

View File

@ -0,0 +1,11 @@
<?php
namespace Friendica\Contact\Introduction\Exception;
class IntroductionPersistenceException extends \RuntimeException
{
public function __construct($message = "", \Throwable $previous = null)
{
parent::__construct($message, 500, $previous);
}
}

View File

@ -0,0 +1,73 @@
<?php
/**
* @copyright Copyright (C) 2010-2021, 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\Contact\Introduction\Factory;
use Friendica\BaseFactory;
use Friendica\Contact\Introduction\Entity;
use Friendica\Capabilities\ICanCreateFromTableRow;
use Friendica\Util\DateTimeFormat;
use Friendica\Util\Strings;
class Introduction extends BaseFactory implements ICanCreateFromTableRow
{
/**
* @inheritDoc
*/
public function createFromTableRow(array $row): Entity\Introduction
{
return new Entity\Introduction(
$row['uid'] ?? 0,
$row['contact-id'] ?? 0,
$row['suggest-cid'] ?? null,
!empty($row['knowyou']),
$row['note'] ?? '',
$row['hash'] ?? '',
new \DateTime($row['datetime'] ?? 'now', new \DateTimeZone('UTC')),
!empty($row['ignore']),
$row['id'] ?? null
);
}
public function createNew(
int $uid,
int $cid,
string $note,
int $sid = null,
bool $knowyou = false
): Entity\Introduction {
return $this->createFromTableRow([
'uid' => $uid,
'suggest-cid' => $sid,
'contact-id' => $cid,
'knowyou' => $knowyou,
'note' => $note,
'hash' => Strings::getRandomHex(),
'datetime' => DateTimeFormat::utcNow(),
'ignore' => false,
]);
}
public function createDummy(?int $id): Entity\Introduction
{
return $this->createFromTableRow(['id' => $id]);
}
}

View File

@ -190,7 +190,7 @@ class Nav
$nav['usermenu'][] = ['profile/' . $a->getLoggedInUserNickname(), DI::l10n()->t('Status'), '', DI::l10n()->t('Your posts and conversations')]; $nav['usermenu'][] = ['profile/' . $a->getLoggedInUserNickname(), DI::l10n()->t('Status'), '', DI::l10n()->t('Your posts and conversations')];
$nav['usermenu'][] = ['profile/' . $a->getLoggedInUserNickname() . '/profile', DI::l10n()->t('Profile'), '', DI::l10n()->t('Your profile page')]; $nav['usermenu'][] = ['profile/' . $a->getLoggedInUserNickname() . '/profile', DI::l10n()->t('Profile'), '', DI::l10n()->t('Your profile page')];
$nav['usermenu'][] = ['photos/' . $a->getLoggedInUserNickname(), DI::l10n()->t('Photos'), '', DI::l10n()->t('Your photos')]; $nav['usermenu'][] = ['photos/' . $a->getLoggedInUserNickname(), DI::l10n()->t('Photos'), '', DI::l10n()->t('Your photos')];
$nav['usermenu'][] = ['videos/' . $a->getLoggedInUserNickname(), DI::l10n()->t('Videos'), '', DI::l10n()->t('Your videos')]; $nav['usermenu'][] = ['media/' . $a->getLoggedInUserNickname(), DI::l10n()->t('Media'), '', DI::l10n()->t('Your postings with media')];
$nav['usermenu'][] = ['events/', DI::l10n()->t('Events'), '', DI::l10n()->t('Your events')]; $nav['usermenu'][] = ['events/', DI::l10n()->t('Events'), '', DI::l10n()->t('Your events')];
$nav['usermenu'][] = ['notes/', DI::l10n()->t('Personal notes'), '', DI::l10n()->t('Your personal notes')]; $nav['usermenu'][] = ['notes/', DI::l10n()->t('Personal notes'), '', DI::l10n()->t('Your personal notes')];

View File

@ -435,11 +435,19 @@ abstract class DI
} }
/** /**
* @return Repository\Introduction * @return Contact\Introduction\Depository\Introduction
*/ */
public static function intro() public static function intro()
{ {
return self::$dice->create(Repository\Introduction::class); return self::$dice->create(Contact\Introduction\Depository\Introduction::class);
}
/**
* @return Contact\Introduction\Factory\Introduction
*/
public static function introFactory()
{
return self::$dice->create(Contact\Introduction\Factory\Introduction::class);
} }
public static function permissionSet(): Security\PermissionSet\Depository\PermissionSet public static function permissionSet(): Security\PermissionSet\Depository\PermissionSet

View File

@ -23,9 +23,9 @@ namespace Friendica\Factory\Api\Mastodon;
use Friendica\App\BaseURL; use Friendica\App\BaseURL;
use Friendica\BaseFactory; use Friendica\BaseFactory;
use Friendica\Contact\Introduction\Entity\Introduction;
use Friendica\Model\APContact; use Friendica\Model\APContact;
use Friendica\Model\Contact; use Friendica\Model\Contact;
use Friendica\Model\Introduction;
use Friendica\Network\HTTPException; use Friendica\Network\HTTPException;
use ImagickException; use ImagickException;
use Psr\Log\LoggerInterface; use Psr\Log\LoggerInterface;
@ -49,7 +49,7 @@ class FollowRequest extends BaseFactory
*/ */
public function createFromIntroduction(Introduction $introduction): \Friendica\Object\Api\Mastodon\FollowRequest public function createFromIntroduction(Introduction $introduction): \Friendica\Object\Api\Mastodon\FollowRequest
{ {
$cdata = Contact::getPublicAndUserContactID($introduction->{'contact-id'}, $introduction->uid); $cdata = Contact::getPublicAndUserContactID($introduction->cid, $introduction->uid);
if (empty($cdata)) { if (empty($cdata)) {
$this->logger->warning('Wrong introduction data', ['Introduction' => $introduction]); $this->logger->warning('Wrong introduction data', ['Introduction' => $introduction]);

View File

@ -22,6 +22,7 @@
namespace Friendica\Model; namespace Friendica\Model;
use Friendica\App\BaseURL; use Friendica\App\BaseURL;
use Friendica\Contact\Introduction\Exception\IntroductionNotFoundException;
use Friendica\Content\Pager; use Friendica\Content\Pager;
use Friendica\Content\Text\HTML; use Friendica\Content\Text\HTML;
use Friendica\Core\Hook; use Friendica\Core\Hook;
@ -1085,9 +1086,11 @@ class Contact
]; ];
if (!empty($contact['pending'])) { if (!empty($contact['pending'])) {
$intro = DBA::selectFirst('intro', ['id'], ['contact-id' => $contact['id']]); try {
if (DBA::isResult($intro)) { $intro = DI::intro()->selectForContact($contact['id']);
$menu['follow'] = [DI::l10n()->t('Approve'), 'notifications/intros/' . $intro['id'], true]; $menu['follow'] = [DI::l10n()->t('Approve'), 'notifications/intros/' . $intro->id, true];
} catch (IntroductionNotFoundException $exception) {
DI::logger()->error('Pending contact doesn\'t have an introduction.', ['exception' => $exception]);
} }
} }
} }
@ -2706,12 +2709,13 @@ class Contact
$user = DBA::selectFirst('user', $fields, ['uid' => $importer['uid']]); $user = DBA::selectFirst('user', $fields, ['uid' => $importer['uid']]);
if (DBA::isResult($user) && !in_array($user['page-flags'], [User::PAGE_FLAGS_SOAPBOX, User::PAGE_FLAGS_FREELOVE, User::PAGE_FLAGS_COMMUNITY])) { if (DBA::isResult($user) && !in_array($user['page-flags'], [User::PAGE_FLAGS_SOAPBOX, User::PAGE_FLAGS_FREELOVE, User::PAGE_FLAGS_COMMUNITY])) {
// create notification // create notification
$hash = Strings::getRandomHex();
if (is_array($contact_record)) { if (is_array($contact_record)) {
DBA::insert('intro', ['uid' => $importer['uid'], 'contact-id' => $contact_record['id'], $intro = DI::introFactory()->createNew(
'blocked' => false, 'knowyou' => false, 'note' => $note, $importer['uid'],
'hash' => $hash, 'datetime' => DateTimeFormat::utcNow()]); $contact_record['id'],
$note
);
DI::intro()->save($intro);
} }
Group::addMember(User::getDefaultGroup($importer['uid'], $contact_record["network"]), $contact_record['id']); Group::addMember(User::getDefaultGroup($importer['uid'], $contact_record["network"]), $contact_record['id']);

View File

@ -19,64 +19,43 @@
* *
*/ */
namespace Friendica\Model; namespace Friendica\Model\Contact;
use Friendica\BaseModel; use Friendica\Contact\Introduction\Entity;
use Friendica\Core\Protocol; use Friendica\Core\Protocol;
use Friendica\Database\Database; use Friendica\DI;
use Friendica\Network\HTTPException; use Friendica\Network\HTTPException;
use Friendica\Model\Contact;
use Friendica\Model\User;
use Friendica\Protocol\ActivityPub; use Friendica\Protocol\ActivityPub;
use Friendica\Protocol\Diaspora; use Friendica\Protocol\Diaspora;
use Friendica\Repository;
use Friendica\Util\DateTimeFormat; use Friendica\Util\DateTimeFormat;
use Psr\Log\LoggerInterface;
/** class Introduction
* @property int uid
* @property int fid
* @property int contact-id
* @property bool knowyou
* @property bool duplex
* @property string note
* @property string hash
* @property string datetime
* @property bool blocked
* @property bool ignore
*/
class Introduction extends BaseModel
{ {
/** @var Repository\Introduction */
protected $intro;
public function __construct(Database $dba, LoggerInterface $logger, Repository\Introduction $intro, array $data = [])
{
parent::__construct($dba, $logger, $data);
$this->intro = $intro;
}
/** /**
* Confirms a follow request and sends a notice to the remote contact. * Confirms a follow request and sends a notice to the remote contact.
* *
* @param bool $duplex Is it a follow back? * @param Entity\Introduction $introduction
* @param bool|null $hidden Should this contact be hidden? null = no change * @param bool $duplex Is it a follow back?
* @return bool * @param bool|null $hidden Should this contact be hidden? null = no change
*
* @throws HTTPException\InternalServerErrorException * @throws HTTPException\InternalServerErrorException
* @throws HTTPException\NotFoundException * @throws HTTPException\NotFoundException
* @throws \ImagickException * @throws \ImagickException
*/ */
public function confirm(bool $duplex = false, bool $hidden = null) public static function confirm(Entity\Introduction $introduction, bool $duplex = false, ?bool $hidden = null): void
{ {
$this->logger->info('Confirming follower', ['cid' => $this->{'contact-id'}]); DI::logger()->info('Confirming follower', ['cid' => $introduction->cid]);
$contact = Contact::selectFirst([], ['id' => $this->{'contact-id'}, 'uid' => $this->uid]); $contact = Contact::selectFirst([], ['id' => $introduction->cid, 'uid' => $introduction->uid]);
if (!$contact) { if (!$contact) {
throw new HTTPException\NotFoundException('Contact record not found.'); throw new HTTPException\NotFoundException('Contact record not found.');
} }
$newRelation = $contact['rel']; $newRelation = $contact['rel'];
$writable = $contact['writable']; $writable = $contact['writable'];
if (!empty($contact['protocol'])) { if (!empty($contact['protocol'])) {
$protocol = $contact['protocol']; $protocol = $contact['protocol'];
@ -117,53 +96,24 @@ class Introduction extends BaseModel
if ($newRelation == Contact::FRIEND) { if ($newRelation == Contact::FRIEND) {
if ($protocol == Protocol::DIASPORA) { if ($protocol == Protocol::DIASPORA) {
$ret = Diaspora::sendShare(User::getById($contact['uid']), $contact); $ret = Diaspora::sendShare(User::getById($contact['uid']), $contact);
$this->logger->info('share returns', ['return' => $ret]); DI::logger()->info('share returns', ['return' => $ret]);
} elseif ($protocol == Protocol::ACTIVITYPUB) { } elseif ($protocol == Protocol::ACTIVITYPUB) {
ActivityPub\Transmitter::sendActivity('Follow', $contact['url'], $contact['uid']); ActivityPub\Transmitter::sendActivity('Follow', $contact['url'], $contact['uid']);
} }
} }
return $this->intro->delete($this);
}
/**
* Silently ignores the introduction, hides it from notifications and prevents the remote contact from submitting
* additional follow requests.
*
* @return bool
* @throws \Exception
*/
public function ignore()
{
$this->ignore = true;
return $this->intro->update($this);
} }
/** /**
* Discards the introduction and sends a rejection message to AP contacts. * Discards the introduction and sends a rejection message to AP contacts.
* *
* @return bool * @param Entity\Introduction $introduction
*
* @throws HTTPException\InternalServerErrorException * @throws HTTPException\InternalServerErrorException
* @throws HTTPException\NotFoundException
* @throws \ImagickException * @throws \ImagickException
*/ */
public function discard() public static function discard(Entity\Introduction $introduction): void
{ {
// If it is a friend suggestion, the contact is not a new friend but an existing friend $contact = Contact::selectFirst([], ['id' => $introduction->cid, 'uid' => $introduction->uid]);
// that should not be deleted.
if (!$this->fid) {
// When the contact entry had been created just for that intro, we want to get rid of it now
$condition = ['id' => $this->{'contact-id'}, 'uid' => $this->uid,
'self' => false, 'pending' => true, 'rel' => [0, Contact::FOLLOWER]];
if ($this->dba->exists('contact', $condition)) {
Contact::remove($this->{'contact-id'});
} else {
Contact::update(['pending' => false], ['id' => $this->{'contact-id'}]);
}
}
$contact = Contact::selectFirst([], ['id' => $this->{'contact-id'}, 'uid' => $this->uid]);
if (!empty($contact)) { if (!empty($contact)) {
if (!empty($contact['protocol'])) { if (!empty($contact['protocol'])) {
$protocol = $contact['protocol']; $protocol = $contact['protocol'];
@ -175,7 +125,5 @@ class Introduction extends BaseModel
ActivityPub\Transmitter::sendContactReject($contact['url'], $contact['hub-verify'], $contact['uid']); ActivityPub\Transmitter::sendContactReject($contact['url'], $contact['hub-verify'], $contact['uid']);
} }
} }
return $this->intro->delete($this);
} }
} }

View File

@ -23,6 +23,7 @@ namespace Friendica\Module\Api\Mastodon;
use Friendica\Core\System; use Friendica\Core\System;
use Friendica\DI; use Friendica\DI;
use Friendica\Model\Contact;
use Friendica\Module\BaseApi; use Friendica\Module\BaseApi;
use Friendica\Network\HTTPException; use Friendica\Network\HTTPException;
@ -34,7 +35,6 @@ class FollowRequests extends BaseApi
/** /**
* @param array $parameters * @param array $parameters
* @throws HTTPException\BadRequestException * @throws HTTPException\BadRequestException
* @throws HTTPException\ForbiddenException
* @throws HTTPException\InternalServerErrorException * @throws HTTPException\InternalServerErrorException
* @throws HTTPException\NotFoundException * @throws HTTPException\NotFoundException
* @throws HTTPException\UnauthorizedException * @throws HTTPException\UnauthorizedException
@ -48,25 +48,28 @@ class FollowRequests extends BaseApi
self::checkAllowedScope(self::SCOPE_FOLLOW); self::checkAllowedScope(self::SCOPE_FOLLOW);
$uid = self::getCurrentUserID(); $uid = self::getCurrentUserID();
$introduction = DI::intro()->selectFirst(['id' => $parameters['id'], 'uid' => $uid]); $introduction = DI::intro()->selectOneById($parameters['id'], $uid);
$contactId = $introduction->{'contact-id'}; $contactId = $introduction->cid;
switch ($parameters['action']) { switch ($parameters['action']) {
case 'authorize': case 'authorize':
$introduction->confirm(); Contact\Introduction::confirm($introduction);
$relationship = DI::mstdnRelationship()->createFromContactId($contactId, $uid); $relationship = DI::mstdnRelationship()->createFromContactId($contactId, $uid);
DI::intro()->delete($introduction);
break; break;
case 'ignore': case 'ignore':
$introduction->ignore(); $introduction->ignore();
$relationship = DI::mstdnRelationship()->createFromContactId($contactId, $uid); $relationship = DI::mstdnRelationship()->createFromContactId($contactId, $uid);
DI::intro()->save($introduction);
break; break;
case 'reject': case 'reject':
$introduction->discard(); Contact\Introduction::discard($introduction);
$relationship = DI::mstdnRelationship()->createFromContactId($contactId, $uid); $relationship = DI::mstdnRelationship()->createFromContactId($contactId, $uid);
DI::intro()->delete($introduction);
break; break;
default: default:
throw new HTTPException\BadRequestException('Unexpected action parameter, expecting "authorize", "ignore" or "reject"'); throw new HTTPException\BadRequestException('Unexpected action parameter, expecting "authorize", "ignore" or "reject"');
@ -92,13 +95,7 @@ class FollowRequests extends BaseApi
'limit' => 40, // Maximum number of results to return. Defaults to 40. Paginate using the HTTP Link header. 'limit' => 40, // Maximum number of results to return. Defaults to 40. Paginate using the HTTP Link header.
]); ]);
$introductions = DI::intro()->selectByBoundaries( $introductions = DI::intro()->selectForUser($uid, $request['min_id'], $request['max_id'], $request['limit']);
['`uid` = ? AND NOT `ignore`', $uid],
['order' => ['id' => 'DESC']],
$request['min_id'],
$request['max_id'],
$request['limit']
);
$return = []; $return = [];

View File

@ -133,7 +133,7 @@ class Delegation extends BaseModule
$params = ['distinct' => true, 'expression' => 'convid']; $params = ['distinct' => true, 'expression' => 'convid'];
$notifications += DBA::count('mail', ['uid' => $identity['uid'], 'seen' => false], $params); $notifications += DBA::count('mail', ['uid' => $identity['uid'], 'seen' => false], $params);
$notifications += DBA::count('intro', ['blocked' => false, 'ignore' => false, 'uid' => $identity['uid']]); $notifications += DI::intro()->countActiveForUser($identity['uid']);
$identities[$key]['notifications'] = $notifications; $identities[$key]['notifications'] = $notifications;
} }

View File

@ -3,6 +3,7 @@ namespace Friendica\Module;
use Friendica\BaseModule; use Friendica\BaseModule;
use Friendica\DI; use Friendica\DI;
use Friendica\Model\Contact;
/** /**
* Process follow request confirmations * Process follow request confirmations
@ -21,12 +22,11 @@ class FollowConfirm extends BaseModule
$duplex = intval($_POST['duplex'] ?? 0); $duplex = intval($_POST['duplex'] ?? 0);
$hidden = intval($_POST['hidden'] ?? 0); $hidden = intval($_POST['hidden'] ?? 0);
$intro = DI::intro()->selectFirst(['id' => $intro_id, 'uid' => local_user()]); $intro = DI::intro()->selectOneById($intro_id, local_user());
$cid = $intro->{'contact-id'}; Contact\Introduction::confirm($intro, $duplex, $hidden);
DI::intro()->delete($intro);
$intro->confirm($duplex, $hidden); DI::baseUrl()->redirect('contact/' . $intro->cid);
DI::baseUrl()->redirect('contact/' . intval($cid));
} }
} }

View File

@ -24,6 +24,7 @@ namespace Friendica\Module\Notifications;
use Friendica\BaseModule; use Friendica\BaseModule;
use Friendica\Core\System; use Friendica\Core\System;
use Friendica\DI; use Friendica\DI;
use Friendica\Model\Contact;
use Friendica\Module\Security\Login; use Friendica\Module\Security\Login;
use Friendica\Network\HTTPException; use Friendica\Network\HTTPException;
@ -50,14 +51,16 @@ class Notification extends BaseModule
$request_id = $parameters['id'] ?? false; $request_id = $parameters['id'] ?? false;
if ($request_id) { if ($request_id) {
$intro = DI::intro()->selectFirst(['id' => $request_id, 'uid' => local_user()]); $intro = DI::intro()->selectOneById($request_id, local_user());
switch ($_POST['submit']) { switch ($_POST['submit']) {
case DI::l10n()->t('Discard'): case DI::l10n()->t('Discard'):
$intro->discard(); Contact\Introduction::discard($intro);
DI::intro()->delete($intro);
break; break;
case DI::l10n()->t('Ignore'): case DI::l10n()->t('Ignore'):
$intro->ignore(); $intro->ignore();
DI::intro()->save($intro);
break; break;
} }

View File

@ -5,8 +5,8 @@ namespace Friendica\Module;
use Friendica\Core\Hook; use Friendica\Core\Hook;
use Friendica\Database\DBA; use Friendica\Database\DBA;
use Friendica\DI; use Friendica\DI;
use Friendica\Model\Item;
use Friendica\Model\Group; use Friendica\Model\Group;
use Friendica\Model\Item;
use Friendica\Model\Post; use Friendica\Model\Post;
use Friendica\Network\HTTPException; use Friendica\Network\HTTPException;
@ -32,6 +32,10 @@ class PermissionTooltip extends \Friendica\BaseModule
} else { } else {
$fields = ['uid', 'allow_cid', 'allow_gid', 'deny_cid', 'deny_gid']; $fields = ['uid', 'allow_cid', 'allow_gid', 'deny_cid', 'deny_gid'];
$model = DBA::selectFirst($type, $fields, $condition); $model = DBA::selectFirst($type, $fields, $condition);
$model['allow_cid'] = DI::aclFormatter()->expand($model['allow_cid']);
$model['allow_gid'] = DI::aclFormatter()->expand($model['allow_gid']);
$model['deny_cid'] = DI::aclFormatter()->expand($model['deny_cid']);
$model['deny_gid'] = DI::aclFormatter()->expand($model['deny_gid']);
} }
if (!DBA::isResult($model)) { if (!DBA::isResult($model)) {

View File

@ -132,6 +132,8 @@ class Index extends BaseSettings
notice(DI::l10n()->t('Profile couldn\'t be updated.')); notice(DI::l10n()->t('Profile couldn\'t be updated.'));
return; return;
} }
DI::baseUrl()->redirect('settings/profile');
} }
public static function content(array $parameters = []) public static function content(array $parameters = [])

View File

@ -92,6 +92,8 @@ class Crop extends BaseSettings
$Image->scaleDown(300); $Image->scaleDown(300);
} }
$condition = ['resource-id' => $resource_id, 'uid' => local_user(), 'contact-id' => 0];
$r = Photo::store( $r = Photo::store(
$Image, $Image,
local_user(), local_user(),
@ -105,7 +107,7 @@ class Crop extends BaseSettings
if ($r === false) { if ($r === false) {
notice(DI::l10n()->t('Image size reduction [%s] failed.', '300')); notice(DI::l10n()->t('Image size reduction [%s] failed.', '300'));
} else { } else {
Photo::update(['profile' => true], ['id' => $r['id']]); Photo::update(['profile' => true], array_merge($condition, ['scale' => 4]));
} }
$Image->scaleDown(80); $Image->scaleDown(80);
@ -123,7 +125,7 @@ class Crop extends BaseSettings
if ($r === false) { if ($r === false) {
notice(DI::l10n()->t('Image size reduction [%s] failed.', '80')); notice(DI::l10n()->t('Image size reduction [%s] failed.', '80'));
} else { } else {
Photo::update(['profile' => true], ['id' => $r['id']]); Photo::update(['profile' => true], array_merge($condition, ['scale' => 5]));
} }
$Image->scaleDown(48); $Image->scaleDown(48);
@ -141,7 +143,7 @@ class Crop extends BaseSettings
if ($r === false) { if ($r === false) {
notice(DI::l10n()->t('Image size reduction [%s] failed.', '48')); notice(DI::l10n()->t('Image size reduction [%s] failed.', '48'));
} else { } else {
Photo::update(['profile' => true], ['id' => $r['id']]); Photo::update(['profile' => true], array_merge($condition, ['scale' => 6]));
} }
Contact::updateSelfFromUserID(local_user(), true); Contact::updateSelfFromUserID(local_user(), true);

View File

@ -485,9 +485,9 @@ class Notify extends BaseDepository
private function storeAndSend($params, $sitelink, $tsitelink, $hsitelink, $title, $subject, $preamble, $epreamble, $body, $itemlink, $show_in_notification_page) private function storeAndSend($params, $sitelink, $tsitelink, $hsitelink, $title, $subject, $preamble, $epreamble, $body, $itemlink, $show_in_notification_page)
{ {
$item_id = $params['item']['id'] ?? 0; $item_id = $params['item']['id'] ?? 0;
$uri_id = $params['item']['uri-id'] ?? 0; $uri_id = $params['item']['uri-id'] ?? null;
$parent_id = $params['item']['parent'] ?? 0; $parent_id = $params['item']['parent'] ?? 0;
$parent_uri_id = $params['item']['parent-uri-id'] ?? 0; $parent_uri_id = $params['item']['parent-uri-id'] ?? null;
// Ensure that the important fields are set at any time // Ensure that the important fields are set at any time
$fields = ['nickname']; $fields = ['nickname'];
@ -564,7 +564,7 @@ class Notify extends BaseDepository
// Is this the first email notification for this parent item and user? // Is this the first email notification for this parent item and user?
if (!DBA::exists('notify-threads', ['master-parent-uri-id' => $parent_uri_id, 'receiver-uid' => $params['uid']])) { if (!DBA::exists('notify-threads', ['master-parent-uri-id' => $parent_uri_id, 'receiver-uid' => $params['uid']])) {
$this->logger->log("notify_id:" . intval($notify_id) . ", parent: " . intval($params['parent']) . "uid: " . intval($params['uid']), $this->logger->DEBUG); $this->logger->info("notify_id:" . intval($notify_id) . ", parent: " . intval($params['parent']) . "uid: " . intval($params['uid']));
$fields = ['notify-id' => $notify_id, 'master-parent-uri-id' => $parent_uri_id, $fields = ['notify-id' => $notify_id, 'master-parent-uri-id' => $parent_uri_id,
'receiver-uid' => $params['uid'], 'parent-item' => 0]; 'receiver-uid' => $params['uid'], 'parent-item' => 0];
@ -573,12 +573,12 @@ class Notify extends BaseDepository
$emailBuilder->setHeader('Message-ID', $message_id); $emailBuilder->setHeader('Message-ID', $message_id);
$log_msg = "include/enotify: No previous notification found for this parent:\n" . $log_msg = "include/enotify: No previous notification found for this parent:\n" .
" parent: ${params['parent']}\n" . " uid : ${params['uid']}\n"; " parent: ${params['parent']}\n" . " uid : ${params['uid']}\n";
$this->logger->log($log_msg, $this->logger->DEBUG); $this->logger->info($log_msg);
} else { } else {
// If not, just "follow" the thread. // If not, just "follow" the thread.
$emailBuilder->setHeader('References', $message_id); $emailBuilder->setHeader('References', $message_id);
$emailBuilder->setHeader('In-Reply-To', $message_id); $emailBuilder->setHeader('In-Reply-To', $message_id);
$this->logger->log("There's already a notification for this parent.", $this->logger->DEBUG); $this->logger->info("There's already a notification for this parent.");
} }
} }

View File

@ -60,14 +60,14 @@ class Notify extends BaseEntity
protected $name_cache; protected $name_cache;
/** @var string */ /** @var string */
protected $msg_cache; protected $msg_cache;
/** @var int */ /** @var int|null */
protected $uriId; protected $uriId;
/** @var int */ /** @var int|null */
protected $parentUriId; protected $parentUriId;
/** @var int */ /** @var int */
protected $id; protected $id;
public function __construct(int $type, string $name, UriInterface $url, UriInterface $photo, DateTime $date, int $uid, UriInterface $link, bool $seen, string $verb, string $otype, string $name_cache, string $msg = null, string $msg_cache = null, int $itemId = null, int $uriId = null, int $parent = null, int $parentUriId = null, int $id = null) public function __construct(int $type, string $name, UriInterface $url, UriInterface $photo, DateTime $date, int $uid, UriInterface $link, bool $seen, string $verb, string $otype, string $name_cache, string $msg = null, string $msg_cache = null, int $itemId = null, int $uriId = null, int $parent = null, ?int $parentUriId = null, ?int $id = null)
{ {
$this->type = $type; $this->type = $type;
$this->name = $name; $this->name = $name;

View File

@ -86,7 +86,6 @@ class ProfileField extends BaseDepository
$Entities = new Collection\ProfileFields(); $Entities = new Collection\ProfileFields();
foreach ($rows as $fields) { foreach ($rows as $fields) {
$this->logger->warning('row', ['row' => $fields]);
$Entities[] = $this->factory->createFromTableRow($fields); $Entities[] = $this->factory->createFromTableRow($fields);
} }

View File

@ -1352,7 +1352,7 @@ class DFRN
} }
// Quit if we already have an introduction for this person // Quit if we already have an introduction for this person
if (DBA::exists('intro', ['uid' => $uid, 'suggest-cid' => $cid])) { if (DI::intro()->suggestionExistsForUser($cid, $uid)) {
return false; return false;
} }
@ -1366,10 +1366,13 @@ class DFRN
$suggest['title'] = ''; $suggest['title'] = '';
$suggest['body'] = $note; $suggest['body'] = $note;
$hash = Strings::getRandomHex(); DI::intro()->save(DI::introFactory()->createNew(
$fields = ['uid' => $suggest['uid'], 'suggest-cid' => $cid, 'contact-id' => $suggest['cid'], $suggest['uid'],
'note' => $suggest['body'], 'hash' => $hash, 'datetime' => DateTimeFormat::utcNow(), 'blocked' => false]; $suggest['cid'],
DBA::insert('intro', $fields); $suggest['body'],
null,
$cid
));
DI::notify()->createFromArray([ DI::notify()->createFromArray([
'type' => Notification\Type::SUGGEST, 'type' => Notification\Type::SUGGEST,

View File

@ -1,79 +0,0 @@
<?php
/**
* @copyright Copyright (C) 2010-2021, 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\Repository;
use Friendica\BaseRepository;
use Friendica\Collection;
use Friendica\Model;
class Introduction extends BaseRepository
{
protected static $table_name = 'intro';
protected static $model_class = Model\Introduction::class;
protected static $collection_class = Collection\Introductions::class;
/**
* @param array $data
* @return Model\Introduction
*/
protected function create(array $data)
{
return new Model\Introduction($this->dba, $this->logger, $this, $data);
}
/**
* @param array $condition
* @return Model\Introduction
* @throws \Friendica\Network\HTTPException\NotFoundException
*/
public function selectFirst(array $condition)
{
return parent::selectFirst($condition);
}
/**
* @param array $condition
* @param array $params
* @return Collection\Introductions
* @throws \Exception
*/
public function select(array $condition = [], array $params = [])
{
return parent::select($condition, $params);
}
/**
* @param array $condition
* @param array $params
* @param int|null $min_id
* @param int|null $max_id
* @param int $limit
* @return Collection\Introductions
* @throws \Exception
*/
public function selectByBoundaries(array $condition = [], array $params = [], int $min_id = null, int $max_id = null, int $limit = self::LIMIT)
{
return parent::selectByBoundaries($condition, $params, $min_id, $max_id, $limit);
}
}

View File

@ -38,7 +38,7 @@ final class ACLFormatter
public function expand(string $acl_string = null) public function expand(string $acl_string = null)
{ {
// In case there is no ID list, return empty array (=> no ACL set) // In case there is no ID list, return empty array (=> no ACL set)
if (!isset($acl_string)) { if (empty($acl_string)) {
return []; return [];
} }

View File

@ -24,6 +24,7 @@ namespace Friendica\Worker\Contact;
use Friendica\Core\Logger; use Friendica\Core\Logger;
use Friendica\Database\DBA; use Friendica\Database\DBA;
use Friendica\Database\DBStructure; use Friendica\Database\DBStructure;
use Friendica\DI;
use Friendica\Model\Photo; use Friendica\Model\Photo;
use Friendica\Model\Post; use Friendica\Model\Post;
@ -84,7 +85,7 @@ class RemoveContent
DBA::delete('user-contact', ['cid' => $id]); DBA::delete('user-contact', ['cid' => $id]);
DBA::delete('group_member', ['contact-id' => $id]); DBA::delete('group_member', ['contact-id' => $id]);
DBA::delete('intro', ['contact-id' => $id]); DI::intro()->delete(DI::introFactory()->createDummy($id));
return $contact; return $contact;
} }

View File

@ -55,7 +55,7 @@
use Friendica\Database\DBA; use Friendica\Database\DBA;
if (!defined('DB_UPDATE_VERSION')) { if (!defined('DB_UPDATE_VERSION')) {
define('DB_UPDATE_VERSION', 1441); define('DB_UPDATE_VERSION', 1442);
} }
return [ return [
@ -778,11 +778,11 @@ return [
"contact-id" => ["type" => "int unsigned", "not null" => "1", "default" => "0", "foreign" => ["contact" => "id"], "comment" => ""], "contact-id" => ["type" => "int unsigned", "not null" => "1", "default" => "0", "foreign" => ["contact" => "id"], "comment" => ""],
"suggest-cid" => ["type" => "int unsigned", "foreign" => ["contact" => "id"], "comment" => "Suggested contact"], "suggest-cid" => ["type" => "int unsigned", "foreign" => ["contact" => "id"], "comment" => "Suggested contact"],
"knowyou" => ["type" => "boolean", "not null" => "1", "default" => "0", "comment" => ""], "knowyou" => ["type" => "boolean", "not null" => "1", "default" => "0", "comment" => ""],
"duplex" => ["type" => "boolean", "not null" => "1", "default" => "0", "comment" => ""], "duplex" => ["type" => "boolean", "not null" => "1", "default" => "0", "comment" => "deprecated"],
"note" => ["type" => "text", "comment" => ""], "note" => ["type" => "text", "comment" => ""],
"hash" => ["type" => "varchar(255)", "not null" => "1", "default" => "", "comment" => ""], "hash" => ["type" => "varchar(255)", "not null" => "1", "default" => "", "comment" => ""],
"datetime" => ["type" => "datetime", "not null" => "1", "default" => DBA::NULL_DATETIME, "comment" => ""], "datetime" => ["type" => "datetime", "not null" => "1", "default" => DBA::NULL_DATETIME, "comment" => ""],
"blocked" => ["type" => "boolean", "not null" => "1", "default" => "1", "comment" => ""], "blocked" => ["type" => "boolean", "not null" => "1", "default" => "0", "comment" => "deprecated"],
"ignore" => ["type" => "boolean", "not null" => "1", "default" => "0", "comment" => ""], "ignore" => ["type" => "boolean", "not null" => "1", "default" => "0", "comment" => ""],
], ],
"indexes" => [ "indexes" => [

View File

@ -0,0 +1,113 @@
<?php
namespace Friendica\Test\src\Contact\Introduction\Factory;
use Friendica\Contact\Introduction\Factory\Introduction;
use PHPUnit\Framework\TestCase;
use Psr\Log\NullLogger;
class IntroductionTest extends TestCase
{
public function dataRow()
{
return [
'default' => [
'input' => [
'uid' => 42,
'suggest-cid' => 13,
'contact-id' => 24,
'knowyou' => 1,
'note' => 'a note',
'hash' => '12345',
'datetime' => '1970-01-01 00:00:00',
'ignore' => 0,
'id' => 56,
],
'assertion' => [
'uid' => 42,
'suggest-cid' => 13,
'contact-id' => 24,
'knowyou' => true,
'note' => 'a note',
'hash' => '12345',
'datetime' => new \DateTime('1970-01-01 00:00:00', new \DateTimeZone('UTC')),
'ignore' => false,
'id' => 56,
]
],
'empty' => [
'input' => [
],
'assertion' => [
'uid' => 0,
'contact-id' => 0,
'suggest-cid' => null,
'knowyou' => false,
'note' => '',
'ignore' => false,
'id' => null,
]
],
];
}
public function assertIntro(\Friendica\Contact\Introduction\Entity\Introduction $intro, array $assertion)
{
self::assertEquals($intro->id, $assertion['id'] ?? null);
self::assertEquals($intro->uid, $assertion['uid'] ?? 0);
self::assertEquals($intro->cid, $assertion['contact-id'] ?? 0);
self::assertEquals($intro->sid, $assertion['suggest-cid'] ?? null);
self::assertEquals($intro->knowyou, $assertion['knowyou'] ?? false);
self::assertEquals($intro->note, $assertion['note'] ?? '');
if (isset($assertion['hash'])) {
self::assertEquals($intro->hash, $assertion['hash']);
} else {
self::assertIsString($intro->hash);
}
if (isset($assertion['datetime'])) {
self::assertEquals($intro->datetime, $assertion['datetime']);
} else {
self::assertInstanceOf(\DateTime::class, $intro->datetime);
}
self::assertEquals($intro->ignore, $assertion['ignore'] ?? false);
}
/**
* @dataProvider dataRow
*/
public function testCreateFromTableRow(array $input, array $assertion)
{
$factory = new Introduction(new NullLogger());
$intro = $factory->createFromTableRow($input);
$this->assertIntro($intro, $assertion);
}
/**
* @dataProvider dataRow
*/
public function testCreateNew(array $input, array $assertion)
{
$factory = new Introduction(new NullLogger());
$intro = $factory->createNew($input['uid'] ?? 0, $input['cid'] ?? 0, $input['note'] ?? '');
$this->assertIntro($intro, [
'uid' => $input['uid'] ?? 0,
'contact-id' => $input['cid'] ?? 0,
'note' => $input['note'] ?? '',
]);
}
/**
* @dataProvider dataRow
*/
public function testCreateDummy(array $input, array $assertion)
{
$factory = new Introduction(new NullLogger());
$intro = $factory->createDummy($input['id'] ?? null);
$this->assertIntro($intro, ['id' => $input['id'] ?? null]);
}
}

View File

@ -1039,7 +1039,7 @@ function update_1440()
return Update::SUCCESS; return Update::SUCCESS;
} }
function update__1441() function update_1441()
{ {
$languages = DI::l10n()->getAvailableLanguages(); $languages = DI::l10n()->getAvailableLanguages();
@ -1053,3 +1053,11 @@ function update__1441()
return Update::SUCCESS; return Update::SUCCESS;
} }
function update_1442()
{
// transform blocked intros into ignored intros
DBA::update('intro', ['ignore' => 1, 'blocked' => 0], ['blocked' => 1]);
return Update::SUCCESS;
}

View File

@ -8,7 +8,7 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: 2021.12-dev\n" "Project-Id-Version: 2021.12-dev\n"
"Report-Msgid-Bugs-To: \n" "Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2021-10-19 20:03+0000\n" "POT-Creation-Date: 2021-10-20 15:10+0200\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n" "Language-Team: LANGUAGE <LL@li.org>\n"
@ -40,7 +40,7 @@ msgstr ""
#: mod/api.php:30 mod/editpost.php:38 mod/events.php:220 mod/follow.php:56 #: mod/api.php:30 mod/editpost.php:38 mod/events.php:220 mod/follow.php:56
#: mod/follow.php:130 mod/item.php:185 mod/item.php:190 mod/item.php:936 #: mod/follow.php:130 mod/item.php:185 mod/item.php:190 mod/item.php:936
#: mod/message.php:69 mod/message.php:111 mod/notes.php:44 #: mod/message.php:69 mod/message.php:111 mod/notes.php:44
#: mod/ostatus_subscribe.php:32 mod/photos.php:163 mod/photos.php:908 #: mod/ostatus_subscribe.php:32 mod/photos.php:160 mod/photos.php:900
#: mod/repair_ostatus.php:31 mod/settings.php:47 mod/settings.php:57 #: mod/repair_ostatus.php:31 mod/settings.php:47 mod/settings.php:57
#: mod/settings.php:409 mod/suggest.php:34 mod/uimport.php:33 #: mod/settings.php:409 mod/suggest.php:34 mod/uimport.php:33
#: mod/unfollow.php:35 mod/unfollow.php:50 mod/unfollow.php:82 #: mod/unfollow.php:35 mod/unfollow.php:50 mod/unfollow.php:82
@ -62,7 +62,7 @@ msgstr ""
#: src/Module/Search/Directory.php:38 src/Module/Settings/Delegation.php:42 #: src/Module/Search/Directory.php:38 src/Module/Settings/Delegation.php:42
#: src/Module/Settings/Delegation.php:70 src/Module/Settings/Display.php:43 #: src/Module/Settings/Delegation.php:70 src/Module/Settings/Display.php:43
#: src/Module/Settings/Display.php:121 #: src/Module/Settings/Display.php:121
#: src/Module/Settings/Profile/Photo/Crop.php:158 #: src/Module/Settings/Profile/Photo/Crop.php:164
#: src/Module/Settings/Profile/Photo/Index.php:112 #: src/Module/Settings/Profile/Photo/Index.php:112
#: src/Module/Settings/UserExport.php:58 src/Module/Settings/UserExport.php:93 #: src/Module/Settings/UserExport.php:58 src/Module/Settings/UserExport.php:93
#: src/Module/Settings/UserExport.php:198 #: src/Module/Settings/UserExport.php:198
@ -80,8 +80,8 @@ msgstr ""
msgid "Access denied." msgid "Access denied."
msgstr "" msgstr ""
#: mod/cal.php:61 mod/cal.php:78 mod/photos.php:69 mod/photos.php:143 #: mod/cal.php:61 mod/cal.php:78 mod/photos.php:69 mod/photos.php:140
#: mod/photos.php:815 src/Model/Profile.php:229 src/Module/HCard.php:52 #: mod/photos.php:807 src/Model/Profile.php:229 src/Module/HCard.php:52
#: src/Module/Profile/Common.php:41 src/Module/Profile/Common.php:52 #: src/Module/Profile/Common.php:41 src/Module/Profile/Common.php:52
#: src/Module/Profile/Contacts.php:40 src/Module/Profile/Contacts.php:50 #: src/Module/Profile/Contacts.php:40 src/Module/Profile/Contacts.php:50
#: src/Module/Profile/Media.php:38 src/Module/Profile/Status.php:58 #: src/Module/Profile/Media.php:38 src/Module/Profile/Status.php:58
@ -156,7 +156,7 @@ msgstr ""
msgid "calendar" msgid "calendar"
msgstr "" msgstr ""
#: mod/display.php:165 mod/photos.php:819 #: mod/display.php:165 mod/photos.php:811
#: src/Module/Conversation/Community.php:176 src/Module/Debug/Probe.php:39 #: src/Module/Conversation/Community.php:176 src/Module/Debug/Probe.php:39
#: src/Module/Debug/WebFinger.php:38 src/Module/Directory.php:49 #: src/Module/Debug/WebFinger.php:38 src/Module/Directory.php:49
#: src/Module/Search/Index.php:50 src/Module/Search/Index.php:55 #: src/Module/Search/Index.php:50 src/Module/Search/Index.php:55
@ -184,7 +184,7 @@ msgstr ""
msgid "Save" msgid "Save"
msgstr "" msgstr ""
#: mod/editpost.php:92 mod/photos.php:1355 src/Content/Conversation.php:326 #: mod/editpost.php:92 mod/photos.php:1347 src/Content/Conversation.php:326
#: src/Module/Contact/Poke.php:157 src/Object/Post.php:964 #: src/Module/Contact/Poke.php:157 src/Object/Post.php:964
msgid "Loading..." msgid "Loading..."
msgstr "" msgstr ""
@ -249,7 +249,7 @@ msgid "clear location"
msgstr "" msgstr ""
#: mod/editpost.php:107 mod/message.php:200 mod/message.php:358 #: mod/editpost.php:107 mod/message.php:200 mod/message.php:358
#: mod/photos.php:1506 mod/wallmessage.php:141 src/Content/Conversation.php:355 #: mod/photos.php:1498 mod/wallmessage.php:141 src/Content/Conversation.php:355
#: src/Content/Conversation.php:689 src/Module/Item/Compose.php:165 #: src/Content/Conversation.php:689 src/Module/Item/Compose.php:165
#: src/Object/Post.php:502 #: src/Object/Post.php:502
msgid "Please wait" msgid "Please wait"
@ -281,14 +281,14 @@ msgstr ""
msgid "Example: bob@example.com, mary@example.com" msgid "Example: bob@example.com, mary@example.com"
msgstr "" msgstr ""
#: mod/editpost.php:128 mod/events.php:517 mod/photos.php:1354 #: mod/editpost.php:128 mod/events.php:517 mod/photos.php:1346
#: mod/photos.php:1410 mod/photos.php:1484 src/Content/Conversation.php:370 #: mod/photos.php:1402 mod/photos.php:1476 src/Content/Conversation.php:370
#: src/Module/Item/Compose.php:160 src/Object/Post.php:974 #: src/Module/Item/Compose.php:160 src/Object/Post.php:974
msgid "Preview" msgid "Preview"
msgstr "" msgstr ""
#: mod/editpost.php:130 mod/fbrowser.php:100 mod/fbrowser.php:127 #: mod/editpost.php:130 mod/fbrowser.php:100 mod/fbrowser.php:127
#: mod/follow.php:144 mod/photos.php:1017 mod/photos.php:1122 mod/tagrm.php:37 #: mod/follow.php:144 mod/photos.php:1013 mod/photos.php:1114 mod/tagrm.php:37
#: mod/tagrm.php:129 mod/unfollow.php:97 src/Content/Conversation.php:373 #: mod/tagrm.php:129 mod/unfollow.php:97 src/Content/Conversation.php:373
#: src/Module/Contact/Revoke.php:99 src/Module/RemoteFollow.php:116 #: src/Module/Contact/Revoke.php:99 src/Module/RemoteFollow.php:116
msgid "Cancel" msgid "Cancel"
@ -305,8 +305,8 @@ msgstr ""
msgid "Browser" msgid "Browser"
msgstr "" msgstr ""
#: mod/editpost.php:136 mod/events.php:522 mod/photos.php:956 #: mod/editpost.php:136 mod/events.php:522 mod/photos.php:948
#: mod/photos.php:1308 src/Content/Conversation.php:357 #: mod/photos.php:1300 src/Content/Conversation.php:357
msgid "Permissions" msgid "Permissions"
msgstr "" msgstr ""
@ -386,8 +386,8 @@ msgid "Share this event"
msgstr "" msgstr ""
#: mod/events.php:519 mod/message.php:201 mod/message.php:357 #: mod/events.php:519 mod/message.php:201 mod/message.php:357
#: mod/photos.php:938 mod/photos.php:1039 mod/photos.php:1312 #: mod/photos.php:930 mod/photos.php:1034 mod/photos.php:1304
#: mod/photos.php:1353 mod/photos.php:1409 mod/photos.php:1483 #: mod/photos.php:1345 mod/photos.php:1401 mod/photos.php:1475
#: src/Module/Admin/Item/Source.php:65 src/Module/Contact.php:523 #: src/Module/Admin/Item/Source.php:65 src/Module/Contact.php:523
#: src/Module/Contact/Advanced.php:133 src/Module/Contact/Poke.php:158 #: src/Module/Contact/Advanced.php:133 src/Module/Contact/Poke.php:158
#: src/Module/Debug/ActivityPubConversion.php:141 #: src/Module/Debug/ActivityPubConversion.php:141
@ -842,255 +842,255 @@ msgstr ""
msgid "Keep this window open until done." msgid "Keep this window open until done."
msgstr "" msgstr ""
#: mod/photos.php:111 src/Module/BaseProfile.php:67 #: mod/photos.php:108 src/Module/BaseProfile.php:67
msgid "Photo Albums" msgid "Photo Albums"
msgstr "" msgstr ""
#: mod/photos.php:112 mod/photos.php:1608 #: mod/photos.php:109 mod/photos.php:1593
msgid "Recent Photos" msgid "Recent Photos"
msgstr "" msgstr ""
#: mod/photos.php:114 mod/photos.php:1090 mod/photos.php:1610 #: mod/photos.php:111 mod/photos.php:1082 mod/photos.php:1595
msgid "Upload New Photos" msgid "Upload New Photos"
msgstr "" msgstr ""
#: mod/photos.php:132 src/Module/BaseSettings.php:37 #: mod/photos.php:129 src/Module/BaseSettings.php:37
msgid "everybody" msgid "everybody"
msgstr "" msgstr ""
#: mod/photos.php:170 #: mod/photos.php:167
msgid "Contact information unavailable" msgid "Contact information unavailable"
msgstr "" msgstr ""
#: mod/photos.php:204 #: mod/photos.php:196
msgid "Album not found." msgid "Album not found."
msgstr "" msgstr ""
#: mod/photos.php:258 #: mod/photos.php:250
msgid "Album successfully deleted" msgid "Album successfully deleted"
msgstr "" msgstr ""
#: mod/photos.php:260 #: mod/photos.php:252
msgid "Album was empty." msgid "Album was empty."
msgstr "" msgstr ""
#: mod/photos.php:292 #: mod/photos.php:284
msgid "Failed to delete the photo." msgid "Failed to delete the photo."
msgstr "" msgstr ""
#: mod/photos.php:567 #: mod/photos.php:559
msgid "a photo" msgid "a photo"
msgstr "" msgstr ""
#: mod/photos.php:567 #: mod/photos.php:559
#, php-format #, php-format
msgid "%1$s was tagged in %2$s by %3$s" msgid "%1$s was tagged in %2$s by %3$s"
msgstr "" msgstr ""
#: mod/photos.php:650 mod/photos.php:653 mod/photos.php:680 #: mod/photos.php:642 mod/photos.php:645 mod/photos.php:672
#: mod/wall_upload.php:207 src/Module/Settings/Profile/Photo/Index.php:60 #: mod/wall_upload.php:207 src/Module/Settings/Profile/Photo/Index.php:60
#, php-format #, php-format
msgid "Image exceeds size limit of %s" msgid "Image exceeds size limit of %s"
msgstr "" msgstr ""
#: mod/photos.php:656 #: mod/photos.php:648
msgid "Image upload didn't complete, please try again" msgid "Image upload didn't complete, please try again"
msgstr "" msgstr ""
#: mod/photos.php:659 #: mod/photos.php:651
msgid "Image file is missing" msgid "Image file is missing"
msgstr "" msgstr ""
#: mod/photos.php:664 #: mod/photos.php:656
msgid "" msgid ""
"Server can't accept new file upload at this time, please contact your " "Server can't accept new file upload at this time, please contact your "
"administrator" "administrator"
msgstr "" msgstr ""
#: mod/photos.php:688 #: mod/photos.php:680
msgid "Image file is empty." msgid "Image file is empty."
msgstr "" msgstr ""
#: mod/photos.php:703 mod/wall_upload.php:166 #: mod/photos.php:695 mod/wall_upload.php:166
#: src/Module/Settings/Profile/Photo/Index.php:69 #: src/Module/Settings/Profile/Photo/Index.php:69
msgid "Unable to process image." msgid "Unable to process image."
msgstr "" msgstr ""
#: mod/photos.php:732 mod/wall_upload.php:232 #: mod/photos.php:724 mod/wall_upload.php:232
#: src/Module/Settings/Profile/Photo/Index.php:96 #: src/Module/Settings/Profile/Photo/Index.php:96
msgid "Image upload failed." msgid "Image upload failed."
msgstr "" msgstr ""
#: mod/photos.php:824 #: mod/photos.php:816
msgid "No photos selected" msgid "No photos selected"
msgstr "" msgstr ""
#: mod/photos.php:893 #: mod/photos.php:885
msgid "Access to this item is restricted." msgid "Access to this item is restricted."
msgstr "" msgstr ""
#: mod/photos.php:948 #: mod/photos.php:940
msgid "Upload Photos" msgid "Upload Photos"
msgstr "" msgstr ""
#: mod/photos.php:952 mod/photos.php:1035 #: mod/photos.php:944 mod/photos.php:1030
msgid "New album name: " msgid "New album name: "
msgstr "" msgstr ""
#: mod/photos.php:953 #: mod/photos.php:945
msgid "or select existing album:" msgid "or select existing album:"
msgstr "" msgstr ""
#: mod/photos.php:954 #: mod/photos.php:946
msgid "Do not show a status post for this upload" msgid "Do not show a status post for this upload"
msgstr "" msgstr ""
#: mod/photos.php:1015 #: mod/photos.php:1011
msgid "Do you really want to delete this photo album and all its photos?" msgid "Do you really want to delete this photo album and all its photos?"
msgstr "" msgstr ""
#: mod/photos.php:1016 mod/photos.php:1040 #: mod/photos.php:1012 mod/photos.php:1035
msgid "Delete Album" msgid "Delete Album"
msgstr "" msgstr ""
#: mod/photos.php:1046 #: mod/photos.php:1039
msgid "Edit Album" msgid "Edit Album"
msgstr "" msgstr ""
#: mod/photos.php:1047 #: mod/photos.php:1040
msgid "Drop Album" msgid "Drop Album"
msgstr "" msgstr ""
#: mod/photos.php:1052 #: mod/photos.php:1044
msgid "Show Newest First" msgid "Show Newest First"
msgstr "" msgstr ""
#: mod/photos.php:1054 #: mod/photos.php:1046
msgid "Show Oldest First" msgid "Show Oldest First"
msgstr "" msgstr ""
#: mod/photos.php:1075 mod/photos.php:1593 #: mod/photos.php:1067 mod/photos.php:1578
msgid "View Photo" msgid "View Photo"
msgstr "" msgstr ""
#: mod/photos.php:1108 #: mod/photos.php:1100
msgid "Permission denied. Access to this item may be restricted." msgid "Permission denied. Access to this item may be restricted."
msgstr "" msgstr ""
#: mod/photos.php:1110 #: mod/photos.php:1102
msgid "Photo not available" msgid "Photo not available"
msgstr "" msgstr ""
#: mod/photos.php:1120 #: mod/photos.php:1112
msgid "Do you really want to delete this photo?" msgid "Do you really want to delete this photo?"
msgstr "" msgstr ""
#: mod/photos.php:1121 mod/photos.php:1313 #: mod/photos.php:1113 mod/photos.php:1305
msgid "Delete Photo" msgid "Delete Photo"
msgstr "" msgstr ""
#: mod/photos.php:1211 #: mod/photos.php:1203
msgid "View photo" msgid "View photo"
msgstr "" msgstr ""
#: mod/photos.php:1213 #: mod/photos.php:1205
msgid "Edit photo" msgid "Edit photo"
msgstr "" msgstr ""
#: mod/photos.php:1214 #: mod/photos.php:1206
msgid "Delete photo" msgid "Delete photo"
msgstr "" msgstr ""
#: mod/photos.php:1215 #: mod/photos.php:1207
msgid "Use as profile photo" msgid "Use as profile photo"
msgstr "" msgstr ""
#: mod/photos.php:1222 #: mod/photos.php:1214
msgid "Private Photo" msgid "Private Photo"
msgstr "" msgstr ""
#: mod/photos.php:1228 #: mod/photos.php:1220
msgid "View Full Size" msgid "View Full Size"
msgstr "" msgstr ""
#: mod/photos.php:1281 #: mod/photos.php:1273
msgid "Tags: " msgid "Tags: "
msgstr "" msgstr ""
#: mod/photos.php:1284 #: mod/photos.php:1276
msgid "[Select tags to remove]" msgid "[Select tags to remove]"
msgstr "" msgstr ""
#: mod/photos.php:1299 #: mod/photos.php:1291
msgid "New album name" msgid "New album name"
msgstr "" msgstr ""
#: mod/photos.php:1300 #: mod/photos.php:1292
msgid "Caption" msgid "Caption"
msgstr "" msgstr ""
#: mod/photos.php:1301 #: mod/photos.php:1293
msgid "Add a Tag" msgid "Add a Tag"
msgstr "" msgstr ""
#: mod/photos.php:1301 #: mod/photos.php:1293
msgid "Example: @bob, @Barbara_Jensen, @jim@example.com, #California, #camping" msgid "Example: @bob, @Barbara_Jensen, @jim@example.com, #California, #camping"
msgstr "" msgstr ""
#: mod/photos.php:1302 #: mod/photos.php:1294
msgid "Do not rotate" msgid "Do not rotate"
msgstr "" msgstr ""
#: mod/photos.php:1303 #: mod/photos.php:1295
msgid "Rotate CW (right)" msgid "Rotate CW (right)"
msgstr "" msgstr ""
#: mod/photos.php:1304 #: mod/photos.php:1296
msgid "Rotate CCW (left)" msgid "Rotate CCW (left)"
msgstr "" msgstr ""
#: mod/photos.php:1350 mod/photos.php:1406 mod/photos.php:1480 #: mod/photos.php:1342 mod/photos.php:1398 mod/photos.php:1472
#: src/Module/Contact.php:993 src/Module/Item/Compose.php:148 #: src/Module/Contact.php:993 src/Module/Item/Compose.php:148
#: src/Object/Post.php:960 #: src/Object/Post.php:960
msgid "This is you" msgid "This is you"
msgstr "" msgstr ""
#: mod/photos.php:1352 mod/photos.php:1408 mod/photos.php:1482 #: mod/photos.php:1344 mod/photos.php:1400 mod/photos.php:1474
#: src/Object/Post.php:496 src/Object/Post.php:962 #: src/Object/Post.php:496 src/Object/Post.php:962
msgid "Comment" msgid "Comment"
msgstr "" msgstr ""
#: mod/photos.php:1441 src/Content/Conversation.php:615 src/Object/Post.php:227 #: mod/photos.php:1433 src/Content/Conversation.php:615 src/Object/Post.php:227
msgid "Select" msgid "Select"
msgstr "" msgstr ""
#: mod/photos.php:1442 mod/settings.php:563 src/Content/Conversation.php:616 #: mod/photos.php:1434 mod/settings.php:563 src/Content/Conversation.php:616
#: src/Module/Admin/Users/Active.php:139 src/Module/Admin/Users/Blocked.php:140 #: src/Module/Admin/Users/Active.php:139 src/Module/Admin/Users/Blocked.php:140
#: src/Module/Admin/Users/Index.php:153 #: src/Module/Admin/Users/Index.php:153
msgid "Delete" msgid "Delete"
msgstr "" msgstr ""
#: mod/photos.php:1503 src/Object/Post.php:349 #: mod/photos.php:1495 src/Object/Post.php:349
msgid "Like" msgid "Like"
msgstr "" msgstr ""
#: mod/photos.php:1504 src/Object/Post.php:349 #: mod/photos.php:1496 src/Object/Post.php:349
msgid "I like this (toggle)" msgid "I like this (toggle)"
msgstr "" msgstr ""
#: mod/photos.php:1505 src/Object/Post.php:350 #: mod/photos.php:1497 src/Object/Post.php:350
msgid "Dislike" msgid "Dislike"
msgstr "" msgstr ""
#: mod/photos.php:1507 src/Object/Post.php:350 #: mod/photos.php:1499 src/Object/Post.php:350
msgid "I don't like this (toggle)" msgid "I don't like this (toggle)"
msgstr "" msgstr ""
#: mod/photos.php:1529 #: mod/photos.php:1521
msgid "Map" msgid "Map"
msgstr "" msgstr ""
#: mod/photos.php:1599 #: mod/photos.php:1584
msgid "View Album" msgid "View Album"
msgstr "" msgstr ""
@ -2063,7 +2063,7 @@ msgstr ""
msgid "File upload failed." msgid "File upload failed."
msgstr "" msgstr ""
#: mod/wall_upload.php:224 src/Model/Photo.php:985 #: mod/wall_upload.php:224 src/Model/Photo.php:987
msgid "Wall Photos" msgid "Wall Photos"
msgstr "" msgstr ""
@ -2846,12 +2846,14 @@ msgstr ""
msgid "Your photos" msgid "Your photos"
msgstr "" msgstr ""
#: src/Content/Nav.php:193 view/theme/frio/theme.php:228 #: src/Content/Nav.php:193 src/Module/BaseProfile.php:72
msgid "Videos" #: src/Module/BaseProfile.php:75 src/Module/Contact.php:838
#: view/theme/frio/theme.php:228
msgid "Media"
msgstr "" msgstr ""
#: src/Content/Nav.php:193 view/theme/frio/theme.php:228 #: src/Content/Nav.php:193 view/theme/frio/theme.php:228
msgid "Your videos" msgid "Your postings with media"
msgstr "" msgstr ""
#: src/Content/Nav.php:194 view/theme/frio/theme.php:229 #: src/Content/Nav.php:194 view/theme/frio/theme.php:229
@ -6889,11 +6891,6 @@ msgstr ""
msgid "Profile Details" msgid "Profile Details"
msgstr "" msgstr ""
#: src/Module/BaseProfile.php:72 src/Module/BaseProfile.php:75
#: src/Module/Contact.php:838
msgid "Media"
msgstr ""
#: src/Module/BaseProfile.php:109 #: src/Module/BaseProfile.php:109
msgid "Only You Can See This" msgid "Only You Can See This"
msgstr "" msgstr ""
@ -9266,41 +9263,41 @@ msgid ""
msgstr "" msgstr ""
#: src/Module/Settings/Profile/Photo/Crop.php:106 #: src/Module/Settings/Profile/Photo/Crop.php:106
#: src/Module/Settings/Profile/Photo/Crop.php:122 #: src/Module/Settings/Profile/Photo/Crop.php:124
#: src/Module/Settings/Profile/Photo/Crop.php:138 #: src/Module/Settings/Profile/Photo/Crop.php:142
#: src/Module/Settings/Profile/Photo/Index.php:102 #: src/Module/Settings/Profile/Photo/Index.php:102
#, php-format #, php-format
msgid "Image size reduction [%s] failed." msgid "Image size reduction [%s] failed."
msgstr "" msgstr ""
#: src/Module/Settings/Profile/Photo/Crop.php:143 #: src/Module/Settings/Profile/Photo/Crop.php:149
msgid "" msgid ""
"Shift-reload the page or clear browser cache if the new photo does not " "Shift-reload the page or clear browser cache if the new photo does not "
"display immediately." "display immediately."
msgstr "" msgstr ""
#: src/Module/Settings/Profile/Photo/Crop.php:148 #: src/Module/Settings/Profile/Photo/Crop.php:154
msgid "Unable to process image" msgid "Unable to process image"
msgstr "" msgstr ""
#: src/Module/Settings/Profile/Photo/Crop.php:167 #: src/Module/Settings/Profile/Photo/Crop.php:173
msgid "Photo not found." msgid "Photo not found."
msgstr "" msgstr ""
#: src/Module/Settings/Profile/Photo/Crop.php:189 #: src/Module/Settings/Profile/Photo/Crop.php:195
msgid "Profile picture successfully updated." msgid "Profile picture successfully updated."
msgstr "" msgstr ""
#: src/Module/Settings/Profile/Photo/Crop.php:215 #: src/Module/Settings/Profile/Photo/Crop.php:221
#: src/Module/Settings/Profile/Photo/Crop.php:219 #: src/Module/Settings/Profile/Photo/Crop.php:225
msgid "Crop Image" msgid "Crop Image"
msgstr "" msgstr ""
#: src/Module/Settings/Profile/Photo/Crop.php:216 #: src/Module/Settings/Profile/Photo/Crop.php:222
msgid "Please adjust the image cropping for optimum viewing." msgid "Please adjust the image cropping for optimum viewing."
msgstr "" msgstr ""
#: src/Module/Settings/Profile/Photo/Crop.php:218 #: src/Module/Settings/Profile/Photo/Crop.php:224
msgid "Use Image As Is" msgid "Use Image As Is"
msgstr "" msgstr ""

File diff suppressed because it is too large Load Diff

View File

@ -14,59 +14,6 @@ $a->strings['Weekly posting limit of %d post reached. The post was rejected.'] =
1 => 'Das wöchentliche Limit von %d Beiträgen wurde erreicht. Der Beitrag wurde verworfen.', 1 => 'Das wöchentliche Limit von %d Beiträgen wurde erreicht. Der Beitrag wurde verworfen.',
]; ];
$a->strings['Monthly posting limit of %d post reached. The post was rejected.'] = 'Das monatliche Limit von %d Beiträgen wurde erreicht. Der Beitrag wurde verworfen.'; $a->strings['Monthly posting limit of %d post reached. The post was rejected.'] = 'Das monatliche Limit von %d Beiträgen wurde erreicht. Der Beitrag wurde verworfen.';
$a->strings['[Friendica:Notify]'] = '[Friendica Meldung]';
$a->strings['%s New mail received at %s'] = '%sNeue Nachricht auf %s empfangen';
$a->strings['%1$s sent you a new private message at %2$s.'] = '%1$s hat dir eine neue, private Nachricht auf %2$s geschickt.';
$a->strings['a private message'] = 'eine private Nachricht';
$a->strings['%1$s sent you %2$s.'] = '%1$s schickte dir %2$s.';
$a->strings['Please visit %s to view and/or reply to your private messages.'] = 'Bitte besuche %s, um Deine privaten Nachrichten anzusehen und/oder zu beantworten.';
$a->strings['%1$s commented on %2$s\'s %3$s %4$s'] = '%1$s kommentierte %2$s\'s %3$s%4$s';
$a->strings['%1$s commented on your %2$s %3$s'] = '%1$s kommentierte auf (%2$s) %3$s';
$a->strings['%1$s commented on their %2$s %3$s'] = '%1$s hat den eigenen %2$s %3$s kommentiert';
$a->strings['%1$s Comment to conversation #%2$d by %3$s'] = '%1$sKommentar von %3$s auf Unterhaltung %2$d';
$a->strings['%s commented on an item/conversation you have been following.'] = '%s hat einen Beitrag kommentiert, dem du folgst.';
$a->strings['Please visit %s to view and/or reply to the conversation.'] = 'Bitte besuche %s, um die Konversation anzusehen und/oder zu kommentieren.';
$a->strings['%s %s posted to your profile wall'] = '%s%s hat auf deine Pinnwand gepostet';
$a->strings['%1$s posted to your profile wall at %2$s'] = '%1$s schrieb um %2$s auf Deine Pinnwand';
$a->strings['%1$s posted to [url=%2$s]your wall[/url]'] = '%1$s hat etwas auf [url=%2$s]Deiner Pinnwand[/url] gepostet';
$a->strings['%1$s %2$s poked you'] = '%1$s%2$shat dich angestubst';
$a->strings['%1$s poked you at %2$s'] = '%1$s hat dich auf %2$s angestupst';
$a->strings['%1$s [url=%2$s]poked you[/url].'] = '%1$s [url=%2$s]hat dich angestupst[/url].';
$a->strings['%s Introduction received'] = '%sVorstellung erhalten';
$a->strings['You\'ve received an introduction from \'%1$s\' at %2$s'] = 'Du hast eine Kontaktanfrage von \'%1$s\' auf %2$s erhalten';
$a->strings['You\'ve received [url=%1$s]an introduction[/url] from %2$s.'] = 'Du hast eine [url=%1$s]Kontaktanfrage[/url] von %2$s erhalten.';
$a->strings['You may visit their profile at %s'] = 'Hier kannst du das Profil betrachten: %s';
$a->strings['Please visit %s to approve or reject the introduction.'] = 'Bitte besuche %s, um die Kontaktanfrage anzunehmen oder abzulehnen.';
$a->strings['%s A new person is sharing with you'] = '%sEine neue Person teilt nun mit dir';
$a->strings['%1$s is sharing with you at %2$s'] = '%1$s teilt mit dir auf %2$s';
$a->strings['%s You have a new follower'] = '%sDu hast einen neuen Kontakt';
$a->strings['You have a new follower at %2$s : %1$s'] = 'Du hast einen neuen Kontakt auf %2$s: %1$s';
$a->strings['%s Friend suggestion received'] = '%sKontaktvorschlag erhalten';
$a->strings['You\'ve received a friend suggestion from \'%1$s\' at %2$s'] = 'Du hast einen Kontakt-Vorschlag von \'%1$s\' auf %2$s erhalten';
$a->strings['You\'ve received [url=%1$s]a friend suggestion[/url] for %2$s from %3$s.'] = 'Du hast einen [url=%1$s]Kontakt-Vorschlag[/url] %2$s von %3$s erhalten.';
$a->strings['Name:'] = 'Name:';
$a->strings['Photo:'] = 'Foto:';
$a->strings['Please visit %s to approve or reject the suggestion.'] = 'Bitte besuche %s, um den Vorschlag zu akzeptieren oder abzulehnen.';
$a->strings['%s Connection accepted'] = '%sKontaktanfrage bestätigt';
$a->strings['\'%1$s\' has accepted your connection request at %2$s'] = '\'%1$s\' hat Deine Kontaktanfrage auf %2$s bestätigt';
$a->strings['%2$s has accepted your [url=%1$s]connection request[/url].'] = '%2$s hat Deine [url=%1$s]Kontaktanfrage[/url] akzeptiert.';
$a->strings['You are now mutual friends and may exchange status updates, photos, and email without restriction.'] = 'Ihr seid nun beidseitige Kontakte und könnt Statusmitteilungen, Bilder und E-Mails ohne Einschränkungen austauschen.';
$a->strings['Please visit %s if you wish to make any changes to this relationship.'] = 'Bitte besuche %s, wenn du Änderungen an eurer Beziehung vornehmen willst.';
$a->strings['\'%1$s\' has chosen to accept you a fan, which restricts some forms of communication - such as private messaging and some profile interactions. If this is a celebrity or community page, these settings were applied automatically.'] = '\'%1$s\' hat sich entschieden dich als Fan zu akzeptieren, dies schränkt einige Kommunikationswege - wie private Nachrichten und einige Interaktionsmöglichkeiten auf der Profilseite - ein. Wenn dies eine Berühmtheiten- oder Gemeinschaftsseite ist, werden diese Einstellungen automatisch vorgenommen.';
$a->strings['\'%1$s\' may choose to extend this into a two-way or more permissive relationship in the future.'] = '\'%1$s\' kann den Kontaktstatus zu einem späteren Zeitpunkt erweitern und diese Einschränkungen aufheben. ';
$a->strings['Please visit %s if you wish to make any changes to this relationship.'] = 'Bitte besuche %s, wenn du Änderungen an eurer Beziehung vornehmen willst.';
$a->strings['[Friendica System Notify]'] = '[Friendica-Systembenachrichtigung]';
$a->strings['registration request'] = 'Registrierungsanfrage';
$a->strings['You\'ve received a registration request from \'%1$s\' at %2$s'] = 'Du hast eine Registrierungsanfrage von %2$s auf \'%1$s\' erhalten';
$a->strings['You\'ve received a [url=%1$s]registration request[/url] from %2$s.'] = 'Du hast eine [url=%1$s]Registrierungsanfrage[/url] von %2$s erhalten.';
$a->strings['Full Name: %s
Site Location: %s
Login Name: %s (%s)'] = 'Kompletter Name: %s
URL der Seite: %s
Login Name: %s(%s)';
$a->strings['Please visit %s to approve or reject the request.'] = 'Bitte besuche %s, um die Anfrage zu bearbeiten.';
$a->strings['%s %s tagged you'] = '%s %s hat dich erwähnt';
$a->strings['%s %s shared a new post'] = '%s%shat einen Beitrag geteilt';
$a->strings['Permission denied.'] = 'Zugriff verweigert.'; $a->strings['Permission denied.'] = 'Zugriff verweigert.';
$a->strings['Access denied.'] = 'Zugriff verweigert.'; $a->strings['Access denied.'] = 'Zugriff verweigert.';
$a->strings['User not found.'] = 'Benutzer nicht gefunden.'; $a->strings['User not found.'] = 'Benutzer nicht gefunden.';
@ -356,6 +303,7 @@ $a->strings['{0} requested registration'] = '{0} möchte sich registrieren';
$a->strings['{0} and %d others requested registration'] = '{0} und %d weitere möchten sich registrieren'; $a->strings['{0} and %d others requested registration'] = '{0} und %d weitere möchten sich registrieren';
$a->strings['Bad Request.'] = 'Ungültige Anfrage.'; $a->strings['Bad Request.'] = 'Ungültige Anfrage.';
$a->strings['Contact not found.'] = 'Kontakt nicht gefunden.'; $a->strings['Contact not found.'] = 'Kontakt nicht gefunden.';
$a->strings['[Friendica System Notify]'] = '[Friendica-Systembenachrichtigung]';
$a->strings['User deleted their account'] = 'Gelöschter Nutzeraccount'; $a->strings['User deleted their account'] = 'Gelöschter Nutzeraccount';
$a->strings['On your Friendica node an user deleted their account. Please ensure that their data is removed from the backups.'] = 'Ein Nutzer deiner Friendica-Instanz hat seinen Account gelöscht. Bitte stelle sicher, dass dessen Daten aus deinen Backups entfernt werden.'; $a->strings['On your Friendica node an user deleted their account. Please ensure that their data is removed from the backups.'] = 'Ein Nutzer deiner Friendica-Instanz hat seinen Account gelöscht. Bitte stelle sicher, dass dessen Daten aus deinen Backups entfernt werden.';
$a->strings['The user id is %d'] = 'Die ID des Users lautet %d'; $a->strings['The user id is %d'] = 'Die ID des Users lautet %d';
@ -740,8 +688,8 @@ $a->strings['Your posts and conversations'] = 'Deine Beiträge und Unterhaltunge
$a->strings['Profile'] = 'Profil'; $a->strings['Profile'] = 'Profil';
$a->strings['Your profile page'] = 'Deine Profilseite'; $a->strings['Your profile page'] = 'Deine Profilseite';
$a->strings['Your photos'] = 'Deine Fotos'; $a->strings['Your photos'] = 'Deine Fotos';
$a->strings['Videos'] = 'Videos'; $a->strings['Media'] = 'Medien';
$a->strings['Your videos'] = 'Deine Videos'; $a->strings['Your postings with media'] = 'Deine Beiträge die Medien beinhalten';
$a->strings['Your events'] = 'Deine Ereignisse'; $a->strings['Your events'] = 'Deine Ereignisse';
$a->strings['Personal notes'] = 'Persönliche Notizen'; $a->strings['Personal notes'] = 'Persönliche Notizen';
$a->strings['Your personal notes'] = 'Deine persönlichen Notizen'; $a->strings['Your personal notes'] = 'Deine persönlichen Notizen';
@ -1780,7 +1728,6 @@ $a->strings['API endpoint %s %s is not implemented'] = 'API Endpunkt %s %s ist n
$a->strings['The API endpoint is currently not implemented but might be in the future.'] = 'The API endpoint is currently not implemented but might be in the future.'; $a->strings['The API endpoint is currently not implemented but might be in the future.'] = 'The API endpoint is currently not implemented but might be in the future.';
$a->strings['Too Many Requests'] = 'Zu viele Abfragen'; $a->strings['Too Many Requests'] = 'Zu viele Abfragen';
$a->strings['Profile Details'] = 'Profildetails'; $a->strings['Profile Details'] = 'Profildetails';
$a->strings['Media'] = 'Medien';
$a->strings['Only You Can See This'] = 'Nur du kannst das sehen'; $a->strings['Only You Can See This'] = 'Nur du kannst das sehen';
$a->strings['Scheduled Posts'] = 'Geplante Beiträge'; $a->strings['Scheduled Posts'] = 'Geplante Beiträge';
$a->strings['Posts that are scheduled for publishing'] = 'Beiträge die für einen späteren Zeitpunkt für die Veröffentlichung geplant sind'; $a->strings['Posts that are scheduled for publishing'] = 'Beiträge die für einen späteren Zeitpunkt für die Veröffentlichung geplant sind';
@ -2510,6 +2457,58 @@ $a->strings['Friendica respects your privacy. By default, your posts will only s
$a->strings['Getting Help'] = 'Hilfe bekommen'; $a->strings['Getting Help'] = 'Hilfe bekommen';
$a->strings['Go to the Help Section'] = 'Zum Hilfe Abschnitt gehen'; $a->strings['Go to the Help Section'] = 'Zum Hilfe Abschnitt gehen';
$a->strings['Our <strong>help</strong> pages may be consulted for detail on other program features and resources.'] = 'Unsere <strong>Hilfe</strong>-Seiten können herangezogen werden, um weitere Einzelheiten zu anderen Programm-Features zu erhalten.'; $a->strings['Our <strong>help</strong> pages may be consulted for detail on other program features and resources.'] = 'Unsere <strong>Hilfe</strong>-Seiten können herangezogen werden, um weitere Einzelheiten zu anderen Programm-Features zu erhalten.';
$a->strings['[Friendica:Notify]'] = '[Friendica Meldung]';
$a->strings['%s New mail received at %s'] = '%sNeue Nachricht auf %s empfangen';
$a->strings['%1$s sent you a new private message at %2$s.'] = '%1$s hat dir eine neue, private Nachricht auf %2$s geschickt.';
$a->strings['a private message'] = 'eine private Nachricht';
$a->strings['%1$s sent you %2$s.'] = '%1$s schickte dir %2$s.';
$a->strings['Please visit %s to view and/or reply to your private messages.'] = 'Bitte besuche %s, um Deine privaten Nachrichten anzusehen und/oder zu beantworten.';
$a->strings['%1$s commented on %2$s\'s %3$s %4$s'] = '%1$s kommentierte %2$s\'s %3$s%4$s';
$a->strings['%1$s commented on your %2$s %3$s'] = '%1$s kommentierte auf (%2$s) %3$s';
$a->strings['%1$s commented on their %2$s %3$s'] = '%1$s hat den eigenen %2$s %3$s kommentiert';
$a->strings['%1$s Comment to conversation #%2$d by %3$s'] = '%1$sKommentar von %3$s auf Unterhaltung %2$d';
$a->strings['%s commented on an item/conversation you have been following.'] = '%s hat einen Beitrag kommentiert, dem du folgst.';
$a->strings['Please visit %s to view and/or reply to the conversation.'] = 'Bitte besuche %s, um die Konversation anzusehen und/oder zu kommentieren.';
$a->strings['%s %s posted to your profile wall'] = '%s%s hat auf deine Pinnwand gepostet';
$a->strings['%1$s posted to your profile wall at %2$s'] = '%1$s schrieb um %2$s auf Deine Pinnwand';
$a->strings['%1$s posted to [url=%2$s]your wall[/url]'] = '%1$s hat etwas auf [url=%2$s]Deiner Pinnwand[/url] gepostet';
$a->strings['%1$s %2$s poked you'] = '%1$s%2$shat dich angestubst';
$a->strings['%1$s poked you at %2$s'] = '%1$s hat dich auf %2$s angestupst';
$a->strings['%1$s [url=%2$s]poked you[/url].'] = '%1$s [url=%2$s]hat dich angestupst[/url].';
$a->strings['%s Introduction received'] = '%sVorstellung erhalten';
$a->strings['You\'ve received an introduction from \'%1$s\' at %2$s'] = 'Du hast eine Kontaktanfrage von \'%1$s\' auf %2$s erhalten';
$a->strings['You\'ve received [url=%1$s]an introduction[/url] from %2$s.'] = 'Du hast eine [url=%1$s]Kontaktanfrage[/url] von %2$s erhalten.';
$a->strings['You may visit their profile at %s'] = 'Hier kannst du das Profil betrachten: %s';
$a->strings['Please visit %s to approve or reject the introduction.'] = 'Bitte besuche %s, um die Kontaktanfrage anzunehmen oder abzulehnen.';
$a->strings['%s A new person is sharing with you'] = '%sEine neue Person teilt nun mit dir';
$a->strings['%1$s is sharing with you at %2$s'] = '%1$s teilt mit dir auf %2$s';
$a->strings['%s You have a new follower'] = '%sDu hast einen neuen Kontakt';
$a->strings['You have a new follower at %2$s : %1$s'] = 'Du hast einen neuen Kontakt auf %2$s: %1$s';
$a->strings['%s Friend suggestion received'] = '%sKontaktvorschlag erhalten';
$a->strings['You\'ve received a friend suggestion from \'%1$s\' at %2$s'] = 'Du hast einen Kontakt-Vorschlag von \'%1$s\' auf %2$s erhalten';
$a->strings['You\'ve received [url=%1$s]a friend suggestion[/url] for %2$s from %3$s.'] = 'Du hast einen [url=%1$s]Kontakt-Vorschlag[/url] %2$s von %3$s erhalten.';
$a->strings['Name:'] = 'Name:';
$a->strings['Photo:'] = 'Foto:';
$a->strings['Please visit %s to approve or reject the suggestion.'] = 'Bitte besuche %s, um den Vorschlag zu akzeptieren oder abzulehnen.';
$a->strings['%s Connection accepted'] = '%sKontaktanfrage bestätigt';
$a->strings['\'%1$s\' has accepted your connection request at %2$s'] = '\'%1$s\' hat Deine Kontaktanfrage auf %2$s bestätigt';
$a->strings['%2$s has accepted your [url=%1$s]connection request[/url].'] = '%2$s hat Deine [url=%1$s]Kontaktanfrage[/url] akzeptiert.';
$a->strings['You are now mutual friends and may exchange status updates, photos, and email without restriction.'] = 'Ihr seid nun beidseitige Kontakte und könnt Statusmitteilungen, Bilder und E-Mails ohne Einschränkungen austauschen.';
$a->strings['Please visit %s if you wish to make any changes to this relationship.'] = 'Bitte besuche %s, wenn du Änderungen an eurer Beziehung vornehmen willst.';
$a->strings['\'%1$s\' has chosen to accept you a fan, which restricts some forms of communication - such as private messaging and some profile interactions. If this is a celebrity or community page, these settings were applied automatically.'] = '\'%1$s\' hat sich entschieden dich als Fan zu akzeptieren, dies schränkt einige Kommunikationswege - wie private Nachrichten und einige Interaktionsmöglichkeiten auf der Profilseite - ein. Wenn dies eine Berühmtheiten- oder Gemeinschaftsseite ist, werden diese Einstellungen automatisch vorgenommen.';
$a->strings['\'%1$s\' may choose to extend this into a two-way or more permissive relationship in the future.'] = '\'%1$s\' kann den Kontaktstatus zu einem späteren Zeitpunkt erweitern und diese Einschränkungen aufheben. ';
$a->strings['Please visit %s if you wish to make any changes to this relationship.'] = 'Bitte besuche %s, wenn du Änderungen an eurer Beziehung vornehmen willst.';
$a->strings['registration request'] = 'Registrierungsanfrage';
$a->strings['You\'ve received a registration request from \'%1$s\' at %2$s'] = 'Du hast eine Registrierungsanfrage von %2$s auf \'%1$s\' erhalten';
$a->strings['You\'ve received a [url=%1$s]registration request[/url] from %2$s.'] = 'Du hast eine [url=%1$s]Registrierungsanfrage[/url] von %2$s erhalten.';
$a->strings['Full Name: %s
Site Location: %s
Login Name: %s (%s)'] = 'Kompletter Name: %s
URL der Seite: %s
Login Name: %s(%s)';
$a->strings['Please visit %s to approve or reject the request.'] = 'Bitte besuche %s, um die Anfrage zu bearbeiten.';
$a->strings['%s %s tagged you'] = '%s %s hat dich erwähnt';
$a->strings['%s %s shared a new post'] = '%s%shat einen Beitrag geteilt';
$a->strings['%s liked %s\'s post'] = '%s mag %ss Beitrag'; $a->strings['%s liked %s\'s post'] = '%s mag %ss Beitrag';
$a->strings['%s disliked %s\'s post'] = '%s mag %ss Beitrag nicht'; $a->strings['%s disliked %s\'s post'] = '%s mag %ss Beitrag nicht';
$a->strings['%s is attending %s\'s event'] = '%s nimmt an %s\'s Event teil'; $a->strings['%s is attending %s\'s event'] = '%s nimmt an %s\'s Event teil';

View File

@ -225,7 +225,7 @@ function frio_remote_nav(App $a, array &$nav_info)
$nav_info['nav']['usermenu'][] = [$server_url . '/profile/' . $remoteUser['nick'], DI::l10n()->t('Status'), '', DI::l10n()->t('Your posts and conversations')]; $nav_info['nav']['usermenu'][] = [$server_url . '/profile/' . $remoteUser['nick'], DI::l10n()->t('Status'), '', DI::l10n()->t('Your posts and conversations')];
$nav_info['nav']['usermenu'][] = [$server_url . '/profile/' . $remoteUser['nick'] . '/profile', DI::l10n()->t('Profile'), '', DI::l10n()->t('Your profile page')]; $nav_info['nav']['usermenu'][] = [$server_url . '/profile/' . $remoteUser['nick'] . '/profile', DI::l10n()->t('Profile'), '', DI::l10n()->t('Your profile page')];
$nav_info['nav']['usermenu'][] = [$server_url . '/photos/' . $remoteUser['nick'], DI::l10n()->t('Photos'), '', DI::l10n()->t('Your photos')]; $nav_info['nav']['usermenu'][] = [$server_url . '/photos/' . $remoteUser['nick'], DI::l10n()->t('Photos'), '', DI::l10n()->t('Your photos')];
$nav_info['nav']['usermenu'][] = [$server_url . '/videos/' . $remoteUser['nick'], DI::l10n()->t('Videos'), '', DI::l10n()->t('Your videos')]; $nav_info['nav']['usermenu'][] = [$server_url . '/media/' . $remoteUser['nick'], DI::l10n()->t('Media'), '', DI::l10n()->t('Your postings with media')];
$nav_info['nav']['usermenu'][] = [$server_url . '/events/', DI::l10n()->t('Events'), '', DI::l10n()->t('Your events')]; $nav_info['nav']['usermenu'][] = [$server_url . '/events/', DI::l10n()->t('Events'), '', DI::l10n()->t('Your events')];
// navbar links // navbar links