mirror of
https://github.com/friendica/friendica
synced 2025-04-26 03:10:13 +00:00
commit
e34d38182c
88 changed files with 618 additions and 482 deletions
|
@ -447,6 +447,7 @@ class App implements AppHelper
|
|||
$requeststring = ($server['REQUEST_METHOD'] ?? '') . ' ' . ($server['REQUEST_URI'] ?? '') . ' ' . ($server['SERVER_PROTOCOL'] ?? '');
|
||||
$this->logger->debug('Request received', ['address' => $server['REMOTE_ADDR'] ?? '', 'request' => $requeststring, 'referer' => $server['HTTP_REFERER'] ?? '', 'user-agent' => $server['HTTP_USER_AGENT'] ?? '']);
|
||||
$request_start = microtime(true);
|
||||
$request = $_REQUEST;
|
||||
|
||||
$this->profiler->set($start_time, 'start');
|
||||
$this->profiler->set(microtime(true), 'classinit');
|
||||
|
@ -581,7 +582,7 @@ class App implements AppHelper
|
|||
|
||||
// Processes data from GET requests
|
||||
$httpinput = $httpInput->process();
|
||||
$input = array_merge($httpinput['variables'], $httpinput['files'], $request ?? $_REQUEST);
|
||||
$input = array_merge($httpinput['variables'], $httpinput['files'], $request);
|
||||
|
||||
// Let the module run its internal process (init, get, post, ...)
|
||||
$timestamp = microtime(true);
|
||||
|
|
|
@ -103,6 +103,8 @@ class BaseURL extends Uri implements UriInterface
|
|||
* @throws HTTPException\TemporaryRedirectException
|
||||
*
|
||||
* @throws HTTPException\InternalServerErrorException In Case the given URL is not relative to the Friendica node
|
||||
*
|
||||
* @return never
|
||||
*/
|
||||
public function redirect(string $toUrl = '', bool $ssl = false)
|
||||
{
|
||||
|
|
|
@ -334,17 +334,17 @@ class Router
|
|||
|
||||
$stamp = microtime(true);
|
||||
|
||||
try {
|
||||
/** @var ICanHandleRequests $module */
|
||||
return $this->dice->create($moduleClass, $this->parameters);
|
||||
} finally {
|
||||
if ($this->dice_profiler_threshold > 0) {
|
||||
$dur = floatval(microtime(true) - $stamp);
|
||||
if ($dur >= $this->dice_profiler_threshold) {
|
||||
$this->logger->notice('Dice module creation lasts too long.', ['duration' => round($dur, 3), 'module' => $moduleClass, 'parameters' => $this->parameters]);
|
||||
}
|
||||
/** @var ICanHandleRequests $module */
|
||||
$module = $this->dice->create($moduleClass, $this->parameters);
|
||||
|
||||
if ($this->dice_profiler_threshold > 0) {
|
||||
$dur = floatval(microtime(true) - $stamp);
|
||||
if ($dur >= $this->dice_profiler_threshold) {
|
||||
$this->logger->notice('Dice module creation lasts too long.', ['duration' => round($dur, 3), 'module' => $moduleClass, 'parameters' => $this->parameters]);
|
||||
}
|
||||
}
|
||||
|
||||
return $module;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -245,10 +245,10 @@ abstract class BaseModule implements ICanHandleRequests
|
|||
|
||||
$this->response->setStatus($e->getCode(), $e->getMessage());
|
||||
$this->response->addContent($httpException->content($e));
|
||||
} finally {
|
||||
$this->profiler->set(microtime(true) - $timestamp, 'content');
|
||||
}
|
||||
|
||||
$this->profiler->set(microtime(true) - $timestamp, 'content');
|
||||
|
||||
return $this->response->generate();
|
||||
}
|
||||
|
||||
|
@ -269,7 +269,7 @@ abstract class BaseModule implements ICanHandleRequests
|
|||
$request[$parameter] = $this->getRequestValue($input, $parameter, $defaultvalue);
|
||||
}
|
||||
|
||||
foreach ($input ?? [] as $parameter => $value) {
|
||||
foreach ($input as $parameter => $value) {
|
||||
if ($parameter == 'pagename') {
|
||||
continue;
|
||||
}
|
||||
|
@ -456,7 +456,7 @@ abstract class BaseModule implements ICanHandleRequests
|
|||
* @param string $content
|
||||
* @param string $type
|
||||
* @param string|null $content_type
|
||||
* @return void
|
||||
* @return never
|
||||
* @throws HTTPException\InternalServerErrorException
|
||||
*/
|
||||
public function httpExit(string $content, string $type = Response::TYPE_HTML, ?string $content_type = null)
|
||||
|
@ -493,7 +493,7 @@ abstract class BaseModule implements ICanHandleRequests
|
|||
* @param mixed $content
|
||||
* @param string $content_type
|
||||
* @param int $options A combination of json_encode() binary flags
|
||||
* @return void
|
||||
* @return never
|
||||
* @throws HTTPException\InternalServerErrorException
|
||||
* @see json_encode()
|
||||
*/
|
||||
|
@ -508,7 +508,7 @@ abstract class BaseModule implements ICanHandleRequests
|
|||
* @param int $httpCode
|
||||
* @param mixed $content
|
||||
* @param string $content_type
|
||||
* @return void
|
||||
* @return never
|
||||
* @throws HTTPException\InternalServerErrorException
|
||||
*/
|
||||
public function jsonError(int $httpCode, $content, string $content_type = 'application/json')
|
||||
|
|
|
@ -12,7 +12,6 @@ use Friendica\Contact\Avatar;
|
|||
use Friendica\Core\L10n;
|
||||
use Friendica\Model\Contact;
|
||||
use Friendica\Model\Photo;
|
||||
use Friendica\Util\Images;
|
||||
use Friendica\Object\Image;
|
||||
use Friendica\Core\Config\Capability\IManageConfigValues;
|
||||
use Friendica\Core\Protocol;
|
||||
|
@ -115,6 +114,10 @@ HELP;
|
|||
|
||||
private function storeAvatar(string $resourceid, array $contact, bool $quit_on_invalid)
|
||||
{
|
||||
$photo = false;
|
||||
$imgdata = false;
|
||||
$image = null;
|
||||
|
||||
$valid = !empty($resourceid);
|
||||
if ($valid) {
|
||||
$this->out('1', false);
|
||||
|
@ -143,7 +146,7 @@ HELP;
|
|||
}
|
||||
}
|
||||
|
||||
if ($valid) {
|
||||
if ($valid && $image instanceof Image) {
|
||||
$this->out('4', false);
|
||||
$fields = Avatar::storeAvatarByImage($contact, $image);
|
||||
} else {
|
||||
|
|
|
@ -142,17 +142,18 @@ class ContactSelector
|
|||
$replace = array_values($nets);
|
||||
|
||||
$networkname = str_replace($search, $replace, $network);
|
||||
$platform = '';
|
||||
|
||||
if (in_array($network, Protocol::FEDERATED) && !empty($gsid)) {
|
||||
$gserver = self::getServerForId($gsid);
|
||||
|
||||
if (!empty($gserver['platform'])) {
|
||||
$platform = $gserver['platform'];
|
||||
$platform = (string) $gserver['platform'];
|
||||
} elseif (!empty($gserver['network']) && ($gserver['network'] != Protocol::ACTIVITYPUB)) {
|
||||
$platform = self::networkToName($gserver['network']);
|
||||
}
|
||||
|
||||
if (!empty($platform)) {
|
||||
if ($platform !== '') {
|
||||
$networkname = $platform;
|
||||
}
|
||||
}
|
||||
|
@ -161,7 +162,7 @@ class ContactSelector
|
|||
$networkname = DI::l10n()->t('%s (via %s)', $networkname, self::networkToName($protocol));
|
||||
} elseif (in_array($network, ['', $protocol]) && ($network == Protocol::DFRN)) {
|
||||
$networkname .= ' (DFRN)';
|
||||
} elseif (in_array($network, ['', $protocol]) && ($network == Protocol::DIASPORA) && ($platform != 'diaspora')) {
|
||||
} elseif (in_array($network, ['', $protocol]) && ($network == Protocol::DIASPORA) && ($platform !== 'diaspora')) {
|
||||
$networkname .= ' (Diaspora)';
|
||||
}
|
||||
|
||||
|
@ -191,7 +192,7 @@ class ContactSelector
|
|||
$nets = [
|
||||
Protocol::ACTIVITYPUB => 'activitypub', // https://commons.wikimedia.org/wiki/File:ActivityPub-logo-symbol.svg
|
||||
Protocol::BLUESKY => 'bluesky', // https://commons.wikimedia.org/wiki/File:Bluesky_Logo.svg
|
||||
Protocol::DFRN => 'friendica',
|
||||
Protocol::DFRN => 'friendica',
|
||||
Protocol::DIASPORA => 'diaspora', // https://www.svgrepo.com/svg/362315/diaspora
|
||||
Protocol::DIASPORA2 => 'diaspora', // https://www.svgrepo.com/svg/362315/diaspora
|
||||
Protocol::DISCOURSE => 'discourse', // https://commons.wikimedia.org/wiki/File:Discourse_icon.svg
|
||||
|
|
|
@ -180,6 +180,7 @@ class Item
|
|||
public static function replaceTag(string &$body, int $profile_uid, string $tag, string $network = '')
|
||||
{
|
||||
$replaced = false;
|
||||
$contact = [];
|
||||
|
||||
//is it a person tag?
|
||||
if (Tag::isType($tag, Tag::MENTION, Tag::IMPLICIT_MENTION, Tag::EXCLUSIVE_MENTION)) {
|
||||
|
@ -247,6 +248,8 @@ class Item
|
|||
}
|
||||
}
|
||||
|
||||
$newname = '';
|
||||
|
||||
// Check if $contact has been successfully loaded
|
||||
if (DBA::isResult($contact)) {
|
||||
$profile = $contact['url'];
|
||||
|
|
|
@ -178,7 +178,7 @@ class OEmbed
|
|||
$oembed->thumbnail_height = $data['images'][0]['height'];
|
||||
}
|
||||
|
||||
Hook::callAll('oembed_fetch_url', $embedurl, $oembed);
|
||||
Hook::callAll('oembed_fetch_url', $embedurl);
|
||||
|
||||
return $oembed;
|
||||
}
|
||||
|
|
|
@ -116,9 +116,10 @@ class PostMedia extends BaseRepository
|
|||
return $attachments;
|
||||
}
|
||||
|
||||
$heights = [];
|
||||
$heights = [];
|
||||
$selected = '';
|
||||
$previews = [];
|
||||
$video = [];
|
||||
|
||||
foreach ($PostMedias as $PostMedia) {
|
||||
foreach ($links as $link) {
|
||||
|
|
|
@ -543,6 +543,8 @@ class NPF
|
|||
return $npf;
|
||||
}
|
||||
|
||||
$block = [];
|
||||
|
||||
$media = Post\Media::getByURL($uri_id, $attributes['src'], [Post\Media::AUDIO, Post\Media::VIDEO]);
|
||||
if (!empty($media)) {
|
||||
switch ($media['type']) {
|
||||
|
|
|
@ -114,6 +114,8 @@ class Plaintext
|
|||
$post['text'] = trim($item['title']);
|
||||
}
|
||||
|
||||
$abstract = '';
|
||||
|
||||
// Fetch the abstract from the given target network
|
||||
switch ($htmlmode) {
|
||||
case BBCode::TWITTER:
|
||||
|
@ -123,7 +125,7 @@ class Plaintext
|
|||
case BBCode::BLUESKY:
|
||||
$abstract = BBCode::getAbstract($item['body'], Protocol::BLUESKY);
|
||||
break;
|
||||
|
||||
|
||||
default: // We don't know the exact target.
|
||||
// We fetch an abstract since there is a posting limit.
|
||||
if ($limit > 0) {
|
||||
|
@ -242,6 +244,8 @@ class Plaintext
|
|||
$part = '';
|
||||
$break_pos = 0;
|
||||
$comma_pos = 0;
|
||||
$pos = 0;
|
||||
$word = '';
|
||||
|
||||
$limit = $baselimit;
|
||||
|
||||
|
@ -256,8 +260,8 @@ class Plaintext
|
|||
} elseif ($pos_paragraph !== false) {
|
||||
$pos = $pos_paragraph + 1;
|
||||
} else {
|
||||
$word = $message;
|
||||
$message = '';
|
||||
$word = $message;
|
||||
$message = '';
|
||||
}
|
||||
|
||||
if (trim($message)) {
|
||||
|
@ -272,7 +276,7 @@ class Plaintext
|
|||
$break = mb_strrpos($word, "\n") !== false;
|
||||
if (!$break && (mb_strrpos($word, '. ') !== false || mb_strrpos($word, '? ') !== false || mb_strrpos($word, '! ') !== false)) {
|
||||
$break = IntlChar::isupper(mb_substr($message, 0, 1));
|
||||
}
|
||||
}
|
||||
|
||||
$comma = (mb_strrpos($word, ', ') !== false) && IntlChar::isalpha(mb_substr($message, 0, 1));
|
||||
|
||||
|
@ -291,7 +295,7 @@ class Plaintext
|
|||
$break_pos = 0;
|
||||
$comma_pos = 0;
|
||||
} elseif ($break) {
|
||||
$break_pos = $pos + mb_strlen($part);
|
||||
$break_pos = $pos + mb_strlen($part);
|
||||
} elseif ($comma) {
|
||||
$comma_pos = $pos + mb_strlen($part);
|
||||
}
|
||||
|
|
|
@ -402,7 +402,7 @@ class Widget
|
|||
return '';
|
||||
}
|
||||
|
||||
$commonContacts = Contact\Relation::listCommon($localPCid, $visitorPCid, $condition, 0, 5, true);
|
||||
$commonContacts = Contact\Relation::listCommon($localPCid, $visitorPCid, $condition, 0, 5);
|
||||
if (!DBA::isResult($commonContacts)) {
|
||||
return '';
|
||||
}
|
||||
|
@ -479,6 +479,10 @@ class Widget
|
|||
DI::cache()->set($cachekey, $dthen, Duration::HOUR);
|
||||
}
|
||||
|
||||
$cutoffday = '';
|
||||
$thisday = '';
|
||||
$nextday = '';
|
||||
|
||||
if ($dthen) {
|
||||
// Set the start and end date to the beginning of the month
|
||||
$cutoffday = $dthen;
|
||||
|
@ -513,7 +517,6 @@ class Widget
|
|||
return $o;
|
||||
}
|
||||
|
||||
|
||||
$cutoff_year = intval(DateTimeFormat::localNow('Y')) - $visible_years;
|
||||
$cutoff = array_key_exists($cutoff_year, $ret);
|
||||
|
||||
|
|
|
@ -34,7 +34,7 @@ class VCard
|
|||
public static function getHTML(array $contact, bool $hide_mention = false, bool $hide_follow = false): string
|
||||
{
|
||||
if (!isset($contact['network']) || !isset($contact['id'])) {
|
||||
Logger::warning('Incomplete contact', ['contact' => $contact ?? []]);
|
||||
Logger::warning('Incomplete contact', ['contact' => $contact]);
|
||||
}
|
||||
|
||||
$contact_url = Contact::getProfileLink($contact);
|
||||
|
@ -61,7 +61,7 @@ class VCard
|
|||
$hide_follow = true;
|
||||
$hide_mention = true;
|
||||
}
|
||||
|
||||
|
||||
if ($contact['uid']) {
|
||||
$id = $contact['id'];
|
||||
$rel = $contact['rel'];
|
||||
|
|
|
@ -14,8 +14,8 @@ use Throwable;
|
|||
*/
|
||||
class AddonInvalidConfigFileException extends \RuntimeException
|
||||
{
|
||||
public function __construct($message = '', $code = 0, Throwable $previous = null)
|
||||
public function __construct($message = '')
|
||||
{
|
||||
parent::__construct($message, 500, $previous);
|
||||
parent::__construct($message, 500);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -47,17 +47,21 @@ class DatabaseCache extends AbstractCache implements ICanCache
|
|||
}
|
||||
|
||||
$stmt = $this->dba->select('cache', ['k'], $where);
|
||||
} catch (\Exception $exception) {
|
||||
throw new CachePersistenceException(sprintf('Cannot fetch all keys with prefix %s', $prefix), $exception);
|
||||
}
|
||||
|
||||
try {
|
||||
$keys = [];
|
||||
while ($key = $this->dba->fetch($stmt)) {
|
||||
array_push($keys, $key['k']);
|
||||
}
|
||||
} catch (\Exception $exception) {
|
||||
throw new CachePersistenceException(sprintf('Cannot fetch all keys with prefix %s', $prefix), $exception);
|
||||
} finally {
|
||||
$this->dba->close($stmt);
|
||||
throw new CachePersistenceException(sprintf('Cannot fetch all keys with prefix %s', $prefix), $exception);
|
||||
}
|
||||
|
||||
$this->dba->close($stmt);
|
||||
return $keys;
|
||||
}
|
||||
|
||||
|
|
|
@ -11,8 +11,8 @@ use Throwable;
|
|||
|
||||
class ConfigFileException extends \RuntimeException
|
||||
{
|
||||
public function __construct($message = "", $code = 0, Throwable $previous = null)
|
||||
public function __construct($message = "")
|
||||
{
|
||||
parent::__construct($message, 500, $previous);
|
||||
parent::__construct($message, 500);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -245,59 +245,61 @@ class ConfigFileManager
|
|||
$fullName = $this->baseDir . DIRECTORY_SEPARATOR . '.' . $name . '.php';
|
||||
|
||||
$config = [];
|
||||
if (file_exists($fullName)) {
|
||||
$a = new \stdClass();
|
||||
$a->config = [];
|
||||
include $fullName;
|
||||
if (!file_exists($fullName)) {
|
||||
return $config;
|
||||
}
|
||||
|
||||
$htConfigCategories = array_keys($a->config);
|
||||
$a = new \stdClass();
|
||||
$a->config = [];
|
||||
include $fullName;
|
||||
|
||||
// map the legacy configuration structure to the current structure
|
||||
foreach ($htConfigCategories as $htConfigCategory) {
|
||||
if (is_array($a->config[$htConfigCategory])) {
|
||||
$keys = array_keys($a->config[$htConfigCategory]);
|
||||
$htConfigCategories = array_keys($a->config);
|
||||
|
||||
foreach ($keys as $key) {
|
||||
$config[$htConfigCategory][$key] = $a->config[$htConfigCategory][$key];
|
||||
}
|
||||
} else {
|
||||
$config['config'][$htConfigCategory] = $a->config[$htConfigCategory];
|
||||
// map the legacy configuration structure to the current structure
|
||||
foreach ($htConfigCategories as $htConfigCategory) {
|
||||
if (is_array($a->config[$htConfigCategory])) {
|
||||
$keys = array_keys($a->config[$htConfigCategory]);
|
||||
|
||||
foreach ($keys as $key) {
|
||||
$config[$htConfigCategory][$key] = $a->config[$htConfigCategory][$key];
|
||||
}
|
||||
} else {
|
||||
$config['config'][$htConfigCategory] = $a->config[$htConfigCategory];
|
||||
}
|
||||
}
|
||||
|
||||
unset($a);
|
||||
unset($a);
|
||||
|
||||
if (isset($db_host)) {
|
||||
$config['database']['hostname'] = $db_host;
|
||||
unset($db_host);
|
||||
}
|
||||
if (isset($db_user)) {
|
||||
$config['database']['username'] = $db_user;
|
||||
unset($db_user);
|
||||
}
|
||||
if (isset($db_pass)) {
|
||||
$config['database']['password'] = $db_pass;
|
||||
unset($db_pass);
|
||||
}
|
||||
if (isset($db_data)) {
|
||||
$config['database']['database'] = $db_data;
|
||||
unset($db_data);
|
||||
}
|
||||
if (isset($config['system']['db_charset'])) {
|
||||
$config['database']['charset'] = $config['system']['db_charset'];
|
||||
}
|
||||
if (isset($pidfile)) {
|
||||
$config['system']['pidfile'] = $pidfile;
|
||||
unset($pidfile);
|
||||
}
|
||||
if (isset($default_timezone)) {
|
||||
$config['system']['default_timezone'] = $default_timezone;
|
||||
unset($default_timezone);
|
||||
}
|
||||
if (isset($lang)) {
|
||||
$config['system']['language'] = $lang;
|
||||
unset($lang);
|
||||
}
|
||||
if (isset($db_host)) {
|
||||
$config['database']['hostname'] = $db_host;
|
||||
unset($db_host);
|
||||
}
|
||||
if (isset($db_user)) {
|
||||
$config['database']['username'] = $db_user;
|
||||
unset($db_user);
|
||||
}
|
||||
if (isset($db_pass)) {
|
||||
$config['database']['password'] = $db_pass;
|
||||
unset($db_pass);
|
||||
}
|
||||
if (isset($db_data)) {
|
||||
$config['database']['database'] = $db_data;
|
||||
unset($db_data);
|
||||
}
|
||||
if (isset($config['system']) && isset($config['system']['db_charset'])) {
|
||||
$config['database']['charset'] = $config['system']['db_charset'];
|
||||
}
|
||||
if (isset($pidfile)) {
|
||||
$config['system']['pidfile'] = $pidfile;
|
||||
unset($pidfile);
|
||||
}
|
||||
if (isset($default_timezone)) {
|
||||
$config['system']['default_timezone'] = $default_timezone;
|
||||
unset($default_timezone);
|
||||
}
|
||||
if (isset($lang)) {
|
||||
$config['system']['language'] = $lang;
|
||||
unset($lang);
|
||||
}
|
||||
|
||||
return $config;
|
||||
|
|
|
@ -182,17 +182,22 @@ class DatabaseLock extends AbstractLock
|
|||
}
|
||||
|
||||
$stmt = $this->dba->select('locks', ['name'], $where);
|
||||
} catch (\Exception $exception) {
|
||||
throw new LockPersistenceException(sprintf('Cannot get lock with prefix %s', $prefix), $exception);
|
||||
}
|
||||
|
||||
try {
|
||||
$keys = [];
|
||||
while ($key = $this->dba->fetch($stmt)) {
|
||||
array_push($keys, $key['name']);
|
||||
}
|
||||
} catch (\Exception $exception) {
|
||||
throw new LockPersistenceException(sprintf('Cannot get lock with prefix %s', $prefix), $exception);
|
||||
} finally {
|
||||
$this->dba->close($stmt);
|
||||
throw new LockPersistenceException(sprintf('Cannot get lock with prefix %s', $prefix), $exception);
|
||||
}
|
||||
|
||||
$this->dba->close($stmt);
|
||||
|
||||
return $keys;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -60,7 +60,11 @@ class PConfig
|
|||
} else {
|
||||
$configs = $this->db->select(static::$table_name, ['cat', 'v', 'k'], ['cat' => $cat, 'uid' => $uid]);
|
||||
}
|
||||
} catch (\Exception $exception) {
|
||||
throw new PConfigPersistenceException(sprintf('Cannot load config category "%s" for user %d', $cat, $uid), $exception);
|
||||
}
|
||||
|
||||
try {
|
||||
while ($config = $this->db->fetch($configs)) {
|
||||
$key = $config['k'];
|
||||
$value = ValueConversion::toConfigValue($config['v']);
|
||||
|
@ -71,11 +75,12 @@ class PConfig
|
|||
}
|
||||
}
|
||||
} catch (\Exception $exception) {
|
||||
throw new PConfigPersistenceException(sprintf('Cannot load config category %s for user %d', $cat, $uid), $exception);
|
||||
} finally {
|
||||
$this->db->close($configs);
|
||||
throw new PConfigPersistenceException(sprintf('Cannot load config category "%s" for user %d', $cat, $uid), $exception);
|
||||
}
|
||||
|
||||
$this->db->close($configs);
|
||||
|
||||
return $return;
|
||||
}
|
||||
|
||||
|
|
|
@ -13,11 +13,14 @@ use Friendica\Core\Cache\Factory\Cache;
|
|||
use Friendica\Core\Cache\Type\DatabaseCache;
|
||||
use Friendica\Core\Config\Capability\IManageConfigValues;
|
||||
use Friendica\Core\Session\Capability\IHandleSessions;
|
||||
use Friendica\Core\Session\Type;
|
||||
use Friendica\Core\Session\Handler;
|
||||
use Friendica\Core\Session\Handler\Cache as CacheHandler;
|
||||
use Friendica\Core\Session\Handler\Database as DatabaseHandler;
|
||||
use Friendica\Core\Session\Type\Memory;
|
||||
use Friendica\Core\Session\Type\Native;
|
||||
use Friendica\Database\Database;
|
||||
use Friendica\Util\Profiler;
|
||||
use Psr\Log\LoggerInterface;
|
||||
use Throwable;
|
||||
|
||||
/**
|
||||
* Factory for creating a valid Session for this run
|
||||
|
@ -49,36 +52,45 @@ class Session
|
|||
$profiler->startRecording('session');
|
||||
$session_handler = $config->get('system', 'session_handler', self::HANDLER_DEFAULT);
|
||||
|
||||
try {
|
||||
if ($mode->isInstall() || $mode->isBackend()) {
|
||||
$session = new Type\Memory();
|
||||
} else {
|
||||
switch ($session_handler) {
|
||||
case self::HANDLER_DATABASE:
|
||||
$handler = new Handler\Database($dba, $logger, $server);
|
||||
break;
|
||||
case self::HANDLER_CACHE:
|
||||
$cache = $cacheFactory->createDistributed();
|
||||
|
||||
// In case we're using the db as cache driver, use the native db session, not the cache
|
||||
if ($config->get('system', 'cache_driver') === DatabaseCache::NAME) {
|
||||
$handler = new Handler\Database($dba, $logger, $server);
|
||||
} else {
|
||||
$handler = new Handler\Cache($cache, $logger);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
$handler = null;
|
||||
}
|
||||
|
||||
$session = new Type\Native($baseURL, $handler);
|
||||
}
|
||||
} catch (\Throwable $e) {
|
||||
$logger->notice('Unable to create session', ['mode' => $mode, 'session_handler' => $session_handler, 'exception' => $e]);
|
||||
$session = new Type\Memory();
|
||||
} finally {
|
||||
if ($mode->isInstall() || $mode->isBackend()) {
|
||||
$session = new Memory();
|
||||
$profiler->stopRecording();
|
||||
return $session;
|
||||
}
|
||||
|
||||
try {
|
||||
switch ($session_handler) {
|
||||
case self::HANDLER_DATABASE:
|
||||
$handler = new DatabaseHandler($dba, $logger, $server);
|
||||
break;
|
||||
case self::HANDLER_CACHE:
|
||||
$cache = $cacheFactory->createDistributed();
|
||||
|
||||
// In case we're using the db as cache driver, use the native db session, not the cache
|
||||
if ($config->get('system', 'cache_driver') === DatabaseCache::NAME) {
|
||||
$handler = new DatabaseHandler($dba, $logger, $server);
|
||||
} else {
|
||||
$handler = new CacheHandler($cache, $logger);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
$handler = null;
|
||||
}
|
||||
} catch (Throwable $e) {
|
||||
$logger->notice('Unable to create session', ['mode' => $mode, 'session_handler' => $session_handler, 'exception' => $e]);
|
||||
$session = new Memory();
|
||||
$profiler->stopRecording();
|
||||
return $session;
|
||||
}
|
||||
|
||||
try {
|
||||
$session = new Native($baseURL, $handler);
|
||||
} catch (Throwable $e) {
|
||||
$logger->notice('Unable to create session', ['mode' => $mode, 'session_handler' => $session_handler, 'exception' => $e]);
|
||||
$session = new Memory();
|
||||
}
|
||||
|
||||
$profiler->stopRecording();
|
||||
return $session;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -54,16 +54,13 @@ class ExternalResource implements ICanReadFromStorage
|
|||
$this->logger->notice('URL is invalid', ['url' => $data->url, 'error' => $exception]);
|
||||
throw new ReferenceStorageException(sprintf('External resource failed to get %s', $reference), $exception->getCode(), $exception);
|
||||
}
|
||||
if (!empty($fetchResult) && $fetchResult->isSuccess()) {
|
||||
$this->logger->debug('Got picture', ['Content-Type' => $fetchResult->getHeader('Content-Type'), 'uid' => $data->uid, 'url' => $data->url]);
|
||||
return $fetchResult->getBodyString();
|
||||
} else {
|
||||
if (empty($fetchResult)) {
|
||||
throw new ReferenceStorageException(sprintf('External resource failed to get %s', $reference));
|
||||
} else {
|
||||
throw new ReferenceStorageException(sprintf('External resource failed to get %s', $reference), $fetchResult->getReturnCode(), new Exception($fetchResult->getBodyString()));
|
||||
}
|
||||
|
||||
if (!$fetchResult->isSuccess()) {
|
||||
throw new ReferenceStorageException(sprintf('External resource failed to get %s', $reference), $fetchResult->getReturnCode(), new Exception($fetchResult->getBodyString()));
|
||||
}
|
||||
|
||||
$this->logger->debug('Got picture', ['Content-Type' => $fetchResult->getHeader('Content-Type'), 'uid' => $data->uid, 'url' => $data->url]);
|
||||
return $fetchResult->getBodyString();
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -393,6 +393,8 @@ class System
|
|||
|
||||
/**
|
||||
* Exit the program execution.
|
||||
*
|
||||
* @return never
|
||||
*/
|
||||
public static function exit()
|
||||
{
|
||||
|
@ -506,6 +508,8 @@ class System
|
|||
* @throws TemporaryRedirectException
|
||||
*
|
||||
* @throws \Friendica\Network\HTTPException\InternalServerErrorException
|
||||
*
|
||||
* @return never
|
||||
*/
|
||||
public static function externalRedirect($url, $code = 302)
|
||||
{
|
||||
|
|
|
@ -275,7 +275,7 @@ class DBStructure
|
|||
$is_new_table = false;
|
||||
$sql3 = "";
|
||||
if (!isset($database[$name])) {
|
||||
$sql = DbaDefinitionSqlWriter::createTable($name, $structure, $verbose, $action);
|
||||
$sql = DbaDefinitionSqlWriter::createTable($name, $structure);
|
||||
if ($verbose) {
|
||||
echo $sql;
|
||||
}
|
||||
|
|
|
@ -534,6 +534,8 @@ class Database
|
|||
throw new ServiceUnavailableException('The Connection is empty, although connected is set true.');
|
||||
}
|
||||
|
||||
$retval = false;
|
||||
|
||||
switch ($this->driver) {
|
||||
case self::PDO:
|
||||
// If there are no arguments we use "query"
|
||||
|
@ -1074,6 +1076,8 @@ class Database
|
|||
*/
|
||||
public function lastInsertId(): int
|
||||
{
|
||||
$id = 0;
|
||||
|
||||
switch ($this->driver) {
|
||||
case self::PDO:
|
||||
$id = $this->connection->lastInsertId();
|
||||
|
@ -1681,6 +1685,8 @@ class Database
|
|||
return false;
|
||||
}
|
||||
|
||||
$ret = false;
|
||||
|
||||
switch ($this->driver) {
|
||||
case self::PDO:
|
||||
$ret = $stmt->closeCursor();
|
||||
|
@ -1695,8 +1701,6 @@ class Database
|
|||
} elseif ($stmt instanceof mysqli_result) {
|
||||
$stmt->free();
|
||||
$ret = true;
|
||||
} else {
|
||||
$ret = false;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -1770,8 +1774,8 @@ class Database
|
|||
/**
|
||||
* Acquire a lock to prevent a table optimization
|
||||
*
|
||||
* @return bool
|
||||
* @throws LockPersistenceException
|
||||
* @return bool
|
||||
* @throws LockPersistenceException
|
||||
*/
|
||||
public function acquireOptimizeLock(): bool
|
||||
{
|
||||
|
@ -1781,8 +1785,8 @@ class Database
|
|||
/**
|
||||
* Release the table optimization lock
|
||||
*
|
||||
* @return bool
|
||||
* @throws LockPersistenceException
|
||||
* @return bool
|
||||
* @throws LockPersistenceException
|
||||
*/
|
||||
public function releaseOptimizeLock(): bool
|
||||
{
|
||||
|
|
|
@ -284,7 +284,7 @@ class PostUpdate
|
|||
}
|
||||
|
||||
while ($item = DBA::fetch($items)) {
|
||||
Tag::storeFromBody($item['uri-id'], $item['body'], '#!@', false);
|
||||
Tag::storeFromBody($item['uri-id'], $item['body'], '#!@');
|
||||
$id = $item['uri-id'];
|
||||
++$rows;
|
||||
if ($rows % 1000 == 0) {
|
||||
|
@ -775,11 +775,8 @@ class PostUpdate
|
|||
|
||||
while ($photo = DBA::fetch($photos)) {
|
||||
$img = Photo::getImageForPhoto($photo);
|
||||
if (!empty($img)) {
|
||||
$md5 = md5($img->asString());
|
||||
} else {
|
||||
$md5 = '';
|
||||
}
|
||||
$md5 = md5($img->asString());
|
||||
|
||||
DBA::update('photo', ['hash' => $md5], ['id' => $photo['id']]);
|
||||
++$rows;
|
||||
}
|
||||
|
@ -1220,7 +1217,7 @@ class PostUpdate
|
|||
$parts = parse_url($contact['url']);
|
||||
unset($parts['path']);
|
||||
$server = (string)Uri::fromParts($parts);
|
||||
|
||||
|
||||
DBA::update('contact',
|
||||
['gsid' => GServer::getID($server, true), 'baseurl' => GServer::cleanURL($server)],
|
||||
['id' => $contact['id']]);
|
||||
|
|
|
@ -25,11 +25,11 @@ class View
|
|||
foreach (['post-view', 'post-thread-view'] as $view) {
|
||||
if (self::isView($view)) {
|
||||
$sql = sprintf("DROP VIEW IF EXISTS `%s`", DBA::escape($view));
|
||||
if (!empty($sql) && $verbose) {
|
||||
if ($verbose) {
|
||||
echo $sql . ";\n";
|
||||
}
|
||||
|
||||
if (!empty($sql) && $action) {
|
||||
if ($action) {
|
||||
DBA::e($sql);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -48,6 +48,9 @@ class DirectMessage extends BaseFactory
|
|||
throw new HTTPException\NotFoundException('Direct message with ID ' . $mail . ' not found.');
|
||||
}
|
||||
|
||||
$title = '';
|
||||
$text = '';
|
||||
|
||||
if (!empty($text_mode)) {
|
||||
$title = $mail['title'];
|
||||
if ($text_mode == 'html') {
|
||||
|
@ -56,7 +59,6 @@ class DirectMessage extends BaseFactory
|
|||
$text = HTML::toPlaintext(BBCode::convertForUriId($mail['uri-id'], $mail['body'], BBCode::TWITTER_API), 0);
|
||||
}
|
||||
} else {
|
||||
$title = '';
|
||||
$text = $mail['title'] . "\n" . HTML::toPlaintext(BBCode::convertForUriId($mail['uri-id'], $mail['body'], BBCode::TWITTER_API), 0);
|
||||
}
|
||||
|
||||
|
|
|
@ -57,7 +57,7 @@ class User extends BaseFactory
|
|||
['author-id' => $publicContact['id'], 'gravity' => [Item::GRAVITY_COMMENT, Item::GRAVITY_PARENT], 'private' => [Item::PUBLIC, Item::UNLISTED]],
|
||||
['order' => ['uri-id' => true]]);
|
||||
if (!empty($post['uri-id'])) {
|
||||
$status = $this->status->createFromUriId($post['uri-id'], $uid)->toArray();
|
||||
$status = $this->status->createFromUriId($post['uri-id'], $uid);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -178,7 +178,7 @@ class APContact
|
|||
|
||||
try {
|
||||
$curlResult = HTTPSignature::fetchRaw($url);
|
||||
$failed = empty($curlResult) || empty($curlResult->getBodyString()) ||
|
||||
$failed = empty($curlResult->getBodyString()) ||
|
||||
(!$curlResult->isSuccess() && ($curlResult->getReturnCode() != 410));
|
||||
|
||||
if (!$failed) {
|
||||
|
|
|
@ -2364,6 +2364,8 @@ class Contact
|
|||
$cache_avatar = !DBA::exists('contact', ['nurl' => $contact['nurl'], 'self' => true]);
|
||||
}
|
||||
|
||||
$fields = [];
|
||||
|
||||
if (in_array($contact['network'], [Protocol::FEED, Protocol::MAIL]) || $cache_avatar) {
|
||||
if (Avatar::deleteCache($contact)) {
|
||||
$force = true;
|
||||
|
@ -2380,6 +2382,8 @@ class Contact
|
|||
Logger::debug('Use default avatar', ['id' => $cid, 'uid' => $uid]);
|
||||
}
|
||||
|
||||
$local_uid = 0;
|
||||
|
||||
// Use the data from the self account
|
||||
if (empty($fields)) {
|
||||
$local_uid = User::getIdForURL($contact['url']);
|
||||
|
@ -2411,8 +2415,15 @@ class Contact
|
|||
if ($update) {
|
||||
$photos = Photo::importProfilePhoto($avatar, $uid, $cid, true);
|
||||
if ($photos) {
|
||||
$fields = ['avatar' => $avatar, 'photo' => $photos[0], 'thumb' => $photos[1], 'micro' => $photos[2], 'blurhash' => $photos[3], 'avatar-date' => DateTimeFormat::utcNow()];
|
||||
$update = !empty($fields);
|
||||
$fields = [
|
||||
'avatar' => $avatar,
|
||||
'photo' => $photos[0],
|
||||
'thumb' => $photos[1],
|
||||
'micro' => $photos[2],
|
||||
'blurhash' => $photos[3],
|
||||
'avatar-date' => DateTimeFormat::utcNow(),
|
||||
];
|
||||
$update = true;
|
||||
Logger::debug('Created new cached avatars', ['id' => $cid, 'uid' => $uid, 'owner-uid' => $local_uid]);
|
||||
} else {
|
||||
$update = false;
|
||||
|
|
|
@ -333,7 +333,7 @@ class Event
|
|||
$item['uri'] = $event['uri'];
|
||||
$item['uri-id'] = ItemURI::getIdByURI($event['uri']);
|
||||
$item['guid'] = $event['guid'];
|
||||
$item['plink'] = $arr['plink'] ?? '';
|
||||
$item['plink'] = '';
|
||||
$item['post-type'] = Item::PT_EVENT;
|
||||
$item['wall'] = $event['cid'] ? 0 : 1;
|
||||
$item['contact-id'] = $contact['id'];
|
||||
|
|
|
@ -224,6 +224,8 @@ class GServer
|
|||
*/
|
||||
public static function reachable(array $contact): bool
|
||||
{
|
||||
$server = '';
|
||||
|
||||
if (!empty($contact['gsid'])) {
|
||||
$gsid = $contact['gsid'];
|
||||
} elseif (!empty($contact['baseurl'])) {
|
||||
|
@ -800,6 +802,8 @@ class GServer
|
|||
$serverdata['failed'] = false;
|
||||
$serverdata['blocked'] = false;
|
||||
|
||||
$id = 0;
|
||||
|
||||
$gserver = DBA::selectFirst('gserver', ['network'], ['nurl' => Strings::normaliseLink($url)]);
|
||||
if (!DBA::isResult($gserver)) {
|
||||
$serverdata['created'] = DateTimeFormat::utcNow();
|
||||
|
@ -1197,10 +1201,6 @@ class GServer
|
|||
}
|
||||
}
|
||||
|
||||
if (empty($server)) {
|
||||
return [];
|
||||
}
|
||||
|
||||
if (empty($server['network'])) {
|
||||
$server['network'] = Protocol::PHANTOM;
|
||||
}
|
||||
|
@ -1337,10 +1337,6 @@ class GServer
|
|||
}
|
||||
}
|
||||
|
||||
if (empty($server)) {
|
||||
return [];
|
||||
}
|
||||
|
||||
if (empty($server['network'])) {
|
||||
$server['network'] = Protocol::PHANTOM;
|
||||
}
|
||||
|
@ -1444,7 +1440,7 @@ class GServer
|
|||
}
|
||||
}
|
||||
|
||||
if (empty($server) || empty($server['platform'])) {
|
||||
if (empty($server['platform'])) {
|
||||
return [];
|
||||
}
|
||||
|
||||
|
@ -1652,10 +1648,11 @@ class GServer
|
|||
}
|
||||
|
||||
$data = json_decode($curlResult->getBodyString(), true);
|
||||
if (empty($data)) {
|
||||
if (!is_string($data)) {
|
||||
return '';
|
||||
}
|
||||
return $data ?? '';
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
private static function getZotData(string $url, array $serverdata): array
|
||||
|
@ -2310,13 +2307,19 @@ class GServer
|
|||
return $serverdata;
|
||||
}
|
||||
|
||||
if (file_exists(__DIR__ . '/../../static/platforms.config.php')) {
|
||||
require __DIR__ . '/../../static/platforms.config.php';
|
||||
} else {
|
||||
if (!file_exists(__DIR__ . '/../../static/platforms.config.php')) {
|
||||
throw new HTTPException\InternalServerErrorException('Invalid platform file');
|
||||
}
|
||||
|
||||
$platforms = array_merge($ap_platforms, $dfrn_platforms, $zap_platforms, $platforms);
|
||||
/** @var array $grouped_platforms */
|
||||
$grouped_platforms = require __DIR__ . '/../../static/platforms.config.php';
|
||||
|
||||
$platforms = array_merge(
|
||||
$grouped_platforms['ap_platforms'],
|
||||
$grouped_platforms['dfrn_platforms'],
|
||||
$grouped_platforms['zap_platforms'],
|
||||
$grouped_platforms['platforms'],
|
||||
);
|
||||
|
||||
$doc = new DOMDocument();
|
||||
@$doc->loadHTML($curlResult->getBodyString());
|
||||
|
@ -2367,11 +2370,11 @@ class GServer
|
|||
$platform = $platform_parts[0];
|
||||
$serverdata['version'] = $platform_parts[1];
|
||||
}
|
||||
if (in_array($platform, array_values($dfrn_platforms))) {
|
||||
if (in_array($platform, array_values($grouped_platforms['dfrn_platforms']))) {
|
||||
$serverdata['network'] = Protocol::DFRN;
|
||||
} elseif (in_array($platform, array_values($ap_platforms))) {
|
||||
} elseif (in_array($platform, array_values($grouped_platforms['ap_platforms']))) {
|
||||
$serverdata['network'] = Protocol::ACTIVITYPUB;
|
||||
} elseif (in_array($platform, array_values($zap_platforms))) {
|
||||
} elseif (in_array($platform, array_values($grouped_platforms['zap_platforms']))) {
|
||||
$serverdata['network'] = Protocol::ZOT;
|
||||
}
|
||||
if (in_array($platform, array_values($platforms))) {
|
||||
|
@ -2414,9 +2417,9 @@ class GServer
|
|||
$assigned = true;
|
||||
}
|
||||
|
||||
if (in_array($attr['content'], array_keys($ap_platforms))) {
|
||||
if (in_array($attr['content'], array_keys($grouped_platforms['ap_platforms']))) {
|
||||
$serverdata['network'] = Protocol::ACTIVITYPUB;
|
||||
} elseif (in_array($attr['content'], array_values($zap_platforms))) {
|
||||
} elseif (in_array($attr['content'], array_values($grouped_platforms['zap_platforms']))) {
|
||||
$serverdata['network'] = Protocol::ZOT;
|
||||
}
|
||||
}
|
||||
|
@ -2492,7 +2495,7 @@ class GServer
|
|||
*/
|
||||
public static function discover()
|
||||
{
|
||||
if (!DI::config('system', 'discover_servers')) {
|
||||
if (!DI::config()->get('system', 'discover_servers')) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -193,6 +193,7 @@ class Item
|
|||
$fields['vid'] = Verb::getID($fields['verb']);
|
||||
}
|
||||
|
||||
$previous = [];
|
||||
if (!empty($fields['edited'])) {
|
||||
$previous = Post::selectFirst(['edited'], $condition);
|
||||
}
|
||||
|
@ -856,6 +857,8 @@ class Item
|
|||
|
||||
$priority = Worker::PRIORITY_HIGH;
|
||||
|
||||
$copy_permissions = false;
|
||||
|
||||
// If it is a posting where users should get notifications, then define it as wall posting
|
||||
if ($notify) {
|
||||
$item = self::prepareOriginPost($item);
|
||||
|
@ -3205,7 +3208,7 @@ class Item
|
|||
} elseif ($remote_user) {
|
||||
// Authenticated visitor - fetch the matching permissionsets
|
||||
$permissionSets = DI::permissionSet()->selectByContactId($remote_user, $owner_id);
|
||||
if (!empty($permissionSets)) {
|
||||
if (count($permissionSets) > 0) {
|
||||
$condition = [
|
||||
"(`private` != ? OR (`private` = ? AND `wall`
|
||||
AND `psid` IN (" . implode(', ', array_fill(0, count($permissionSets), '?')) . ")))",
|
||||
|
@ -3234,17 +3237,12 @@ class Item
|
|||
$table = DBA::quoteIdentifier($table) . '.';
|
||||
}
|
||||
|
||||
/*
|
||||
* Construct permissions
|
||||
*
|
||||
* default permissions - anonymous user
|
||||
*/
|
||||
$sql = sprintf(" AND " . $table . "`private` != %d", self::PRIVATE);
|
||||
|
||||
// Profile owner - everything is visible
|
||||
if ($local_user && ($local_user == $owner_id)) {
|
||||
$sql = '';
|
||||
} elseif ($remote_user) {
|
||||
return '';
|
||||
}
|
||||
|
||||
if ($remote_user) {
|
||||
/*
|
||||
* Authenticated visitor. Unless pre-verified,
|
||||
* check that the contact belongs to this $owner_id
|
||||
|
@ -3254,16 +3252,21 @@ class Item
|
|||
*/
|
||||
$permissionSets = DI::permissionSet()->selectByContactId($remote_user, $owner_id);
|
||||
|
||||
if (!empty($permissionSets)) {
|
||||
$sql_set = '';
|
||||
|
||||
if (count($permissionSets) > 0) {
|
||||
$sql_set = sprintf(" OR (" . $table . "`private` = %d AND " . $table . "`wall` AND " . $table . "`psid` IN (", self::PRIVATE) . implode(',', $permissionSets->column('id')) . "))";
|
||||
} else {
|
||||
$sql_set = '';
|
||||
}
|
||||
|
||||
$sql = sprintf(" AND (" . $table . "`private` != %d", self::PRIVATE) . $sql_set . ")";
|
||||
return sprintf(" AND (" . $table . "`private` != %d", self::PRIVATE) . $sql_set . ")";
|
||||
}
|
||||
|
||||
return $sql;
|
||||
/*
|
||||
* Construct permissions
|
||||
*
|
||||
* default permissions - anonymous user
|
||||
*/
|
||||
return sprintf(" AND " . $table . "`private` != %d", self::PRIVATE);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -3387,6 +3390,7 @@ class Item
|
|||
$shared_uri_id = 0;
|
||||
$shared_links = [];
|
||||
$quote_shared_links = [];
|
||||
$shared_item = [];
|
||||
|
||||
$shared = DI::contentItem()->getSharedPost($item, $fields);
|
||||
if (!empty($shared['post'])) {
|
||||
|
@ -3430,6 +3434,8 @@ class Item
|
|||
}
|
||||
}
|
||||
|
||||
$sharedSplitAttachments = [];
|
||||
|
||||
if (!empty($shared_item['uri-id'])) {
|
||||
$shared_uri_id = $shared_item['uri-id'];
|
||||
$shared_links[] = strtolower($shared_item['plink']);
|
||||
|
@ -3503,7 +3509,7 @@ class Item
|
|||
$s = self::addGallery($s, $sharedSplitAttachments['visual']);
|
||||
$s = self::addVisualAttachments($sharedSplitAttachments['visual'], $shared_item, $s, true);
|
||||
$s = self::addLinkAttachment($shared_uri_id ?: $item['uri-id'], $sharedSplitAttachments, $body, $s, true, $quote_shared_links);
|
||||
$s = self::addNonVisualAttachments($sharedSplitAttachments['additional'], $item, $s, true);
|
||||
$s = self::addNonVisualAttachments($sharedSplitAttachments['additional'], $item, $s);
|
||||
$body = BBCode::removeSharedData($body);
|
||||
}
|
||||
|
||||
|
@ -3516,7 +3522,7 @@ class Item
|
|||
$s = self::addGallery($s, $itemSplitAttachments['visual']);
|
||||
$s = self::addVisualAttachments($itemSplitAttachments['visual'], $item, $s, false);
|
||||
$s = self::addLinkAttachment($item['uri-id'], $itemSplitAttachments, $body, $s, false, $shared_links);
|
||||
$s = self::addNonVisualAttachments($itemSplitAttachments['additional'], $item, $s, false);
|
||||
$s = self::addNonVisualAttachments($itemSplitAttachments['additional'], $item, $s);
|
||||
$s = self::addQuestions($item, $s);
|
||||
|
||||
// Map.
|
||||
|
|
|
@ -128,7 +128,7 @@ class Engagement
|
|||
return ($ret && !$exists) ? $engagement['uri-id'] : 0;
|
||||
}
|
||||
|
||||
public static function getContentSize(array $item): int
|
||||
public static function getContentSize(array $item): int
|
||||
{
|
||||
$body = ' ' . $item['title'] . ' ' . $item['content-warning'] . ' ' . $item['body'];
|
||||
$body = BBCode::removeAttachment($body);
|
||||
|
@ -318,6 +318,8 @@ class Engagement
|
|||
$result = Post::selectPosts(['author-addr', 'author-nick', 'author-contact-type'],
|
||||
['thr-parent-id' => $uri_id, 'gravity' => Item::GRAVITY_ACTIVITY, 'verb' => Activity::ANNOUNCE, 'author-contact-type' => [Contact::TYPE_RELAY, Contact::TYPE_COMMUNITY]]);
|
||||
while ($reshare = Post::fetch($result)) {
|
||||
$prefix = '';
|
||||
|
||||
switch ($reshare['author-contact-type']) {
|
||||
case Contact::TYPE_RELAY:
|
||||
$prefix = ' application_';
|
||||
|
|
|
@ -113,9 +113,6 @@ class Link
|
|||
|
||||
try {
|
||||
$curlResult = HTTPSignature::fetchRaw($url, 0, [HttpClientOptions::TIMEOUT => $timeout, HttpClientOptions::ACCEPT_CONTENT => $accept]);
|
||||
if (empty($curlResult) || !$curlResult->isSuccess()) {
|
||||
return [];
|
||||
}
|
||||
} catch (\Exception $exception) {
|
||||
Logger::notice('Error fetching url', ['url' => $url, 'exception' => $exception]);
|
||||
return [];
|
||||
|
|
|
@ -699,7 +699,7 @@ class Media
|
|||
if (preg_match_all("/\[url\](https?:.*?)\[\/url\]/ism", $body, $matches)) {
|
||||
foreach ($matches[1] as $url) {
|
||||
Logger::info('Got page url (link without description)', ['uri-id' => $uriid, 'url' => $url]);
|
||||
$result = self::insert(['uri-id' => $uriid, 'type' => self::UNKNOWN, 'url' => $url], false, $network);
|
||||
$result = self::insert(['uri-id' => $uriid, 'type' => self::UNKNOWN, 'url' => $url], false);
|
||||
if ($result && !in_array($network, [Protocol::ACTIVITYPUB, Protocol::DIASPORA])) {
|
||||
self::revertHTMLType($uriid, $url, $fullbody);
|
||||
Logger::debug('Revert HTML type', ['uri-id' => $uriid, 'url' => $url]);
|
||||
|
@ -715,7 +715,7 @@ class Media
|
|||
if (preg_match_all("/\[url\=(https?:.*?)\].*?\[\/url\]/ism", $body, $matches)) {
|
||||
foreach ($matches[1] as $url) {
|
||||
Logger::info('Got page url (link with description)', ['uri-id' => $uriid, 'url' => $url]);
|
||||
$result = self::insert(['uri-id' => $uriid, 'type' => self::UNKNOWN, 'url' => $url], false, $network);
|
||||
$result = self::insert(['uri-id' => $uriid, 'type' => self::UNKNOWN, 'url' => $url], false);
|
||||
if ($result && !in_array($network, [Protocol::ACTIVITYPUB, Protocol::DIASPORA])) {
|
||||
self::revertHTMLType($uriid, $url, $fullbody);
|
||||
Logger::debug('Revert HTML type', ['uri-id' => $uriid, 'url' => $url]);
|
||||
|
|
|
@ -49,7 +49,7 @@ class Embed extends BaseAdmin
|
|||
require_once "view/theme/$theme/config.php";
|
||||
if (function_exists('theme_admin_post')) {
|
||||
self::checkFormSecurityTokenRedirectOnError('/admin/themes/' . $theme . '/embed?mode=minimal', 'admin_theme_settings');
|
||||
theme_admin_post($this->appHelper);
|
||||
theme_admin_post();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -31,7 +31,7 @@ class Markers extends BaseApi
|
|||
}
|
||||
}
|
||||
|
||||
if (empty($timeline) || empty($last_read_id) || empty($application['id'])) {
|
||||
if ($timeline === '' || $last_read_id === '' || empty($application['id'])) {
|
||||
$this->logAndJsonError(422, $this->errorFactory->UnprocessableEntity());
|
||||
}
|
||||
|
||||
|
|
|
@ -28,12 +28,12 @@ class Show extends ContactEndpoint
|
|||
$target_cid = BaseApi::getContactIDForSearchterm($this->getRequestValue($request, 'target_screen_name', ''), '', $this->getRequestValue($request, 'target_id', 0), $uid);
|
||||
|
||||
$source = Contact::getById($source_cid);
|
||||
if (empty($source)) {
|
||||
if ($source === false) {
|
||||
throw new NotFoundException('Source not found');
|
||||
}
|
||||
|
||||
$target = Contact::getById($target_cid);
|
||||
if (empty($source)) {
|
||||
if ($target === false) {
|
||||
throw new NotFoundException('Target not found');
|
||||
}
|
||||
|
||||
|
|
|
@ -511,7 +511,7 @@ class BaseApi extends BaseModule
|
|||
/**
|
||||
* @param int $errorno
|
||||
* @param Error $error
|
||||
* @return void
|
||||
* @return never
|
||||
* @throws HTTPException\InternalServerErrorException
|
||||
*/
|
||||
protected function logAndJsonError(int $errorno, Error $error)
|
||||
|
|
|
@ -131,7 +131,7 @@ abstract class BaseNotifications extends BaseModule
|
|||
|
||||
$notif_tpl = Renderer::getMarkupTemplate('notifications/notifications.tpl');
|
||||
return Renderer::replaceMacros($notif_tpl, [
|
||||
'$header' => $header ?? $this->t('Notifications'),
|
||||
'$header' => $header ?: $this->t('Notifications'),
|
||||
'$tabs' => $tabs,
|
||||
'$notifications' => $notifications,
|
||||
'$noContent' => $noContent,
|
||||
|
|
|
@ -140,9 +140,9 @@ class API extends BaseModule
|
|||
$share = intval($request['share'] ?? 0);
|
||||
$isPreview = intval($request['preview'] ?? 0);
|
||||
|
||||
$start = DateTimeFormat::convert($strStartDateTime ?? DBA::NULL_DATETIME, 'UTC', $this->timezone);
|
||||
$start = DateTimeFormat::convert($strStartDateTime, 'UTC', $this->timezone);
|
||||
if (!$noFinish) {
|
||||
$finish = DateTimeFormat::convert($strFinishDateTime ?? DBA::NULL_DATETIME, 'UTC', $this->timezone);
|
||||
$finish = DateTimeFormat::convert($strFinishDateTime, 'UTC', $this->timezone);
|
||||
} else {
|
||||
$finish = DBA::NULL_DATETIME;
|
||||
}
|
||||
|
|
|
@ -70,6 +70,8 @@ class Circle extends BaseModule
|
|||
throw new \Exception(DI::l10n()->t('Permission denied.'), 403);
|
||||
}
|
||||
|
||||
$message = '';
|
||||
|
||||
if (isset($this->parameters['command'])) {
|
||||
$circle_id = $this->parameters['circle'];
|
||||
$contact_id = $this->parameters['contact'];
|
||||
|
@ -169,7 +171,9 @@ class Circle extends BaseModule
|
|||
]);
|
||||
}
|
||||
|
||||
$nocircle = false;
|
||||
$nocircle = false;
|
||||
$members = [];
|
||||
$preselected = [];
|
||||
|
||||
// @TODO: Replace with parameter from router
|
||||
if ((DI::args()->getArgc() == 2) && (DI::args()->getArgv()[1] === 'none') ||
|
||||
|
@ -181,9 +185,6 @@ class Circle extends BaseModule
|
|||
'name' => DI::l10n()->t('Contacts not in any circle'),
|
||||
];
|
||||
|
||||
$members = [];
|
||||
$preselected = [];
|
||||
|
||||
$context = $context + [
|
||||
'$title' => $circle['name'],
|
||||
'$gname' => ['circle_name', DI::l10n()->t('Circle Name: '), $circle['name'], ''],
|
||||
|
|
|
@ -7,18 +7,19 @@
|
|||
|
||||
namespace Friendica\Module\Contact;
|
||||
|
||||
use Friendica\App;
|
||||
use Friendica\App\Arguments;
|
||||
use Friendica\App\BaseURL;
|
||||
use Friendica\App\Page;
|
||||
use Friendica\BaseModule;
|
||||
use Friendica\Contact\LocalRelationship\Repository\LocalRelationship;
|
||||
use Friendica\Content\Conversation;
|
||||
use Friendica\Content\Nav;
|
||||
use Friendica\Content\Widget;
|
||||
use Friendica\Content\Widget\VCard;
|
||||
use Friendica\Core\ACL;
|
||||
use Friendica\Core\L10n;
|
||||
use Friendica\Core\Protocol;
|
||||
use Friendica\Core\Session\Capability\IHandleUserSessions;
|
||||
use Friendica\Core\Theme;
|
||||
use Friendica\Model;
|
||||
use Friendica\Model\Contact as ModelContact;
|
||||
use Friendica\Module\Contact;
|
||||
use Friendica\Module\Response;
|
||||
|
@ -33,7 +34,7 @@ use Psr\Log\LoggerInterface;
|
|||
class Conversations extends BaseModule
|
||||
{
|
||||
/**
|
||||
* @var App\Page
|
||||
* @var Page
|
||||
*/
|
||||
private $page;
|
||||
/**
|
||||
|
@ -49,7 +50,7 @@ class Conversations extends BaseModule
|
|||
*/
|
||||
private $userSession;
|
||||
|
||||
public function __construct(L10n $l10n, LocalRelationship $localRelationship, App\BaseURL $baseUrl, App\Arguments $args, LoggerInterface $logger, Profiler $profiler, Response $response, App\Page $page, Conversation $conversation, IHandleUserSessions $userSession, $server, array $parameters = [])
|
||||
public function __construct(L10n $l10n, LocalRelationship $localRelationship, BaseURL $baseUrl, Arguments $args, LoggerInterface $logger, Profiler $profiler, Response $response, Page $page, Conversation $conversation, IHandleUserSessions $userSession, $server, array $parameters = [])
|
||||
{
|
||||
parent::__construct($l10n, $baseUrl, $args, $logger, $profiler, $response, $server, $parameters);
|
||||
|
||||
|
@ -67,12 +68,12 @@ class Conversations extends BaseModule
|
|||
|
||||
// Backward compatibility: Ensure to use the public contact when the user contact is provided
|
||||
// Remove by version 2022.03
|
||||
$pcid = Model\Contact::getPublicContactId(intval($this->parameters['id']), $this->userSession->getLocalUserId());
|
||||
$pcid = ModelContact::getPublicContactId(intval($this->parameters['id']), $this->userSession->getLocalUserId());
|
||||
if (!$pcid) {
|
||||
throw new NotFoundException($this->t('Contact not found.'));
|
||||
}
|
||||
|
||||
$contact = Model\Contact::getAccountById($pcid);
|
||||
$contact = ModelContact::getAccountById($pcid);
|
||||
if (empty($contact)) {
|
||||
throw new NotFoundException($this->t('Contact not found.'));
|
||||
}
|
||||
|
@ -83,7 +84,7 @@ class Conversations extends BaseModule
|
|||
}
|
||||
|
||||
$localRelationship = $this->localRelationship->getForUserContact($this->userSession->getLocalUserId(), $contact['id']);
|
||||
if ($localRelationship->rel === Model\Contact::SELF) {
|
||||
if ($localRelationship->rel === ModelContact::SELF) {
|
||||
$this->baseUrl->redirect('profile/' . $contact['nick']);
|
||||
}
|
||||
|
||||
|
@ -93,10 +94,12 @@ class Conversations extends BaseModule
|
|||
$this->page->registerStylesheet(Theme::getPathForFile('js/friendica-tagsinput/friendica-tagsinput.css'));
|
||||
$this->page->registerStylesheet(Theme::getPathForFile('js/friendica-tagsinput/friendica-tagsinput-typeahead.css'));
|
||||
|
||||
$this->page['aside'] .= Widget\VCard::getHTML($contact, true);
|
||||
$this->page['aside'] .= VCard::getHTML($contact, true);
|
||||
|
||||
Nav::setSelected('contact');
|
||||
|
||||
$output = '';
|
||||
|
||||
if (!$contact['ap-posting-restricted']) {
|
||||
$options = [
|
||||
'lockstate' => ACL::getLockstateForUserId($this->userSession->getLocalUserId()) ? 'lock' : 'unlock',
|
||||
|
@ -104,12 +107,12 @@ class Conversations extends BaseModule
|
|||
'bang' => '',
|
||||
'content' => ($contact['contact-type'] == ModelContact::TYPE_COMMUNITY ? '!' : '@') . ($contact['addr'] ?: $contact['url']),
|
||||
];
|
||||
$o = $this->conversation->statusEditor($options);
|
||||
$output = $this->conversation->statusEditor($options);
|
||||
}
|
||||
|
||||
$o .= Contact::getTabsHTML($contact, Contact::TAB_CONVERSATIONS);
|
||||
$o .= Model\Contact::getThreadsFromId($contact['id'], $this->userSession->getLocalUserId(), 0, 0, $request['last_created'] ?? '');
|
||||
$output .= Contact::getTabsHTML($contact, Contact::TAB_CONVERSATIONS);
|
||||
$output .= ModelContact::getThreadsFromId($contact['id'], $this->userSession->getLocalUserId(), 0, 0, $request['last_created'] ?? '');
|
||||
|
||||
return $o;
|
||||
return $output;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,7 +7,8 @@
|
|||
|
||||
namespace Friendica\Module\Conversation;
|
||||
|
||||
use Friendica\App;
|
||||
use Friendica\App\Arguments;
|
||||
use Friendica\App\BaseURL;
|
||||
use Friendica\App\Mode;
|
||||
use Friendica\BaseModule;
|
||||
use Friendica\Content\Conversation\Collection\Timelines;
|
||||
|
@ -31,6 +32,8 @@ use Friendica\Model\Post;
|
|||
use Friendica\Model\Post\Engagement;
|
||||
use Friendica\Model\Post\SearchIndex;
|
||||
use Friendica\Module\Response;
|
||||
use Friendica\Network\HTTPException\BadRequestException;
|
||||
use Friendica\Network\HTTPException\ForbiddenException;
|
||||
use Friendica\Protocol\Activity;
|
||||
use Friendica\Util\DateTimeFormat;
|
||||
use Friendica\Util\Profiler;
|
||||
|
@ -67,7 +70,7 @@ class Timeline extends BaseModule
|
|||
/** @var string */
|
||||
protected $network;
|
||||
|
||||
/** @var App\Mode $mode */
|
||||
/** @var Mode $mode */
|
||||
protected $mode;
|
||||
/** @var IHandleUserSessions */
|
||||
protected $session;
|
||||
|
@ -82,7 +85,7 @@ class Timeline extends BaseModule
|
|||
/** @var UserDefinedChannel */
|
||||
protected $channelRepository;
|
||||
|
||||
public function __construct(UserDefinedChannel $channel, Mode $mode, IHandleUserSessions $session, Database $database, IManagePersonalConfigValues $pConfig, IManageConfigValues $config, ICanCache $cache, L10n $l10n, App\BaseURL $baseUrl, App\Arguments $args, LoggerInterface $logger, Profiler $profiler, Response $response, array $server = [], array $parameters = [])
|
||||
public function __construct(UserDefinedChannel $channel, Mode $mode, IHandleUserSessions $session, Database $database, IManagePersonalConfigValues $pConfig, IManageConfigValues $config, ICanCache $cache, L10n $l10n, BaseURL $baseUrl, Arguments $args, LoggerInterface $logger, Profiler $profiler, Response $response, array $server = [], array $parameters = [])
|
||||
{
|
||||
parent::__construct($l10n, $baseUrl, $args, $logger, $profiler, $response, $server, $parameters);
|
||||
|
||||
|
@ -98,8 +101,8 @@ class Timeline extends BaseModule
|
|||
/**
|
||||
* Computes module parameters from the request and local configuration
|
||||
*
|
||||
* @throws HTTPException\BadRequestException
|
||||
* @throws HTTPException\ForbiddenException
|
||||
* @throws BadRequestException
|
||||
* @throws ForbiddenException
|
||||
*/
|
||||
protected function parseRequest(array $request)
|
||||
{
|
||||
|
@ -308,6 +311,8 @@ class Timeline extends BaseModule
|
|||
{
|
||||
$table = 'post-engagement';
|
||||
|
||||
$condition = [];
|
||||
|
||||
if ($this->selectedTab == ChannelEntity::WHATSHOT) {
|
||||
if (!is_null($this->accountType)) {
|
||||
$condition = ["(`comments` > ? OR `activities` > ?) AND `contact-type` = ?", $this->getMedianComments($uid, 4), $this->getMedianActivities($uid, 4), $this->accountType];
|
||||
|
@ -331,11 +336,11 @@ class Timeline extends BaseModule
|
|||
"`owner-id` IN (SELECT `cid` FROM `contact-relation` WHERE `relation-cid` = ? AND NOT `follows`) AND
|
||||
(`owner-id` IN (SELECT `cid` FROM `contact-relation` WHERE `relation-cid` = ? AND NOT `follows` AND `relation-thread-score` > ?) OR
|
||||
`owner-id` IN (SELECT `cid` FROM `contact-relation` WHERE `cid` = ? AND `relation-thread-score` > ?) OR
|
||||
((`comments` >= ? OR `activities` >= ?) AND
|
||||
(`owner-id` IN (SELECT `cid` FROM `contact-relation` WHERE `cid` = ? AND `relation-thread-score` > ?)) OR
|
||||
((`comments` >= ? OR `activities` >= ?) AND
|
||||
(`owner-id` IN (SELECT `cid` FROM `contact-relation` WHERE `cid` = ? AND `relation-thread-score` > ?)) OR
|
||||
(`owner-id` IN (SELECT `cid` FROM `contact-relation` WHERE `relation-cid` = ? AND `relation-thread-score` > ?))))",
|
||||
$cid, $cid, $this->getMedianRelationThreadScore($cid, 4), $cid, $this->getMedianRelationThreadScore($cid, 4),
|
||||
$this->getMedianComments($uid, 4), $this->getMedianActivities($uid, 4), $cid, 0, $cid, 0
|
||||
$this->getMedianComments($uid, 4), $this->getMedianActivities($uid, 4), $cid, 0, $cid, 0
|
||||
];
|
||||
|
||||
} elseif ($this->selectedTab == ChannelEntity::FOLLOWERS) {
|
||||
|
@ -490,7 +495,7 @@ class Timeline extends BaseModule
|
|||
$placeholders = substr(str_repeat("?, ", count($search)), 0, -2);
|
||||
$condition = DBA::mergeConditions($condition, array_merge(["`uri-id` IN (SELECT `uri-id` FROM `post-tag` INNER JOIN `tag` ON `tag`.`id` = `post-tag`.`tid` WHERE `post-tag`.`type` = 1 AND `name` IN (" . $placeholders . "))"], $search));
|
||||
}
|
||||
|
||||
|
||||
if (!empty($channel->excludeTags)) {
|
||||
$search = explode(',', mb_strtolower($channel->excludeTags));
|
||||
$placeholders = substr(str_repeat("?, ", count($search)), 0, -2);
|
||||
|
@ -500,7 +505,7 @@ class Timeline extends BaseModule
|
|||
if (!empty($channel->mediaType)) {
|
||||
$condition = DBA::mergeConditions($condition, ["`media-type` & ?", $channel->mediaType]);
|
||||
}
|
||||
|
||||
|
||||
// For "addLanguageCondition" to work, the condition must not be empty
|
||||
$condition = $this->addLanguageCondition($uid, $condition ?: ["true"], $channel->languages);
|
||||
}
|
||||
|
@ -684,6 +689,7 @@ class Timeline extends BaseModule
|
|||
protected function getCommunityItems()
|
||||
{
|
||||
$items = $this->selectItems();
|
||||
$key = '';
|
||||
|
||||
if ($this->selectedTab == Community::LOCAL) {
|
||||
$maxpostperauthor = (int)$this->config->get('system', 'max_author_posts_community_page');
|
||||
|
@ -692,49 +698,52 @@ class Timeline extends BaseModule
|
|||
$maxpostperauthor = (int)$this->config->get('system', 'max_server_posts_community_page');
|
||||
$key = 'author-gsid';
|
||||
} else {
|
||||
$maxpostperauthor = 0;
|
||||
$this->setItemsSeenByCondition([
|
||||
'unseen' => true,
|
||||
'uid' => $this->session->getLocalUserId(),
|
||||
'parent-uri-id' => array_column($items, 'uri-id')
|
||||
]);
|
||||
|
||||
return $items;
|
||||
}
|
||||
if ($maxpostperauthor != 0) {
|
||||
$count = 1;
|
||||
$author_posts = [];
|
||||
$selected_items = [];
|
||||
|
||||
while (count($selected_items) < $this->itemsPerPage && ++$count < 50 && count($items) > 0) {
|
||||
$maxposts = round((count($items) / $this->itemsPerPage) * $maxpostperauthor);
|
||||
$minId = $items[array_key_first($items)]['received'];
|
||||
$maxId = $items[array_key_last($items)]['received'];
|
||||
$count = 1;
|
||||
$author_posts = [];
|
||||
$selected_items = [];
|
||||
|
||||
foreach ($items as $item) {
|
||||
$author_posts[$item[$key]][$item['uri-id']] = $item['received'];
|
||||
while (count($selected_items) < $this->itemsPerPage && ++$count < 50 && count($items) > 0) {
|
||||
$maxposts = round((count($items) / $this->itemsPerPage) * $maxpostperauthor);
|
||||
$minId = $items[array_key_first($items)]['received'];
|
||||
$maxId = $items[array_key_last($items)]['received'];
|
||||
|
||||
foreach ($items as $item) {
|
||||
$author_posts[$item[$key]][$item['uri-id']] = $item['received'];
|
||||
}
|
||||
foreach ($author_posts as $posts) {
|
||||
if (count($posts) <= $maxposts) {
|
||||
continue;
|
||||
}
|
||||
foreach ($author_posts as $posts) {
|
||||
if (count($posts) <= $maxposts) {
|
||||
continue;
|
||||
}
|
||||
asort($posts);
|
||||
while (count($posts) > $maxposts) {
|
||||
$uri_id = array_key_first($posts);
|
||||
unset($posts[$uri_id]);
|
||||
unset($items[$uri_id]);
|
||||
}
|
||||
}
|
||||
$selected_items = array_merge($selected_items, $items);
|
||||
|
||||
// If we're looking at a "previous page", the lookup continues forward in time because the list is
|
||||
// sorted in chronologically decreasing order
|
||||
if (!empty($this->minId)) {
|
||||
$this->minId = $minId;
|
||||
} else {
|
||||
// In any other case, the lookup continues backwards in time
|
||||
$this->maxId = $maxId;
|
||||
}
|
||||
|
||||
if (count($selected_items) < $this->itemsPerPage) {
|
||||
$items = $this->selectItems();
|
||||
asort($posts);
|
||||
while (count($posts) > $maxposts) {
|
||||
$uri_id = array_key_first($posts);
|
||||
unset($posts[$uri_id]);
|
||||
unset($items[$uri_id]);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
$selected_items = $items;
|
||||
$selected_items = array_merge($selected_items, $items);
|
||||
|
||||
// If we're looking at a "previous page", the lookup continues forward in time because the list is
|
||||
// sorted in chronologically decreasing order
|
||||
if (!empty($this->minId)) {
|
||||
$this->minId = $minId;
|
||||
} else {
|
||||
// In any other case, the lookup continues backwards in time
|
||||
$this->maxId = $maxId;
|
||||
}
|
||||
|
||||
if (count($selected_items) < $this->itemsPerPage) {
|
||||
$items = $this->selectItems();
|
||||
}
|
||||
}
|
||||
|
||||
$condition = ['unseen' => true, 'uid' => $this->session->getLocalUserId(), 'parent-uri-id' => array_column($selected_items, 'uri-id')];
|
||||
|
@ -808,7 +817,7 @@ class Timeline extends BaseModule
|
|||
}
|
||||
|
||||
$uriids = array_keys($items);
|
||||
|
||||
|
||||
foreach (Post\Counts::get(['parent-uri-id' => $uriids, 'verb' => Activity::POST]) as $count) {
|
||||
$items[$count['parent-uri-id']]['comments'] += $count['count'];
|
||||
}
|
||||
|
|
|
@ -37,26 +37,13 @@ class PageNotFound extends BaseModule
|
|||
|
||||
public function run(ModuleHTTPException $httpException, array $request = []): ResponseInterface
|
||||
{
|
||||
/* The URL provided does not resolve to a valid module.
|
||||
*
|
||||
* On Dreamhost sites, quite often things go wrong for no apparent reason and they send us to '/internal_error.html'.
|
||||
* We don't like doing this, but as it occasionally accounts for 10-20% or more of all site traffic -
|
||||
* we are going to trap this and redirect back to the requested page. As long as you don't have a critical error on your page
|
||||
* this will often succeed and eventually do the right thing.
|
||||
*
|
||||
* Otherwise we are going to emit a 404 not found.
|
||||
*/
|
||||
// The URL provided does not resolve to a valid module.
|
||||
$queryString = $this->server['QUERY_STRING'];
|
||||
// Stupid browser tried to pre-fetch our JavaScript img template. Don't log the event or return anything - just quietly exit.
|
||||
if (!empty($queryString) && preg_match('/{[0-9]}/', $queryString) !== 0) {
|
||||
System::exit();
|
||||
}
|
||||
|
||||
if (!empty($queryString) && ($queryString === 'q=internal_error.html') && isset($dreamhost_error_hack)) {
|
||||
$this->logger->info('index.php: dreamhost_error_hack invoked.', ['Original URI' => $this->server['REQUEST_URI']]);
|
||||
$this->baseUrl->redirect($this->server['REQUEST_URI']);
|
||||
}
|
||||
|
||||
$this->logger->debug('index.php: page not found.', [
|
||||
'request_uri' => $this->server['REQUEST_URI'],
|
||||
'address' => $this->remoteAddress,
|
||||
|
|
|
@ -166,12 +166,13 @@ class Display extends BaseModule
|
|||
*/
|
||||
protected function displaySidebar(array $item)
|
||||
{
|
||||
$author = [];
|
||||
$shared = $this->contentItem->getSharedPost($item, ['author-link']);
|
||||
if (!empty($shared) && empty($shared['comment'])) {
|
||||
if (array_key_exists('comment', $shared) && strval($shared['comment']) === '') {
|
||||
$author = Contact::getByURLForUser($shared['post']['author-link'], $this->session->getLocalUserId());
|
||||
}
|
||||
|
||||
if (empty($contact)) {
|
||||
if ($author === []) {
|
||||
$author = Contact::getById($item['author-id']);
|
||||
}
|
||||
|
||||
|
|
|
@ -65,31 +65,26 @@ class Magic extends BaseModule
|
|||
|
||||
$this->logger->debug('Invoked', ['request' => $request]);
|
||||
|
||||
$addr = $request['addr'] ?? '';
|
||||
$bdest = $request['bdest'] ?? '';
|
||||
$dest = $request['dest'] ?? '';
|
||||
$rev = intval($request['rev'] ?? 0);
|
||||
$addr = (string) $request['addr'] ?? '';
|
||||
$bdest = (string) $request['bdest'] ?? '';
|
||||
$dest = (string) $request['dest'] ?? '';
|
||||
$owa = intval($request['owa'] ?? 0);
|
||||
$delegate = $request['delegate'] ?? '';
|
||||
|
||||
// bdest is preferred as it is hex-encoded and can survive url rewrite and argument parsing
|
||||
if (!empty($bdest)) {
|
||||
if ($bdest !== '') {
|
||||
$dest = hex2bin($bdest);
|
||||
$this->logger->debug('bdest detected', ['dest' => $dest]);
|
||||
}
|
||||
|
||||
$target = $dest ?: $addr;
|
||||
|
||||
if ($addr ?: $dest) {
|
||||
$contact = Contact::getByURL($addr ?: $dest);
|
||||
$contact = Contact::getByURL($addr ?: $dest);
|
||||
if ($contact === [] && $owa === 0) {
|
||||
$this->logger->info('No contact record found, no oWA, redirecting to destination.', ['request' => $request, 'server' => $_SERVER, 'dest' => $dest]);
|
||||
$this->appHelper->redirect($dest);
|
||||
}
|
||||
|
||||
if (empty($contact)) {
|
||||
if (!$owa) {
|
||||
$this->logger->info('No contact record found, no oWA, redirecting to destination.', ['request' => $request, 'server' => $_SERVER, 'dest' => $dest]);
|
||||
$this->appHelper->redirect($dest);
|
||||
}
|
||||
} else {
|
||||
if ($contact !== []) {
|
||||
// Redirect if the contact is already authenticated on this site.
|
||||
if ($this->appHelper->getContactId() && strpos($contact['nurl'], Strings::normaliseLink($this->baseUrl)) !== false) {
|
||||
$this->logger->info('Contact is already authenticated, redirecting to destination.', ['dest' => $dest]);
|
||||
|
@ -99,7 +94,7 @@ class Magic extends BaseModule
|
|||
$this->logger->debug('Contact found', ['url' => $contact['url']]);
|
||||
}
|
||||
|
||||
if (!$this->userSession->getLocalUserId() || !$owa) {
|
||||
if (!$this->userSession->getLocalUserId() || $owa === 0) {
|
||||
$this->logger->notice('Not logged in or not OWA, redirecting to destination.', ['uid' => $this->userSession->getLocalUserId(), 'owa' => $owa, 'dest' => $dest]);
|
||||
$this->appHelper->redirect($dest);
|
||||
}
|
||||
|
|
|
@ -48,15 +48,18 @@ class Active extends BaseUsers
|
|||
{
|
||||
parent::content();
|
||||
|
||||
$action = $this->parameters['action'] ?? '';
|
||||
$uid = $this->parameters['uid'] ?? 0;
|
||||
$action = (string) $this->parameters['action'] ?? '';
|
||||
$uid = (int) $this->parameters['uid'] ?? 0;
|
||||
|
||||
if ($uid) {
|
||||
$user = User::getById($uid, ['username', 'blocked']);
|
||||
if (!$user) {
|
||||
$this->systemMessages->addNotice($this->t('User not found'));
|
||||
$this->baseUrl->redirect('moderation/users');
|
||||
}
|
||||
if ($uid === 0) {
|
||||
$this->systemMessages->addNotice($this->t('User not found'));
|
||||
$this->baseUrl->redirect('moderation/users');
|
||||
}
|
||||
|
||||
$user = User::getById($uid, ['username', 'blocked']);
|
||||
if (!is_array($user)) {
|
||||
$this->systemMessages->addNotice($this->t('User not found'));
|
||||
$this->baseUrl->redirect('moderation/users');
|
||||
}
|
||||
|
||||
switch ($action) {
|
||||
|
|
|
@ -48,15 +48,18 @@ class Blocked extends BaseUsers
|
|||
{
|
||||
parent::content();
|
||||
|
||||
$action = $this->parameters['action'] ?? '';
|
||||
$uid = $this->parameters['uid'] ?? 0;
|
||||
$action = (string) $this->parameters['action'] ?? '';
|
||||
$uid = (int) $this->parameters['uid'] ?? 0;
|
||||
|
||||
if ($uid) {
|
||||
$user = User::getById($uid, ['username', 'blocked']);
|
||||
if (!$user) {
|
||||
$this->systemMessages->addNotice($this->t('User not found'));
|
||||
$this->baseUrl->redirect('moderation/users');
|
||||
}
|
||||
if ($uid === 0) {
|
||||
$this->systemMessages->addNotice($this->t('User not found'));
|
||||
$this->baseUrl->redirect('moderation/users');
|
||||
}
|
||||
|
||||
$user = User::getById($uid, ['username', 'blocked']);
|
||||
if (!is_array($user)) {
|
||||
$this->systemMessages->addNotice($this->t('User not found'));
|
||||
$this->baseUrl->redirect('moderation/users');
|
||||
}
|
||||
|
||||
switch ($action) {
|
||||
|
|
|
@ -55,15 +55,18 @@ class Index extends BaseUsers
|
|||
{
|
||||
parent::content();
|
||||
|
||||
$action = $this->parameters['action'] ?? '';
|
||||
$uid = $this->parameters['uid'] ?? 0;
|
||||
$action = (string) $this->parameters['action'] ?? '';
|
||||
$uid = (int) $this->parameters['uid'] ?? 0;
|
||||
|
||||
if ($uid) {
|
||||
$user = User::getById($uid, ['username', 'blocked']);
|
||||
if (!$user) {
|
||||
$this->systemMessages->addNotice($this->t('User not found'));
|
||||
$this->baseUrl->redirect('moderation/users');
|
||||
}
|
||||
if ($uid === 0) {
|
||||
$this->systemMessages->addNotice($this->t('User not found'));
|
||||
$this->baseUrl->redirect('moderation/users');
|
||||
}
|
||||
|
||||
$user = User::getById($uid, ['username', 'blocked']);
|
||||
if (!is_array($user)) {
|
||||
$this->systemMessages->addNotice($this->t('User not found'));
|
||||
$this->baseUrl->redirect('moderation/users');
|
||||
}
|
||||
|
||||
switch ($action) {
|
||||
|
|
|
@ -66,32 +66,52 @@ class Token extends BaseApi
|
|||
$this->logAndJsonError(401, $this->errorFactory->Unauthorized('invalid_client', $this->t('Invalid data or unknown client')));
|
||||
}
|
||||
|
||||
if ($request['grant_type'] == 'client_credentials') {
|
||||
// the "client_credentials" are used as a token for the application itself.
|
||||
// see https://aaronparecki.com/oauth-2-simplified/#client-credentials
|
||||
$token = OAuth::createTokenForUser($application, 0, '');
|
||||
$me = null;
|
||||
} elseif ($request['grant_type'] == 'authorization_code') {
|
||||
// For security reasons only allow freshly created tokens
|
||||
$redirect_uri = strtok($request['redirect_uri'],'?');
|
||||
$condition = [
|
||||
"`redirect_uri` LIKE ? AND `id` = ? AND `code` = ? AND `created_at` > ?",
|
||||
$redirect_uri, $application['id'], $request['code'], DateTimeFormat::utc('now - 5 minutes')
|
||||
];
|
||||
$grant_type = (string) $request['grant_type'];
|
||||
|
||||
$token = DBA::selectFirst('application-view', ['access_token', 'created_at', 'uid'], $condition);
|
||||
if (!DBA::isResult($token)) {
|
||||
$this->logger->notice('Token not found or outdated', $condition);
|
||||
$this->logAndJsonError(401, $this->errorFactory->Unauthorized());
|
||||
}
|
||||
$owner = User::getOwnerDataById($token['uid']);
|
||||
$me = $owner['url'];
|
||||
} else {
|
||||
if (!in_array($grant_type, ['client_credentials', 'authorization_code'])) {
|
||||
Logger::warning('Unsupported or missing grant type', ['request' => $_REQUEST]);
|
||||
$this->logAndJsonError(422, $this->errorFactory->UnprocessableEntity($this->t('Unsupported or missing grant type')));
|
||||
}
|
||||
|
||||
$object = new \Friendica\Object\Api\Mastodon\Token($token['access_token'], 'Bearer', $application['scopes'], $token['created_at'], $me);
|
||||
if ($grant_type === 'client_credentials') {
|
||||
// the "client_credentials" are used as a token for the application itself.
|
||||
// see https://aaronparecki.com/oauth-2-simplified/#client-credentials
|
||||
$token = OAuth::createTokenForUser($application, 0, '');
|
||||
|
||||
$object = new \Friendica\Object\Api\Mastodon\Token(
|
||||
$token['access_token'],
|
||||
'Bearer',
|
||||
$application['scopes'],
|
||||
$token['created_at'],
|
||||
null
|
||||
);
|
||||
|
||||
$this->jsonExit($object->toArray());
|
||||
}
|
||||
|
||||
// now check for $grant_type === 'authorization_code'
|
||||
// For security reasons only allow freshly created tokens
|
||||
$redirect_uri = strtok($request['redirect_uri'],'?');
|
||||
$condition = [
|
||||
"`redirect_uri` LIKE ? AND `id` = ? AND `code` = ? AND `created_at` > ?",
|
||||
$redirect_uri, $application['id'], $request['code'], DateTimeFormat::utc('now - 5 minutes')
|
||||
];
|
||||
|
||||
$token = DBA::selectFirst('application-view', ['access_token', 'created_at', 'uid'], $condition);
|
||||
if (!DBA::isResult($token)) {
|
||||
$this->logger->notice('Token not found or outdated', $condition);
|
||||
$this->logAndJsonError(401, $this->errorFactory->Unauthorized());
|
||||
}
|
||||
|
||||
$owner = User::getOwnerDataById($token['uid']);
|
||||
|
||||
$object = new \Friendica\Object\Api\Mastodon\Token(
|
||||
$token['access_token'],
|
||||
'Bearer',
|
||||
$application['scopes'],
|
||||
$token['created_at'],
|
||||
$owner['url']
|
||||
);
|
||||
|
||||
$this->jsonExit($object->toArray());
|
||||
}
|
||||
|
|
|
@ -142,7 +142,9 @@ class Photo extends BaseApi
|
|||
|
||||
$cacheable = ($photo['allow_cid'] . $photo['allow_gid'] . $photo['deny_cid'] . $photo['deny_gid'] === '') && (isset($photo['cacheable']) ? $photo['cacheable'] : true);
|
||||
|
||||
$stamp = microtime(true);
|
||||
$stamp = microtime(true);
|
||||
$imgdata = '';
|
||||
$mimetype = false;
|
||||
|
||||
if (empty($request['blur']) || empty($photo['blurhash'])) {
|
||||
$imgdata = MPhoto::getImageDataForPhoto($photo);
|
||||
|
@ -150,7 +152,9 @@ class Photo extends BaseApi
|
|||
}
|
||||
if (empty($imgdata) && empty($photo['blurhash'])) {
|
||||
throw new HTTPException\NotFoundException();
|
||||
} elseif (empty($imgdata) && !empty($photo['blurhash'])) {
|
||||
}
|
||||
|
||||
if (empty($imgdata) && !empty($photo['blurhash'])) {
|
||||
$image = new Image('', image_type_to_mime_type(IMAGETYPE_WEBP));
|
||||
$image->getFromBlurHash($photo['blurhash'], $photo['width'], $photo['height']);
|
||||
$imgdata = $image->asString();
|
||||
|
@ -376,6 +380,9 @@ class Photo extends BaseApi
|
|||
Logger::debug('Expected Content-Type', ['mime' => $mimetext, 'url' => $url]);
|
||||
}
|
||||
}
|
||||
|
||||
$url = '';
|
||||
|
||||
if (empty($mimetext) && !empty($contact['blurhash'])) {
|
||||
$image = new Image('', image_type_to_mime_type(IMAGETYPE_WEBP));
|
||||
$image->getFromBlurHash($contact['blurhash'], $customsize, $customsize);
|
||||
|
|
|
@ -77,10 +77,11 @@ class Remove extends \Friendica\BaseModule
|
|||
|
||||
$tag_text = Tag::getCSVByURIId($item['uri-id']);
|
||||
|
||||
$tags = explode(',', $tag_text);
|
||||
if (empty($tags)) {
|
||||
if ($tag_text === '') {
|
||||
$this->baseUrl->redirect($returnUrl);
|
||||
}
|
||||
|
||||
$tags = explode(',', $tag_text);
|
||||
|
||||
$tag_checkboxes = array_map(function ($tag_text) {
|
||||
return ['tag[' . bin2hex($tag_text) . ']', BBCode::toPlaintext($tag_text)];
|
||||
|
|
|
@ -127,7 +127,11 @@ class Photos extends \Friendica\Module\BaseProfile
|
|||
$visible = 0;
|
||||
}
|
||||
|
||||
$ret = ['src' => '', 'filename' => '', 'filesize' => 0, 'type' => ''];
|
||||
$ret = ['src' => '', 'filename' => '', 'filesize' => 0, 'type' => ''];
|
||||
$src = null;
|
||||
$filename = '';
|
||||
$filesize = 0;
|
||||
$type = '';
|
||||
|
||||
Hook::callAll('photo_post_file', $ret);
|
||||
|
||||
|
@ -167,7 +171,11 @@ class Photos extends \Friendica\Module\BaseProfile
|
|||
$this->systemMessages->addNotice($this->t('Server can\'t accept new file upload at this time, please contact your administrator'));
|
||||
break;
|
||||
}
|
||||
@unlink($src);
|
||||
|
||||
if ($src !== null) {
|
||||
@unlink($src);
|
||||
}
|
||||
|
||||
$foo = 0;
|
||||
Hook::callAll('photo_post_end', $foo);
|
||||
return;
|
||||
|
|
|
@ -96,7 +96,7 @@ class Trust extends BaseModule
|
|||
// exception wanted!
|
||||
throw $e;
|
||||
} catch (\Exception $e) {
|
||||
$this->logger->warning('Unexpected error during authentication.', ['user' => $this->session->getLocalUserId(), 'exception' => $exception]);
|
||||
$this->logger->warning('Unexpected error during authentication.', ['user' => $this->session->getLocalUserId(), 'exception' => $e]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -46,9 +46,6 @@ class Crop extends BaseSettings
|
|||
$base_image = Photo::selectFirst([], ['resource-id' => $resource_id, 'uid' => DI::userSession()->getLocalUserId(), 'scale' => $scale]);
|
||||
if (DBA::isResult($base_image)) {
|
||||
$Image = Photo::getImageForPhoto($base_image);
|
||||
if (empty($Image)) {
|
||||
throw new HTTPException\InternalServerErrorException();
|
||||
}
|
||||
|
||||
if ($Image->isValid()) {
|
||||
// If setting for the default profile, unset the profile photo flag from any other photos I own
|
||||
|
@ -185,7 +182,7 @@ class Crop extends BaseSettings
|
|||
}
|
||||
|
||||
$Image = Photo::getImageForPhoto($photos[0]);
|
||||
if (empty($Image)) {
|
||||
if (!$Image->isValid()) {
|
||||
throw new HTTPException\InternalServerErrorException();
|
||||
}
|
||||
|
||||
|
|
|
@ -92,8 +92,6 @@ class RemoveMe extends BaseSettings
|
|||
$this->baseUrl->redirect();
|
||||
} catch (\RuntimeException $e) {
|
||||
$this->systemMessages->addNotice($e->getMessage());
|
||||
} finally {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -64,6 +64,8 @@ class Xrd extends BaseModule
|
|||
|
||||
header('Vary: Accept', false);
|
||||
|
||||
$alias = '';
|
||||
|
||||
if ($name == User::getActorName()) {
|
||||
$owner = User::getSystemAccount();
|
||||
if (empty($owner)) {
|
||||
|
@ -108,7 +110,7 @@ class Xrd extends BaseModule
|
|||
$parts[] = current(explode(';', $part));
|
||||
}
|
||||
|
||||
if (empty($parts)) {
|
||||
if ($parts === []) {
|
||||
return $default;
|
||||
} elseif (in_array('application/jrd+json', $parts) && !in_array('application/xrd+xml', $parts)) {
|
||||
return Response::TYPE_JSON;
|
||||
|
|
|
@ -41,13 +41,13 @@ class FormattedNotify extends BaseDataTransferObject
|
|||
|
||||
public function __construct(string $label, string $link, string $image, string $url, string $text, string $when, string $ago, bool $seen)
|
||||
{
|
||||
$this->label = $label ?? '';
|
||||
$this->link = $link ?? '';
|
||||
$this->image = $image ?? '';
|
||||
$this->url = $url ?? '';
|
||||
$this->text = $text ?? '';
|
||||
$this->when = $when ?? '';
|
||||
$this->ago = $ago ?? '';
|
||||
$this->seen = $seen ?? false;
|
||||
$this->label = $label;
|
||||
$this->link = $link;
|
||||
$this->image = $image;
|
||||
$this->url = $url;
|
||||
$this->text = $text;
|
||||
$this->when = $when;
|
||||
$this->ago = $ago;
|
||||
$this->seen = $seen;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -220,14 +220,16 @@ class Probe
|
|||
Logger::notice('Got exception', ['code' => $th->getCode(), 'message' => $th->getMessage()]);
|
||||
return [];
|
||||
}
|
||||
|
||||
$ssl_connection_error = ($curlResult->getErrorNumber() == CURLE_COULDNT_CONNECT) || ($curlResult->getReturnCode() == 0);
|
||||
|
||||
$host_url = $host;
|
||||
|
||||
if ($curlResult->isSuccess()) {
|
||||
$xml = $curlResult->getBodyString();
|
||||
$xrd = XML::parseString($xml, true);
|
||||
if (!empty($url)) {
|
||||
$host_url = 'https://' . $host;
|
||||
} else {
|
||||
$host_url = $host;
|
||||
}
|
||||
} elseif ($curlResult->isTimeout()) {
|
||||
Logger::info('Probing timeout', ['url' => $ssl_url]);
|
||||
|
@ -550,6 +552,7 @@ class Probe
|
|||
public static function getWebfingerArray(string $uri): array
|
||||
{
|
||||
$parts = parse_url($uri);
|
||||
$lrdd = [];
|
||||
|
||||
if (!empty($parts['scheme']) && !empty($parts['host'])) {
|
||||
$host = $parts['host'];
|
||||
|
@ -562,8 +565,11 @@ class Probe
|
|||
$nick = '';
|
||||
$addr = '';
|
||||
|
||||
$path_parts = explode('/', trim($parts['path'] ?? '', '/'));
|
||||
if (!empty($path_parts)) {
|
||||
$path_parts = [];
|
||||
|
||||
if (array_key_exists('path', $parts) && trim(strval($parts['path']), '/') !== '') {
|
||||
$path_parts = explode('/', trim($parts['path'], '/'));
|
||||
|
||||
$nick = ltrim(end($path_parts), '@');
|
||||
$addr = $nick . '@' . $host;
|
||||
}
|
||||
|
@ -574,7 +580,7 @@ class Probe
|
|||
}
|
||||
|
||||
if (empty($webfinger) && empty($lrdd)) {
|
||||
while (empty($lrdd) && empty($webfinger) && (sizeof($path_parts) > 1)) {
|
||||
while (empty($lrdd) && empty($webfinger) && (count($path_parts) > 1)) {
|
||||
$host .= '/' . array_shift($path_parts);
|
||||
$baseurl = $parts['scheme'] . '://' . $host;
|
||||
|
||||
|
@ -668,8 +674,10 @@ class Probe
|
|||
return null;
|
||||
}
|
||||
|
||||
$detected = '';
|
||||
|
||||
// First try the address because this is the primary purpose of webfinger
|
||||
if (!empty($addr)) {
|
||||
if ($addr !== '') {
|
||||
$detected = $addr;
|
||||
$path = str_replace('{uri}', urlencode('acct:' . $addr), $template);
|
||||
$webfinger = self::webfinger($path, $type);
|
||||
|
@ -823,13 +831,15 @@ class Probe
|
|||
*/
|
||||
private static function zot(array $webfinger, array $data): array
|
||||
{
|
||||
$zot_url = '';
|
||||
|
||||
foreach ($webfinger['links'] as $link) {
|
||||
if (($link['rel'] == 'http://purl.org/zot/protocol/6.0') && !empty($link['href'])) {
|
||||
$zot_url = $link['href'];
|
||||
}
|
||||
}
|
||||
|
||||
if (empty($zot_url)) {
|
||||
if ($zot_url === '') {
|
||||
return $data;
|
||||
}
|
||||
|
||||
|
@ -871,7 +881,7 @@ class Probe
|
|||
$data['url'] = $link['href'];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
$data = self::pollZot($zot_url, $data);
|
||||
|
||||
if (!empty($data['url']) && !empty($webfinger['aliases']) && is_array($webfinger['aliases'])) {
|
||||
|
@ -1429,7 +1439,7 @@ class Probe
|
|||
&& !empty($data['guid'])
|
||||
&& !empty($data['baseurl'])
|
||||
&& !empty($data['pubkey'])
|
||||
&& !empty($hcard_url)
|
||||
&& $hcard_url !== ''
|
||||
) {
|
||||
$data['network'] = Protocol::DIASPORA;
|
||||
$data['manually-approve'] = false;
|
||||
|
@ -1776,7 +1786,7 @@ class Probe
|
|||
$password = '';
|
||||
openssl_private_decrypt(hex2bin($mailacct['pass']), $password, $user['prvkey']);
|
||||
$mbox = Email::connect($mailbox, $mailacct['user'], $password);
|
||||
if (!$mbox) {
|
||||
if ($mbox === false) {
|
||||
return [];
|
||||
}
|
||||
|
||||
|
@ -1828,7 +1838,7 @@ class Probe
|
|||
}
|
||||
}
|
||||
|
||||
if (!empty($mbox)) {
|
||||
if ($mbox !== false) {
|
||||
imap_close($mbox);
|
||||
}
|
||||
|
||||
|
|
|
@ -62,7 +62,7 @@ class User extends BaseDataTransferObject
|
|||
protected $default_profile;
|
||||
/** @var bool */
|
||||
protected $default_profile_image;
|
||||
/** @var Status */
|
||||
/** @var array */
|
||||
protected $status;
|
||||
/** @var array */
|
||||
protected $withheld_in_countries;
|
||||
|
@ -117,12 +117,11 @@ class User extends BaseDataTransferObject
|
|||
* @param array $publicContact Full contact table record with uid = 0
|
||||
* @param array $apcontact Optional full apcontact table record
|
||||
* @param array $userContact Optional full contact table record with uid != 0
|
||||
* @param null $status
|
||||
* @param bool $include_user_entities Whether to add the entities property
|
||||
*
|
||||
* @throws InternalServerErrorException
|
||||
*/
|
||||
public function __construct(array $publicContact, array $apcontact = [], array $userContact = [], $status = null, bool $include_user_entities = true)
|
||||
public function __construct(array $publicContact, array $apcontact = [], array $userContact = [], ?Status $status = null, bool $include_user_entities = true)
|
||||
{
|
||||
$uid = $userContact['uid'] ?? 0;
|
||||
|
||||
|
@ -156,10 +155,10 @@ class User extends BaseDataTransferObject
|
|||
$this->default_profile = false;
|
||||
$this->default_profile_image = false;
|
||||
|
||||
if (!empty($status)) {
|
||||
$this->status = $status;
|
||||
} else {
|
||||
if ($status === null) {
|
||||
unset($this->status);
|
||||
} else {
|
||||
$this->status = $status->toArray();
|
||||
}
|
||||
|
||||
// Unused optional fields
|
||||
|
|
|
@ -771,7 +771,7 @@ class Image
|
|||
public function getBlurHash(): string
|
||||
{
|
||||
$image = New Image($this->asString(), $this->getType(), $this->filename, false);
|
||||
if (empty($image) || !$this->isValid()) {
|
||||
if (!$this->isValid()) {
|
||||
return '';
|
||||
}
|
||||
|
||||
|
@ -827,6 +827,7 @@ class Image
|
|||
{
|
||||
$scaled = Images::getScalingDimensions($width, $height, 90);
|
||||
$pixels = Blurhash::decode($blurhash, $scaled['width'], $scaled['height']);
|
||||
$draw = null;
|
||||
|
||||
if ($this->isImagick()) {
|
||||
$this->image = new Imagick();
|
||||
|
@ -839,7 +840,7 @@ class Image
|
|||
for ($y = 0; $y < $scaled['height']; ++$y) {
|
||||
for ($x = 0; $x < $scaled['width']; ++$x) {
|
||||
[$r, $g, $b] = $pixels[$y][$x];
|
||||
if ($this->isImagick()) {
|
||||
if ($draw !== null) {
|
||||
$draw->setFillColor("rgb($r, $g, $b)");
|
||||
$draw->point($x, $y);
|
||||
} else {
|
||||
|
@ -848,7 +849,7 @@ class Image
|
|||
}
|
||||
}
|
||||
|
||||
if ($this->isImagick()) {
|
||||
if ($draw !== null) {
|
||||
$this->image->drawImage($draw);
|
||||
$this->width = $this->image->getImageWidth();
|
||||
$this->height = $this->image->getImageHeight();
|
||||
|
|
|
@ -323,7 +323,7 @@ class ClientToServer
|
|||
$requester_id = Contact::getIdForURL($requester, $owner['uid']);
|
||||
if (!empty($requester_id)) {
|
||||
$permissionSets = DI::permissionSet()->selectByContactId($requester_id, $owner['uid']);
|
||||
if (!empty($permissionSets)) {
|
||||
if (count($permissionSets) > 0) {
|
||||
$condition = ['psid' => array_merge($permissionSets->column('id'),
|
||||
[DI::permissionSet()->selectPublicForUser($owner['uid'])])];
|
||||
}
|
||||
|
|
|
@ -42,6 +42,8 @@ class Delivery
|
|||
continue;
|
||||
}
|
||||
|
||||
$result = [];
|
||||
|
||||
if (!$serverfail) {
|
||||
$result = self::deliverToInbox($post['command'], 0, $inbox, $owner, $post['receivers'], $post['uri-id']);
|
||||
|
||||
|
@ -121,11 +123,12 @@ class Delivery
|
|||
$serverfail = $response->isTimeout();
|
||||
} catch (\Throwable $th) {
|
||||
Logger::notice('Got exception', ['code' => $th->getCode(), 'message' => $th->getMessage()]);
|
||||
$response = null;
|
||||
$success = false;
|
||||
$serverfail = true;
|
||||
}
|
||||
$runtime = microtime(true) - $timestamp;
|
||||
if (!$success) {
|
||||
if ($success === false) {
|
||||
// 5xx errors are problems on the server. We don't need to continue delivery then.
|
||||
if (!$serverfail && ($response->getReturnCode() >= 500) && ($response->getReturnCode() <= 599)) {
|
||||
$serverfail = true;
|
||||
|
|
|
@ -520,7 +520,7 @@ class Processor
|
|||
if (!DI::config()->get('system', 'decoupled_receiver')) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
$replies = [$item['thr-parent']];
|
||||
if (!empty($item['parent-uri'])) {
|
||||
$replies[] = $item['parent-uri'];
|
||||
|
@ -561,7 +561,7 @@ class Processor
|
|||
if (in_array($activity['reply-to-id'], $activity['children'] ?? [])) {
|
||||
Logger::notice('reply-to-id is already in the list of children', ['id' => $activity['reply-to-id'], 'children' => $activity['children'], 'depth' => count($activity['children'])]);
|
||||
return '';
|
||||
}
|
||||
}
|
||||
|
||||
self::addActivityId($activity['reply-to-id']);
|
||||
|
||||
|
@ -1361,6 +1361,7 @@ class Processor
|
|||
}
|
||||
|
||||
$hash = substr($tag['name'], 0, 1);
|
||||
$type = 0;
|
||||
|
||||
if ($tag['type'] == 'Mention') {
|
||||
if (in_array($hash, [Tag::TAG_CHARACTER[Tag::MENTION],
|
||||
|
@ -1616,7 +1617,7 @@ class Processor
|
|||
return [];
|
||||
}
|
||||
|
||||
if (!self::isValidObject($object, $url)) {
|
||||
if (!self::isValidObject($object)) {
|
||||
return [];
|
||||
}
|
||||
|
||||
|
@ -1657,10 +1658,6 @@ class Processor
|
|||
return '';
|
||||
}
|
||||
|
||||
if (empty($curlResult)) {
|
||||
return '';
|
||||
}
|
||||
|
||||
$body = $curlResult->getBodyString();
|
||||
if (!$curlResult->isSuccess() || empty($body)) {
|
||||
if (in_array($curlResult->getReturnCode(), [403, 404, 406, 410])) {
|
||||
|
@ -1680,7 +1677,7 @@ class Processor
|
|||
return null;
|
||||
}
|
||||
|
||||
if (!self::isValidObject($object, $url)) {
|
||||
if (!self::isValidObject($object)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
@ -1747,7 +1744,7 @@ class Processor
|
|||
$ldactivity['children'] = $child['children'] ?? [];
|
||||
$ldactivity['callstack'] = $child['callstack'] ?? [];
|
||||
// This check is mostly superfluous, since there are similar checks before. This covers the case, when the fetched id doesn't match the url
|
||||
if (in_array($activity['id'], $ldactivity['children'])) {
|
||||
if (in_array($activity['id'], $ldactivity['children'])) {
|
||||
Logger::notice('Fetched id is already in the list of children. It will not be processed.', ['id' => $activity['id'], 'children' => $ldactivity['children'], 'depth' => count($ldactivity['children'])]);
|
||||
return null;
|
||||
}
|
||||
|
@ -1829,6 +1826,8 @@ class Processor
|
|||
Logger::notice('Fetch replies - start', ['replies' => $url, 'callstack' => $child['callstack'], 'system' => $callstack]);
|
||||
$fetched = 0;
|
||||
foreach ($replies as $reply) {
|
||||
$id = '';
|
||||
|
||||
if (is_array($reply)) {
|
||||
$ldobject = JsonLD::compact($reply);
|
||||
$id = JsonLD::fetchElement($ldobject, '@id');
|
||||
|
@ -2120,9 +2119,8 @@ class Processor
|
|||
self::transmitPendingEvents($cid, $owner['uid']);
|
||||
}
|
||||
|
||||
if (empty($contact)) {
|
||||
Contact::update(['hub-verify' => $activity['id'], 'protocol' => Protocol::ACTIVITYPUB], ['id' => $cid]);
|
||||
}
|
||||
Contact::update(['hub-verify' => $activity['id'], 'protocol' => Protocol::ACTIVITYPUB], ['id' => $cid]);
|
||||
|
||||
Logger::notice('Follow user ' . $uid . ' from contact ' . $cid . ' with id ' . $activity['id']);
|
||||
Queue::remove($activity);
|
||||
}
|
||||
|
@ -2334,9 +2332,10 @@ class Processor
|
|||
*/
|
||||
public static function acceptFollowUser(array $activity)
|
||||
{
|
||||
$check_id = false;
|
||||
|
||||
if (!empty($activity['object_actor'])) {
|
||||
$uid = User::getIdForURL($activity['object_actor']);
|
||||
$check_id = false;
|
||||
} elseif (!empty($activity['receiver']) && (count($activity['receiver']) == 1)) {
|
||||
$uid = array_shift($activity['receiver']);
|
||||
$check_id = true;
|
||||
|
|
|
@ -414,7 +414,7 @@ class Queue
|
|||
{
|
||||
$entries = DBA::select('inbox-entry', ['id'], ["NOT `trust` AND `wid` IS NULL"], ['order' => ['id' => true]]);
|
||||
while ($entry = DBA::fetch($entries)) {
|
||||
$data = self::reprepareActivityById($entry['id'], false);
|
||||
$data = self::reprepareActivityById($entry['id']);
|
||||
if ($data['trust']) {
|
||||
DBA::update('inbox-entry', ['trust' => true], ['id' => $entry['id']]);
|
||||
}
|
||||
|
|
|
@ -304,9 +304,10 @@ class Receiver
|
|||
*/
|
||||
public static function prepareObjectData(array $activity, int $uid, bool $push, bool &$trust_source, string $original_actor = ''): array
|
||||
{
|
||||
$id = JsonLD::fetchElement($activity, '@id');
|
||||
$type = JsonLD::fetchElement($activity, '@type');
|
||||
$object_id = JsonLD::fetchElement($activity, 'as:object', '@id');
|
||||
$id = JsonLD::fetchElement($activity, '@id');
|
||||
$type = JsonLD::fetchElement($activity, '@type');
|
||||
$object_id = JsonLD::fetchElement($activity, 'as:object', '@id');
|
||||
$object_type = '';
|
||||
|
||||
if (!empty($object_id) && in_array($type, ['as:Create', 'as:Update'])) {
|
||||
$fetch_id = $object_id;
|
||||
|
@ -618,7 +619,7 @@ class Receiver
|
|||
}
|
||||
|
||||
$actor = JsonLD::fetchElement($activity, 'as:actor', '@id');
|
||||
if (empty($actor)) {
|
||||
if ($actor === null || $actor === '') {
|
||||
Logger::info('Empty actor', ['activity' => $activity]);
|
||||
return true;
|
||||
}
|
||||
|
@ -630,7 +631,7 @@ class Receiver
|
|||
$id = JsonLD::fetchElement($activity, '@id');
|
||||
$object_id = JsonLD::fetchElement($activity, 'as:object', '@id');
|
||||
|
||||
if (!empty($published) && !empty($object_id) && in_array($type, ['as:Create', 'as:Update']) && in_array($object_type, self::CONTENT_TYPES)
|
||||
if (!empty($published) && $object_id !== null && in_array($type, ['as:Create', 'as:Update']) && in_array($object_type, self::CONTENT_TYPES)
|
||||
&& ($push || ($completion != self::COMPLETION_MANUAL)) && DI::contentItem()->isTooOld($published) && !Post::exists(['uri' => $object_id])) {
|
||||
Logger::debug('Activity is too old. It will not be processed', ['push' => $push, 'completion' => $completion, 'type' => $type, 'object-type' => $object_type, 'published' => $published, 'id' => $id, 'object-id' => $object_id]);
|
||||
return true;
|
||||
|
@ -641,7 +642,7 @@ class Receiver
|
|||
|
||||
// Test the provided signatures against the actor and "attributedTo"
|
||||
if ($trust_source) {
|
||||
if (!empty($attributed_to) && !empty($actor)) {
|
||||
if ($attributed_to !== false && $attributed_to !== '') {
|
||||
$trust_source = (in_array($actor, $signer) && in_array($attributed_to, $signer));
|
||||
} else {
|
||||
$trust_source = in_array($actor, $signer);
|
||||
|
@ -1185,6 +1186,8 @@ class Receiver
|
|||
}
|
||||
|
||||
$parent_followers = '';
|
||||
$parent_profile = [];
|
||||
|
||||
$parent = Post::selectFirstPost(['parent-author-link'], ['uri' => $reply]);
|
||||
if (!empty($parent['parent-author-link'])) {
|
||||
$parent_profile = APContact::getByURL($parent['parent-author-link']);
|
||||
|
|
|
@ -573,11 +573,12 @@ class Transmitter
|
|||
$exclusive = false;
|
||||
$mention = false;
|
||||
$audience = [];
|
||||
$owner = false;
|
||||
|
||||
// Check if we should always deliver our stuff via BCC
|
||||
if (!empty($item['uid'])) {
|
||||
$owner = User::getOwnerDataById($item['uid']);
|
||||
if (!empty($owner)) {
|
||||
if (is_array($owner)) {
|
||||
$always_bcc = $owner['hide-friends'];
|
||||
$is_group = ($owner['account-type'] == User::ACCOUNT_TYPE_COMMUNITY);
|
||||
|
||||
|
@ -1399,7 +1400,7 @@ class Transmitter
|
|||
$type = self::getTypeOfItem($item);
|
||||
|
||||
if (!$object_mode) {
|
||||
$data = ['@context' => $context ?? ActivityPub::CONTEXT];
|
||||
$data = ['@context' => ActivityPub::CONTEXT];
|
||||
|
||||
if ($item['deleted'] && ($item['gravity'] == Item::GRAVITY_ACTIVITY)) {
|
||||
$type = 'Undo';
|
||||
|
@ -1750,6 +1751,7 @@ class Transmitter
|
|||
|
||||
$title = $item['title'];
|
||||
$summary = $item['content-warning'] ?: BBCode::toPlaintext(BBCode::getAbstract($item['body'], Protocol::ACTIVITYPUB));
|
||||
$type = '';
|
||||
|
||||
if ($item['event-type'] == 'event') {
|
||||
$type = 'Event';
|
||||
|
|
|
@ -12,7 +12,6 @@ use Friendica\Contact\FriendSuggest\Exception\FriendSuggestNotFoundException;
|
|||
use Friendica\Core\Logger;
|
||||
use Friendica\Core\Protocol;
|
||||
use Friendica\Core\Worker;
|
||||
use Friendica\Database\Database;
|
||||
use Friendica\Database\DBA;
|
||||
use Friendica\DI;
|
||||
use Friendica\Model\Contact;
|
||||
|
@ -48,6 +47,8 @@ class Delivery
|
|||
$top_level = false;
|
||||
$followup = false;
|
||||
$public_message = false;
|
||||
$parent = false;
|
||||
$thr_parent = false;
|
||||
|
||||
$items = [];
|
||||
if ($cmd == self::MAIL) {
|
||||
|
|
|
@ -623,22 +623,21 @@ class Diaspora
|
|||
*/
|
||||
private static function validPosting(array $msg)
|
||||
{
|
||||
$data = XML::parseString($msg['message']);
|
||||
$element = XML::parseString($msg['message']);
|
||||
|
||||
if (!is_object($data)) {
|
||||
if (!is_object($element)) {
|
||||
Logger::info('No valid XML', ['message' => $msg['message']]);
|
||||
return false;
|
||||
}
|
||||
|
||||
$oldXML = false;
|
||||
|
||||
// Is this the new or the old version?
|
||||
if ($data->getName() == 'XML') {
|
||||
if ($element->getName() === 'XML') {
|
||||
$oldXML = true;
|
||||
foreach ($data->post->children() as $child) {
|
||||
foreach ($element->post->children() as $child) {
|
||||
$element = $child;
|
||||
}
|
||||
} else {
|
||||
$oldXML = false;
|
||||
$element = $data;
|
||||
}
|
||||
|
||||
$type = $element->getName();
|
||||
|
@ -1460,7 +1459,7 @@ class Diaspora
|
|||
*/
|
||||
|
||||
foreach ($matches as $match) {
|
||||
if (empty($match)) {
|
||||
if ($match === '') {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -3030,7 +3029,7 @@ class Diaspora
|
|||
// The "addr" field should always be filled.
|
||||
// If this isn't the case, it will raise a notice some lines later.
|
||||
// And in the log we will see where it came from, and we can handle it there.
|
||||
Logger::notice('Empty addr', ['contact' => $contact ?? []]);
|
||||
Logger::notice('Empty addr', ['contact' => $contact]);
|
||||
}
|
||||
|
||||
$envelope = self::buildMessage($msg, $owner, $contact, $owner['uprvkey'], $pubkey ?? '', $public_batch);
|
||||
|
@ -3655,6 +3654,8 @@ class Diaspora
|
|||
*/
|
||||
public static function sendFollowup(array $item, array $owner, array $contact, bool $public_batch = false): int
|
||||
{
|
||||
$type = '';
|
||||
|
||||
if (in_array($item['verb'], [Activity::ATTEND, Activity::ATTENDNO, Activity::ATTENDMAYBE])) {
|
||||
$message = self::constructAttend($item, $owner);
|
||||
$type = 'event_participation';
|
||||
|
|
|
@ -25,7 +25,7 @@ class Email
|
|||
* @param string $mailbox The mailbox name
|
||||
* @param string $username The username
|
||||
* @param string $password The password
|
||||
* @return Connection|resource|bool
|
||||
* @return Connection|false
|
||||
* @throws \Exception
|
||||
*/
|
||||
public static function connect(string $mailbox, string $username, string $password)
|
||||
|
|
|
@ -736,7 +736,7 @@ class Feed
|
|||
$publish_at = date(DateTimeFormat::MYSQL, $publish_time);
|
||||
|
||||
if (Post\Delayed::add($posting['item']['uri'], $posting['item'], $posting['notify'], Post\Delayed::PREPARED, $publish_at, $posting['taglist'], $posting['attachments'])) {
|
||||
DI::pConfig()->set($item['uid'], 'system', 'last_publish', $publish_time);
|
||||
DI::pConfig()->set($posting['item']['uid'], 'system', 'last_publish', $publish_time);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1407,7 +1407,7 @@ class Feed
|
|||
|
||||
$contact = Contact::getByURL($item['author-link']) ?: $owner;
|
||||
$contact['nickname'] = $contact['nickname'] ?? $contact['nick'];
|
||||
$author = self::addAuthor($doc, $contact, false);
|
||||
$author = self::addAuthor($doc, $contact);
|
||||
$entry->appendChild($author);
|
||||
}
|
||||
} else {
|
||||
|
|
|
@ -109,9 +109,9 @@ class NotifyMailBuilder extends MailBuilder
|
|||
public function withPhoto(string $image, string $link, string $name)
|
||||
{
|
||||
$this->photo = [
|
||||
'image' => $image ?? '',
|
||||
'link' => $link ?? '',
|
||||
'name' => $name ?? '',
|
||||
'image' => $image,
|
||||
'link' => $link,
|
||||
'name' => $name,
|
||||
];
|
||||
|
||||
return $this;
|
||||
|
|
|
@ -480,10 +480,6 @@ class HTTPSignature
|
|||
return [];
|
||||
}
|
||||
|
||||
if (empty($curlResult)) {
|
||||
return [];
|
||||
}
|
||||
|
||||
if (!$curlResult->isSuccess() || empty($curlResult->getBodyString())) {
|
||||
Logger::debug('Fetching was unsuccessful', ['url' => $request, 'return-code' => $curlResult->getReturnCode(), 'error-number' => $curlResult->getErrorNumber(), 'error' => $curlResult->getError()]);
|
||||
return [];
|
||||
|
|
|
@ -308,13 +308,13 @@ class Images
|
|||
|
||||
$data = DI::cache()->get($cacheKey);
|
||||
|
||||
if (empty($data) || !is_array($data)) {
|
||||
if (!is_array($data)) {
|
||||
$data = self::getInfoFromURL($url, $ocr);
|
||||
|
||||
DI::cache()->set($cacheKey, $data);
|
||||
}
|
||||
|
||||
return $data ?? [];
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -370,7 +370,7 @@ class Images
|
|||
|
||||
if ($image->isValid()) {
|
||||
$data['blurhash'] = $image->getBlurHash();
|
||||
|
||||
|
||||
if ($ocr) {
|
||||
$media = ['img_str' => $img_str];
|
||||
Hook::callAll('ocr-detection', $media);
|
||||
|
|
|
@ -286,7 +286,7 @@ class JsonLD
|
|||
* @param $type
|
||||
* @param $type_value
|
||||
*
|
||||
* @return string fetched element
|
||||
* @return string|null fetched element
|
||||
*/
|
||||
public static function fetchElement($array, $element, $key = '@id', $type = null, $type_value = null)
|
||||
{
|
||||
|
|
|
@ -1087,7 +1087,7 @@ class ParseUrl
|
|||
$content = JsonLD::fetchElement($jsonld, 'logo', 'url', '@type', 'ImageObject');
|
||||
if (!empty($content) && is_string($content)) {
|
||||
$jsonldinfo['publisher_img'] = trim($content);
|
||||
} elseif (!empty($content) && is_array($content)) {
|
||||
} elseif (is_array($content) && array_key_exists(0, $content)) {
|
||||
$jsonldinfo['publisher_img'] = trim($content[0]);
|
||||
}
|
||||
|
||||
|
|
|
@ -220,7 +220,7 @@ class OnePoll
|
|||
|
||||
Logger::info('Mail is enabled');
|
||||
|
||||
$mbox = null;
|
||||
$mbox = false;
|
||||
$user = DBA::selectFirst('user', ['prvkey'], ['uid' => $importer_uid]);
|
||||
|
||||
$condition = ["`server` != ? AND `user` != ? AND `port` != ? AND `uid` = ?", '', '', 0, $importer_uid];
|
||||
|
@ -232,17 +232,18 @@ class OnePoll
|
|||
$mbox = Email::connect($mailbox, $mailconf['user'], $password);
|
||||
unset($password);
|
||||
Logger::notice('Connect', ['user' => $mailconf['user']]);
|
||||
if ($mbox) {
|
||||
$fields = ['last_check' => $updated];
|
||||
DBA::update('mailacct', $fields, ['id' => $mailconf['id']]);
|
||||
Logger::notice('Connected', ['user' => $mailconf['user']]);
|
||||
} else {
|
||||
|
||||
if ($mbox === false) {
|
||||
Logger::notice('Connection error', ['user' => $mailconf['user'], 'error' => imap_errors()]);
|
||||
return false;
|
||||
}
|
||||
|
||||
$fields = ['last_check' => $updated];
|
||||
DBA::update('mailacct', $fields, ['id' => $mailconf['id']]);
|
||||
Logger::notice('Connected', ['user' => $mailconf['user']]);
|
||||
}
|
||||
|
||||
if (empty($mbox)) {
|
||||
if ($mbox === false) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue