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

This commit is contained in:
Michael 2020-03-02 15:05:00 +00:00
commit 72c198990e
60 changed files with 985 additions and 637 deletions

View file

@ -1037,6 +1037,7 @@ class Contact
}
if (DBA::isResult($r)) {
$authoritativeResult = true;
// If there is more than one entry we filter out the connector networks
if (count($r) > 1) {
foreach ($r as $id => $result) {
@ -1070,6 +1071,7 @@ class Contact
$profile["bd"] = DBA::NULL_DATE;
}
} else {
$authoritativeResult = false;
$profile = $default;
}
@ -1106,7 +1108,11 @@ class Contact
$profile["birthday"] = DBA::NULL_DATE;
}
$cache[$url][$uid] = $profile;
// Only cache the result if it came from the DB since this method is used in widely different contexts
// @see display_fetch_author for an example of $default parameter diverging from the DB result
if ($authoritativeResult) {
$cache[$url][$uid] = $profile;
}
return $profile;
}

View file

@ -3634,7 +3634,7 @@ class Item
$title .= ' ' . $mtch[2] . ' ' . DI::l10n()->t('bytes');
$icon = '<div class="attachtype icon s22 type-' . $filetype . ' subtype-' . $filesubtype . '"></div>';
$as .= '<a href="' . strip_tags($the_url) . '" title="' . $title . '" class="attachlink" target="_blank" >' . $icon . '</a>';
$as .= '<a href="' . strip_tags($the_url) . '" title="' . $title . '" class="attachlink" target="_blank" rel="noopener noreferrer" >' . $icon . '</a>';
}
if ($as != '') {

View file

@ -330,7 +330,8 @@ class Profile
if (!$local_user_is_self && $show_connect) {
if (!$visitor_is_authenticated) {
if (!empty($profile['nickname'])) {
// Remote follow is only available for local profiles
if (!empty($profile['nickname']) && strpos($profile_url, DI::baseUrl()->get()) === 0) {
$follow_link = 'remote_follow/' . $profile['nickname'];
}
} elseif ($profile_is_native) {

View file

@ -21,6 +21,7 @@
namespace Friendica\Model;
use Friendica\Content\Pager;
use Friendica\Database\DBA;
use Friendica\Util\DateTimeFormat;
use Friendica\Util\Strings;
@ -33,21 +34,46 @@ class Register
/**
* Return the list of pending registrations
*
* @param int $start Start count (Default is 0)
* @param int $count Count of the items per page (Default is @see Pager::ITEMS_PER_PAGE)
*
* @return array
* @throws \Exception
*/
public static function getPending()
public static function getPending($start = 0, $count = Pager::ITEMS_PER_PAGE)
{
$stmt = DBA::p(
"SELECT `register`.*, `contact`.`name`, `contact`.`url`, `contact`.`micro`, `user`.`email`
"SELECT `register`.*, `contact`.`name`, `contact`.`url`, `contact`.`micro`, `user`.`email`, `contact`.`nick`
FROM `register`
INNER JOIN `contact` ON `register`.`uid` = `contact`.`uid`
INNER JOIN `user` ON `register`.`uid` = `user`.`uid`"
INNER JOIN `user` ON `register`.`uid` = `user`.`uid`
LIMIT ?, ?", $start, $count
);
return DBA::toArray($stmt);
}
/**
* Returns the pending user based on a given user id
*
* @param int $uid The user id
*
* @return array The pending user information
*
* @throws \Exception
*/
public static function getPendingForUser(int $uid)
{
return DBA::fetchFirst(
"SELECT `register`.*, `contact`.`name`, `contact`.`url`, `contact`.`micro`, `user`.`email`
FROM `register`
INNER JOIN `contact` ON `register`.`uid` = `contact`.`uid`
INNER JOIN `user` ON `register`.`uid` = `user`.`uid`
WHERE `register`.uid = ?",
$uid
);
}
/**
* Returns the pending registration count
*

View file

@ -463,13 +463,13 @@ class Term
$item['body'] = str_replace($orig_tag, $tag['url'], $item['body']);
}
$return['hashtags'][] = $prefix . '<a href="' . $tag['url'] . '" target="_blank">' . htmlspecialchars($tag['term']) . '</a>';
$return['tags'][] = $prefix . '<a href="' . $tag['url'] . '" target="_blank">' . htmlspecialchars($tag['term']) . '</a>';
$return['hashtags'][] = $prefix . '<a href="' . $tag['url'] . '" target="_blank" rel="noopener noreferrer">' . htmlspecialchars($tag['term']) . '</a>';
$return['tags'][] = $prefix . '<a href="' . $tag['url'] . '" target="_blank" rel="noopener noreferrer">' . htmlspecialchars($tag['term']) . '</a>';
break;
case self::MENTION:
$tag['url'] = Contact::magicLink($tag['url']);
$return['mentions'][] = $prefix . '<a href="' . $tag['url'] . '" target="_blank">' . htmlspecialchars($tag['term']) . '</a>';
$return['tags'][] = $prefix . '<a href="' . $tag['url'] . '" target="_blank">' . htmlspecialchars($tag['term']) . '</a>';
$return['mentions'][] = $prefix . '<a href="' . $tag['url'] . '" target="_blank" rel="noopener noreferrer">' . htmlspecialchars($tag['term']) . '</a>';
$return['tags'][] = $prefix . '<a href="' . $tag['url'] . '" target="_blank" rel="noopener noreferrer">' . htmlspecialchars($tag['term']) . '</a>';
break;
case self::IMPLICIT_MENTION:
$return['implicit_mentions'][] = $prefix . $tag['term'];

View file

@ -23,7 +23,9 @@ namespace Friendica\Model;
use DivineOmega\PasswordExposed;
use Exception;
use Friendica\Content\Pager;
use Friendica\Core\Hook;
use Friendica\Core\L10n;
use Friendica\Core\Logger;
use Friendica\Core\Protocol;
use Friendica\Core\System;
@ -31,6 +33,7 @@ use Friendica\Core\Worker;
use Friendica\Database\DBA;
use Friendica\DI;
use Friendica\Model\TwoFactor\AppSpecificPassword;
use Friendica\Network\HTTPException\InternalServerErrorException;
use Friendica\Object\Image;
use Friendica\Util\Crypto;
use Friendica\Util\DateTimeFormat;
@ -279,7 +282,7 @@ class User
* @param string $network network name
*
* @return int group id
* @throws \Friendica\Network\HTTPException\InternalServerErrorException
* @throws InternalServerErrorException
*/
public static function getDefaultGroup($uid, $network = '')
{
@ -556,7 +559,7 @@ class User
*
* @param string $nickname The nickname that should be checked
* @return boolean True is the nickname is blocked on the node
* @throws \Friendica\Network\HTTPException\InternalServerErrorException
* @throws InternalServerErrorException
*/
public static function isNicknameBlocked($nickname)
{
@ -593,7 +596,7 @@ class User
* @param array $data
* @return array
* @throws \ErrorException
* @throws \Friendica\Network\HTTPException\InternalServerErrorException
* @throws InternalServerErrorException
* @throws \ImagickException
* @throws Exception
*/
@ -880,6 +883,166 @@ class User
return $return;
}
/**
* Sets block state for a given user
*
* @param int $uid The user id
* @param bool $block Block state (default is true)
*
* @return bool True, if successfully blocked
* @throws Exception
*/
public static function block(int $uid, bool $block = true)
{
return DBA::update('user', ['blocked' => $block], ['uid' => $uid]);
}
/**
* Allows a registration based on a hash
*
* @param string $hash
*
* @return bool True, if the allow was successful
*
* @throws InternalServerErrorException
* @throws Exception
*/
public static function allow(string $hash)
{
$register = Register::getByHash($hash);
if (!DBA::isResult($register)) {
return false;
}
$user = User::getById($register['uid']);
if (!DBA::isResult($user)) {
return false;
}
Register::deleteByHash($hash);
DBA::update('user', ['blocked' => false, 'verified' => true], ['uid' => $register['uid']]);
$profile = DBA::selectFirst('profile', ['net-publish'], ['uid' => $register['uid']]);
if (DBA::isResult($profile) && $profile['net-publish'] && DI::config()->get('system', 'directory')) {
$url = DI::baseUrl() . '/profile/' . $user['nickname'];
Worker::add(PRIORITY_LOW, "Directory", $url);
}
$l10n = DI::l10n()->withLang($register['language']);
return User::sendRegisterOpenEmail(
$l10n,
$user,
DI::config()->get('config', 'sitename'),
DI::baseUrl()->get(),
($register['password'] ?? '') ?: 'Sent in a previous email'
);
}
/**
* Denys a pending registration
*
* @param string $hash The hash of the pending user
*
* This does not have to go through user_remove() and save the nickname
* permanently against re-registration, as the person was not yet
* allowed to have friends on this system
*
* @return bool True, if the deny was successfull
* @throws Exception
*/
public static function deny(string $hash)
{
$register = Register::getByHash($hash);
if (!DBA::isResult($register)) {
return false;
}
$user = User::getById($register['uid']);
if (!DBA::isResult($user)) {
return false;
}
return DBA::delete('user', ['uid' => $register['uid']]) &&
Register::deleteByHash($register['hash']);
}
/**
* Creates a new user based on a minimal set and sends an email to this user
*
* @param string $name The user's name
* @param string $email The user's email address
* @param string $nick The user's nick name
* @param string $lang The user's language (default is english)
*
* @return bool True, if the user was created successfully
* @throws InternalServerErrorException
* @throws \ErrorException
* @throws \ImagickException
*/
public static function createMinimal(string $name, string $email, string $nick, string $lang = L10n::DEFAULT)
{
if (empty($name) ||
empty($email) ||
empty($nick)) {
throw new InternalServerErrorException('Invalid arguments.');
}
$result = self::create([
'username' => $name,
'email' => $email,
'nickname' => $nick,
'verified' => 1,
'language' => $lang
]);
$user = $result['user'];
$preamble = Strings::deindent(DI::l10n()->t('
Dear %1$s,
the administrator of %2$s has set up an account for you.'));
$body = Strings::deindent(DI::l10n()->t('
The login details are as follows:
Site Location: %1$s
Login Name: %2$s
Password: %3$s
You may change your password from your account "Settings" page after logging
in.
Please take a few moments to review the other account settings on that page.
You may also wish to add some basic information to your default profile
(on the "Profiles" page) so that other people can easily find you.
We recommend setting your full name, adding a profile photo,
adding some profile "keywords" (very useful in making new friends) - and
perhaps what country you live in; if you do not wish to be more specific
than that.
We fully respect your right to privacy, and none of these items are necessary.
If you are new and do not know anybody here, they may help
you to make some new and interesting friends.
If you ever want to delete your account, you can do so at %1$s/removeme
Thank you and welcome to %4$s.'));
$preamble = sprintf($preamble, $user['username'], DI::config()->get('config', 'sitename'));
$body = sprintf($body, DI::baseUrl()->get(), $user['nickname'], $result['password'], DI::config()->get('config', 'sitename'));
$email = DI::emailer()
->newSystemMail()
->withMessage(DI::l10n()->t('Registration details for %s', DI::config()->get('config', 'sitename')), $preamble, $body)
->forUser($user)
->withRecipient($user['email'])
->build();
return DI::emailer()->send($email);
}
/**
* Sends pending registration confirmation email
*
@ -888,7 +1051,7 @@ class User
* @param string $siteurl
* @param string $password Plaintext password
* @return NULL|boolean from notification() and email() inherited
* @throws \Friendica\Network\HTTPException\InternalServerErrorException
* @throws InternalServerErrorException
*/
public static function sendRegisterPendingEmail($user, $sitename, $siteurl, $password)
{
@ -931,7 +1094,7 @@ class User
* @param string $password Plaintext password
*
* @return NULL|boolean from notification() and email() inherited
* @throws \Friendica\Network\HTTPException\InternalServerErrorException
* @throws InternalServerErrorException
*/
public static function sendRegisterOpenEmail(\Friendica\Core\L10n $l10n, $user, $sitename, $siteurl, $password)
{
@ -988,11 +1151,11 @@ class User
}
/**
* @param object $uid user to remove
* @param int $uid user to remove
* @return bool
* @throws \Friendica\Network\HTTPException\InternalServerErrorException
* @throws InternalServerErrorException
*/
public static function remove($uid)
public static function remove(int $uid)
{
if (!$uid) {
return false;
@ -1154,4 +1317,47 @@ class User
return $statistics;
}
/**
* Get all users of the current node
*
* @param int $start Start count (Default is 0)
* @param int $count Count of the items per page (Default is @see Pager::ITEMS_PER_PAGE)
* @param string $type The type of users, which should get (all, bocked, removed)
* @param string $order Order of the user list (Default is 'contact.name')
* @param string $order_direction Order direction (Default is ASC)
*
* @return array The list of the users
* @throws Exception
*/
public static function getList($start = 0, $count = Pager::ITEMS_PER_PAGE, $type = 'all', $order = 'contact.name', $order_direction = '+')
{
$sql_order = '`' . str_replace('.', '`.`', $order) . '`';
$sql_order_direction = ($order_direction === '+') ? 'ASC' : 'DESC';
switch ($type) {
case 'active':
$sql_extra = 'AND `user`.`blocked` = 0';
break;
case 'blocked':
$sql_extra = 'AND `user`.`blocked` = 1';
break;
case 'removed':
$sql_extra = 'AND `user`.`account_removed` = 1';
break;
case 'all':
default:
$sql_extra = '';
break;
}
$usersStmt = DBA::p("SELECT `user`.*, `contact`.`name`, `contact`.`url`, `contact`.`micro`, `user`.`account_expired`, `contact`.`last-item` AS `lastitem_date`, `contact`.`nick`, `contact`.`created`
FROM `user`
INNER JOIN `contact` ON `contact`.`uid` = `user`.`uid` AND `contact`.`self`
WHERE `user`.`verified` $sql_extra
ORDER BY $sql_order $sql_order_direction LIMIT ?, ?", $start, $count
);
return DBA::toArray($usersStmt);
}
}