1
0
Fork 0

Merge remote-tracking branch 'upstream/develop' into no-api-post

This commit is contained in:
Michael 2022-11-23 06:28:24 +00:00
commit 25992b063a
71 changed files with 5016 additions and 4336 deletions

View file

@ -115,76 +115,40 @@ class Page implements ArrayAccess
}
}
// ArrayAccess interface
/**
* Whether a offset exists
*
* @link https://php.net/manual/en/arrayaccess.offsetexists.php
*
* @param mixed $offset <p>
* An offset to check for.
* </p>
*
* @return boolean true on success or false on failure.
* </p>
* <p>
* The return value will be casted to boolean if non-boolean was returned.
* @since 5.0.0
* @inheritDoc
*/
#[\ReturnTypeWillChange]
public function offsetExists($offset): bool
{
return isset($this->page[$offset]);
}
/**
* Offset to retrieve
*
* @link https://php.net/manual/en/arrayaccess.offsetget.php
*
* @param mixed $offset <p>
* The offset to retrieve.
* </p>
*
* @return mixed Can return all value types.
* @since 5.0.0
* @inheritDoc
*/
#[\ReturnTypeWillChange]
public function offsetGet($offset)
{
return $this->page[$offset] ?? null;
}
/**
* Offset to set
*
* @link https://php.net/manual/en/arrayaccess.offsetset.php
*
* @param mixed $offset <p>
* The offset to assign the value to.
* </p>
* @param mixed $value <p>
* The value to set.
* </p>
*
* @return void
* @since 5.0.0
* @inheritDoc
*/
public function offsetSet($offset, $value)
#[\ReturnTypeWillChange]
public function offsetSet($offset, $value): void
{
$this->page[$offset] = $value;
}
/**
* Offset to unset
*
* @link https://php.net/manual/en/arrayaccess.offsetunset.php
*
* @param mixed $offset <p>
* The offset to unset.
* </p>
*
* @return void
* @since 5.0.0
* @inheritDoc
*/
public function offsetUnset($offset)
#[\ReturnTypeWillChange]
public function offsetUnset($offset): void
{
if (isset($this->page[$offset])) {
unset($this->page[$offset]);
@ -310,7 +274,7 @@ class Page implements ArrayAccess
}
return $pageURL;
}
/**
* Initializes Page->page['footer'].
*

View file

@ -526,7 +526,7 @@ class Conversation
$live_update_div = '<div id="live-search"></div>' . "\r\n";
}
$page_dropping = $this->session->getLocalUserId() && $this->session->getLocalUserId() == $uid;
$page_dropping = $this->session->getLocalUserId() && $this->session->getLocalUserId() == $uid && $mode != 'search';
if (!$update) {
$_SESSION['return_path'] = $this->args->getQueryString();

View file

@ -361,7 +361,7 @@ class Item
if ($sparkle) {
$status_link = $profile_link . '/status';
$photos_link = str_replace('/profile/', '/photos/', $profile_link);
$photos_link = $profile_link . '/photos';
$profile_link = $profile_link . '/profile';
}
@ -729,7 +729,7 @@ class Item
'message_id' => $shared['uri'],
'comment' => $item['body'],
'shared' => $shared['body'],
];
];
}
}
@ -737,7 +737,7 @@ class Item
}
/**
* Add a link to a shared post at the end of the post
* Add a link to a shared post at the end of the post
*
* @param string $body
* @param integer $quote_uri_id

View file

@ -192,7 +192,7 @@ class Nav
// user menu
$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'][] = ['photos/' . $a->getLoggedInUserNickname(), DI::l10n()->t('Photos'), '', DI::l10n()->t('Your photos')];
$nav['usermenu'][] = ['profile/' . $a->getLoggedInUserNickname() . '/photos', DI::l10n()->t('Photos'), '', DI::l10n()->t('Your photos')];
$nav['usermenu'][] = ['profile/' . $a->getLoggedInUserNickname() . '/media', DI::l10n()->t('Media'), '', DI::l10n()->t('Your postings with media')];
$nav['usermenu'][] = ['calendar/', DI::l10n()->t('Calendar'), '', DI::l10n()->t('Your calendar')];
$nav['usermenu'][] = ['notes/', DI::l10n()->t('Personal notes'), '', DI::l10n()->t('Your personal notes')];
@ -244,12 +244,8 @@ class Nav
}
$gdirpath = 'directory';
if (strlen(DI::config()->get('system', 'singleuser'))) {
$gdir = DI::config()->get('system', 'directory');
if (strlen($gdir)) {
$gdirpath = Profile::zrl($gdir, true);
}
if (DI::config()->get('system', 'singleuser') && DI::config()->get('system', 'directory')) {
$gdirpath = Profile::zrl(DI::config()->get('system', 'directory'), true);
}
if ((DI::userSession()->getLocalUserId() || DI::config()->get('system', 'community_page_style') != Community::DISABLED_VISITOR) &&

View file

@ -43,12 +43,12 @@ use Psr\Log\NullLogger;
*/
class Database
{
const PDO = 'pdo';
const PDO = 'pdo';
const MYSQLI = 'mysqli';
const INSERT_DEFAULT = 0;
const INSERT_UPDATE = 1;
const INSERT_IGNORE = 2;
const INSERT_UPDATE = 1;
const INSERT_IGNORE = 2;
protected $connected = false;
@ -64,18 +64,18 @@ class Database
* @var LoggerInterface
*/
protected $logger;
protected $server_info = '';
protected $server_info = '';
/** @var PDO|mysqli */
protected $connection;
protected $driver = '';
protected $pdo_emulate_prepares = false;
private $error = '';
private $errorno = 0;
private $affected_rows = 0;
private $error = '';
private $errorno = 0;
private $affected_rows = 0;
protected $in_transaction = false;
protected $in_retrial = false;
protected $testmode = false;
private $relation = [];
protected $in_retrial = false;
protected $testmode = false;
private $relation = [];
/** @var DbaDefinition */
protected $dbaDefinition;
/** @var ViewDefinition */
@ -112,23 +112,22 @@ class Database
$port = 0;
$serveraddr = trim($this->configCache->get('database', 'hostname'));
$serverdata = explode(':', $serveraddr);
$server = $serverdata[0];
$host = trim($serverdata[0]);
if (count($serverdata) > 1) {
$port = trim($serverdata[1]);
}
if (!empty(trim($this->configCache->get('database', 'port')))) {
$port = trim($this->configCache->get('database', 'port'));
if (trim($this->configCache->get('database', 'port') ?? 0)) {
$port = trim($this->configCache->get('database', 'port') ?? 0);
}
$server = trim($server);
$user = trim($this->configCache->get('database', 'username'));
$pass = trim($this->configCache->get('database', 'password'));
$db = trim($this->configCache->get('database', 'database'));
$charset = trim($this->configCache->get('database', 'charset'));
$socket = trim($this->configCache->get('database', 'socket'));
$user = trim($this->configCache->get('database', 'username'));
$pass = trim($this->configCache->get('database', 'password'));
$database = trim($this->configCache->get('database', 'database'));
$charset = trim($this->configCache->get('database', 'charset'));
$socket = trim($this->configCache->get('database', 'socket'));
if (!(strlen($server) && strlen($user))) {
if (!$host && !$socket || !$user) {
return false;
}
@ -138,19 +137,20 @@ class Database
if (!$this->configCache->get('database', 'disable_pdo') && class_exists('\PDO') && in_array('mysql', PDO::getAvailableDrivers())) {
$this->driver = self::PDO;
$connect = "mysql:host=" . $server . ";dbname=" . $db;
if ($port > 0) {
$connect .= ";port=" . $port;
if ($socket) {
$connect = 'mysql:unix_socket=' . $socket;
} else {
$connect = 'mysql:host=' . $host;
if ($port > 0) {
$connect .= ';port=' . $port;
}
}
if ($charset) {
$connect .= ";charset=" . $charset;
$connect .= ';charset=' . $charset;
}
if ($socket) {
$connect .= ";$unix_socket=" . $socket;
}
$connect .= ';dbname=' . $database;
try {
$this->connection = @new PDO($connect, $user, $pass, [PDO::ATTR_PERSISTENT => $persistent]);
@ -165,10 +165,12 @@ class Database
if (!$this->connected && class_exists('\mysqli')) {
$this->driver = self::MYSQLI;
if ($port > 0) {
$this->connection = @new mysqli($server, $user, $pass, $db, $port);
if ($socket) {
$this->connection = @new mysqli(null, $user, $pass, $database, null, $socket);
} elseif ($port > 0) {
$this->connection = @new mysqli($host, $user, $pass, $database, $port);
} else {
$this->connection = @new mysqli($server, $user, $pass, $db);
$this->connection = @new mysqli($host, $user, $pass, $database);
}
if (!mysqli_connect_errno()) {
@ -177,11 +179,6 @@ class Database
if ($charset) {
$this->connection->set_charset($charset);
}
if ($socket) {
$this->connection->set_socket($socket);
}
}
}
@ -198,6 +195,7 @@ class Database
{
$this->testmode = $test;
}
/**
* Sets the logger for DBA
*
@ -222,6 +220,7 @@ class Database
{
$this->profiler = $profiler;
}
/**
* Disconnects the current database connection
*/
@ -338,12 +337,12 @@ class Database
}
$watchlist = explode(',', $this->configCache->get('system', 'db_log_index_watch'));
$denylist = explode(',', $this->configCache->get('system', 'db_log_index_denylist'));
$denylist = explode(',', $this->configCache->get('system', 'db_log_index_denylist'));
while ($row = $this->fetch($r)) {
if ((intval($this->configCache->get('system', 'db_loglimit_index')) > 0)) {
$log = (in_array($row['key'], $watchlist) &&
($row['rows'] >= intval($this->configCache->get('system', 'db_loglimit_index'))));
($row['rows'] >= intval($this->configCache->get('system', 'db_loglimit_index'))));
} else {
$log = false;
}
@ -358,11 +357,15 @@ class Database
if ($log) {
$backtrace = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS);
@file_put_contents($this->configCache->get('system', 'db_log_index'), DateTimeFormat::utcNow() . "\t" .
$row['key'] . "\t" . $row['rows'] . "\t" . $row['Extra'] . "\t" .
basename($backtrace[1]["file"]) . "\t" .
$backtrace[1]["line"] . "\t" . $backtrace[2]["function"] . "\t" .
substr($query, 0, 4000) . "\n", FILE_APPEND);
@file_put_contents(
$this->configCache->get('system', 'db_log_index'),
DateTimeFormat::utcNow() . "\t" .
$row['key'] . "\t" . $row['rows'] . "\t" . $row['Extra'] . "\t" .
basename($backtrace[1]["file"]) . "\t" .
$backtrace[1]["line"] . "\t" . $backtrace[2]["function"] . "\t" .
substr($query, 0, 4000) . "\n",
FILE_APPEND
);
}
}
}
@ -449,7 +452,7 @@ class Database
{
$server_info = $this->serverInfo();
if (version_compare($server_info, '5.7.5', '<') ||
(stripos($server_info, 'MariaDB') !== false)) {
(stripos($server_info, 'MariaDB') !== false)) {
$sql = str_ireplace('ANY_VALUE(', 'MIN(', $sql);
}
return $sql;
@ -647,7 +650,7 @@ class Database
} elseif (is_string($args[$param])) {
$param_types .= 's';
} elseif (is_object($args[$param]) && method_exists($args[$param], '__toString')) {
$param_types .= 's';
$param_types .= 's';
$args[$param] = (string)$args[$param];
} else {
$param_types .= 'b';
@ -743,10 +746,14 @@ class Database
$duration = round($duration, 3);
$backtrace = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS);
@file_put_contents($this->configCache->get('system', 'db_log'), DateTimeFormat::utcNow() . "\t" . $duration . "\t" .
basename($backtrace[1]["file"]) . "\t" .
$backtrace[1]["line"] . "\t" . $backtrace[2]["function"] . "\t" .
substr($this->replaceParameters($sql, $args), 0, 4000) . "\n", FILE_APPEND);
@file_put_contents(
$this->configCache->get('system', 'db_log'),
DateTimeFormat::utcNow() . "\t" . $duration . "\t" .
basename($backtrace[1]["file"]) . "\t" .
$backtrace[1]["line"] . "\t" . $backtrace[2]["function"] . "\t" .
substr($this->replaceParameters($sql, $args), 0, 4000) . "\n",
FILE_APPEND
);
}
}
return $retval;
@ -1365,7 +1372,7 @@ class Database
. $condition_string;
// Combines the updated fields parameter values with the condition parameter values
$params = array_merge(array_values($fields), $condition);
$params = array_merge(array_values($fields), $condition);
return $this->e($sql, $params);
}
@ -1415,8 +1422,8 @@ class Database
/**
* Escape fields, adding special treatment for "group by" handling
*
* @param array $fields
* @param array $options
* @param array $fields
* @param array $options
* @return array Escaped fields
*/
private function escapeFields(array $fields, array $options): array
@ -1438,8 +1445,7 @@ class Database
}
}
array_walk($fields, function(&$value, $key) use ($options)
{
array_walk($fields, function (&$value, $key) use ($options) {
$field = $value;
$value = DBA::quoteIdentifier($field);
@ -1487,7 +1493,7 @@ class Database
}
if (count($fields) > 0) {
$fields = $this->escapeFields($fields, $params);
$fields = $this->escapeFields($fields, $params);
$select_string = implode(', ', $fields);
} else {
$select_string = '*';
@ -1827,16 +1833,16 @@ class Database
/**
* Replaces a string in the provided fields of the provided table
*
* @param string $table Table name
* @param array $fields List of field names in the provided table
* @param string $search String to search for
* @param string $table Table name
* @param array $fields List of field names in the provided table
* @param string $search String to search for
* @param string $replace String to replace with
* @return void
* @throws \Exception
*/
public function replaceInTableFields(string $table, array $fields, string $search, string $replace)
{
$search = $this->escape($search);
$search = $this->escape($search);
$replace = $this->escape($replace);
$upd = [];

View file

@ -383,7 +383,7 @@ class APContact
// kroeg:blocks, updated
// When the photo is too large, try to shorten it by removing parts
if (strlen($apcontact['photo']) > 255) {
if (strlen($apcontact['photo'] ?? '') > 255) {
$parts = parse_url($apcontact['photo']);
unset($parts['fragment']);
$apcontact['photo'] = (string)Uri::fromParts($parts);
@ -574,7 +574,7 @@ class APContact
*
* @param array $apcontact
*
* @return bool
* @return bool
*/
public static function isRelay(array $apcontact): bool
{

View file

@ -1158,7 +1158,7 @@ class Contact
if ($sparkle) {
$status_link = $profile_link . '/status';
$photos_link = str_replace('/profile/', '/photos/', $profile_link);
$photos_link = $profile_link . '/photos';
$profile_link = $profile_link . '/profile';
}

View file

@ -210,7 +210,7 @@ class Item
$fields['raw-body'] = BBCode::removeSharedData($fields['raw-body']);
}
}
Post\Media::insertFromAttachmentData($item['uri-id'], $fields['body']);
$content_fields = ['raw-body' => trim($fields['raw-body'] ?? $fields['body'])];
@ -337,7 +337,7 @@ class Item
* generate a resource-id and therefore aren't intimately linked to the item.
*/
/// @TODO: this should first check if photo is used elsewhere
if (strlen($item['resource-id'])) {
if ($item['resource-id']) {
Photo::delete(['resource-id' => $item['resource-id'], 'uid' => $item['uid']]);
}
@ -2714,7 +2714,7 @@ class Item
}
$condition = ['vid' => $vids, 'deleted' => false, 'gravity' => self::GRAVITY_ACTIVITY,
'author-id' => $author_id, 'uid' => $item['uid'], 'thr-parent-id' => $uri_id];
'author-id' => $author_id, 'uid' => $uid, 'thr-parent-id' => $uri_id];
$like_item = Post::selectFirst(['id', 'guid', 'verb'], $condition);
if (DBA::isResult($like_item)) {

View file

@ -160,7 +160,7 @@ class ParsedLogIterator implements \Iterator
* @see Iterator::next()
* @return void
*/
public function next()
public function next(): void
{
$parsed = $this->read();
@ -177,7 +177,7 @@ class ParsedLogIterator implements \Iterator
* @see Iterator::rewind()
* @return void
*/
public function rewind()
public function rewind(): void
{
$this->value = null;
$this->reader->rewind();
@ -200,9 +200,9 @@ class ParsedLogIterator implements \Iterator
* Return current iterator value
*
* @see Iterator::current()
* @return ?ParsedLogLing
* @return ?ParsedLogLine
*/
public function current()
public function current(): ?ParsedLogLine
{
return $this->value;
}

View file

@ -80,19 +80,17 @@ class Nodeinfo
$config = DI::config();
$usage = new stdClass();
$usage->users = [];
$usage->users = new \stdClass;
if (!empty($config->get('system', 'nodeinfo'))) {
$usage->users = [
'total' => intval($config->get('nodeinfo', 'total_users')),
'activeHalfyear' => intval($config->get('nodeinfo', 'active_users_halfyear')),
'activeMonth' => intval($config->get('nodeinfo', 'active_users_monthly'))
];
$usage->users->total = intval($config->get('nodeinfo', 'total_users'));
$usage->users->activeHalfyear = intval($config->get('nodeinfo', 'active_users_halfyear'));
$usage->users->activeMonth = intval($config->get('nodeinfo', 'active_users_monthly'));
$usage->localPosts = intval($config->get('nodeinfo', 'local_posts'));
$usage->localComments = intval($config->get('nodeinfo', 'local_comments'));
if ($version2) {
$usage->users['activeWeek'] = intval($config->get('nodeinfo', 'active_users_weekly'));
$usage->users->activeWeek = intval($config->get('nodeinfo', 'active_users_weekly'));
}
}

View file

@ -1130,8 +1130,8 @@ class Photo
$picture['height'] = $photo['height'];
$picture['type'] = $photo['type'];
$picture['albumpage'] = DI::baseUrl() . '/photos/' . $user['nickname'] . '/image/' . $resource_id;
$picture['picture'] = DI::baseUrl() . '/photo/{$resource_id}-0.' . $image->getExt();
$picture['preview'] = DI::baseUrl() . '/photo/{$resource_id}-{$smallest}.' . $image->getExt();
$picture['picture'] = DI::baseUrl() . '/photo/' . $resource_id . '-0.' . $image->getExt();
$picture['preview'] = DI::baseUrl() . '/photo/' . $resource_id . '-' . $smallest . '.' . $image->getExt();
Logger::info('upload done', ['picture' => $picture]);
return $picture;
@ -1272,4 +1272,3 @@ class Photo
return $resource_id;
}
}

View file

@ -279,7 +279,7 @@ class Media
if (!empty($contact['gsid'])) {
$gserver = DBA::selectFirst('gserver', ['url', 'site_name'], ['id' => $contact['gsid']]);
}
$media['type'] = self::ACTIVITY;
$media['media-uri-id'] = $item['uri-id'];
$media['height'] = null;
@ -687,7 +687,7 @@ class Media
$previews[] = $medium['preview'];
}
$type = explode('/', current(explode(';', $medium['mimetype'])));
$type = explode('/', explode(';', $medium['mimetype'])[0]);
if (count($type) < 2) {
Logger::info('Unknown MimeType', ['type' => $type, 'media' => $medium]);
$filetype = 'unkn';

View file

@ -23,6 +23,7 @@ namespace Friendica\Model;
use Friendica\Content\Pager;
use Friendica\Database\DBA;
use Friendica\Network\HTTPException;
use Friendica\Util\DateTimeFormat;
use Friendica\Util\Strings;
@ -113,21 +114,27 @@ class Register
}
/**
* Creates a register record for approval and returns the success of the database insert
* Creates a register record for approval
* Checks for the existence of the provided user id
*
* @param integer $uid The ID of the user needing approval
* @param string $language The registration language
* @param string $note An additional message from the user
* @return boolean
* @throws \Exception
* @param integer $uid The ID of the user needing approval
* @param string $language The registration language
* @param string $note An additional message from the user
* @return void
* @throws \OutOfBoundsException
* @throws HTTPException\InternalServerErrorException
* @throws HTTPException\NotFoundException
*/
public static function createForApproval(int $uid, string $language, string $note = ''): bool
public static function createForApproval(int $uid, string $language, string $note = ''): void
{
$hash = Strings::getRandomHex();
if (!$uid) {
throw new \OutOfBoundsException("User ID can't be empty");
}
if (!User::exists($uid)) {
return false;
throw new HTTPException\NotFoundException("User ID doesn't exist");
}
$fields = [
@ -139,7 +146,9 @@ class Register
'note' => $note
];
return DBA::insert('register', $fields);
if (!DBA::insert('register', $fields)) {
throw new HTTPException\InternalServerErrorException('Unable to insert a `register` record');
}
}
/**

View file

@ -65,7 +65,7 @@ class Seen extends BaseApi
DI::notify()->save($Notify);
if ($Notify->otype === Notification\ObjectType::ITEM) {
$item = Post::selectFirstForUser($uid, [], ['id' => $Notify->iid, 'uid' => $uid]);
$item = Post::selectFirstForUser($uid, [], ['id' => $Notify->itemId, 'uid' => $uid]);
if (DBA::isResult($item)) {
// we found the item, return it to the user
$ret = [DI::twitterStatus()->createFromUriId($item['uri-id'], $item['uid'], $include_entities)->toArray()];

View file

@ -62,7 +62,7 @@ class BaseProfile extends BaseModule
],
[
'label' => DI::l10n()->t('Photos'),
'url' => DI::baseUrl() . '/photos/' . $nickname,
'url' => $baseProfileUrl . '/photos',
'sel' => $current == 'photos' ? 'active' : '',
'title' => DI::l10n()->t('Photo Albums'),
'id' => 'photo-tab',
@ -78,7 +78,7 @@ class BaseProfile extends BaseModule
],
];
// the calendar link for the full featured events calendar
// the calendar link for the full-featured events calendar
if ($is_owner && $a->getThemeInfoValue('events_in_profile')) {
$tabs[] = [
'label' => DI::l10n()->t('Calendar'),

View file

@ -88,7 +88,9 @@ class Follow extends BaseModule
}
$uid = $this->session->getLocalUserId();
$url = Probe::cleanURI(trim($request['url'] ?? ''));
// uri is used by the /authorize_interaction Mastodon route
$url = Probe::cleanURI(trim($request['uri'] ?? $request['url'] ?? ''));
// Issue 6874: Allow remote following from Peertube
if (strpos($url, 'acct:') === 0) {

View file

@ -44,23 +44,15 @@ class Hovercard extends BaseModule
throw new HTTPException\ForbiddenException();
}
// If a contact is connected the url is internally changed to 'contact/redir/CID'. We need the pure url to search for
// the contact. So we strip out the contact id from the internal url and look in the contact table for
// the real url (nurl)
if (strpos($contact_url, 'contact/redir/') === 0) {
$cid = intval(substr($contact_url, 6));
} elseif (strpos($contact_url, 'contact/') === 0) {
$cid = intval(substr($contact_url, 8));
}
if (!empty($cid)) {
$remote_contact = Contact::selectFirst(['nurl'], ['id' => $cid]);
/* Possible formats for relative URLs that need to be converted to the absolute contact URL:
* - contact/redir/123456
* - contact/123456/conversations
*/
if (strpos($contact_url, 'contact/') === 0 && preg_match('/(\d+)/', $contact_url, $matches)) {
$remote_contact = Contact::selectFirst(['nurl'], ['id' => $matches[1]]);
$contact_url = $remote_contact['nurl'] ?? '';
}
$contact = [];
// if it's the url containing https it should be converted to http
if (!$contact_url) {
throw new HTTPException\BadRequestException();
}

View file

@ -46,7 +46,7 @@ class Home extends BaseModule
DI::baseUrl()->redirect('network');
}
if (strlen($config->get('system', 'singleuser'))) {
if ($config->get('system', 'singleuser')) {
DI::baseUrl()->redirect('/profile/' . $config->get('system', 'singleuser'));
}

View file

@ -136,7 +136,7 @@ class Display extends BaseModule
}
if ($item['gravity'] != Item::GRAVITY_PARENT) {
$parent = Post::selectFirstForUser($itemUid, $fields, [
$parent = Post::selectFirst($fields, [
'uid' => [0, $itemUid],
'uri-id' => $item['parent-uri-id']
], ['order' => ['uid' => true]]);
@ -249,7 +249,15 @@ class Display extends BaseModule
$item = Post::selectFirstForUser($pageUid, $fields, $condition);
if (empty($item)) {
throw new HTTPException\NotFoundException($this->t('The requested item doesn\'t exist or has been deleted.'));
$this->page['aside'] = '';
throw new HTTPException\NotFoundException($this->t('Unfortunately, the requested conversation isn\'t available to you.</p>
<p>Possible reasons include:</p>
<ul>
<li>The top-level post isn\'t visible.</li>
<li>The top-level post was deleted.</li>
<li>The node has blocked the top-level author or the author of the shared post.</li>
<li>You have ignored or blocked the top-level author or the author of the shared post.</li>
</ul><p>'));
}
$item['uri-id'] = $item['parent-uri-id'];

227
src/Module/Post/Edit.php Normal file
View file

@ -0,0 +1,227 @@
<?php
/**
* @copyright Copyright (C) 2010-2022, the Friendica project
*
* @license GNU AGPL version 3 or any later version
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*
*/
namespace Friendica\Module\Post;
use Friendica\App;
use Friendica\BaseModule;
use Friendica\Content\Feature;
use Friendica\Core\Hook;
use Friendica\Core\L10n;
use Friendica\Core\Renderer;
use Friendica\Core\Session\Capability\IHandleUserSessions;
use Friendica\Model\Contact;
use Friendica\Model\Post;
use Friendica\Model\User;
use Friendica\Module\Response;
use Friendica\Navigation\SystemMessages;
use Friendica\Network\HTTPException;
use Friendica\Util\Crypto;
use Friendica\Util\Profiler;
use Psr\Log\LoggerInterface;
/**
* Controller to edit a post
*/
class Edit extends BaseModule
{
/** @var IHandleUserSessions */
protected $session;
/** @var SystemMessages */
protected $sysMessages;
/** @var App\Page */
protected $page;
/** @var App\Mode */
protected $mode;
/** @var App */
protected $app;
/** @var bool */
protected $isModal = false;
public function __construct(L10n $l10n, App\BaseURL $baseUrl, App\Arguments $args, LoggerInterface $logger, Profiler $profiler, Response $response, IHandleUserSessions $session, SystemMessages $sysMessages, App\Page $page, App\Mode $mode, App $app, array $server, array $parameters = [])
{
parent::__construct($l10n, $baseUrl, $args, $logger, $profiler, $response, $server, $parameters);
$this->session = $session;
$this->sysMessages = $sysMessages;
$this->page = $page;
$this->mode = $mode;
$this->app = $app;
}
protected function content(array $request = []): string
{
$this->isModal = $request['mode'] ?? '' === 'none';
if (!$this->session->getLocalUserId()) {
$this->errorExit($this->t('Permission denied.'), HTTPException\UnauthorizedException::class);
}
$postId = $this->parameters['post_id'] ?? 0;
if (empty($postId)) {
$this->errorExit($this->t('Post not found.'), HTTPException\BadRequestException::class);
}
$fields = [
'allow_cid', 'allow_gid', 'deny_cid', 'deny_gid',
'body', 'title', 'uri-id', 'wall', 'post-type', 'guid'
];
$item = Post::selectFirstForUser($this->session->getLocalUserId(), $fields, [
'id' => $postId,
'uid' => $this->session->getLocalUserId(),
]);
if (empty($item)) {
$this->errorExit($this->t('Post not found.'), HTTPException\BadRequestException::class);
}
$user = User::getById($this->session->getLocalUserId());
$output = Renderer::replaceMacros(Renderer::getMarkupTemplate('section_title.tpl'), [
'$title' => $this->t('Edit post'),
]);
$this->page['htmlhead'] .= Renderer::replaceMacros(Renderer::getMarkupTemplate('jot-header.tpl'), [
'$ispublic' => '&nbsp;',
'$geotag' => '',
'$nickname' => $this->app->getLoggedInUserNickname(),
'$is_mobile' => $this->mode->isMobile(),
]);
if (strlen($item['allow_cid']) || strlen($item['allow_gid']) || strlen($item['deny_cid']) || strlen($item['deny_gid'])) {
$lockstate = 'lock';
} else {
$lockstate = 'unlock';
}
$jotplugins = '';
Hook::callAll('jot_tool', $jotplugins);
$output .= Renderer::replaceMacros(Renderer::getMarkupTemplate('jot.tpl'), [
'$is_edit' => true,
'$return_path' => '/display/' . $item['guid'],
'$action' => 'item',
'$share' => $this->t('Save'),
'$loading' => $this->t('Loading...'),
'$upload' => $this->t('Upload photo'),
'$shortupload' => $this->t('upload photo'),
'$attach' => $this->t('Attach file'),
'$shortattach' => $this->t('attach file'),
'$weblink' => $this->t('Insert web link'),
'$shortweblink' => $this->t('web link'),
'$video' => $this->t('Insert video link'),
'$shortvideo' => $this->t('video link'),
'$audio' => $this->t('Insert audio link'),
'$shortaudio' => $this->t('audio link'),
'$setloc' => $this->t('Set your location'),
'$shortsetloc' => $this->t('set location'),
'$noloc' => $this->t('Clear browser location'),
'$shortnoloc' => $this->t('clear location'),
'$wait' => $this->t('Please wait'),
'$permset' => $this->t('Permission settings'),
'$wall' => $item['wall'],
'$posttype' => $item['post-type'],
'$content' => $this->undoPostTagging($item['body']),
'$post_id' => $postId,
'$defloc' => $user['default-location'],
'$visitor' => 'none',
'$pvisit' => 'none',
'$emailcc' => $this->t('CC: email addresses'),
'$public' => $this->t('Public post'),
'$title' => $item['title'],
'$placeholdertitle' => $this->t('Set title'),
'$category' => Post\Category::getCSVByURIId($item['uri-id'], $this->session->getLocalUserId(), Post\Category::CATEGORY),
'$placeholdercategory' => (Feature::isEnabled($this->session->getLocalUserId(), 'categories') ? $this->t("Categories \x28comma-separated list\x29") : ''),
'$emtitle' => $this->t('Example: bob@example.com, mary@example.com'),
'$lockstate' => $lockstate,
'$acl' => '',
'$bang' => ($lockstate === 'lock' ? '!' : ''),
'$profile_uid' => $this->session->getLocalUserId(),
'$preview' => $this->t('Preview'),
'$jotplugins' => $jotplugins,
'$cancel' => $this->t('Cancel'),
'$rand_num' => Crypto::randomDigits(12),
// Formatting button labels
'$edbold' => $this->t('Bold'),
'$editalic' => $this->t('Italic'),
'$eduline' => $this->t('Underline'),
'$edquote' => $this->t('Quote'),
'$edcode' => $this->t('Code'),
'$edurl' => $this->t('Link'),
'$edattach' => $this->t('Link or Media'),
//jot nav tab (used in some themes)
'$message' => $this->t('Message'),
'$browser' => $this->t('Browser'),
'$shortpermset' => $this->t('Permissions'),
'$compose_link_title' => $this->t('Open Compose page'),
]);
return $output;
}
/**
* Removes Tags from the item-body
*
* @param string $body The item body
*
* @return string the new item body without tagging
*/
protected function undoPostTagging(string $body)
{
$matches = null;
$content = preg_match_all('/([!#@])\[url=(.*?)\](.*?)\[\/url\]/ism', $body, $matches, PREG_SET_ORDER);
if ($content) {
foreach ($matches as $match) {
if (in_array($match[1], ['!', '@'])) {
$contact = Contact::getByURL($match[2], false, ['addr']);
$match[3] = empty($contact['addr']) ? $match[2] : $contact['addr'];
}
$body = str_replace($match[0], $match[1] . $match[3], $body);
}
}
return $body;
}
/**
* Exists the current Module because of an error
*
* @param string $message The error message
* @param string $exceptionClass In case it's a modal, throw an exception instead of an redirect
*
* @return void
*/
protected function errorExit(string $message, string $exceptionClass)
{
if ($this->isModal) {
throw new $exceptionClass($message);
} else {
$this->sysMessages->addNotice($message);
$this->baseUrl->redirect();
}
}
}

View file

@ -0,0 +1,196 @@
<?php
/**
* @copyright Copyright (C) 2010-2022, the Friendica project
*
* @license GNU AGPL version 3 or any later version
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*
*/
namespace Friendica\Module\Profile\Photos;
use Friendica\App;
use Friendica\Content\Pager;
use Friendica\Content\Widget;
use Friendica\Core\Config\Capability\IManageConfigValues;
use Friendica\Core\L10n;
use Friendica\Core\Renderer;
use Friendica\Core\Session\Capability\IHandleUserSessions;
use Friendica\Database\Database;
use Friendica\Model\Contact;
use Friendica\Model\Photo;
use Friendica\Model\Profile;
use Friendica\Model\User;
use Friendica\Module\Response;
use Friendica\Network\HTTPException;
use Friendica\Security\Security;
use Friendica\Util\Images;
use Friendica\Util\Profiler;
use Psr\Log\LoggerInterface;
class Index extends \Friendica\Module\BaseProfile
{
/** @var IHandleUserSessions */
private $session;
/** @var App\Page */
private $page;
/** @var IManageConfigValues */
private $config;
/** @var App */
private $app;
/** @var Database */
private $database;
public function __construct(Database $database, App $app, IManageConfigValues $config, App\Page $page, IHandleUserSessions $session, L10n $l10n, App\BaseURL $baseUrl, App\Arguments $args, LoggerInterface $logger, Profiler $profiler, Response $response, array $server, array $parameters = [])
{
parent::__construct($l10n, $baseUrl, $args, $logger, $profiler, $response, $server, $parameters);
$this->session = $session;
$this->page = $page;
$this->config = $config;
$this->app = $app;
$this->database = $database;
}
protected function content(array $request = []): string
{
parent::content($request);
if ($this->config->get('system', 'block_public') && !$this->session->isAuthenticated()) {
throw new HttpException\ForbiddenException($this->t('Public access denied.'));
}
$owner = User::getOwnerDataByNick($this->parameters['nickname']);
if (!isset($owner['account_removed']) || $owner['account_removed']) {
throw new HTTPException\NotFoundException($this->t('User not found.'));
}
$owner_uid = $owner['uid'];
$is_owner = $this->session->getLocalUserId() && ($this->session->getLocalUserId() == $owner_uid);
$remote_contact = false;
if ($this->session->getRemoteContactID($owner_uid)) {
$contact_id = $this->session->getRemoteContactID($owner_uid);
$contact = Contact::getContactForUser($contact_id, $owner_uid, ['blocked', 'pending']);
$remote_contact = $contact && !$contact['blocked'] && !$contact['pending'];
}
if ($owner['hidewall'] && !$is_owner && !$remote_contact) {
throw new HttpException\ForbiddenException($this->t('Access to this item is restricted.'));
}
$this->session->set('photo_return', $this->args->getCommand());
$sql_extra = Security::getPermissionsSQLByUserId($owner_uid);
$photo = $this->database->toArray($this->database->p(
"SELECT COUNT(DISTINCT `resource-id`) AS `count`
FROM `photo`
WHERE `uid` = ?
AND `photo-type` = ?
$sql_extra",
$owner['uid'],
Photo::DEFAULT,
));
$total = $photo[0]['count'];
$pager = new Pager($this->l10n, $this->args->getQueryString(), 20);
$photos = $this->database->toArray($this->database->p(
"SELECT
`resource-id`,
ANY_VALUE(`id`) AS `id`,
ANY_VALUE(`filename`) AS `filename`,
ANY_VALUE(`type`) AS `type`,
ANY_VALUE(`album`) AS `album`,
max(`scale`) AS `scale`,
ANY_VALUE(`created`) AS `created`
FROM `photo`
WHERE `uid` = ?
AND `photo-type` = ?
$sql_extra
GROUP BY `resource-id`
ORDER BY `created` DESC
LIMIT ? , ?",
$owner['uid'],
Photo::DEFAULT,
$pager->getStart(),
$pager->getItemsPerPage()
));
$phototypes = Images::supportedTypes();
$photos = array_map(function ($photo) use ($owner, $phototypes) {
return [
'id' => $photo['id'],
'link' => 'photos/' . $owner['nickname'] . '/image/' . $photo['resource-id'],
'title' => $this->t('View Photo'),
'src' => 'photo/' . $photo['resource-id'] . '-' . ((($photo['scale']) == 6) ? 4 : $photo['scale']) . '.' . $phototypes[$photo['type']],
'alt' => $photo['filename'],
'album' => [
'link' => 'photos/' . $owner['nickname'] . '/album/' . bin2hex($photo['album']),
'name' => $photo['album'],
'alt' => $this->t('View Album'),
],
];
}, $photos);
$tpl = Renderer::getMarkupTemplate('photos_head.tpl');
$this->page['htmlhead'] .= Renderer::replaceMacros($tpl, [
'$ispublic' => $this->t('everybody')
]);
if ($albums = Photo::getAlbums($owner['uid'])) {
$albums = array_map(function ($album) use ($owner) {
return [
'text' => $album['album'],
'total' => $album['total'],
'url' => 'photos/' . $owner['nickname'] . '/album/' . bin2hex($album['album']),
'urlencode' => urlencode($album['album']),
'bin2hex' => bin2hex($album['album'])
];
}, $albums);
$photo_albums_widget = Renderer::replaceMacros(Renderer::getMarkupTemplate('photo_albums.tpl'), [
'$nick' => $owner['nickname'],
'$title' => $this->t('Photo Albums'),
'$recent' => $this->t('Recent Photos'),
'$albums' => $albums,
'$upload' => [$this->t('Upload New Photos'), 'photos/' . $owner['nickname'] . '/upload'],
'$can_post' => $this->session->getLocalUserId() && $owner['uid'] == $this->session->getLocalUserId(),
]);
}
$this->page['aside'] .= Widget\VCard::getHTML($owner);
if (!empty($photo_albums_widget)) {
$this->page['aside'] .= $photo_albums_widget;
}
$o = self::getTabsHTML($this->app, 'photos', $is_owner, $owner['nickname'], Profile::getByUID($owner['uid'])['hide-friends'] ?? false);
$tpl = Renderer::getMarkupTemplate('photos_recent.tpl');
$o .= Renderer::replaceMacros($tpl, [
'$title' => $this->t('Recent Photos'),
'$can_post' => $is_owner || $remote_contact && $owner['page-flags'] == User::PAGE_FLAGS_COMMUNITY,
'$upload' => [$this->t('Upload New Photos'), 'photos/' . $owner['nickname'] . '/upload'],
'$photos' => $photos,
'$paginate' => $pager->renderFull($total),
]);
return $o;
}
}

View file

@ -353,6 +353,7 @@ class Register extends BaseModule
}
} elseif (intval(DI::config()->get('config', 'register_policy')) === self::APPROVE) {
if (!User::getAdminEmailList()) {
$this->logger->critical('Registration policy is set to APPROVE but no admin email address has been set in config.admin_email');
DI::sysmsg()->addNotice(DI::l10n()->t('Your registration can not be processed.'));
DI::baseUrl()->redirect();
}
@ -362,10 +363,17 @@ class Register extends BaseModule
DI::sysmsg()->addNotice(DI::l10n()->t('You have to leave a request note for the admin.')
. DI::l10n()->t('Your registration can not be processed.'));
DI::baseUrl()->redirect('register/');
$this->baseUrl->redirect('register');
}
Model\Register::createForApproval($user['uid'], DI::config()->get('system', 'language'), $_POST['permonlybox']);
try {
Model\Register::createForApproval($user['uid'], DI::config()->get('system', 'language'), $_POST['permonlybox']);
} catch (\Throwable $e) {
$this->logger->error('Unable to create a `register` record.', ['user' => $user]);
DI::sysmsg()->addNotice(DI::l10n()->t('An internal error occured.')
. DI::l10n()->t('Your registration can not be processed.'));
$this->baseUrl->redirect('register');
}
// invite system
if ($using_invites && $invite_id) {

View file

@ -230,7 +230,7 @@ class Index extends BaseSettings
'$banner' => DI::l10n()->t('Edit Profile Details'),
'$submit' => DI::l10n()->t('Submit'),
'$profpic' => DI::l10n()->t('Change Profile Photo'),
'$profpiclink' => '/photos/' . $profile['nickname'],
'$profpiclink' => '/profile/' . $profile['nickname'] . '/photos',
'$viewprof' => DI::l10n()->t('View Profile'),
'$lbl_personal_section' => DI::l10n()->t('Personal'),

View file

@ -132,7 +132,7 @@ class Index extends BaseSettings
DI::l10n()->t('or'),
($newuser) ?
'<a href="' . DI::baseUrl() . '">' . DI::l10n()->t('skip this step') . '</a>'
: '<a href="' . DI::baseUrl() . '/photos/' . DI::app()->getLoggedInUserNickname() . '">'
: '<a href="' . DI::baseUrl() . '/profile/' . DI::app()->getLoggedInUserNickname() . '/photos">'
. DI::l10n()->t('select a photo from your photo albums') . '</a>'
),
]);

View file

@ -25,6 +25,7 @@ use Friendica\App;
use Friendica\Core\L10n;
use Friendica\Core\PConfig\Capability\IManagePersonalConfigValues;
use Friendica\Core\Renderer;
use Friendica\Core\Session\Capability\IHandleUserSessions;
use Friendica\DI;
use Friendica\Module\Response;
use Friendica\Security\TwoFactor\Model\AppSpecificPassword;
@ -45,9 +46,9 @@ class AppSpecific extends BaseSettings
/** @var IManagePersonalConfigValues */
protected $pConfig;
public function __construct(L10n $l10n, App\BaseURL $baseUrl, App\Arguments $args, LoggerInterface $logger, Profiler $profiler, Response $response, IManagePersonalConfigValues $pConfig, array $server, array $parameters = [])
public function __construct(IManagePersonalConfigValues $pConfig, IHandleUserSessions $session, App\Page $page, L10n $l10n, App\BaseURL $baseUrl, App\Arguments $args, LoggerInterface $logger, Profiler $profiler, Response $response, array $server, array $parameters = [])
{
parent::__construct($l10n, $baseUrl, $args, $logger, $profiler, $response, $server, $parameters);
parent::__construct($session, $page, $l10n, $baseUrl, $args, $logger, $profiler, $response, $server, $parameters);
$this->pConfig = $pConfig;

View file

@ -25,6 +25,7 @@ use Friendica\App;
use Friendica\Core\L10n;
use Friendica\Core\PConfig\Capability\IManagePersonalConfigValues;
use Friendica\Core\Renderer;
use Friendica\Core\Session\Capability\IHandleUserSessions;
use Friendica\DI;
use Friendica\Module\Response;
use Friendica\Security\TwoFactor\Model\RecoveryCode;
@ -43,9 +44,9 @@ class Recovery extends BaseSettings
/** @var IManagePersonalConfigValues */
protected $pConfig;
public function __construct(L10n $l10n, App\BaseURL $baseUrl, App\Arguments $args, LoggerInterface $logger, Profiler $profiler, Response $response, IManagePersonalConfigValues $pConfig, array $server, array $parameters = [])
public function __construct(IManagePersonalConfigValues $pConfig, IHandleUserSessions $session, App\Page $page, L10n $l10n, App\BaseURL $baseUrl, App\Arguments $args, LoggerInterface $logger, Profiler $profiler, Response $response, array $server, array $parameters = [])
{
parent::__construct($l10n, $baseUrl, $args, $logger, $profiler, $response, $server, $parameters);
parent::__construct($session, $page, $l10n, $baseUrl, $args, $logger, $profiler, $response, $server, $parameters);
$this->pConfig = $pConfig;
@ -97,7 +98,7 @@ class Recovery extends BaseSettings
$recoveryCodes = RecoveryCode::getListForUser(DI::userSession()->getLocalUserId());
$verified = $this->pConfig->get(DI::userSession()->getLocalUserId(), '2fa', 'verified');
return Renderer::replaceMacros(Renderer::getMarkupTemplate('settings/twofactor/recovery.tpl'), [
'$form_security_token' => self::getFormSecurityToken('settings_2fa_recovery'),
'$password_security_token' => self::getFormSecurityToken('settings_2fa_password'),

View file

@ -25,6 +25,7 @@ use Friendica\App;
use Friendica\Core\L10n;
use Friendica\Core\PConfig\Capability\IManagePersonalConfigValues;
use Friendica\Core\Renderer;
use Friendica\Core\Session\Capability\IHandleUserSessions;
use Friendica\DI;
use Friendica\Module\BaseSettings;
use Friendica\Module\Response;
@ -45,9 +46,9 @@ class Trusted extends BaseSettings
/** @var TwoFactor\Repository\TrustedBrowser */
protected $trustedBrowserRepo;
public function __construct(L10n $l10n, App\BaseURL $baseUrl, App\Arguments $args, LoggerInterface $logger, Profiler $profiler, Response $response, IManagePersonalConfigValues $pConfig, TwoFactor\Repository\TrustedBrowser $trustedBrowserRepo, array $server, array $parameters = [])
public function __construct(IManagePersonalConfigValues $pConfig, TwoFactor\Repository\TrustedBrowser $trustedBrowserRepo, IHandleUserSessions $session, App\Page $page, L10n $l10n, App\BaseURL $baseUrl, App\Arguments $args, LoggerInterface $logger, Profiler $profiler, Response $response, array $server, array $parameters = [])
{
parent::__construct($l10n, $baseUrl, $args, $logger, $profiler, $response, $server, $parameters);
parent::__construct($session, $page, $l10n, $baseUrl, $args, $logger, $profiler, $response, $server, $parameters);
$this->pConfig = $pConfig;
$this->trustedBrowserRepo = $trustedBrowserRepo;

View file

@ -29,6 +29,7 @@ use Friendica\App;
use Friendica\Core\L10n;
use Friendica\Core\PConfig\Capability\IManagePersonalConfigValues;
use Friendica\Core\Renderer;
use Friendica\Core\Session\Capability\IHandleUserSessions;
use Friendica\DI;
use Friendica\Module\BaseSettings;
use Friendica\Module\Response;
@ -47,9 +48,9 @@ class Verify extends BaseSettings
/** @var IManagePersonalConfigValues */
protected $pConfig;
public function __construct(L10n $l10n, App\BaseURL $baseUrl, App\Arguments $args, LoggerInterface $logger, Profiler $profiler, Response $response, IManagePersonalConfigValues $pConfig, array $server, array $parameters = [])
public function __construct(IManagePersonalConfigValues $pConfig, IHandleUserSessions $session, App\Page $page, L10n $l10n, App\BaseURL $baseUrl, App\Arguments $args, LoggerInterface $logger, Profiler $profiler, Response $response, array $server, array $parameters = [])
{
parent::__construct($l10n, $baseUrl, $args, $logger, $profiler, $response, $server, $parameters);
parent::__construct($session, $page, $l10n, $baseUrl, $args, $logger, $profiler, $response, $server, $parameters);
$this->pConfig = $pConfig;

View file

@ -254,7 +254,7 @@ class HttpClient implements ICanSendHttpRequests
$urlResult = $this->resolver->resolveURL($url);
if ($urlResult->didErrorOccur()) {
throw new TransferException($urlResult->getErrorMessageString(), $urlResult->getHTTPStatusCode());
throw new TransferException($urlResult->getErrorMessageString(), $urlResult->getHTTPStatusCode() ?? 0);
}
return $urlResult->getURL();

View file

@ -44,6 +44,8 @@ class Attachment extends BaseDataTransferObject
protected $text_url;
/** @var string */
protected $description;
/** @var array */
protected $meta;
/**
* Creates an attachment
@ -60,6 +62,21 @@ class Attachment extends BaseDataTransferObject
$this->remote_url = $remote;
$this->text_url = $this->remote_url ?? $this->url;
$this->description = $attachment['description'];
if ($type === 'image') {
if ((int) $attachment['width'] > 0 && (int) $attachment['height'] > 0) {
$this->meta['original']['width'] = (int) $attachment['width'];
$this->meta['original']['height'] = (int) $attachment['height'];
$this->meta['original']['size'] = (int) $attachment['width'] . 'x' . (int) $attachment['height'];
$this->meta['original']['aspect'] = (float) ((int) $attachment['width'] / (int) $attachment['height']);
}
if ((int) $attachment['preview-width'] > 0 && (int) $attachment['preview-height'] > 0) {
$this->meta['small']['width'] = (int) $attachment['preview-width'];
$this->meta['small']['height'] = (int) $attachment['preview-height'];
$this->meta['small']['size'] = (int) $attachment['preview-width'] . 'x' . (int) $attachment['preview-height'];
$this->meta['small']['aspect'] = (float) ((int) $attachment['preview-width'] / (int) $attachment['preview-height']);
}
}
}
/**

View file

@ -80,7 +80,7 @@ interface IEmail extends JsonSerializable
*
* @return string
*/
function getMessage(bool $plain = false);
function getMessage(bool $plain = false): string;
/**
* Gets the additional mail header array

View file

@ -110,12 +110,12 @@ class Email implements IEmail
/**
* {@inheritDoc}
*/
public function getMessage(bool $plain = false)
public function getMessage(bool $plain = false): string
{
if ($plain) {
return $this->msgText;
} else {
return $this->msgHtml;
return $this->msgHtml ?? '';
}
}

View file

@ -220,7 +220,7 @@ class Post
if ($item['event-id'] != 0) {
$edpost = ['calendar/event/edit/' . $item['event-id'], DI::l10n()->t('Edit')];
} else {
$edpost = ['editpost/' . $item['id'], DI::l10n()->t('Edit')];
$edpost = [sprintf('post/%s/edit', $item['id']), DI::l10n()->t('Edit')];
}
}
$dropping = in_array($item['uid'], [0, DI::userSession()->getLocalUserId()]);

View file

@ -3201,7 +3201,7 @@ class Diaspora
*/
public static function getReshareDetails(array $item): array
{
$reshared = DI::contentItem()->getSharedPost($item, ['network', 'author-addr']);
$reshared = DI::contentItem()->getSharedPost($item, ['guid', 'network', 'author-addr']);
if (empty($reshared)) {
return [];
}
@ -3213,7 +3213,7 @@ class Diaspora
return [
'root_handle' => strtolower($reshared['post']['author-addr']),
'root_guid' => $reshared['guid']
'root_guid' => $reshared['post']['guid'],
];
}
@ -3638,7 +3638,7 @@ class Diaspora
Logger::info('Got relayable data ' . $type . ' for item ' . $item['guid'] . ' (' . $item['id'] . ')');
$msg = json_decode($item['signed_text'], true);
$msg = json_decode($item['signed_text'] ?? '', true);
$message = [];
if (is_array($msg)) {

View file

@ -81,7 +81,7 @@ final class FriendicaSmartyEngine extends TemplateEngine
// "middleware": inject variables into templates
$arr = [
'template' => basename($this->smarty->filename),
'template' => basename($this->smarty->filename ?? ''),
'vars' => $vars
];
Hook::callAll('template_vars', $arr);

View file

@ -336,7 +336,7 @@ class Notifier
foreach ($items as $item) {
$recipients[] = $item['contact-id'];
// pull out additional tagged people to notify (if public message)
if ($public_message && strlen($item['inform'])) {
if ($public_message && $item['inform']) {
$people = explode(',',$item['inform']);
foreach ($people as $person) {
if (substr($person,0,4) === 'cid:') {