Merge branch 'master' into develop
- Updated new develop version label - Incremented database build number
This commit is contained in:
commit
93daf7883e
474 changed files with 75160 additions and 91301 deletions
23
src/App.php
23
src/App.php
|
@ -9,6 +9,8 @@ use Friendica\Core\Config;
|
|||
use Friendica\Core\L10n;
|
||||
use Friendica\Core\PConfig;
|
||||
use Friendica\Core\System;
|
||||
use Friendica\Database\DBM;
|
||||
use dba;
|
||||
|
||||
use Detection\MobileDetect;
|
||||
|
||||
|
@ -861,18 +863,6 @@ class App
|
|||
return;
|
||||
}
|
||||
|
||||
// If the last worker fork was less than 2 seconds before then don't fork another one.
|
||||
// This should prevent the forking of masses of workers.
|
||||
$cachekey = 'app:proc_run:started';
|
||||
$result = Cache::get($cachekey);
|
||||
|
||||
if (!is_null($result) && ( time() - $result) < 2) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Set the timestamp of the last proc_run
|
||||
Cache::set($cachekey, time(), CACHE_MINUTE);
|
||||
|
||||
array_unshift($args, ((x($this->config, 'php_path')) && (strlen($this->config['php_path'])) ? $this->config['php_path'] : 'php'));
|
||||
|
||||
for ($x = 0; $x < count($args); $x ++) {
|
||||
|
@ -1103,10 +1093,15 @@ class App
|
|||
*/
|
||||
public function getCurrentTheme()
|
||||
{
|
||||
if (!$this->current_theme) {
|
||||
$this->computeCurrentTheme();
|
||||
if ($this->mode == App::MODE_INSTALL) {
|
||||
return '';
|
||||
}
|
||||
|
||||
//// @TODO Compute the current theme only once (this behavior has
|
||||
/// already been implemented, but it didn't work well -
|
||||
/// https://github.com/friendica/friendica/issues/5092)
|
||||
$this->computeCurrentTheme();
|
||||
|
||||
return $this->current_theme;
|
||||
}
|
||||
|
||||
|
|
|
@ -92,8 +92,8 @@ class Feature
|
|||
|
||||
// Network sidebar widgets
|
||||
'widgets' => [
|
||||
L10n::t('Network Sidebar Widgets'),
|
||||
['archives', L10n::t('Search by Date'), L10n::t('Ability to select posts by date ranges'), false, Config::get('feature_lock', 'archives', false)],
|
||||
L10n::t('Network Sidebar'),
|
||||
['archives', L10n::t('Archives'), L10n::t('Ability to select posts by date ranges'), false, Config::get('feature_lock', 'archives', false)],
|
||||
['forumlist_widget', L10n::t('List Forums'), L10n::t('Enable widget to display the forums your are connected with'), true, Config::get('feature_lock', 'forumlist_widget', false)],
|
||||
['groups', L10n::t('Group Filter'), L10n::t('Enable widget to display Network posts only from selected group'), false, Config::get('feature_lock', 'groups', false)],
|
||||
['networks', L10n::t('Network Filter'), L10n::t('Enable widget to display Network posts only from selected network'), false, Config::get('feature_lock', 'networks', false)],
|
||||
|
|
|
@ -174,6 +174,10 @@ class Nav
|
|||
|
||||
$nav['about'] = ['friendica', L10n::t('Information'), '', L10n::t('Information about this friendica instance')];
|
||||
|
||||
if (Config::get('system', 'tosdisplay')) {
|
||||
$nav['tos'] = ['tos', L10n::t('Terms of Service'), '', L10n::t('Terms of Service of this Friendica instance')];
|
||||
}
|
||||
|
||||
// The following nav links are only show to logged in users
|
||||
if (local_user()) {
|
||||
$nav['network'] = ['network', L10n::t('Network'), '', L10n::t('Conversations from your friends')];
|
||||
|
|
|
@ -359,6 +359,16 @@ class BBCode extends BaseObject
|
|||
return $naked_text;
|
||||
}
|
||||
|
||||
private static function proxyUrl($image, $simplehtml = false)
|
||||
{
|
||||
// Only send proxied pictures to API and for internal display
|
||||
if (in_array($simplehtml, [false, 2])) {
|
||||
return proxy_url($image);
|
||||
} else {
|
||||
return $image;
|
||||
}
|
||||
}
|
||||
|
||||
public static function scaleExternalImages($srctext, $include_link = true, $scale_replace = false)
|
||||
{
|
||||
// Suppress "view full size"
|
||||
|
@ -562,13 +572,13 @@ class BBCode extends BaseObject
|
|||
}
|
||||
|
||||
if ($data["image"] != "") {
|
||||
$return .= sprintf('<a href="%s" target="_blank"><img src="%s" alt="" title="%s" class="attachment-image" /></a><br />', $data["url"], proxy_url($data["image"]), $data["title"]);
|
||||
$return .= sprintf('<a href="%s" target="_blank"><img src="%s" alt="" title="%s" class="attachment-image" /></a><br />', $data["url"], self::proxyUrl($data["image"], $simplehtml), $data["title"]);
|
||||
} elseif ($data["preview"] != "") {
|
||||
$return .= sprintf('<a href="%s" target="_blank"><img src="%s" alt="" title="%s" class="attachment-preview" /></a><br />', $data["url"], proxy_url($data["preview"]), $data["title"]);
|
||||
$return .= sprintf('<a href="%s" target="_blank"><img src="%s" alt="" title="%s" class="attachment-preview" /></a><br />', $data["url"], self::proxyUrl($data["preview"], $simplehtml), $data["title"]);
|
||||
}
|
||||
|
||||
if (($data["type"] == "photo") && ($data["url"] != "") && ($data["image"] != "")) {
|
||||
$return .= sprintf('<a href="%s" target="_blank"><img src="%s" alt="" title="%s" class="attachment-image" /></a>', $data["url"], proxy_url($data["image"]), $data["title"]);
|
||||
$return .= sprintf('<a href="%s" target="_blank"><img src="%s" alt="" title="%s" class="attachment-image" /></a>', $data["url"], self::proxyUrl($data["image"], $simplehtml), $data["title"]);
|
||||
} else {
|
||||
$return .= sprintf('<h4><a href="%s">%s</a></h4>', $data['url'], $data['title']);
|
||||
}
|
||||
|
@ -839,7 +849,7 @@ class BBCode extends BaseObject
|
|||
// it loops over the array starting from the first element and going sequentially
|
||||
// to the last element
|
||||
$newbody = str_replace('[$#saved_image' . $cnt . '#$]',
|
||||
'<img src="' . proxy_url($image) . '" alt="' . L10n::t('Image/photo') . '" />', $newbody);
|
||||
'<img src="' . self::proxyUrl($image) . '" alt="' . L10n::t('Image/photo') . '" />', $newbody);
|
||||
$cnt++;
|
||||
}
|
||||
|
||||
|
@ -1571,12 +1581,12 @@ class BBCode extends BaseObject
|
|||
// [img=widthxheight]image source[/img]
|
||||
$text = preg_replace_callback(
|
||||
"/\[img\=([0-9]*)x([0-9]*)\](.*?)\[\/img\]/ism",
|
||||
function ($matches) {
|
||||
function ($matches) use ($simple_html) {
|
||||
if (strpos($matches[3], "data:image/") === 0) {
|
||||
return $matches[0];
|
||||
}
|
||||
|
||||
$matches[3] = proxy_url($matches[3]);
|
||||
$matches[3] = self::proxyUrl($matches[3], $simple_html);
|
||||
return "[img=" . $matches[1] . "x" . $matches[2] . "]" . $matches[3] . "[/img]";
|
||||
},
|
||||
$text
|
||||
|
@ -1586,8 +1596,8 @@ class BBCode extends BaseObject
|
|||
$text = preg_replace("/\[zmg\=([0-9]*)x([0-9]*)\](.*?)\[\/zmg\]/ism", '<img class="zrl" src="$3" style="width: $1px;" >', $text);
|
||||
|
||||
$text = preg_replace_callback("/\[img\=([$URLSearchString]*)\](.*?)\[\/img\]/ism",
|
||||
function ($matches) {
|
||||
$matches[1] = proxy_url($matches[1]);
|
||||
function ($matches) use ($simple_html) {
|
||||
$matches[1] = self::proxyUrl($matches[1], $simple_html);
|
||||
$matches[2] = htmlspecialchars($matches[2], ENT_COMPAT);
|
||||
return '<img src="' . $matches[1] . '" alt="' . $matches[2] . '">';
|
||||
},
|
||||
|
@ -1597,12 +1607,12 @@ class BBCode extends BaseObject
|
|||
// [img]pathtoimage[/img]
|
||||
$text = preg_replace_callback(
|
||||
"/\[img\](.*?)\[\/img\]/ism",
|
||||
function ($matches) {
|
||||
function ($matches) use ($simple_html) {
|
||||
if (strpos($matches[1], "data:image/") === 0) {
|
||||
return $matches[0];
|
||||
}
|
||||
|
||||
$matches[1] = proxy_url($matches[1]);
|
||||
$matches[1] = self::proxyUrl($matches[1], $simple_html);
|
||||
return "[img]" . $matches[1] . "[/img]";
|
||||
},
|
||||
$text
|
||||
|
|
|
@ -6,6 +6,7 @@ use Asika\SimpleConsole\Console;
|
|||
use dba;
|
||||
use Friendica\App;
|
||||
use Friendica\Core\Install;
|
||||
use Friendica\Core\Theme;
|
||||
|
||||
require_once 'mod/install.php';
|
||||
require_once 'include/dba.php';
|
||||
|
@ -90,6 +91,15 @@ HELP;
|
|||
|
||||
$this->out(" Complete!\n\n");
|
||||
|
||||
// Install theme
|
||||
$this->out("Installing theme\n");
|
||||
if (!empty($a->config['system']['theme'])) {
|
||||
Theme::install($a->config['system']['theme']);
|
||||
$this->out(" Complete\n\n");
|
||||
} else {
|
||||
$this->out(" Theme setting is empty. Please check the file htconfig.php\n\n");
|
||||
}
|
||||
|
||||
// Copy config file
|
||||
$this->out("Saving config file...\n");
|
||||
if ($config_file != '.htconfig.php' && !copy($config_file, '.htconfig.php')) {
|
||||
|
|
|
@ -94,6 +94,7 @@ HELP;
|
|||
$fnname = 'string_plural_select_' . $lang;
|
||||
$out .= 'if(! function_exists("' . $fnname . '")) {' . "\n";
|
||||
$out .= 'function ' . $fnname . '($n){' . "\n";
|
||||
$out .= ' $n = intval($n);' . "\n";
|
||||
$out .= ' return ' . $cond . ';' . "\n";
|
||||
$out .= '}}' . "\n";
|
||||
}
|
||||
|
|
|
@ -999,6 +999,7 @@ class Worker
|
|||
}
|
||||
|
||||
/**
|
||||
* @brief Spawns a new worker
|
||||
* @return void
|
||||
*/
|
||||
public static function spawnWorker()
|
||||
|
|
|
@ -207,7 +207,7 @@ class DBStructure
|
|||
public static function update($verbose, $action, $install = false, array $tables = null, array $definition = null) {
|
||||
if ($action && !$install) {
|
||||
Config::set('system', 'maintenance', 1);
|
||||
Config::set('system', 'maintenance_reason', L10n::t(': Database update', DBM::date().' '.date('e')));
|
||||
Config::set('system', 'maintenance_reason', L10n::t('%s: Database update', DBM::date().' '.date('e')));
|
||||
}
|
||||
|
||||
$errors = '';
|
||||
|
@ -1553,12 +1553,15 @@ class DBStructure
|
|||
"callback_url" => ["type" => "varchar(255)", "not null" => "1", "default" => "", "comment" => ""],
|
||||
"topic" => ["type" => "varchar(255)", "not null" => "1", "default" => "", "comment" => ""],
|
||||
"nickname" => ["type" => "varchar(255)", "not null" => "1", "default" => "", "comment" => ""],
|
||||
"push" => ["type" => "tinyint unsigned", "not null" => "1", "default" => "0", "comment" => ""],
|
||||
"last_update" => ["type" => "datetime", "not null" => "1", "default" => NULL_DATE, "comment" => ""],
|
||||
"push" => ["type" => "tinyint", "not null" => "1", "default" => "0", "comment" => "Retrial counter"],
|
||||
"last_update" => ["type" => "datetime", "not null" => "1", "default" => NULL_DATE, "comment" => "Date of last successful trial"],
|
||||
"next_try" => ["type" => "datetime", "not null" => "1", "default" => NULL_DATE, "comment" => "Next retrial date"],
|
||||
"renewed" => ["type" => "datetime", "not null" => "1", "default" => NULL_DATE, "comment" => "Date of last subscription renewal"],
|
||||
"secret" => ["type" => "varchar(255)", "not null" => "1", "default" => "", "comment" => ""],
|
||||
],
|
||||
"indexes" => [
|
||||
"PRIMARY" => ["id"],
|
||||
"next_try" => ["next_try"],
|
||||
]
|
||||
];
|
||||
$database["queue"] = [
|
||||
|
@ -1783,6 +1786,17 @@ class DBStructure
|
|||
"username" => ["username(32)"],
|
||||
]
|
||||
];
|
||||
$database["user-item"] = [
|
||||
"comment" => "User specific item data",
|
||||
"fields" => [
|
||||
"iid" => ["type" => "int unsigned", "not null" => "1", "default" => "0", "primary" => "1", "relation" => ["item" => "id"], "comment" => "Item id"],
|
||||
"uid" => ["type" => "mediumint unsigned", "not null" => "1", "default" => "0", "primary" => "1", "relation" => ["user" => "uid"], "comment" => "User id"],
|
||||
"hidden" => ["type" => "boolean", "not null" => "1", "default" => "0", "comment" => "Marker to hide an item from the user"],
|
||||
],
|
||||
"indexes" => [
|
||||
"PRIMARY" => ["uid", "iid"],
|
||||
]
|
||||
];
|
||||
$database["workerqueue"] = [
|
||||
"comment" => "Background tasks queue entries",
|
||||
"fields" => [
|
||||
|
@ -1799,7 +1813,7 @@ class DBStructure
|
|||
"pid" => ["pid"],
|
||||
"parameter" => ["parameter(64)"],
|
||||
"priority_created" => ["priority", "created"],
|
||||
"executed" => ["executed"],
|
||||
"done_executed" => ["done", "executed"],
|
||||
]
|
||||
];
|
||||
|
||||
|
|
|
@ -120,7 +120,8 @@ class PostUpdate
|
|||
logger("Start", LOGGER_DEBUG);
|
||||
|
||||
// Check if the first step is done (Setting "author-id" and "owner-id" in the item table)
|
||||
$r = dba::select('item', ['author-link', 'owner-link', 'uid'], ['author-id' => 0, 'owner-id' => 0], ['limit' => 1000]);
|
||||
$fields = ['author-link', 'author-name', 'author-avatar', 'owner-link', 'owner-name', 'owner-avatar', 'network', 'uid'];
|
||||
$r = dba::select('item', $fields, ['author-id' => 0, 'owner-id' => 0], ['limit' => 1000]);
|
||||
if (!$r) {
|
||||
// Are there unfinished entries in the thread table?
|
||||
$r = q("SELECT COUNT(*) AS `total` FROM `thread`
|
||||
|
@ -162,8 +163,13 @@ class PostUpdate
|
|||
|
||||
// Set the "author-id" and "owner-id" in the item table and add a new public contact entry if needed
|
||||
foreach ($item_arr as $item) {
|
||||
$author_id = Contact::getIdForURL($item["author-link"]);
|
||||
$owner_id = Contact::getIdForURL($item["owner-link"]);
|
||||
$default = ['url' => $item['author-link'], 'name' => $item['author-name'],
|
||||
'photo' => $item['author-avatar'], 'network' => $item['network']];
|
||||
$author_id = Contact::getIdForURL($item["author-link"], 0, false, $default);
|
||||
|
||||
$default = ['url' => $item['owner-link'], 'name' => $item['owner-name'],
|
||||
'photo' => $item['owner-avatar'], 'network' => $item['network']];
|
||||
$owner_id = Contact::getIdForURL($item["owner-link"], 0, false, $default);
|
||||
|
||||
if ($author_id == 0) {
|
||||
$author_id = -1;
|
||||
|
|
|
@ -206,6 +206,16 @@ class Contact extends BaseObject
|
|||
$fields['forum'] = $user['page-flags'] == PAGE_COMMUNITY;
|
||||
$fields['prv'] = $user['page-flags'] == PAGE_PRVGROUP;
|
||||
|
||||
// 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'];
|
||||
$fields['nurl'] = normalise_link($fields['url']);
|
||||
$fields['addr'] = $user['nickname'] . '@' . substr(System::baseUrl(), strpos(System::baseUrl(), '://') + 3);
|
||||
$fields['request'] = System::baseUrl() . '/dfrn_request/' . $user['nickname'];
|
||||
$fields['notify'] = System::baseUrl() . '/dfrn_notify/' . $user['nickname'];
|
||||
$fields['poll'] = System::baseUrl() . '/dfrn_poll/' . $user['nickname'];
|
||||
$fields['confirm'] = System::baseUrl() . '/dfrn_confirm/' . $user['nickname'];
|
||||
$fields['poco'] = System::baseUrl() . '/poco/' . $user['nickname'];
|
||||
|
||||
$update = false;
|
||||
|
||||
foreach ($fields as $field => $content) {
|
||||
|
@ -752,10 +762,11 @@ class Contact extends BaseObject
|
|||
* @param string $url Contact URL
|
||||
* @param integer $uid The user id for the contact (0 = public contact)
|
||||
* @param boolean $no_update Don't update the contact
|
||||
* @param array $default Default value for creating the contact when every else fails
|
||||
*
|
||||
* @return integer Contact ID
|
||||
*/
|
||||
public static function getIdForURL($url, $uid = 0, $no_update = false)
|
||||
public static function getIdForURL($url, $uid = 0, $no_update = false, $default = [])
|
||||
{
|
||||
logger("Get contact data for url " . $url . " and user " . $uid . " - " . System::callstack(), LOGGER_DEBUG);
|
||||
|
||||
|
@ -804,18 +815,48 @@ class Contact extends BaseObject
|
|||
$data = Probe::uri($url, "", $uid);
|
||||
|
||||
// Last try in gcontact for unsupported networks
|
||||
if (!in_array($data["network"], [NETWORK_DFRN, NETWORK_OSTATUS, NETWORK_DIASPORA, NETWORK_PUMPIO, NETWORK_MAIL])) {
|
||||
if (!in_array($data["network"], [NETWORK_DFRN, NETWORK_OSTATUS, NETWORK_DIASPORA, NETWORK_PUMPIO, NETWORK_MAIL, NETWORK_FEED])) {
|
||||
if ($uid != 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Get data from the gcontact table
|
||||
$gcontact = dba::selectFirst('gcontact', ['name', 'nick', 'url', 'photo', 'addr', 'alias', 'network'], ['nurl' => normalise_link($url)]);
|
||||
if (!DBM::is_result($gcontact)) {
|
||||
return 0;
|
||||
$fields = ['name', 'nick', 'url', 'photo', 'addr', 'alias', 'network'];
|
||||
$contact = dba::selectFirst('gcontact', $fields, ['nurl' => normalise_link($url)]);
|
||||
if (!DBM::is_result($contact)) {
|
||||
$contact = dba::selectFirst('contact', $fields, ['nurl' => normalise_link($url)]);
|
||||
}
|
||||
|
||||
$data = array_merge($data, $gcontact);
|
||||
if (!DBM::is_result($contact)) {
|
||||
$fields = ['url', 'addr', 'alias', 'notify', 'poll', 'name', 'nick',
|
||||
'photo', 'keywords', 'location', 'about', 'network',
|
||||
'priority', 'batch', 'request', 'confirm', 'poco'];
|
||||
$contact = dba::selectFirst('contact', $fields, ['addr' => $url]);
|
||||
}
|
||||
|
||||
if (!DBM::is_result($contact)) {
|
||||
// The link could be provided as http although we stored it as https
|
||||
$ssl_url = str_replace('http://', 'https://', $url);
|
||||
$condition = ['alias' => [$url, normalise_link($url), $ssl_url]];
|
||||
$contact = dba::selectFirst('contact', $fields, $condition);
|
||||
}
|
||||
|
||||
if (!DBM::is_result($contact)) {
|
||||
$fields = ['url', 'addr', 'alias', 'notify', 'poll', 'name', 'nick',
|
||||
'photo', 'network', 'priority', 'batch', 'request', 'confirm'];
|
||||
$condition = ['url' => [$url, normalise_link($url), $ssl_url]];
|
||||
$contact = dba::selectFirst('fcontact', $fields, $condition);
|
||||
}
|
||||
|
||||
if (!empty($default)) {
|
||||
$contact = $default;
|
||||
}
|
||||
|
||||
if (!DBM::is_result($contact)) {
|
||||
return 0;
|
||||
} else {
|
||||
$data = array_merge($data, $contact);
|
||||
}
|
||||
}
|
||||
|
||||
if (!$contact_id && ($data["alias"] != '') && ($data["alias"] != $url)) {
|
||||
|
@ -1008,7 +1049,7 @@ class Contact extends BaseObject
|
|||
|
||||
$contact = ($r[0]["contact-type"] == ACCOUNT_TYPE_COMMUNITY ? 'owner-id' : 'author-id');
|
||||
|
||||
$r = q(item_query() . " AND `item`.`" . $contact . "` = %d AND " . $sql .
|
||||
$r = q(item_query(local_user()) . " AND `item`.`" . $contact . "` = %d AND " . $sql .
|
||||
" AND `item`.`verb` = '%s' ORDER BY `item`.`created` DESC LIMIT %d, %d",
|
||||
intval($author_id), intval(local_user()), dbesc(ACTIVITY_POST),
|
||||
intval($a->pager['start']), intval($a->pager['itemspage'])
|
||||
|
@ -1263,7 +1304,7 @@ class Contact extends BaseObject
|
|||
|
||||
if (($network != '') && ($ret['network'] != $network)) {
|
||||
logger('Expected network ' . $network . ' does not match actual network ' . $ret['network']);
|
||||
return result;
|
||||
return $result;
|
||||
}
|
||||
|
||||
// check if we already have a contact
|
||||
|
|
|
@ -239,7 +239,7 @@ class GContact
|
|||
|
||||
if ($alternate && ($gcontact['network'] == NETWORK_OSTATUS)) {
|
||||
// Delete the old entry - if it exists
|
||||
if (dba::exists('item', ['nurl' => normalise_link($orig_profile)])) {
|
||||
if (dba::exists('gcontact', ['nurl' => normalise_link($orig_profile)])) {
|
||||
dba::delete('gcontact', ['nurl' => normalise_link($orig_profile)]);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -52,28 +52,38 @@ class Item extends BaseObject
|
|||
return false;
|
||||
}
|
||||
|
||||
// To ensure the data integrity we do it in an transaction
|
||||
dba::transaction();
|
||||
|
||||
// We cannot simply expand the condition to check for origin entries
|
||||
// The condition needn't to be a simple array but could be a complex condition.
|
||||
// And we have to execute this query before the update to ensure to fetch the same data.
|
||||
$items = dba::select('item', ['id', 'origin'], $condition);
|
||||
|
||||
$success = dba::update('item', $fields, $condition);
|
||||
|
||||
if (!$success) {
|
||||
dba::close($items);
|
||||
dba::rollback();
|
||||
return false;
|
||||
}
|
||||
|
||||
$rows = dba::affected_rows();
|
||||
|
||||
// We cannot simply expand the condition to check for origin entries
|
||||
// The condition needn't to be a simple array but could be a complex condition.
|
||||
$items = dba::select('item', ['id', 'origin'], $condition);
|
||||
while ($item = dba::fetch($items)) {
|
||||
Term::insertFromTagFieldByItemId($item['id']);
|
||||
Term::insertFromFileFieldByItemId($item['id']);
|
||||
self::updateThread($item['id']);
|
||||
|
||||
// We only need to notfiy others when it is an original entry from us
|
||||
if ($item['origin']) {
|
||||
// We only need to notfiy others when it is an original entry from us.
|
||||
// Only call the notifier when the item has some content relevant change.
|
||||
if ($item['origin'] && in_array('edited', array_keys($fields))) {
|
||||
Worker::add(PRIORITY_HIGH, "Notifier", 'edit_post', $item['id']);
|
||||
}
|
||||
}
|
||||
|
||||
dba::close($items);
|
||||
dba::commit();
|
||||
return $rows;
|
||||
}
|
||||
|
||||
|
@ -92,6 +102,32 @@ class Item extends BaseObject
|
|||
dba::close($items);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Delete an item for an user and notify others about it - if it was ours
|
||||
*
|
||||
* @param array $condition The condition for finding the item entries
|
||||
* @param integer $uid User who wants to delete this item
|
||||
*/
|
||||
public static function deleteForUser($condition, $uid)
|
||||
{
|
||||
if ($uid == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
$items = dba::select('item', ['id', 'uid'], $condition);
|
||||
while ($item = dba::fetch($items)) {
|
||||
// "Deleting" global items just means hiding them
|
||||
if ($item['uid'] == 0) {
|
||||
dba::update('user-item', ['hidden' => true], ['iid' => $item['id'], 'uid' => $uid], true);
|
||||
} elseif ($item['uid'] == $uid) {
|
||||
self::deleteById($item['id'], PRIORITY_HIGH);
|
||||
} else {
|
||||
logger('Wrong ownership. Not deleting item ' . $item['id']);
|
||||
}
|
||||
}
|
||||
dba::close($items);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Delete an item and notify others about it - if it was ours
|
||||
*
|
||||
|
@ -100,18 +136,20 @@ class Item extends BaseObject
|
|||
*
|
||||
* @return boolean success
|
||||
*/
|
||||
public static function deleteById($item_id, $priority = PRIORITY_HIGH)
|
||||
private static function deleteById($item_id, $priority = PRIORITY_HIGH)
|
||||
{
|
||||
// locate item to be deleted
|
||||
$fields = ['id', 'uid', 'parent', 'parent-uri', 'origin', 'deleted',
|
||||
'file', 'resource-id', 'event-id', 'attach',
|
||||
$fields = ['id', 'uri', 'uid', 'parent', 'parent-uri', 'origin',
|
||||
'deleted', 'file', 'resource-id', 'event-id', 'attach',
|
||||
'verb', 'object-type', 'object', 'target', 'contact-id'];
|
||||
$item = dba::selectFirst('item', $fields, ['id' => $item_id]);
|
||||
if (!DBM::is_result($item)) {
|
||||
logger('Item with ID ' . $item_id . " hasn't been found.", LOGGER_DEBUG);
|
||||
return false;
|
||||
}
|
||||
|
||||
if ($item['deleted']) {
|
||||
logger('Item with ID ' . $item_id . ' has already been deleted.', LOGGER_DEBUG);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -120,8 +158,6 @@ class Item extends BaseObject
|
|||
$parent = ['origin' => false];
|
||||
}
|
||||
|
||||
logger('delete item: ' . $item['id'], LOGGER_DEBUG);
|
||||
|
||||
// clean up categories and tags so they don't end up as orphans
|
||||
|
||||
$matches = false;
|
||||
|
@ -174,16 +210,34 @@ class Item extends BaseObject
|
|||
Term::insertFromFileFieldByItemId($item['id']);
|
||||
self::deleteThread($item['id'], $item['parent-uri']);
|
||||
|
||||
// If it's the parent of a comment thread, kill all the kids
|
||||
if ($item['id'] == $item['parent']) {
|
||||
self::delete(['parent' => $item['parent']], $priority);
|
||||
if (!dba::exists('item', ["`uri` = ? AND `uid` != 0 AND NOT `deleted`", $item['uri']])) {
|
||||
self::delete(['uri' => $item['uri'], 'uid' => 0, 'deleted' => false], $priority);
|
||||
}
|
||||
|
||||
// send the notification upstream/downstream
|
||||
if ($item['origin'] || $parent['origin']) {
|
||||
Worker::add(['priority' => $priority, 'dont_fork' => true], "Notifier", "drop", intval($item['id']));
|
||||
// If it's the parent of a comment thread, kill all the kids
|
||||
if ($item['id'] == $item['parent']) {
|
||||
self::delete(['parent' => $item['parent'], 'deleted' => false], $priority);
|
||||
}
|
||||
|
||||
// Is it our comment and/or our thread?
|
||||
if ($item['origin'] || $parent['origin']) {
|
||||
|
||||
// When we delete the original post we will delete all existing copies on the server as well
|
||||
self::delete(['uri' => $item['uri'], 'deleted' => false], $priority);
|
||||
|
||||
// send the notification upstream/downstream
|
||||
Worker::add(['priority' => $priority, 'dont_fork' => true], "Notifier", "drop", intval($item['id']));
|
||||
} elseif ($item['uid'] != 0) {
|
||||
|
||||
// When we delete just our local user copy of an item, we have to set a marker to hide it
|
||||
$global_item = dba::selectFirst('item', ['id'], ['uri' => $item['uri'], 'uid' => 0, 'deleted' => false]);
|
||||
if (DBM::is_result($global_item)) {
|
||||
dba::update('user-item', ['hidden' => true], ['iid' => $global_item['id'], 'uid' => $item['uid']], true);
|
||||
}
|
||||
}
|
||||
|
||||
logger('Item with ID ' . $item_id . " has been deleted.", LOGGER_DEBUG);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -324,6 +378,12 @@ class Item extends BaseObject
|
|||
$item['origin'] = 1;
|
||||
$item['network'] = NETWORK_DFRN;
|
||||
$item['protocol'] = PROTOCOL_DFRN;
|
||||
|
||||
if (is_int($notify)) {
|
||||
$priority = $notify;
|
||||
} else {
|
||||
$priority = PRIORITY_HIGH;
|
||||
}
|
||||
} else {
|
||||
$item['network'] = trim(defaults($item, 'network', NETWORK_PHANTOM));
|
||||
}
|
||||
|
@ -346,6 +406,13 @@ class Item extends BaseObject
|
|||
unset($item['dsprsig']);
|
||||
}
|
||||
|
||||
if (!empty($item['diaspora_signed_text'])) {
|
||||
$diaspora_signed_text = $item['diaspora_signed_text'];
|
||||
unset($item['diaspora_signed_text']);
|
||||
} else {
|
||||
$diaspora_signed_text = '';
|
||||
}
|
||||
|
||||
// Converting the plink
|
||||
/// @TODO Check if this is really still needed
|
||||
if ($item['network'] == NETWORK_OSTATUS) {
|
||||
|
@ -479,14 +546,20 @@ class Item extends BaseObject
|
|||
// The contact-id should be set before "self::insert" was called - but there seems to be issues sometimes
|
||||
$item["contact-id"] = self::contactId($item);
|
||||
|
||||
$item['author-id'] = defaults($item, 'author-id', Contact::getIdForURL($item["author-link"]));
|
||||
$default = ['url' => $item['author-link'], 'name' => $item['author-name'],
|
||||
'photo' => $item['author-avatar'], 'network' => $item['network']];
|
||||
|
||||
$item['author-id'] = defaults($item, 'author-id', Contact::getIdForURL($item["author-link"], 0, false, $default));
|
||||
|
||||
if (Contact::isBlocked($item["author-id"])) {
|
||||
logger('Contact '.$item["author-id"].' is blocked, item '.$item["uri"].' will not be stored');
|
||||
return 0;
|
||||
}
|
||||
|
||||
$item['owner-id'] = defaults($item, 'owner-id', Contact::getIdForURL($item["owner-link"]));
|
||||
$default = ['url' => $item['owner-link'], 'name' => $item['owner-name'],
|
||||
'photo' => $item['owner-avatar'], 'network' => $item['network']];
|
||||
|
||||
$item['owner-id'] = defaults($item, 'owner-id', Contact::getIdForURL($item["owner-link"], 0, false, $default));
|
||||
|
||||
if (Contact::isBlocked($item["owner-id"])) {
|
||||
logger('Contact '.$item["owner-id"].' is blocked, item '.$item["uri"].' will not be stored');
|
||||
|
@ -538,7 +611,7 @@ class Item extends BaseObject
|
|||
|
||||
$fields = ['uri', 'parent-uri', 'id', 'deleted',
|
||||
'allow_cid', 'allow_gid', 'deny_cid', 'deny_gid',
|
||||
'wall', 'private', 'forum_mode'];
|
||||
'wall', 'private', 'forum_mode', 'origin'];
|
||||
$condition = ['uri' => $item['parent-uri'], 'uid' => $item['uid']];
|
||||
$params = ['order' => ['id' => false]];
|
||||
$parent = dba::selectFirst('item', $fields, $condition, $params);
|
||||
|
@ -790,6 +863,12 @@ class Item extends BaseObject
|
|||
'signature' => $dsprsig->signature, 'signer' => $dsprsig->signer]);
|
||||
}
|
||||
|
||||
if (!empty($diaspora_signed_text)) {
|
||||
// Formerly we stored the signed text, the signature and the author in different fields.
|
||||
// We now store the raw data so that we are more flexible.
|
||||
dba::insert('sign', ['iid' => $current_post, 'signed_text' => $diaspora_signed_text]);
|
||||
}
|
||||
|
||||
$deleted = self::tagDeliver($item['uid'], $current_post);
|
||||
|
||||
/*
|
||||
|
@ -833,7 +912,9 @@ class Item extends BaseObject
|
|||
check_user_notification($current_post);
|
||||
|
||||
if ($notify) {
|
||||
Worker::add(['priority' => PRIORITY_HIGH, 'dont_fork' => true], "Notifier", $notify_type, $current_post);
|
||||
Worker::add(['priority' => $priority, 'dont_fork' => true], "Notifier", $notify_type, $current_post);
|
||||
} elseif (!empty($parent) && $parent['origin']) {
|
||||
Worker::add(['priority' => PRIORITY_HIGH, 'dont_fork' => true], "Notifier", "comment-import", $current_post);
|
||||
}
|
||||
|
||||
return $current_post;
|
||||
|
@ -842,9 +923,10 @@ class Item extends BaseObject
|
|||
/**
|
||||
* @brief Distributes public items to the receivers
|
||||
*
|
||||
* @param integer $itemid Item ID that should be added
|
||||
* @param integer $itemid Item ID that should be added
|
||||
* @param string $signed_text Original text (for Diaspora signatures), JSON encoded.
|
||||
*/
|
||||
public static function distribute($itemid)
|
||||
public static function distribute($itemid, $signed_text = '')
|
||||
{
|
||||
$condition = ["`id` IN (SELECT `parent` FROM `item` WHERE `id` = ?)", $itemid];
|
||||
$parent = dba::selectFirst('item', ['owner-id'], $condition);
|
||||
|
@ -879,14 +961,22 @@ class Item extends BaseObject
|
|||
$users[$contact['uid']] = $contact['uid'];
|
||||
}
|
||||
|
||||
$origin_uid = 0;
|
||||
|
||||
if ($item['uri'] != $item['parent-uri']) {
|
||||
$parents = dba::select('item', ['uid'], ["`uri` = ? AND `uid` != 0", $item['parent-uri']]);
|
||||
$parents = dba::select('item', ['uid', 'origin'], ["`uri` = ? AND `uid` != 0", $item['parent-uri']]);
|
||||
while ($parent = dba::fetch($parents)) {
|
||||
$users[$parent['uid']] = $parent['uid'];
|
||||
if ($parent['origin'] && !$item['origin']) {
|
||||
$origin_uid = $parent['uid'];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($users as $uid) {
|
||||
if ($origin_uid == $uid) {
|
||||
$item['diaspora_signed_text'] = $signed_text;
|
||||
}
|
||||
self::storeForUser($itemid, $item, $uid);
|
||||
}
|
||||
}
|
||||
|
@ -1192,7 +1282,7 @@ class Item extends BaseObject
|
|||
}
|
||||
}
|
||||
|
||||
private static function setHashtags(&$item)
|
||||
public static function setHashtags(&$item)
|
||||
{
|
||||
|
||||
$tags = get_tags($item["body"]);
|
||||
|
@ -2007,7 +2097,7 @@ EOT;
|
|||
{
|
||||
$fields = ['uid', 'guid', 'title', 'body', 'created', 'edited', 'commented', 'received', 'changed',
|
||||
'wall', 'private', 'pubmail', 'moderated', 'visible', 'spam', 'starred', 'bookmark', 'contact-id',
|
||||
'deleted', 'origin', 'forum_mode', 'network', 'rendered-html', 'rendered-hash'];
|
||||
'deleted', 'origin', 'forum_mode', 'network', 'author-id', 'owner-id', 'rendered-html', 'rendered-hash'];
|
||||
$condition = ["`id` = ? AND (`parent` = ? OR `parent` = 0)", $itemid, $itemid];
|
||||
|
||||
$item = dba::selectFirst('item', $fields, $condition);
|
||||
|
@ -2031,7 +2121,7 @@ EOT;
|
|||
|
||||
$result = dba::update('thread', $fields, ['iid' => $itemid]);
|
||||
|
||||
logger("Update thread for item ".$itemid." - guid ".$item["guid"]." - ".(int)$result." ".print_r($item, true), LOGGER_DEBUG);
|
||||
logger("Update thread for item ".$itemid." - guid ".$item["guid"]." - ".(int)$result, LOGGER_DEBUG);
|
||||
|
||||
// Updating a shadow item entry
|
||||
$items = dba::selectFirst('item', ['id'], ['guid' => $item['guid'], 'uid' => 0]);
|
||||
|
|
|
@ -90,7 +90,7 @@ class Profile
|
|||
*/
|
||||
public static function load(App $a, $nickname, $profile = 0, $profiledata = [], $show_connect = true)
|
||||
{
|
||||
$user = dba::selectFirst('user', ['uid'], ['nickname' => $nickname]);
|
||||
$user = dba::selectFirst('user', ['uid'], ['nickname' => $nickname, 'account_removed' => false]);
|
||||
|
||||
if (!DBM::is_result($user) && empty($profiledata)) {
|
||||
logger('profile error: ' . $a->query_string, LOGGER_DEBUG);
|
||||
|
|
154
src/Model/PushSubscriber.php
Normal file
154
src/Model/PushSubscriber.php
Normal file
|
@ -0,0 +1,154 @@
|
|||
<?php
|
||||
/**
|
||||
* @file src/Model/PushSubscriber.php
|
||||
*/
|
||||
namespace Friendica\Model;
|
||||
|
||||
use Friendica\Core\Worker;
|
||||
use Friendica\Util\DateTimeFormat;
|
||||
use Friendica\Database\DBM;
|
||||
use dba;
|
||||
|
||||
require_once 'include/dba.php';
|
||||
|
||||
class PushSubscriber
|
||||
{
|
||||
/**
|
||||
* @brief Send subscription notifications for the given user
|
||||
*
|
||||
* @param integer $uid User ID
|
||||
* @param string $priority Priority for push workers
|
||||
*/
|
||||
public static function publishFeed($uid, $default_priority = PRIORITY_HIGH)
|
||||
{
|
||||
$condition = ['push' => 0, 'uid' => $uid];
|
||||
dba::update('push_subscriber', ['push' => 1, 'next_try' => NULL_DATE], $condition);
|
||||
|
||||
self::requeue($default_priority);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief start workers to transmit the feed data
|
||||
*
|
||||
* @param string $priority Priority for push workers
|
||||
*/
|
||||
public static function requeue($default_priority = PRIORITY_HIGH)
|
||||
{
|
||||
// We'll push to each subscriber that has push > 0,
|
||||
// i.e. there has been an update (set in notifier.php).
|
||||
$subscribers = dba::select('push_subscriber', ['id', 'push', 'callback_url', 'nickname'], ["`push` > 0 AND `next_try` < UTC_TIMESTAMP()"]);
|
||||
|
||||
while ($subscriber = dba::fetch($subscribers)) {
|
||||
// We always handle retries with low priority
|
||||
if ($subscriber['push'] > 1) {
|
||||
$priority = PRIORITY_LOW;
|
||||
} else {
|
||||
$priority = $default_priority;
|
||||
}
|
||||
|
||||
logger('Publish feed to ' . $subscriber['callback_url'] . ' for ' . $subscriber['nickname'] . ' with priority ' . $priority, LOGGER_DEBUG);
|
||||
Worker::add($priority, 'PubSubPublish', (int)$subscriber['id']);
|
||||
}
|
||||
|
||||
dba::close($subscribers);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Renew the feed subscription
|
||||
*
|
||||
* @param integer $uid User ID
|
||||
* @param string $nick Priority for push workers
|
||||
* @param integer $subscribe Subscribe (Unsubscribe = false)
|
||||
* @param string $hub_callback Callback address
|
||||
* @param string $hub_topic Feed topic
|
||||
* @param string $hub_secret Subscription secret
|
||||
*/
|
||||
public static function renew($uid, $nick, $subscribe, $hub_callback, $hub_topic, $hub_secret)
|
||||
{
|
||||
// fetch the old subscription if it exists
|
||||
$subscriber = dba::selectFirst('push_subscriber', ['last_update', 'push'], ['callback_url' => $hub_callback]);
|
||||
|
||||
// delete old subscription if it exists
|
||||
dba::delete('push_subscriber', ['callback_url' => $hub_callback]);
|
||||
|
||||
if ($subscribe) {
|
||||
// if we are just updating an old subscription, keep the
|
||||
// old values for last_update but reset the push
|
||||
if (DBM::is_result($subscriber)) {
|
||||
$last_update = $subscriber['last_update'];
|
||||
$push_flag = min($subscriber['push'], 1);
|
||||
} else {
|
||||
$last_update = DateTimeFormat::utcNow();
|
||||
$push_flag = 0;
|
||||
}
|
||||
|
||||
// subscribe means adding the row to the table
|
||||
$fields = ['uid' => $uid, 'callback_url' => $hub_callback,
|
||||
'topic' => $hub_topic, 'nickname' => $nick, 'push' => $push_flag,
|
||||
'last_update' => $last_update, 'renewed' => DateTimeFormat::utcNow(),
|
||||
'secret' => $hub_secret];
|
||||
dba::insert('push_subscriber', $fields);
|
||||
|
||||
logger("Successfully subscribed [$hub_callback] for $nick");
|
||||
} else {
|
||||
logger("Successfully unsubscribed [$hub_callback] for $nick");
|
||||
// we do nothing here, since the row was already deleted
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Delay the push subscriber
|
||||
*
|
||||
* @param integer $id Subscriber ID
|
||||
*/
|
||||
public static function delay($id)
|
||||
{
|
||||
$subscriber = dba::selectFirst('push_subscriber', ['push', 'callback_url', 'renewed', 'nickname'], ['id' => $id]);
|
||||
if (!DBM::is_result($subscriber)) {
|
||||
return;
|
||||
}
|
||||
|
||||
$retrial = $subscriber['push'];
|
||||
|
||||
if ($retrial > 14) {
|
||||
// End subscriptions if they weren't renewed for more than two months
|
||||
$days = round((time() - strtotime($subscriber['renewed'])) / (60 * 60 * 24));
|
||||
|
||||
if ($days > 60) {
|
||||
dba::update('push_subscriber', ['push' => -1, 'next_try' => NULL_DATE], ['id' => $id]);
|
||||
logger('Delivery error: Subscription ' . $subscriber['callback_url'] . ' for ' . $subscriber['nickname'] . ' is marked as ended.', LOGGER_DEBUG);
|
||||
} else {
|
||||
dba::update('push_subscriber', ['push' => 0, 'next_try' => NULL_DATE], ['id' => $id]);
|
||||
logger('Delivery error: Giving up ' . $subscriber['callback_url'] . ' for ' . $subscriber['nickname'] . ' for now.', LOGGER_DEBUG);
|
||||
}
|
||||
} else {
|
||||
// Calculate the delay until the next trial
|
||||
$delay = (($retrial + 3) ** 4) + (rand(1, 30) * ($retrial + 1));
|
||||
$next = DateTimeFormat::utc('now + ' . $delay . ' seconds');
|
||||
|
||||
$retrial = $retrial + 1;
|
||||
|
||||
dba::update('push_subscriber', ['push' => $retrial, 'next_try' => $next], ['id' => $id]);
|
||||
logger('Delivery error: Next try (' . $retrial . ') ' . $subscriber['callback_url'] . ' for ' . $subscriber['nickname'] . ' at ' . $next, LOGGER_DEBUG);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Reset the push subscriber
|
||||
*
|
||||
* @param integer $id Subscriber ID
|
||||
* @param date $last_update Date of last transmitted item
|
||||
*/
|
||||
public static function reset($id, $last_update)
|
||||
{
|
||||
$subscriber = dba::selectFirst('push_subscriber', ['callback_url', 'nickname'], ['id' => $id]);
|
||||
if (!DBM::is_result($subscriber)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// set last_update to the 'created' date of the last item, and reset push=0
|
||||
$fields = ['push' => 0, 'next_try' => NULL_DATE, 'last_update' => $last_update];
|
||||
dba::update('push_subscriber', $fields, ['id' => $id]);
|
||||
logger('Subscriber ' . $subscriber['callback_url'] . ' for ' . $subscriber['nickname'] . ' is marked as vital', LOGGER_DEBUG);
|
||||
}
|
||||
}
|
|
@ -331,6 +331,7 @@ class User
|
|||
$confirm = x($data, 'confirm') ? trim($data['confirm']) : '';
|
||||
$blocked = x($data, 'blocked') ? intval($data['blocked']) : 0;
|
||||
$verified = x($data, 'verified') ? intval($data['verified']) : 0;
|
||||
$language = x($data, 'language') ? notags(trim($data['language'])) : 'en';
|
||||
|
||||
$publish = x($data, 'profile_publish_reg') && intval($data['profile_publish_reg']) ? 1 : 0;
|
||||
$netpublish = strlen(Config::get('system', 'directory')) ? $publish : 0;
|
||||
|
@ -359,7 +360,7 @@ class User
|
|||
$_SESSION['register'] = 1;
|
||||
$_SESSION['openid'] = $openid_url;
|
||||
|
||||
$openid = new LightOpenID;
|
||||
$openid = new LightOpenID($a->get_hostname());
|
||||
$openid->identity = $openid_url;
|
||||
$openid->returnUrl = System::baseUrl() . '/openid';
|
||||
$openid->required = ['namePerson/friendly', 'contact/email', 'namePerson'];
|
||||
|
@ -466,6 +467,7 @@ class User
|
|||
'sprvkey' => $sprvkey,
|
||||
'verified' => $verified,
|
||||
'blocked' => $blocked,
|
||||
'language' => $language,
|
||||
'timezone' => 'UTC',
|
||||
'register_date' => DateTimeFormat::utcNow(),
|
||||
'default-location' => ''
|
||||
|
|
|
@ -90,7 +90,8 @@ class Login extends BaseModule
|
|||
|
||||
// Otherwise it's probably an openid.
|
||||
try {
|
||||
$openid = new LightOpenID;
|
||||
$a = get_app();
|
||||
$openid = new LightOpenID($a->get_hostname());
|
||||
$openid->identity = $openid_url;
|
||||
$_SESSION['openid'] = $openid_url;
|
||||
$_SESSION['remember'] = $remember;
|
||||
|
|
|
@ -16,6 +16,29 @@ use Friendica\Content\Text\BBCode;
|
|||
|
||||
class Tos extends BaseModule
|
||||
{
|
||||
// Some text elements we need more than once to keep updating them easy.
|
||||
public $privacy_operate;
|
||||
public $privacy_distribute;
|
||||
public $privacy_delete;
|
||||
public $privacy_complete;
|
||||
|
||||
/**
|
||||
* @brief constructor for the module, initializing the text variables
|
||||
*
|
||||
* To make the text variables available outside of the module, they need to
|
||||
* be properties of the class, however cannot be set directly as the property
|
||||
* cannot depend on a function result when declaring the variable.
|
||||
**/
|
||||
public function __construct()
|
||||
{
|
||||
$this->privacy_operate = L10n::t('At the time of registration, and for providing communications between the user account and their contacts, the user has to provide a display name (pen name), an username (nickname) and a working email address. The names will be accessible on the profile page of the account by any visitor of the page, even if other profile details are not displayed. The email address will only be used to send the user notifications about interactions, but wont be visibly displayed. The listing of an account in the node\'s user directory or the global user directory is optional and can be controlled in the user settings, it is not necessary for communication.');
|
||||
$this->privacy_distribute = L10n::t('This data is required for communication and is passed on to the nodes of the communication partners and is stored there. Users can enter additional private data that may be transmitted to the communication partners accounts.');
|
||||
$this->privacy_delete = L10n::t('At any point in time a logged in user can export their account data from the <a href="%1$s/settings/uexport">account settings</a>. If the user wants to delete their account they can do so at <a href="%1$s/removeme">%1$s/removeme</a>. The deletion of the account will be permanent. Deletion of the data will also be requested from the nodes of the communication partners.', System::baseurl());
|
||||
// In some cases we don't need every single one of the above separate, but all in one block.
|
||||
// So here is an array to look over
|
||||
$this->privacy_complete = [L10n::t('Privacy Statement'), $this->privacy_operate, $this->privacy_distribute, $this->privacy_delete];
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief initialize the TOS module.
|
||||
*
|
||||
|
@ -42,17 +65,16 @@ class Tos extends BaseModule
|
|||
**/
|
||||
public static function content() {
|
||||
$tpl = get_markup_template('tos.tpl');
|
||||
if (Config::get('system', 'tosdisplay'))
|
||||
{
|
||||
return replace_macros($tpl, [
|
||||
'$title' => L10n::t("Terms of Service"),
|
||||
'$tostext' => BBCode::convert(Config::get('system', 'tostext')),
|
||||
'$displayprivstatement' => Config::get('system', 'tosprivstatement'),
|
||||
'$privstatementtitle' => L10n::t("Privacy Statement"),
|
||||
'$privoperate' => L10n::t('At the time of registration, and for providing communications between the user account and their contacts, the user has to provide a display name (pen name), an username (nickname) and a working email address. The names will be accessible on the profile page of the account by any visitor of the page, even if other profile details are not displayed. The email address will only be used to send the user notifications about interactions, but wont be visibly displayed. The listing of an account in the node\'s user directory or the global user directory is optional and can be controlled in the user settings, it is not necessary for communication.'),
|
||||
'$privdistribute' => L10n::t('This data is required for communication and is passed on to the nodes of the communication partners. Users can enter additional private data that may be transmitted to the communication partners accounts.'),
|
||||
'$privdelete' => L10n::t('At any point in time a logged in user can export their account data from the <a href="%1$s/settings/uexport">account settings</a>. If the user wants to delete their account they can do so at <a href="%1$s/removeme">%1$s/removeme</a>. The deletion of the account will be permanent.', System::baseurl())
|
||||
]);
|
||||
if (Config::get('system', 'tosdisplay')) {
|
||||
return replace_macros($tpl, [
|
||||
'$title' => L10n::t('Terms of Service'),
|
||||
'$tostext' => BBCode::convert(Config::get('system', 'tostext')),
|
||||
'$displayprivstatement' => Config::get('system', 'tosprivstatement'),
|
||||
'$privstatementtitle' => L10n::t('Privacy Statement'),
|
||||
'$privacy_operate' => L10n::t('At the time of registration, and for providing communications between the user account and their contacts, the user has to provide a display name (pen name), an username (nickname) and a working email address. The names will be accessible on the profile page of the account by any visitor of the page, even if other profile details are not displayed. The email address will only be used to send the user notifications about interactions, but wont be visibly displayed. The listing of an account in the node\'s user directory or the global user directory is optional and can be controlled in the user settings, it is not necessary for communication.'),
|
||||
'$privacy_distribute' => L10n::t('This data is required for communication and is passed on to the nodes of the communication partners and is stored there. Users can enter additional private data that may be transmitted to the communication partners accounts.'),
|
||||
'$privacy_delete' => L10n::t('At any point in time a logged in user can export their account data from the <a href="%1$s/settings/uexport">account settings</a>. If the user wants to delete their account they can do so at <a href="%1$s/removeme">%1$s/removeme</a>. The deletion of the account will be permanent. Deletion of the data will also be requested from the nodes of the communication partners.', System::baseurl())
|
||||
]);
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -20,7 +20,7 @@ use Friendica\Protocol\Feed;
|
|||
use Friendica\Util\Crypto;
|
||||
use Friendica\Util\Network;
|
||||
use Friendica\Util\XML;
|
||||
|
||||
use Friendica\Util\DateTimeFormat;
|
||||
use dba;
|
||||
use DOMXPath;
|
||||
use DOMDocument;
|
||||
|
@ -357,11 +357,11 @@ class Probe
|
|||
}
|
||||
}
|
||||
|
||||
if (self::$baseurl != "") {
|
||||
if (!empty(self::$baseurl)) {
|
||||
$data["baseurl"] = self::$baseurl;
|
||||
}
|
||||
|
||||
if (!isset($data["network"])) {
|
||||
if (empty($data["network"])) {
|
||||
$data["network"] = NETWORK_PHANTOM;
|
||||
}
|
||||
|
||||
|
@ -395,6 +395,12 @@ class Probe
|
|||
'network' => $data['network'],
|
||||
'server_url' => $data['baseurl']];
|
||||
|
||||
// This doesn't cover the case when a community isn't a community anymore
|
||||
if (!empty($data['community']) && $data['community']) {
|
||||
$fields['community'] = $data['community'];
|
||||
$fields['contact-type'] = ACCOUNT_TYPE_COMMUNITY;
|
||||
}
|
||||
|
||||
$fieldnames = [];
|
||||
|
||||
foreach ($fields as $key => $val) {
|
||||
|
@ -411,6 +417,17 @@ class Probe
|
|||
|
||||
$old_fields = dba::selectFirst('gcontact', $fieldnames, $condition);
|
||||
|
||||
// When the gcontact doesn't exist, the value "true" will trigger an insert.
|
||||
// In difference to the public contacts we want to have every contact
|
||||
// in the world in our global contacts.
|
||||
if (!$old_fields) {
|
||||
$old_fields = true;
|
||||
|
||||
// These values have to be set only on insert
|
||||
$fields['photo'] = $data['photo'];
|
||||
$fields['created'] = DateTimeFormat::utcNow();
|
||||
}
|
||||
|
||||
dba::update('gcontact', $fields, $condition, $old_fields);
|
||||
|
||||
$fields = ['name' => $data['name'],
|
||||
|
@ -428,7 +445,10 @@ class Probe
|
|||
'confirm' => $data['confirm'],
|
||||
'poco' => $data['poco'],
|
||||
'network' => $data['network'],
|
||||
'success_update' => DBM::date()];
|
||||
'pubkey' => $data['pubkey'],
|
||||
'priority' => $data['priority'],
|
||||
'writable' => true,
|
||||
'rel' => CONTACT_IS_SHARING];
|
||||
|
||||
$fieldnames = [];
|
||||
|
||||
|
@ -442,14 +462,15 @@ class Probe
|
|||
|
||||
$condition = ['nurl' => normalise_link($data["url"]), 'self' => false, 'uid' => 0];
|
||||
|
||||
// "$old_fields" will return a "false" when the contact doesn't exist.
|
||||
// This won't trigger an insert. This is intended, since we only need
|
||||
// public contacts for everyone we store items from.
|
||||
// We don't need to store every contact on the planet.
|
||||
$old_fields = dba::selectFirst('contact', $fieldnames, $condition);
|
||||
|
||||
// When the contact doesn't exist, the value "true" will trigger an insert
|
||||
if (!$old_fields) {
|
||||
$old_fields = true;
|
||||
$fields['blocked'] = false;
|
||||
$fields['pending'] = false;
|
||||
}
|
||||
$fields['name-date'] = DateTimeFormat::utcNow();
|
||||
$fields['uri-date'] = DateTimeFormat::utcNow();
|
||||
$fields['success_update'] = DateTimeFormat::utcNow();
|
||||
|
||||
dba::update('contact', $fields, $condition, $old_fields);
|
||||
}
|
||||
|
|
|
@ -172,13 +172,31 @@ class Post extends BaseObject
|
|||
$dropping = true;
|
||||
}
|
||||
|
||||
$origin = $item['origin'];
|
||||
|
||||
if (!$origin) {
|
||||
/// @todo This shouldn't be done as query here, but better during the data creation.
|
||||
// it is now done here, since during the RC phase we shouldn't make to intense changes.
|
||||
$parent = dba::selectFirst('item', ['origin'], ['id' => $item['parent']]);
|
||||
if (DBM::is_result($parent)) {
|
||||
$origin = $parent['origin'];
|
||||
}
|
||||
}
|
||||
|
||||
// Showing the one or the other text, depending upon if we can only hide it or really delete it.
|
||||
$delete = $origin ? L10n::t('Delete') : L10n::t('Remove from your stream');
|
||||
|
||||
$drop = [
|
||||
'dropping' => $dropping,
|
||||
'pagedrop' => ((Feature::isEnabled($conv->getProfileOwner(), 'multi_delete')) ? $item['pagedrop'] : ''),
|
||||
'select' => L10n::t('Select'),
|
||||
'delete' => L10n::t('Delete'),
|
||||
'delete' => $delete,
|
||||
];
|
||||
|
||||
if (!local_user()) {
|
||||
$drop = false;
|
||||
}
|
||||
|
||||
$filer = (($conv->getProfileOwner() == local_user() && ($item['uid'] != 0)) ? L10n::t("save to folder") : false);
|
||||
|
||||
$diff_author = !link_compare($item['url'], $item['author-link']);
|
||||
|
@ -199,22 +217,12 @@ class Post extends BaseObject
|
|||
$profile_link = Profile::zrl($profile_link);
|
||||
}
|
||||
|
||||
if (!isset($item['author-thumb']) || ($item['author-thumb'] == "")) {
|
||||
$author_contact = Contact::getDetailsByURL($item['author-link'], $conv->getProfileOwner());
|
||||
if ($author_contact["thumb"]) {
|
||||
$item['author-thumb'] = $author_contact["thumb"];
|
||||
} else {
|
||||
$item['author-thumb'] = $item['author-avatar'];
|
||||
}
|
||||
if (($item['network'] == NETWORK_FEED) || empty($item['author-thumb'])) {
|
||||
$item['author-thumb'] = $item['author-avatar'];
|
||||
}
|
||||
|
||||
if (!isset($item['owner-thumb']) || ($item['owner-thumb'] == "")) {
|
||||
$owner_contact = Contact::getDetailsByURL($item['owner-link'], $conv->getProfileOwner());
|
||||
if ($owner_contact["thumb"]) {
|
||||
$item['owner-thumb'] = $owner_contact["thumb"];
|
||||
} else {
|
||||
$item['owner-thumb'] = $item['owner-avatar'];
|
||||
}
|
||||
if (($item['network'] == NETWORK_FEED) || empty($item['owner-thumb'])) {
|
||||
$item['owner-thumb'] = $item['owner-avatar'];
|
||||
}
|
||||
|
||||
$locate = ['location' => $item['location'], 'coord' => $item['coord'], 'html' => ''];
|
||||
|
|
|
@ -50,9 +50,9 @@ require_once "include/text.php";
|
|||
class DFRN
|
||||
{
|
||||
|
||||
const DFRN_TOP_LEVEL = 0; // Top level posting
|
||||
const DFRN_REPLY = 1; // Regular reply that is stored locally
|
||||
const DFRN_REPLY_RC = 2; // Reply that will be relayed
|
||||
const TOP_LEVEL = 0; // Top level posting
|
||||
const REPLY = 1; // Regular reply that is stored locally
|
||||
const REPLY_RC = 2; // Reply that will be relayed
|
||||
|
||||
/**
|
||||
* @brief Generates the atom entries for delivery.php
|
||||
|
@ -2146,10 +2146,6 @@ class DFRN
|
|||
Item::update($fields, $condition);
|
||||
|
||||
$changed = true;
|
||||
|
||||
if ($entrytype == DFRN_REPLY_RC) {
|
||||
Worker::add(PRIORITY_HIGH, "Notifier", "comment-import", $current["id"]);
|
||||
}
|
||||
}
|
||||
return $changed;
|
||||
}
|
||||
|
@ -2217,12 +2213,12 @@ class DFRN
|
|||
}
|
||||
|
||||
if ($is_a_remote_action) {
|
||||
return DFRN_REPLY_RC;
|
||||
return DFRN::REPLY_RC;
|
||||
} else {
|
||||
return DFRN_REPLY;
|
||||
return DFRN::REPLY;
|
||||
}
|
||||
} else {
|
||||
return DFRN_TOP_LEVEL;
|
||||
return DFRN::TOP_LEVEL;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2296,7 +2292,7 @@ class DFRN
|
|||
{
|
||||
logger("Process verb ".$item["verb"]." and object-type ".$item["object-type"]." for entrytype ".$entrytype, LOGGER_DEBUG);
|
||||
|
||||
if (($entrytype == DFRN_TOP_LEVEL)) {
|
||||
if (($entrytype == DFRN::TOP_LEVEL)) {
|
||||
// The filling of the the "contact" variable is done for legcy reasons
|
||||
// The functions below are partly used by ostatus.php as well - where we have this variable
|
||||
$r = q("SELECT * FROM `contact` WHERE `id` = %d", intval($importer["id"]));
|
||||
|
@ -2640,7 +2636,7 @@ class DFRN
|
|||
$entrytype = self::getEntryType($importer, $item);
|
||||
|
||||
// Now assign the rest of the values that depend on the type of the message
|
||||
if (in_array($entrytype, [DFRN_REPLY, DFRN_REPLY_RC])) {
|
||||
if (in_array($entrytype, [DFRN::REPLY, DFRN::REPLY_RC])) {
|
||||
if (!isset($item["object-type"])) {
|
||||
$item["object-type"] = ACTIVITY_OBJ_COMMENT;
|
||||
}
|
||||
|
@ -2662,10 +2658,10 @@ class DFRN
|
|||
}
|
||||
}
|
||||
|
||||
if ($entrytype == DFRN_REPLY_RC) {
|
||||
if ($entrytype == DFRN::REPLY_RC) {
|
||||
$item["type"] = "remote-comment";
|
||||
$item["wall"] = 1;
|
||||
} elseif ($entrytype == DFRN_TOP_LEVEL) {
|
||||
} elseif ($entrytype == DFRN::TOP_LEVEL) {
|
||||
if (!isset($item["object-type"])) {
|
||||
$item["object-type"] = ACTIVITY_OBJ_NOTE;
|
||||
}
|
||||
|
@ -2714,7 +2710,7 @@ class DFRN
|
|||
return;
|
||||
}
|
||||
|
||||
if (in_array($entrytype, [DFRN_REPLY, DFRN_REPLY_RC])) {
|
||||
if (in_array($entrytype, [DFRN::REPLY, DFRN::REPLY_RC])) {
|
||||
$posted_id = Item::insert($item);
|
||||
$parent = 0;
|
||||
|
||||
|
@ -2725,26 +2721,9 @@ class DFRN
|
|||
Item::distribute($posted_id);
|
||||
}
|
||||
|
||||
$item["id"] = $posted_id;
|
||||
|
||||
$r = q(
|
||||
"SELECT `parent`, `parent-uri` FROM `item` WHERE `id` = %d AND `uid` = %d LIMIT 1",
|
||||
intval($posted_id),
|
||||
intval($importer["importer_uid"])
|
||||
);
|
||||
if (DBM::is_result($r)) {
|
||||
$parent = $r[0]["parent"];
|
||||
$parent_uri = $r[0]["parent-uri"];
|
||||
}
|
||||
|
||||
if ($posted_id && $parent && ($entrytype == DFRN_REPLY_RC)) {
|
||||
logger("Notifying followers about comment ".$posted_id, LOGGER_DEBUG);
|
||||
Worker::add(PRIORITY_HIGH, "Notifier", "comment-import", $posted_id);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
} else { // $entrytype == DFRN_TOP_LEVEL
|
||||
} else { // $entrytype == DFRN::TOP_LEVEL
|
||||
if (($importer["uid"] == 0) && ($importer["importer_uid"] != 0)) {
|
||||
logger("Contact ".$importer["id"]." isn't known to user ".$importer["importer_uid"].". The post will be ignored.", LOGGER_DEBUG);
|
||||
return;
|
||||
|
@ -2835,23 +2814,13 @@ class DFRN
|
|||
}
|
||||
}
|
||||
|
||||
$entrytype = self::getEntryType($importer, $item);
|
||||
|
||||
if (!$item["deleted"]) {
|
||||
logger('deleting item '.$item["id"].' uri='.$uri, LOGGER_DEBUG);
|
||||
} else {
|
||||
if ($item["deleted"]) {
|
||||
return;
|
||||
}
|
||||
|
||||
Item::deleteById($item["id"]);
|
||||
logger('deleting item '.$item['id'].' uri='.$uri, LOGGER_DEBUG);
|
||||
|
||||
if ($entrytype != DFRN_TOP_LEVEL) {
|
||||
// if this is a relayed delete, propagate it to other recipients
|
||||
if ($entrytype == DFRN_REPLY_RC) {
|
||||
logger("Notifying followers about deletion of post " . $item["id"], LOGGER_DEBUG);
|
||||
Worker::add(PRIORITY_HIGH, "Notifier", "drop", $item["id"]);
|
||||
}
|
||||
}
|
||||
Item::delete(['id' => $item['id']]);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -920,7 +920,7 @@ class Diaspora
|
|||
// Note that Friendica contacts will return a "Diaspora person"
|
||||
// if Diaspora connectivity is enabled on their server
|
||||
if ($r && ($r["network"] === NETWORK_DIASPORA)) {
|
||||
self::addFContact($r, $update);
|
||||
self::updateFContact($r);
|
||||
|
||||
// Fetch the updated or added contact
|
||||
$person = dba::selectFirst('fcontact', [], ['network' => NETWORK_DIASPORA, 'addr' => $handle]);
|
||||
|
@ -936,70 +936,21 @@ class Diaspora
|
|||
/**
|
||||
* @brief Updates the fcontact table
|
||||
*
|
||||
* @param array $arr The fcontact data
|
||||
* @param bool $update Update or insert?
|
||||
*
|
||||
* @return string The id of the fcontact entry
|
||||
* @param array $arr The fcontact data
|
||||
*/
|
||||
private static function addFContact($arr, $update = false)
|
||||
private static function updateFContact($arr)
|
||||
{
|
||||
if ($update) {
|
||||
$r = q(
|
||||
"UPDATE `fcontact` SET
|
||||
`name` = '%s',
|
||||
`photo` = '%s',
|
||||
`request` = '%s',
|
||||
`nick` = '%s',
|
||||
`addr` = '%s',
|
||||
`guid` = '%s',
|
||||
`batch` = '%s',
|
||||
`notify` = '%s',
|
||||
`poll` = '%s',
|
||||
`confirm` = '%s',
|
||||
`alias` = '%s',
|
||||
`pubkey` = '%s',
|
||||
`updated` = '%s'
|
||||
WHERE `url` = '%s' AND `network` = '%s'",
|
||||
dbesc($arr["name"]),
|
||||
dbesc($arr["photo"]),
|
||||
dbesc($arr["request"]),
|
||||
dbesc($arr["nick"]),
|
||||
dbesc(strtolower($arr["addr"])),
|
||||
dbesc($arr["guid"]),
|
||||
dbesc($arr["batch"]),
|
||||
dbesc($arr["notify"]),
|
||||
dbesc($arr["poll"]),
|
||||
dbesc($arr["confirm"]),
|
||||
dbesc($arr["alias"]),
|
||||
dbesc($arr["pubkey"]),
|
||||
dbesc(DateTimeFormat::utcNow()),
|
||||
dbesc($arr["url"]),
|
||||
dbesc($arr["network"])
|
||||
);
|
||||
} else {
|
||||
$r = q(
|
||||
"INSERT INTO `fcontact` (`url`,`name`,`photo`,`request`,`nick`,`addr`, `guid`,
|
||||
`batch`, `notify`,`poll`,`confirm`,`network`,`alias`,`pubkey`,`updated`)
|
||||
VALUES ('%s','%s','%s','%s','%s','%s','%s','%s','%s','%s','%s','%s','%s','%s','%s')",
|
||||
dbesc($arr["url"]),
|
||||
dbesc($arr["name"]),
|
||||
dbesc($arr["photo"]),
|
||||
dbesc($arr["request"]),
|
||||
dbesc($arr["nick"]),
|
||||
dbesc($arr["addr"]),
|
||||
dbesc($arr["guid"]),
|
||||
dbesc($arr["batch"]),
|
||||
dbesc($arr["notify"]),
|
||||
dbesc($arr["poll"]),
|
||||
dbesc($arr["confirm"]),
|
||||
dbesc($arr["network"]),
|
||||
dbesc($arr["alias"]),
|
||||
dbesc($arr["pubkey"]),
|
||||
dbesc(DateTimeFormat::utcNow())
|
||||
);
|
||||
}
|
||||
$fields = ['name' => $arr["name"], 'photo' => $arr["photo"],
|
||||
'request' => $arr["request"], 'nick' => $arr["nick"],
|
||||
'addr' => strtolower($arr["addr"]), 'guid' => $arr["guid"],
|
||||
'batch' => $arr["batch"], 'notify' => $arr["notify"],
|
||||
'poll' => $arr["poll"], 'confirm' => $arr["confirm"],
|
||||
'alias' => $arr["alias"], 'pubkey' => $arr["pubkey"],
|
||||
'updated' => DateTimeFormat::utcNow()];
|
||||
|
||||
return $r;
|
||||
$condition = ['url' => $arr["url"], 'network' => $arr["network"]];
|
||||
|
||||
dba::update('fcontact', $fields, $condition, true);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1796,6 +1747,12 @@ class Diaspora
|
|||
|
||||
self::fetchGuid($datarray);
|
||||
|
||||
// If we are the origin of the parent we store the original data.
|
||||
// We notify our followers during the item storage.
|
||||
if ($parent_item["origin"]) {
|
||||
$datarray['diaspora_signed_text'] = json_encode($data);
|
||||
}
|
||||
|
||||
$message_id = Item::insert($datarray);
|
||||
|
||||
if ($message_id <= 0) {
|
||||
|
@ -1805,20 +1762,10 @@ class Diaspora
|
|||
if ($message_id) {
|
||||
logger("Stored comment ".$datarray["guid"]." with message id ".$message_id, LOGGER_DEBUG);
|
||||
if ($datarray['uid'] == 0) {
|
||||
Item::distribute($message_id);
|
||||
Item::distribute($message_id, json_encode($data));
|
||||
}
|
||||
}
|
||||
|
||||
// If we are the origin of the parent we store the original data and notify our followers
|
||||
if ($message_id && $parent_item["origin"]) {
|
||||
// Formerly we stored the signed text, the signature and the author in different fields.
|
||||
// We now store the raw data so that we are more flexible.
|
||||
dba::insert('sign', ['iid' => $message_id, 'signed_text' => json_encode($data)]);
|
||||
|
||||
// notify others
|
||||
Worker::add(PRIORITY_HIGH, "Notifier", "comment-import", $message_id);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -2120,6 +2067,20 @@ class Diaspora
|
|||
|
||||
$datarray["body"] = self::constructLikeBody($contact, $parent_item, $guid);
|
||||
|
||||
// like on comments have the comment as parent. So we need to fetch the toplevel parent
|
||||
if ($parent_item["id"] != $parent_item["parent"]) {
|
||||
$toplevel = dba::selectFirst('item', ['origin'], ['id' => $parent_item["parent"]]);
|
||||
$origin = $toplevel["origin"];
|
||||
} else {
|
||||
$origin = $parent_item["origin"];
|
||||
}
|
||||
|
||||
// If we are the origin of the parent we store the original data.
|
||||
// We notify our followers during the item storage.
|
||||
if ($origin) {
|
||||
$datarray['diaspora_signed_text'] = json_encode($data);
|
||||
}
|
||||
|
||||
$message_id = Item::insert($datarray);
|
||||
|
||||
if ($message_id <= 0) {
|
||||
|
@ -2129,28 +2090,10 @@ class Diaspora
|
|||
if ($message_id) {
|
||||
logger("Stored like ".$datarray["guid"]." with message id ".$message_id, LOGGER_DEBUG);
|
||||
if ($datarray['uid'] == 0) {
|
||||
Item::distribute($message_id);
|
||||
Item::distribute($message_id, json_encode($data));
|
||||
}
|
||||
}
|
||||
|
||||
// like on comments have the comment as parent. So we need to fetch the toplevel parent
|
||||
if ($parent_item["id"] != $parent_item["parent"]) {
|
||||
$toplevel = dba::selectFirst('item', ['origin'], ['id' => $parent_item["parent"]]);
|
||||
$origin = $toplevel["origin"];
|
||||
} else {
|
||||
$origin = $parent_item["origin"];
|
||||
}
|
||||
|
||||
// If we are the origin of the parent we store the original data and notify our followers
|
||||
if ($message_id && $origin) {
|
||||
// Formerly we stored the signed text, the signature and the author in different fields.
|
||||
// We now store the raw data so that we are more flexible.
|
||||
dba::insert('sign', ['iid' => $message_id, 'signed_text' => json_encode($data)]);
|
||||
|
||||
// notify others
|
||||
Worker::add(PRIORITY_HIGH, "Notifier", "comment-import", $message_id);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -2398,21 +2341,17 @@ class Diaspora
|
|||
$birthday = $contact["bd"];
|
||||
}
|
||||
|
||||
$r = q(
|
||||
"UPDATE `contact` SET `name` = '%s', `nick` = '%s', `addr` = '%s', `name-date` = '%s', `bd` = '%s',
|
||||
`location` = '%s', `about` = '%s', `keywords` = '%s', `gender` = '%s' WHERE `id` = %d AND `uid` = %d",
|
||||
dbesc($name),
|
||||
dbesc($nick),
|
||||
dbesc($author),
|
||||
dbesc(DateTimeFormat::utcNow()),
|
||||
dbesc($birthday),
|
||||
dbesc($location),
|
||||
dbesc($about),
|
||||
dbesc($keywords),
|
||||
dbesc($gender),
|
||||
intval($contact["id"]),
|
||||
intval($importer["uid"])
|
||||
);
|
||||
$fields = ['name' => $name, 'location' => $location,
|
||||
'name-date' => DateTimeFormat::utcNow(),
|
||||
'about' => $about, 'gender' => $gender,
|
||||
'addr' => $author, 'nick' => $nick,
|
||||
'keywords' => $keywords];
|
||||
|
||||
if (!empty($birthday)) {
|
||||
$fields['bd'] = $birthday;
|
||||
}
|
||||
|
||||
dba::update('contact', $fields, ['id' => $contact['id']]);
|
||||
|
||||
$gcontact = ["url" => $contact["url"], "network" => NETWORK_DIASPORA, "generation" => 2,
|
||||
"photo" => $image_url, "name" => $name, "location" => $location,
|
||||
|
@ -2447,78 +2386,6 @@ class Diaspora
|
|||
['id' => $contact["id"], 'uid' => $importer["uid"]]
|
||||
);
|
||||
}
|
||||
// send notification
|
||||
|
||||
$r = q(
|
||||
"SELECT `hide-friends` FROM `profile` WHERE `uid` = %d AND `is-default` = 1 LIMIT 1",
|
||||
intval($importer["uid"])
|
||||
);
|
||||
|
||||
if ($r && !$r[0]["hide-friends"] && !$contact["hidden"] && intval(PConfig::get($importer["uid"], "system", "post_newfriend"))) {
|
||||
$self = q(
|
||||
"SELECT * FROM `contact` WHERE `self` AND `uid` = %d LIMIT 1",
|
||||
intval($importer["uid"])
|
||||
);
|
||||
|
||||
// they are not CONTACT_IS_FOLLOWER anymore but that's what we have in the array
|
||||
|
||||
if ($self && $contact["rel"] == CONTACT_IS_FOLLOWER) {
|
||||
$arr = [];
|
||||
$arr["protocol"] = PROTOCOL_DIASPORA;
|
||||
$arr["uri"] = $arr["parent-uri"] = item_new_uri($a->get_hostname(), $importer["uid"]);
|
||||
$arr["uid"] = $importer["uid"];
|
||||
$arr["contact-id"] = $self[0]["id"];
|
||||
$arr["wall"] = 1;
|
||||
$arr["type"] = 'wall';
|
||||
$arr["gravity"] = 0;
|
||||
$arr["origin"] = 1;
|
||||
$arr["author-name"] = $arr["owner-name"] = $self[0]["name"];
|
||||
$arr["author-link"] = $arr["owner-link"] = $self[0]["url"];
|
||||
$arr["author-avatar"] = $arr["owner-avatar"] = $self[0]["thumb"];
|
||||
$arr["verb"] = ACTIVITY_FRIEND;
|
||||
$arr["object-type"] = ACTIVITY_OBJ_PERSON;
|
||||
|
||||
$A = "[url=".$self[0]["url"]."]".$self[0]["name"]."[/url]";
|
||||
$B = "[url=".$contact["url"]."]".$contact["name"]."[/url]";
|
||||
$BPhoto = "[url=".$contact["url"]."][img]".$contact["thumb"]."[/img][/url]";
|
||||
$arr["body"] = L10n::t('%1$s is now friends with %2$s', $A, $B)."\n\n\n".$BPhoto;
|
||||
|
||||
$arr["object"] = self::constructNewFriendObject($contact);
|
||||
|
||||
$user = dba::selectFirst('user', ['allow_cid', 'allow_gid', 'deny_cid', 'deny_gid'], ['uid' => $importer["uid"]]);
|
||||
|
||||
$arr["allow_cid"] = $user["allow_cid"];
|
||||
$arr["allow_gid"] = $user["allow_gid"];
|
||||
$arr["deny_cid"] = $user["deny_cid"];
|
||||
$arr["deny_gid"] = $user["deny_gid"];
|
||||
|
||||
$i = Item::insert($arr);
|
||||
if ($i) {
|
||||
Worker::add(PRIORITY_HIGH, "Notifier", "activity", $i);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Creates a XML object for a "new friend" message
|
||||
*
|
||||
* @param array $contact Array of the contact
|
||||
*
|
||||
* @return string The XML
|
||||
*/
|
||||
private static function constructNewFriendObject($contact)
|
||||
{
|
||||
$objtype = ACTIVITY_OBJ_PERSON;
|
||||
$link = '<link rel="alternate" type="text/html" href="'.$contact["url"].'" />'."\n".
|
||||
'<link rel="photo" type="image/jpeg" href="'.$contact["thumb"].'" />'."\n";
|
||||
|
||||
$xmldata = ["object" => ["type" => $objtype,
|
||||
"title" => $contact["name"],
|
||||
"id" => $contact["url"]."/".$contact["name"],
|
||||
"link" => $link]];
|
||||
|
||||
return XML::fromArray($xmldata, $xml, true);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -2918,7 +2785,7 @@ class Diaspora
|
|||
|
||||
while ($item = dba::fetch($r)) {
|
||||
// Fetch the parent item
|
||||
$parent = dba::selectFirst('item', ['author-link', 'origin'], ['id' => $item["parent"]]);
|
||||
$parent = dba::selectFirst('item', ['author-link'], ['id' => $item["parent"]]);
|
||||
|
||||
// Only delete it if the parent author really fits
|
||||
if (!link_compare($parent["author-link"], $contact["url"]) && !link_compare($item["author-link"], $contact["url"])) {
|
||||
|
@ -2926,15 +2793,9 @@ class Diaspora
|
|||
continue;
|
||||
}
|
||||
|
||||
Item::deleteById($item["id"]);
|
||||
Item::delete(['id' => $item['id']]);
|
||||
|
||||
logger("Deleted target ".$target_guid." (".$item["id"].") from user ".$item["uid"]." parent: ".$item["parent"], LOGGER_DEBUG);
|
||||
|
||||
// Now check if the retraction needs to be relayed by us
|
||||
if ($parent["origin"]) {
|
||||
// notify others
|
||||
Worker::add(PRIORITY_HIGH, "Notifier", "drop", $item["id"]);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
|
@ -3568,6 +3429,10 @@ class Diaspora
|
|||
$ret["root_handle"] = self::handleFromContact($item["contact-id"]);
|
||||
$ret["root_guid"] = $guid;
|
||||
return $ret;
|
||||
} elseif ($complete) {
|
||||
// We are resharing something that isn't a DFRN or Diaspora post.
|
||||
// So we have to return "false" on "$complete" to not trigger a reshare.
|
||||
return false;
|
||||
}
|
||||
} elseif (($guid == "") && $complete) {
|
||||
return false;
|
||||
|
|
|
@ -430,6 +430,9 @@ class Feed {
|
|||
$item['guid'] = Item::guidFromUri($orig_plink, $a->get_hostname());
|
||||
unset($item['uri']);
|
||||
unset($item['parent-uri']);
|
||||
|
||||
// Set the delivery priority for "remote self" to "medium"
|
||||
$notify = PRIORITY_MEDIUM;
|
||||
}
|
||||
|
||||
$id = Item::insert($item, false, $notify);
|
||||
|
|
|
@ -537,13 +537,12 @@ class OStatus
|
|||
private static function deleteNotice($item)
|
||||
{
|
||||
$condition = ['uid' => $item['uid'], 'author-link' => $item['author-link'], 'uri' => $item['uri']];
|
||||
$deleted = dba::selectFirst('item', ['id', 'parent-uri'], $condition);
|
||||
if (!DBM::is_result($deleted)) {
|
||||
logger('Item from '.$item['author-link'].' with uri '.$item['uri'].' for user '.$item['uid']." wasn't found. We don't delete it. ");
|
||||
if (!dba::exists('item', $condition)) {
|
||||
logger('Item from '.$item['author-link'].' with uri '.$item['uri'].' for user '.$item['uid']." wasn't found. We don't delete it.");
|
||||
return;
|
||||
}
|
||||
|
||||
Item::deleteById($deleted["id"]);
|
||||
Item::delete($condition);
|
||||
|
||||
logger('Deleted item with uri '.$item['uri'].' for user '.$item['uid']);
|
||||
}
|
||||
|
|
|
@ -522,7 +522,12 @@ class PortableContact
|
|||
}
|
||||
}
|
||||
|
||||
$fields = ['updated' => $last_updated, 'last_contact' => DateTimeFormat::utcNow()];
|
||||
$fields = ['last_contact' => DateTimeFormat::utcNow()];
|
||||
|
||||
if (!empty($last_updated)) {
|
||||
$fields['updated'] = $last_updated;
|
||||
}
|
||||
|
||||
dba::update('gcontact', $fields, ['nurl' => normalise_link($profile)]);
|
||||
|
||||
if (($gcontacts[0]["generation"] == 0)) {
|
||||
|
@ -1415,7 +1420,7 @@ class PortableContact
|
|||
}
|
||||
|
||||
foreach ($tags as $tag) {
|
||||
dba::insert('gserver-tag', ['gserver-id' => $gserver['id'], 'tag' => $tag]);
|
||||
dba::insert('gserver-tag', ['gserver-id' => $gserver['id'], 'tag' => $tag], true);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1424,11 +1429,19 @@ class PortableContact
|
|||
if (isset($data->protocols)) {
|
||||
if (isset($data->protocols->diaspora)) {
|
||||
$fields['network'] = NETWORK_DIASPORA;
|
||||
$fields['batch'] = $data->protocols->diaspora;
|
||||
if (isset($data->protocols->diaspora->receive)) {
|
||||
$fields['batch'] = $data->protocols->diaspora->receive;
|
||||
} elseif (is_string($data->protocols->diaspora)) {
|
||||
$fields['batch'] = $data->protocols->diaspora;
|
||||
}
|
||||
}
|
||||
if (isset($data->protocols->dfrn)) {
|
||||
$fields['network'] = NETWORK_DFRN;
|
||||
$fields['batch'] = $data->protocols->dfrn;
|
||||
if (isset($data->protocols->dfrn->receive)) {
|
||||
$fields['batch'] = $data->protocols->dfrn->receive;
|
||||
} elseif (is_string($data->protocols->dfrn)) {
|
||||
$fields['batch'] = $data->protocols->dfrn;
|
||||
}
|
||||
}
|
||||
}
|
||||
Diaspora::setRelayContact($server_url, $fields);
|
||||
|
@ -1502,8 +1515,10 @@ class PortableContact
|
|||
if ($serverdata) {
|
||||
$servers = json_decode($serverdata);
|
||||
|
||||
foreach ($servers->pods as $server) {
|
||||
Worker::add(PRIORITY_LOW, "DiscoverPoCo", "server", "https://".$server->host);
|
||||
if (is_array($servers->pods)) {
|
||||
foreach ($servers->pods as $server) {
|
||||
Worker::add(PRIORITY_LOW, "DiscoverPoCo", "server", "https://".$server->host);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -58,9 +58,6 @@ Class Cron {
|
|||
// Call possible post update functions
|
||||
Worker::add(PRIORITY_LOW, "CronJobs", "post_update");
|
||||
|
||||
// update nodeinfo data
|
||||
Worker::add(PRIORITY_LOW, "CronJobs", "nodeinfo");
|
||||
|
||||
// Clear cache entries
|
||||
Worker::add(PRIORITY_LOW, "CronJobs", "clear_cache");
|
||||
|
||||
|
@ -74,27 +71,42 @@ Class Cron {
|
|||
$d1 = Config::get('system', 'last_expire_day');
|
||||
$d2 = intval(DateTimeFormat::utcNow('d'));
|
||||
|
||||
// Daily cron calls
|
||||
if ($d2 != intval($d1)) {
|
||||
|
||||
Worker::add(PRIORITY_LOW, "CronJobs", "update_contact_birthdays");
|
||||
|
||||
Worker::add(PRIORITY_LOW, "CronJobs", "update_photo_albums");
|
||||
|
||||
// update nodeinfo data
|
||||
Worker::add(PRIORITY_LOW, "CronJobs", "nodeinfo");
|
||||
|
||||
Worker::add(PRIORITY_LOW, "DiscoverPoCo", "update_server");
|
||||
|
||||
Worker::add(PRIORITY_LOW, "DiscoverPoCo", "suggestions");
|
||||
|
||||
Config::set('system', 'last_expire_day', $d2);
|
||||
|
||||
Worker::add(PRIORITY_LOW, 'Expire');
|
||||
|
||||
Worker::add(PRIORITY_MEDIUM, 'DBClean');
|
||||
|
||||
Worker::add(PRIORITY_LOW, "CronJobs", "update_photo_albums");
|
||||
|
||||
// Delete all done workerqueue entries
|
||||
dba::delete('workerqueue', ['`done` AND `executed` < UTC_TIMESTAMP() - INTERVAL 12 HOUR']);
|
||||
|
||||
// check upstream version?
|
||||
Worker::add(PRIORITY_LOW, 'CheckVersion');
|
||||
|
||||
Config::set('system', 'last_expire_day', $d2);
|
||||
}
|
||||
|
||||
// Hourly cron calls
|
||||
if (Config::get('system', 'last_cron_hourly', 0) + 3600 < time()) {
|
||||
|
||||
// Delete all done workerqueue entries
|
||||
dba::delete('workerqueue', ['`done` AND `executed` < UTC_TIMESTAMP() - INTERVAL 1 HOUR']);
|
||||
|
||||
// Optimizing this table only last seconds
|
||||
if (Config::get('system', 'optimize_workerqueue', false)) {
|
||||
dba::e("OPTIMIZE TABLE `workerqueue`");
|
||||
}
|
||||
|
||||
Config::set('system', 'last_cron_hourly', time());
|
||||
}
|
||||
|
||||
// Poll contacts
|
||||
|
|
|
@ -26,8 +26,6 @@ class CronJobs
|
|||
{
|
||||
global $a;
|
||||
|
||||
require_once 'mod/nodeinfo.php';
|
||||
|
||||
// No parameter set? So return
|
||||
if ($command == '') {
|
||||
return;
|
||||
|
|
|
@ -11,6 +11,7 @@ use Friendica\Database\DBM;
|
|||
use Friendica\Model\Contact;
|
||||
use Friendica\Model\Group;
|
||||
use Friendica\Model\User;
|
||||
use Friendica\Model\PushSubscriber;
|
||||
use Friendica\Network\Probe;
|
||||
use Friendica\Protocol\Diaspora;
|
||||
use Friendica\Protocol\OStatus;
|
||||
|
@ -498,19 +499,13 @@ class Notifier {
|
|||
|
||||
// Notify PuSH subscribers (Used for OStatus distribution of regular posts)
|
||||
if ($push_notify) {
|
||||
// Set push flag for PuSH subscribers to this topic,
|
||||
// they will be notified in queue.php
|
||||
$condition = ['push' => false, 'nickname' => $owner['nickname']];
|
||||
dba::update('push_subscriber', ['push' => true], $condition);
|
||||
|
||||
logger('Activating internal PuSH for item '.$item_id, LOGGER_DEBUG);
|
||||
|
||||
// Handling the pubsubhubbub requests
|
||||
Worker::add(['priority' => PRIORITY_HIGH, 'created' => $a->queue['created'], 'dont_fork' => true],
|
||||
'PubSubPublish');
|
||||
PushSubscriber::publishFeed($owner['uid'], $a->queue['priority']);
|
||||
}
|
||||
|
||||
logger('notifier: calling hooks', LOGGER_DEBUG);
|
||||
logger('notifier: calling hooks for ' . $cmd . ' ' . $item_id, LOGGER_DEBUG);
|
||||
|
||||
if ($normal_mode) {
|
||||
Addon::forkHooks($a->queue['priority'], 'notifier_normal', $target_item);
|
||||
|
|
|
@ -7,11 +7,10 @@ namespace Friendica\Worker;
|
|||
|
||||
use Friendica\App;
|
||||
use Friendica\Core\System;
|
||||
use Friendica\Core\Config;
|
||||
use Friendica\Core\Worker;
|
||||
use Friendica\Database\DBM;
|
||||
use Friendica\Protocol\OStatus;
|
||||
use Friendica\Util\Network;
|
||||
use Friendica\Model\PushSubscriber;
|
||||
use dba;
|
||||
|
||||
require_once 'include/items.php';
|
||||
|
@ -19,78 +18,56 @@ require_once 'include/items.php';
|
|||
class PubSubPublish {
|
||||
public static function execute($pubsubpublish_id = 0)
|
||||
{
|
||||
global $a;
|
||||
|
||||
if ($pubsubpublish_id == 0) {
|
||||
// We'll push to each subscriber that has push > 0,
|
||||
// i.e. there has been an update (set in notifier.php).
|
||||
$r = q("SELECT `id`, `callback_url` FROM `push_subscriber` WHERE `push` > 0 ORDER BY `last_update` DESC");
|
||||
|
||||
foreach ($r as $rr) {
|
||||
logger("Publish feed to ".$rr["callback_url"], LOGGER_DEBUG);
|
||||
Worker::add(['priority' => PRIORITY_HIGH, 'created' => $a->queue['created'], 'dont_fork' => true],
|
||||
'PubSubPublish', (int)$rr["id"]);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
self::publish($pubsubpublish_id);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
private static function publish($id) {
|
||||
global $a;
|
||||
|
||||
$r = q("SELECT * FROM `push_subscriber` WHERE `id` = %d", intval($id));
|
||||
if (!DBM::is_result($r)) {
|
||||
$subscriber = dba::selectFirst('push_subscriber', [], ['id' => $id]);
|
||||
if (!DBM::is_result($subscriber)) {
|
||||
return;
|
||||
}
|
||||
|
||||
$rr = $r[0];
|
||||
|
||||
/// @todo Check server status with PortableContact::checkServer()
|
||||
// Before this can be done we need a way to safely detect the server url.
|
||||
|
||||
logger("Generate feed of user ".$rr['nickname']." to ".$rr['callback_url']." - last updated ".$rr['last_update'], LOGGER_DEBUG);
|
||||
logger("Generate feed of user " . $subscriber['nickname']. " to " . $subscriber['callback_url']. " - last updated " . $subscriber['last_update'], LOGGER_DEBUG);
|
||||
|
||||
$last_update = $rr['last_update'];
|
||||
$params = OStatus::feed($rr['nickname'], $last_update);
|
||||
$last_update = $subscriber['last_update'];
|
||||
$params = OStatus::feed($subscriber['nickname'], $last_update);
|
||||
|
||||
if (!$params) {
|
||||
return;
|
||||
}
|
||||
|
||||
$hmac_sig = hash_hmac("sha1", $params, $rr['secret']);
|
||||
$hmac_sig = hash_hmac("sha1", $params, $subscriber['secret']);
|
||||
|
||||
$headers = ["Content-type: application/atom+xml",
|
||||
sprintf("Link: <%s>;rel=hub,<%s>;rel=self",
|
||||
System::baseUrl().'/pubsubhubbub/'.$rr['nickname'],
|
||||
$rr['topic']),
|
||||
"X-Hub-Signature: sha1=".$hmac_sig];
|
||||
System::baseUrl() . '/pubsubhubbub/' . $subscriber['nickname'],
|
||||
$subscriber['topic']),
|
||||
"X-Hub-Signature: sha1=" . $hmac_sig];
|
||||
|
||||
logger('POST '.print_r($headers, true)."\n".$params, LOGGER_DATA);
|
||||
logger('POST ' . print_r($headers, true) . "\n" . $params, LOGGER_DATA);
|
||||
|
||||
Network::post($rr['callback_url'], $params, $headers);
|
||||
Network::post($subscriber['callback_url'], $params, $headers);
|
||||
$ret = $a->get_curl_code();
|
||||
|
||||
$condition = ['id' => $subscriber['id']];
|
||||
|
||||
if ($ret >= 200 && $ret <= 299) {
|
||||
logger('successfully pushed to '.$rr['callback_url']);
|
||||
|
||||
// set last_update to the "created" date of the last item, and reset push=0
|
||||
$fields = ['push' => 0, 'last_update' => $last_update];
|
||||
dba::update('push_subscriber', $fields, ['id' => $rr['id']]);
|
||||
logger('Successfully pushed to ' . $subscriber['callback_url']);
|
||||
|
||||
PushSubscriber::reset($subscriber['id'], $last_update);
|
||||
} else {
|
||||
logger('error when pushing to '.$rr['callback_url'].' HTTP: '.$ret);
|
||||
logger('Delivery error when pushing to ' . $subscriber['callback_url'] . ' HTTP: ' . $ret);
|
||||
|
||||
// we use the push variable also as a counter, if we failed we
|
||||
// increment this until some upper limit where we give up
|
||||
$new_push = intval($rr['push']) + 1;
|
||||
|
||||
if ($new_push > 30) // OK, let's give up
|
||||
$new_push = 0;
|
||||
|
||||
dba::update('push_subscriber', ['push' => $new_push], ['id' => $rr['id']]);
|
||||
PushSubscriber::delay($subscriber['id']);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -10,6 +10,7 @@ use Friendica\Core\Config;
|
|||
use Friendica\Core\Worker;
|
||||
use Friendica\Database\DBM;
|
||||
use Friendica\Model\Queue as QueueModel;
|
||||
use Friendica\Model\PushSubscriber;
|
||||
use Friendica\Protocol\DFRN;
|
||||
use Friendica\Protocol\Diaspora;
|
||||
use Friendica\Protocol\PortableContact;
|
||||
|
@ -34,7 +35,7 @@ class Queue
|
|||
logger('filling queue jobs - start');
|
||||
|
||||
// Handling the pubsubhubbub requests
|
||||
Worker::add(['priority' => PRIORITY_HIGH, 'dont_fork' => true], 'PubSubPublish');
|
||||
PushSubscriber::requeue();
|
||||
|
||||
$r = dba::inArray(dba::p("SELECT `id` FROM `queue` WHERE `next` < UTC_TIMESTAMP() ORDER BY `batch`, `cid`"));
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue