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

This commit is contained in:
Michael
2019-09-30 06:30:13 +00:00
50 changed files with 16732 additions and 15722 deletions
+3 -2
View File
@@ -106,15 +106,16 @@ class Mode
/**
* Checks if the site is called via a backend process
*
* @param bool $isBackend True, if the call is from a backend script (daemon, worker, ...)
* @param Module $module The pre-loaded module (just name, not class!)
* @param array $server The $_SERVER variable
* @param MobileDetect $mobileDetect The mobile detection library
*
* @return Mode returns the determined mode
*/
public function determineRunMode(Module $module, array $server, MobileDetect $mobileDetect)
public function determineRunMode(bool $isBackend, Module $module, array $server, MobileDetect $mobileDetect)
{
$isBackend = basename(($server['PHP_SELF'] ?? ''), '.php') !== 'index' ||
$isBackend = $isBackend ||
$module->isBackend();
$isMobile = $mobileDetect->isMobile();
$isTablet = $mobileDetect->isTablet();
+13 -8
View File
@@ -129,16 +129,13 @@ HELP;
$config_file = $this->getOption(['f', 'file']);
if (!empty($config_file)) {
if ($config_file != 'config' . DIRECTORY_SEPARATOR . 'local.config.php') {
// Copy config file
$this->out("Copying config file...\n");
if (!copy($basePathConf . DIRECTORY_SEPARATOR . $config_file, $basePathConf . DIRECTORY_SEPARATOR . 'config' . DIRECTORY_SEPARATOR . 'local.config.php')) {
throw new RuntimeException("ERROR: Saving config file failed. Please copy '$config_file' to '" . $basePathConf . "'" . DIRECTORY_SEPARATOR . "config" . DIRECTORY_SEPARATOR . "local.config.php' manually.\n");
}
if (!file_exists($config_file)) {
throw new RuntimeException("ERROR: Config file does not exist.\n");
}
//reload the config cache
$loader = new ConfigFileLoader($basePathConf);
$loader = new ConfigFileLoader($config_file);
$loader->setupCache($configCache);
} else {
@@ -195,7 +192,7 @@ HELP;
$installer->createConfig($configCache);
}
$this->out(" Complete!\n\n");
$this->out("Complete!\n\n");
// Check database connection
$this->out("Checking database...\n");
@@ -219,6 +216,14 @@ HELP;
throw new RuntimeException($errorMessage);
}
if (!empty($config_file) && $config_file != 'config' . DIRECTORY_SEPARATOR . 'local.config.php') {
// Copy config file
$this->out("Copying config file...\n");
if (!copy($basePathConf . DIRECTORY_SEPARATOR . $config_file, $basePathConf . DIRECTORY_SEPARATOR . 'config' . DIRECTORY_SEPARATOR . 'local.config.php')) {
throw new RuntimeException("ERROR: Saving config file failed. Please copy '$config_file' to '" . $basePathConf . "'" . DIRECTORY_SEPARATOR . "config" . DIRECTORY_SEPARATOR . "local.config.php' manually.\n");
}
}
$this->out(" Complete!\n\n");
// Install theme
+5 -2
View File
@@ -1466,6 +1466,11 @@ class BBCode extends BaseObject
$text = str_replace('[hr]', '<hr />', $text);
if (!$for_plaintext) {
// Autolinker for isolated URLs
$text = preg_replace(Strings::autoLinkRegEx(), '[url]$1[/url]', $text);
}
// This is actually executed in Item::prepareBody()
$nosmile = strpos($text, '[nosmile]') !== false;
@@ -1648,9 +1653,7 @@ class BBCode extends BaseObject
$text = Smilies::replace($text);
}
// if the HTML is used to generate plain text, then don't do this search, but replace all URL of that kind to text
if (!$for_plaintext) {
$text = preg_replace(Strings::autoLinkRegEx(), '[url]$1[/url]', $text);
if (in_array($simple_html, [7, 9])) {
$text = preg_replace_callback("/\[url\](.*?)\[\/url\]/ism", 'self::convertUrlForOStatusCallback', $text);
$text = preg_replace_callback("/\[url\=(.*?)\](.*?)\[\/url\]/ism", 'self::convertUrlForOStatusCallback', $text);
+28 -10
View File
@@ -42,14 +42,32 @@ class HTML
return $cleaned;
}
private static function tagToBBCode(DOMDocument $doc, $tag, $attributes, $startbb, $endbb)
/**
* Search all instances of a specific HTML tag node in the provided DOM document and replaces them with BBCode text nodes.
*
* @see HTML::tagToBBCodeSub()
*/
private static function tagToBBCode(DOMDocument $doc, string $tag, array $attributes, string $startbb, string $endbb, bool $ignoreChildren = false)
{
do {
$done = self::tagToBBCodeSub($doc, $tag, $attributes, $startbb, $endbb);
$done = self::tagToBBCodeSub($doc, $tag, $attributes, $startbb, $endbb, $ignoreChildren);
} while ($done);
}
private static function tagToBBCodeSub(DOMDocument $doc, $tag, $attributes, $startbb, $endbb)
/**
* Search the first specific HTML tag node in the provided DOM document and replaces it with BBCode text nodes.
*
* @param DOMDocument $doc
* @param string $tag HTML tag name
* @param array $attributes Array of attributes to match and optionally use the value from
* @param string $startbb BBCode tag opening
* @param string $endbb BBCode tag closing
* @param bool $ignoreChildren If set to false, the HTML tag children will be appended as text inside the BBCode tag
* Otherwise, they will be entirely ignored. Useful for simple BBCode that draw their
* inner value from an attribute value and disregard the tag children.
* @return bool Whether a replacement was done
*/
private static function tagToBBCodeSub(DOMDocument $doc, string $tag, array $attributes, string $startbb, string $endbb, bool $ignoreChildren = false)
{
$savestart = str_replace('$', '\x01', $startbb);
$replace = false;
@@ -98,7 +116,7 @@ class HTML
$node->parentNode->insertBefore($StartCode, $node);
if ($node->hasChildNodes()) {
if (!$ignoreChildren && $node->hasChildNodes()) {
/** @var \DOMNode $child */
foreach ($node->childNodes as $key => $child) {
/* Remove empty text nodes at the start or at the end of the children list */
@@ -296,14 +314,14 @@ class HTML
self::tagToBBCode($doc, 'a', ['href' => '/mailto:(.+)/'], '[mail=$1]', '[/mail]');
self::tagToBBCode($doc, 'a', ['href' => '/(.+)/'], '[url=$1]', '[/url]');
self::tagToBBCode($doc, 'img', ['src' => '/(.+)/', 'alt' => '/(.+)/'], '[img=$1]$2', '[/img]');
self::tagToBBCode($doc, 'img', ['src' => '/(.+)/', 'width' => '/(\d+)/', 'height' => '/(\d+)/'], '[img=$2x$3]$1', '[/img]');
self::tagToBBCode($doc, 'img', ['src' => '/(.+)/'], '[img]$1', '[/img]');
self::tagToBBCode($doc, 'img', ['src' => '/(.+)/', 'alt' => '/(.+)/'], '[img=$1]$2', '[/img]', true);
self::tagToBBCode($doc, 'img', ['src' => '/(.+)/', 'width' => '/(\d+)/', 'height' => '/(\d+)/'], '[img=$2x$3]$1', '[/img]', true);
self::tagToBBCode($doc, 'img', ['src' => '/(.+)/'], '[img]$1', '[/img]', true);
self::tagToBBCode($doc, 'video', ['src' => '/(.+)/'], '[video]$1', '[/video]');
self::tagToBBCode($doc, 'audio', ['src' => '/(.+)/'], '[audio]$1', '[/audio]');
self::tagToBBCode($doc, 'iframe', ['src' => '/(.+)/'], '[iframe]$1', '[/iframe]');
self::tagToBBCode($doc, 'video', ['src' => '/(.+)/'], '[video]$1', '[/video]', true);
self::tagToBBCode($doc, 'audio', ['src' => '/(.+)/'], '[audio]$1', '[/audio]', true);
self::tagToBBCode($doc, 'iframe', ['src' => '/(.+)/'], '[iframe]$1', '[/iframe]', true);
self::tagToBBCode($doc, 'key', [], '[code]', '[/code]');
self::tagToBBCode($doc, 'code', [], '[code]', '[/code]');
+2 -9
View File
@@ -337,16 +337,9 @@ class Widget
return;
}
$cid = $zcid = 0;
$zcid = 0;
if (!empty($_SESSION['remote'])) {
foreach ($_SESSION['remote'] as $visitor) {
if ($visitor['uid'] == $profile_uid) {
$cid = $visitor['cid'];
break;
}
}
}
$cid = remote_user($profile_uid);
if (!$cid) {
if (Profile::getMyURL()) {
+15
View File
@@ -9,8 +9,10 @@ use Friendica\App;
use Friendica\Core\Session\CacheSessionHandler;
use Friendica\Core\Session\DatabaseSessionHandler;
use Friendica\Database\DBA;
use Friendica\Model\Contact;
use Friendica\Model\User;
use Friendica\Util\DateTimeFormat;
use Friendica\Util\Strings;
/**
* High-level Session service class
@@ -118,8 +120,21 @@ class Session
'my_url' => $a->getBaseURL() . '/profile/' . $user_record['nickname'],
'my_address' => $user_record['nickname'] . '@' . substr($a->getBaseURL(), strpos($a->getBaseURL(), '://') + 3),
'addr' => defaults($_SERVER, 'REMOTE_ADDR', '0.0.0.0'),
'remote' => []
]);
$remote_contacts = DBA::select('contact', ['id', 'uid'], ['nurl' => Strings::normaliseLink($_SESSION['my_url']), 'rel' => [Contact::FOLLOWER, Contact::FRIEND], 'self' => false]);
while ($contact = DBA::fetch($remote_contacts)) {
if (($contact['uid'] == 0) || Contact::isBlockedByUser($contact['id'], $contact['uid'])) {
continue;
}
/// @todo Change it to this format to save space
// $_SESSION['remote'][$contact['uid']] = $contact['id'];
$_SESSION['remote'][$contact['uid']] = ['cid' => $contact['id'], 'uid' => $contact['uid']];
}
DBA::close($remote_contacts);
$member_since = strtotime($user_record['register_date']);
self::set('new_member', time() < ($member_since + ( 60 * 60 * 24 * 14)));
+17 -12
View File
@@ -90,9 +90,12 @@ class Database
public function connect()
{
if (!is_null($this->connection) && $this->connected()) {
return true;
return $this->connected;
}
// Reset connected state
$this->connected = false;
$port = 0;
$serveraddr = trim($this->configCache->get('database', 'hostname'));
$serverdata = explode(':', $serveraddr);
@@ -187,19 +190,20 @@ class Database
*/
public function disconnect()
{
if (is_null($this->connection)) {
return;
if (!is_null($this->connection)) {
switch ($this->driver) {
case 'pdo':
$this->connection = null;
break;
case 'mysqli':
$this->connection->close();
$this->connection = null;
break;
}
}
switch ($this->driver) {
case 'pdo':
$this->connection = null;
break;
case 'mysqli':
$this->connection->close();
$this->connection = null;
break;
}
$this->driver = null;
$this->connected = false;
}
/**
@@ -369,6 +373,7 @@ class Database
$connected = $this->connection->ping();
break;
}
return $connected;
}
+9 -11
View File
@@ -38,19 +38,17 @@ class LoggerFactory
'Friendica\\Util\\Logger',
];
/**
* Retrieve the channel based on the __FILE__
*
* @return string
*/
private function findChannel()
private $channel;
public function __construct(string $channel)
{
return basename($_SERVER['PHP_SELF'], '.php');
$this->channel = $channel;
}
/**
* Creates a new PSR-3 compliant logger instances
*
* @param Database $database The Friendica Database instance
* @param Configuration $config The config
* @param Profiler $profiler The profiler of the app
*
@@ -59,7 +57,7 @@ class LoggerFactory
* @throws \Exception
* @throws InternalServerErrorException
*/
public function create(Database $database, Configuration $config, Profiler $profiler)
public function create( Database $database, Configuration $config, Profiler $profiler)
{
if (empty($config->get('system', 'debugging', false))) {
$logger = new VoidLogger();
@@ -76,7 +74,7 @@ class LoggerFactory
$loggerTimeZone = new \DateTimeZone('UTC');
Monolog\Logger::setTimezone($loggerTimeZone);
$logger = new Monolog\Logger($this->findChannel());
$logger = new Monolog\Logger($this->channel);
$logger->pushProcessor(new Monolog\Processor\PsrLogMessageProcessor());
$logger->pushProcessor(new Monolog\Processor\ProcessIdProcessor());
$logger->pushProcessor(new Monolog\Processor\UidProcessor());
@@ -91,7 +89,7 @@ class LoggerFactory
break;
case 'syslog':
$logger = new SyslogLogger($this->findChannel(), $introspection, $loglevel);
$logger = new SyslogLogger($this->channel, $introspection, $loglevel);
break;
case 'stream':
@@ -99,7 +97,7 @@ class LoggerFactory
$stream = $config->get('system', 'logfile');
// just add a stream in case it's either writable or not file
if (!is_file($stream) || is_writable($stream)) {
$logger = new StreamLogger($this->findChannel(), $stream, $introspection, $loglevel);
$logger = new StreamLogger($this->channel, $stream, $introspection, $loglevel);
} else {
$logger = new VoidLogger();
}
+35 -19
View File
@@ -270,14 +270,17 @@ class Contact extends BaseObject
* @param string $url The contact link
*
* @return string basepath
* @return boolean $dont_update Don't update the contact
* @throws \Friendica\Network\HTTPException\InternalServerErrorException
* @throws \ImagickException
*/
public static function getBasepath($url)
public static function getBasepath($url, $dont_update = false)
{
$contact = DBA::selectFirst('contact', ['baseurl'], ['uid' => 0, 'nurl' => Strings::normaliseLink($url)]);
if (!empty($contact['baseurl'])) {
return $contact['baseurl'];
} elseif ($dont_update) {
return '';
}
self::updateFromProbeByURL($url, true);
@@ -290,6 +293,18 @@ class Contact extends BaseObject
return '';
}
/**
* Check if the given contact url is on the same server
*
* @param string $url The contact link
*
* @return boolean Is it the same server?
*/
public static function isLocal($url)
{
return Strings::compareLink(self::getBasepath($url, true), System::baseUrl());
}
/**
* Returns the public contact id of the given user id
*
@@ -668,21 +683,21 @@ class Contact extends BaseObject
public static function updateSelfFromUserID($uid, $update_avatar = false)
{
$fields = ['id', 'name', 'nick', 'location', 'about', 'keywords', 'gender', 'avatar',
'xmpp', 'contact-type', 'forum', 'prv', 'avatar-date', 'url', 'nurl',
'xmpp', 'contact-type', 'forum', 'prv', 'avatar-date', 'url', 'nurl', 'unsearchable',
'photo', 'thumb', 'micro', 'addr', 'request', 'notify', 'poll', 'confirm', 'poco'];
$self = DBA::selectFirst('contact', $fields, ['uid' => $uid, 'self' => true]);
if (!DBA::isResult($self)) {
return;
}
$fields = ['nickname', 'page-flags', 'account-type'];
$fields = ['nickname', 'page-flags', 'account-type', 'hidewall'];
$user = DBA::selectFirst('user', $fields, ['uid' => $uid]);
if (!DBA::isResult($user)) {
return;
}
$fields = ['name', 'photo', 'thumb', 'about', 'address', 'locality', 'region',
'country-name', 'gender', 'pub_keywords', 'xmpp'];
'country-name', 'gender', 'pub_keywords', 'xmpp', 'net-publish'];
$profile = DBA::selectFirst('profile', $fields, ['uid' => $uid, 'is-default' => true]);
if (!DBA::isResult($profile)) {
return;
@@ -727,6 +742,7 @@ class Contact extends BaseObject
$fields['avatar'] = System::baseUrl() . '/photo/profile/' .$uid . '.' . $file_suffix;
$fields['forum'] = $user['page-flags'] == User::PAGE_FLAGS_COMMUNITY;
$fields['prv'] = $user['page-flags'] == User::PAGE_FLAGS_PRVGROUP;
$fields['unsearchable'] = $user['hidewall'] || !$profile['net-publish'];
// it seems as if ported accounts can have wrong values, so we make sure that now everything is fine.
$fields['url'] = System::baseUrl() . '/profile/' . $user['nickname'];
@@ -1177,7 +1193,7 @@ class Contact extends BaseObject
$sparkle = false;
if (($contact['network'] === Protocol::DFRN) && !$contact['self'] && empty($contact['pending'])) {
$sparkle = true;
$profile_link = System::baseUrl() . '/redir/' . $contact['id'] . '?url=' . $contact['url'];
$profile_link = System::baseUrl() . '/redir/' . $contact['id'];
} else {
$profile_link = $contact['url'];
}
@@ -1462,7 +1478,6 @@ class Contact extends BaseObject
if (empty($data)) {
$data = Probe::uri($url, "", $uid);
// Ensure that there is a gserver entry
if (!empty($data['baseurl']) && ($data['network'] != Protocol::PHANTOM)) {
PortableContact::checkServer($data['baseurl']);
@@ -2021,9 +2036,8 @@ class Contact extends BaseObject
return true;
}
// If Probe::uri fails the network code will be different (mostly "feed" or "unkn")
if (!in_array($ret['network'], Protocol::NATIVE_SUPPORT) ||
(in_array($ret['network'], [Protocol::FEED, Protocol::PHANTOM]) && ($ret['network'] != $contact['network']))) {
// If Probe::uri fails the network code will be different ("feed" or "unkn")
if (in_array($ret['network'], [Protocol::FEED, Protocol::PHANTOM]) && ($ret['network'] != $contact['network'])) {
if ($force && ($uid == 0)) {
self::updateContact($id, $uid, $ret['url'], ['last-update' => $updated, 'failure_update' => $updated]);
}
@@ -2063,7 +2077,7 @@ class Contact extends BaseObject
}
}
if ($ret['network'] != Protocol::FEED) {
if (!empty($ret['photo']) && ($ret['network'] != Protocol::FEED)) {
self::updateAvatar($ret['photo'], $uid, $id, $update || $force);
}
@@ -2487,6 +2501,9 @@ class Contact extends BaseObject
['id' => $contact['id'], 'uid' => $importer['uid']]);
}
// Ensure to always have the correct network type, independent from the connection request method
self::updateFromProbe($contact['id'], '', true);
return true;
} else {
// send email notification to owner?
@@ -2512,15 +2529,14 @@ class Contact extends BaseObject
'writable' => 1,
]);
$contact_record = [
'id' => DBA::lastInsertId(),
'network' => $network,
'name' => $name,
'url' => $url,
'photo' => $photo
];
$contact_id = DBA::lastInsertId();
Contact::updateAvatar($photo, $importer["uid"], $contact_record["id"], true);
// Ensure to always have the correct network type, independent from the connection request method
self::updateFromProbe($contact_id, '', true);
Contact::updateAvatar($photo, $importer["uid"], $contact_id, true);
$contact_record = DBA::selectFirst('contact', ['id', 'network', 'name', 'url', 'photo'], ['id' => $contact_id]);
/// @TODO Encapsulate this into a function/method
$fields = ['uid', 'username', 'email', 'page-flags', 'notify-flags', 'language'];
@@ -2728,7 +2744,7 @@ class Contact extends BaseObject
$redirect = 'redir/' . $contact['id'];
if ($url != '') {
if (($url != '') && !Strings::compareLink($contact['url'], $url)) {
$redirect .= '?url=' . $url;
}
+3 -3
View File
@@ -248,7 +248,7 @@ class Profile
*/
public static function getByNickname($nickname, $uid = 0, $profile_id = 0)
{
if (remote_user() && !empty($_SESSION['remote'])) {
if (remote_user($uid) && !empty($_SESSION['remote'])) {
foreach ($_SESSION['remote'] as $visitor) {
if ($visitor['uid'] == $uid) {
$contact = DBA::selectFirst('contact', ['profile-id'], ['id' => $visitor['cid']]);
@@ -1124,13 +1124,13 @@ class Profile
/// @todo replace this and the query for this variable with some cleaner functionality
$_SESSION['remote'] = [];
$remote_contacts = DBA::select('contact', ['id', 'uid'], ['nurl' => $visitor['nurl'], 'rel' => [Contact::FOLLOWER, Contact::FRIEND]]);
$remote_contacts = DBA::select('contact', ['id', 'uid'], ['nurl' => $visitor['nurl'], 'rel' => [Contact::FOLLOWER, Contact::FRIEND], 'self' => false]);
while ($contact = DBA::fetch($remote_contacts)) {
if (($contact['uid'] == 0) || Contact::isBlockedByUser($visitor['id'], $contact['uid'])) {
continue;
}
$_SESSION['remote'][] = ['cid' => $contact['id'], 'uid' => $contact['uid'], 'url' => $visitor['url']];
$_SESSION['remote'][$contact['uid']] = ['cid' => $contact['id'], 'uid' => $contact['uid']];
}
$a->contact = $visitor;
+3 -6
View File
@@ -33,13 +33,10 @@ class Magic extends BaseModule
$test = (!empty($_REQUEST['test']) ? intval($_REQUEST['test']) : 0);
$owa = (!empty($_REQUEST['owa']) ? intval($_REQUEST['owa']) : 0);
// NOTE: I guess $dest isn't just the profile url (could be also
// other profile pages e.g. photo). We need to find a solution
// to be able to redirct to other pages than the contact profile.
$cid = Contact::getIdForURL($dest);
if (!$cid && !empty($addr)) {
if (!empty($addr)) {
$cid = Contact::getIdForURL($addr);
} else {
$cid = Contact::getIdForURL($dest);
}
if (!$cid) {
-1
View File
@@ -36,7 +36,6 @@ class Contacts extends BaseModule
throw new \Friendica\Network\HTTPException\NotFoundException(L10n::t('User not found.'));
}
$a->data['user'] = $user;
$a->profile_uid = $user['uid'];
Profile::load($a, $nickname);
+32 -3
View File
@@ -1504,10 +1504,39 @@ class Probe
$data['baseurl'] = 'https://twitter.com';
$curlResult = Network::curl($data['url'], false);
if ($curlResult->isSuccess()) {
return $data;
if (!$curlResult->isSuccess()) {
return [];
}
return [];
$body = $curlResult->getBody();
$doc = new DOMDocument();
@$doc->loadHTML($body);
$xpath = new DOMXPath($doc);
$list = $xpath->query('//img[@class]');
foreach ($list as $node) {
$img_attr = [];
if ($node->attributes->length) {
foreach ($node->attributes as $attribute) {
$img_attr[$attribute->name] = $attribute->value;
}
}
if (empty($img_attr['class'])) {
continue;
}
if (strpos($img_attr['class'], 'ProfileAvatar-image') !== false) {
if (!empty($img_attr['src'])) {
$data['photo'] = $img_attr['src'];
}
if (!empty($img_attr['alt'])) {
$data['name'] = $img_attr['alt'];
}
}
}
return $data;
}
/**
+8
View File
@@ -544,6 +544,10 @@ class Transmitter
$contacts = DBA::select('contact', ['url', 'network', 'protocol'], $condition);
while ($contact = DBA::fetch($contacts)) {
if (Contact::isLocal($contact['url'])) {
continue;
}
if (!in_array($contact['network'], $networks) && ($contact['protocol'] != Protocol::ACTIVITYPUB)) {
continue;
}
@@ -611,6 +615,10 @@ class Transmitter
if ($receiver == $item_profile['followers']) {
$inboxes = array_merge($inboxes, self::fetchTargetInboxesforUser($uid, $personal));
} else {
if (Contact::isLocal($receiver)) {
continue;
}
$profile = APContact::getByURL($receiver, false);
if (!empty($profile)) {
if (empty($profile['sharedinbox']) || $personal || $blindcopy) {
+2 -12
View File
@@ -33,7 +33,7 @@ class Security extends BaseObject
return true;
}
if (remote_user()) {
if (remote_user($owner)) {
// use remembered decision and avoid a DB lookup for each and every display item
// DO NOT use this function if there are going to be multiple owners
// We have a contact-id for an authenticated remote user, this block determines if the contact
@@ -44,17 +44,7 @@ class Security extends BaseObject
} elseif ($verified === 1) {
return false;
} else {
$cid = 0;
if (!empty($_SESSION['remote'])) {
foreach ($_SESSION['remote'] as $visitor) {
if ($visitor['uid'] == $owner) {
$cid = $visitor['cid'];
break;
}
}
}
$cid = remote_user($owner);
if (!$cid) {
return false;
}
+4 -5
View File
@@ -122,13 +122,12 @@ class Temporal
* @brief Wrapper for date selector, tailored for use in birthday fields.
*
* @param string $dob Date of Birth
* @param string $timezone
* @return string Formatted HTML
* @throws \Friendica\Network\HTTPException\InternalServerErrorException
* @throws \Exception
*/
public static function getDateofBirthField($dob)
public static function getDateofBirthField(string $dob, string $timezone = 'UTC')
{
$a = \get_app();
list($year, $month, $day) = sscanf($dob, '%4d-%2d-%2d');
if ($dob < '0000-01-01') {
@@ -137,7 +136,7 @@ class Temporal
$value = DateTimeFormat::utc(($year > 1000) ? $dob : '1000-' . $month . '-' . $day, 'Y-m-d');
}
$age = (intval($value) ? self::getAgeByTimezone($value, $a->user["timezone"], $a->user["timezone"]) : "");
$age = (intval($value) ? self::getAgeByTimezone($value, $timezone, $timezone) : "");
$tpl = Renderer::getMarkupTemplate("field_input.tpl");
$o = Renderer::replaceMacros($tpl,
+4 -1
View File
@@ -304,8 +304,11 @@ class CronJobs
/// - set contact-id in item when not present
// Add intro entries for pending contacts
// We don't do this for DFRN entries since such revived contact requests seem to mostly fail.
$pending_contacts = DBA::p("SELECT `uid`, `id`, `url`, `network`, `created` FROM `contact`
WHERE `pending` AND `rel` IN (?, ?) AND NOT EXISTS (SELECT `id` FROM `intro` WHERE `contact-id` = `contact`.`id`)", 0, Contact::FOLLOWER);
WHERE `pending` AND `rel` IN (?, ?) AND `network` != ?
AND NOT EXISTS (SELECT `id` FROM `intro` WHERE `contact-id` = `contact`.`id`)",
0, Contact::FOLLOWER, Protocol::DFRN);
while ($contact = DBA::fetch($pending_contacts)) {
DBA::insert('intro', ['uid' => $contact['uid'], 'contact-id' => $contact['id'], 'blocked' => false,
'hash' => Strings::getRandomHex(), 'datetime' => $contact['created']]);
+5
View File
@@ -568,6 +568,11 @@ class Notifier
*/
private static function skipDFRN($contact, $item, $cmd)
{
// Use DFRN if we are on the same site
if (!empty($contact['url']) && Contact::isLocal($contact['url'])) {
return false;
}
// Don't skip when author or owner don't have AP profiles
if ((!empty($item['author-link']) && empty(APContact::getByURL($item['author-link'], false))) || (!empty($item['owner-link']) && empty(APContact::getByURL($item['owner-link'], false)))) {
return false;