Merge remote-tracking branch 'upstream/develop' into push-pull
This commit is contained in:
commit
6f0d40c6c0
82 changed files with 1178 additions and 798 deletions
|
@ -11,7 +11,7 @@ services:
|
||||||
- redis-server
|
- redis-server
|
||||||
- memcached
|
- memcached
|
||||||
env:
|
env:
|
||||||
- MYSQL_HOST=localhost MYSQL_PORT=3306 MYSQL_USERNAME=travis MYSQL_PASSWORD= MYSQL_DATABASE=test
|
- MYSQL_HOST=localhost MYSQL_PORT=3306 MYSQL_USERNAME=travis MYSQL_PASSWORD="" MYSQL_DATABASE=test
|
||||||
|
|
||||||
install:
|
install:
|
||||||
- composer install
|
- composer install
|
||||||
|
|
35
database.sql
35
database.sql
|
@ -1,6 +1,6 @@
|
||||||
-- ------------------------------------------
|
-- ------------------------------------------
|
||||||
-- Friendica 2020.03-dev (Dalmatian Bellflower)
|
-- Friendica 2020.03-dev (Dalmatian Bellflower)
|
||||||
-- DB_UPDATE_VERSION 1333
|
-- DB_UPDATE_VERSION 1334
|
||||||
-- ------------------------------------------
|
-- ------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
@ -179,7 +179,7 @@ CREATE TABLE IF NOT EXISTS `contact` (
|
||||||
`location` varchar(255) DEFAULT '' COMMENT '',
|
`location` varchar(255) DEFAULT '' COMMENT '',
|
||||||
`about` text COMMENT '',
|
`about` text COMMENT '',
|
||||||
`keywords` text COMMENT 'public keywords (interests) of the contact',
|
`keywords` text COMMENT 'public keywords (interests) of the contact',
|
||||||
`gender` varchar(32) NOT NULL DEFAULT '' COMMENT '',
|
`gender` varchar(32) NOT NULL DEFAULT '' COMMENT 'Deprecated',
|
||||||
`xmpp` varchar(255) NOT NULL DEFAULT '' COMMENT '',
|
`xmpp` varchar(255) NOT NULL DEFAULT '' COMMENT '',
|
||||||
`attag` varchar(255) NOT NULL DEFAULT '' COMMENT '',
|
`attag` varchar(255) NOT NULL DEFAULT '' COMMENT '',
|
||||||
`avatar` varchar(255) NOT NULL DEFAULT '' COMMENT '',
|
`avatar` varchar(255) NOT NULL DEFAULT '' COMMENT '',
|
||||||
|
@ -397,7 +397,7 @@ CREATE TABLE IF NOT EXISTS `gcontact` (
|
||||||
`location` varchar(255) NOT NULL DEFAULT '' COMMENT '',
|
`location` varchar(255) NOT NULL DEFAULT '' COMMENT '',
|
||||||
`about` text COMMENT '',
|
`about` text COMMENT '',
|
||||||
`keywords` text COMMENT 'puplic keywords (interests)',
|
`keywords` text COMMENT 'puplic keywords (interests)',
|
||||||
`gender` varchar(32) NOT NULL DEFAULT '' COMMENT '',
|
`gender` varchar(32) NOT NULL DEFAULT '' COMMENT 'Deprecated',
|
||||||
`birthday` varchar(32) NOT NULL DEFAULT '0001-01-01' COMMENT '',
|
`birthday` varchar(32) NOT NULL DEFAULT '0001-01-01' COMMENT '',
|
||||||
`community` boolean NOT NULL DEFAULT '0' COMMENT '1 if contact is forum account',
|
`community` boolean NOT NULL DEFAULT '0' COMMENT '1 if contact is forum account',
|
||||||
`contact-type` tinyint NOT NULL DEFAULT -1 COMMENT '',
|
`contact-type` tinyint NOT NULL DEFAULT -1 COMMENT '',
|
||||||
|
@ -568,7 +568,7 @@ CREATE TABLE IF NOT EXISTS `item` (
|
||||||
`extid` varchar(255) NOT NULL DEFAULT '' COMMENT '',
|
`extid` varchar(255) NOT NULL DEFAULT '' COMMENT '',
|
||||||
`post-type` tinyint unsigned NOT NULL DEFAULT 0 COMMENT 'Post type (personal note, bookmark, ...)',
|
`post-type` tinyint unsigned NOT NULL DEFAULT 0 COMMENT 'Post type (personal note, bookmark, ...)',
|
||||||
`global` boolean NOT NULL DEFAULT '0' COMMENT '',
|
`global` boolean NOT NULL DEFAULT '0' COMMENT '',
|
||||||
`private` boolean NOT NULL DEFAULT '0' COMMENT 'distribution is restricted',
|
`private` tinyint unsigned NOT NULL DEFAULT 0 COMMENT '0=public, 1=private, 2=unlisted',
|
||||||
`visible` boolean NOT NULL DEFAULT '0' COMMENT '',
|
`visible` boolean NOT NULL DEFAULT '0' COMMENT '',
|
||||||
`moderated` boolean NOT NULL DEFAULT '0' COMMENT '',
|
`moderated` boolean NOT NULL DEFAULT '0' COMMENT '',
|
||||||
`deleted` boolean NOT NULL DEFAULT '0' COMMENT 'item has been deleted',
|
`deleted` boolean NOT NULL DEFAULT '0' COMMENT 'item has been deleted',
|
||||||
|
@ -1057,19 +1057,18 @@ CREATE TABLE IF NOT EXISTS `profile_check` (
|
||||||
-- TABLE profile_field
|
-- TABLE profile_field
|
||||||
--
|
--
|
||||||
CREATE TABLE IF NOT EXISTS `profile_field` (
|
CREATE TABLE IF NOT EXISTS `profile_field` (
|
||||||
`id` int(10) unsigned NOT NULL AUTO_INCREMENT COMMENT 'sequential ID',
|
`id` int unsigned NOT NULL auto_increment COMMENT 'sequential ID',
|
||||||
`uid` mediumint(8) unsigned NOT NULL DEFAULT 0 COMMENT 'Owner user id',
|
`uid` mediumint unsigned NOT NULL DEFAULT 0 COMMENT 'Owner user id',
|
||||||
`psid` int(10) unsigned DEFAULT NULL COMMENT 'ID of the permission set of this profile field - 0 = public',
|
`order` mediumint unsigned NOT NULL DEFAULT 1 COMMENT 'Field ordering per user',
|
||||||
`name` varchar(255) NOT NULL DEFAULT '' COMMENT 'Name of the field',
|
`psid` int unsigned COMMENT 'ID of the permission set of this profile field - 0 = public',
|
||||||
`value` text COMMENT 'Value of the field',
|
`label` varchar(255) NOT NULL DEFAULT '' COMMENT 'Label of the field',
|
||||||
`order` mediumint(8) unsigned NOT NULL DEFAULT 1 COMMENT 'Field ordering per user',
|
`value` text COMMENT 'Value of the field',
|
||||||
`label` varchar(255) NOT NULL DEFAULT '' COMMENT 'Label of the field',
|
`created` datetime NOT NULL DEFAULT '0001-01-01 00:00:00' COMMENT 'creation time',
|
||||||
`created` datetime NOT NULL DEFAULT '0001-01-01 00:00:00' COMMENT '',
|
`edited` datetime NOT NULL DEFAULT '0001-01-01 00:00:00' COMMENT 'last edit time',
|
||||||
`edited` datetime NOT NULL DEFAULT '0001-01-01 00:00:00' COMMENT '',
|
PRIMARY KEY(`id`),
|
||||||
PRIMARY KEY (`id`),
|
INDEX `uid` (`uid`),
|
||||||
KEY `uid` (`uid`),
|
INDEX `order` (`order`),
|
||||||
KEY `psid` (`psid`),
|
INDEX `psid` (`psid`)
|
||||||
KEY `order` (`order`)
|
|
||||||
) DEFAULT COLLATE utf8mb4_general_ci COMMENT='Custom profile fields';
|
) DEFAULT COLLATE utf8mb4_general_ci COMMENT='Custom profile fields';
|
||||||
|
|
||||||
--
|
--
|
||||||
|
@ -1179,7 +1178,7 @@ CREATE TABLE IF NOT EXISTS `thread` (
|
||||||
`received` datetime NOT NULL DEFAULT '0001-01-01 00:00:00' COMMENT '',
|
`received` datetime NOT NULL DEFAULT '0001-01-01 00:00:00' COMMENT '',
|
||||||
`changed` datetime NOT NULL DEFAULT '0001-01-01 00:00:00' COMMENT '',
|
`changed` datetime NOT NULL DEFAULT '0001-01-01 00:00:00' COMMENT '',
|
||||||
`wall` boolean NOT NULL DEFAULT '0' COMMENT '',
|
`wall` boolean NOT NULL DEFAULT '0' COMMENT '',
|
||||||
`private` boolean NOT NULL DEFAULT '0' COMMENT '',
|
`private` tinyint unsigned NOT NULL DEFAULT 0 COMMENT '0=public, 1=private, 2=unlisted',
|
||||||
`pubmail` boolean NOT NULL DEFAULT '0' COMMENT '',
|
`pubmail` boolean NOT NULL DEFAULT '0' COMMENT '',
|
||||||
`moderated` boolean NOT NULL DEFAULT '0' COMMENT '',
|
`moderated` boolean NOT NULL DEFAULT '0' COMMENT '',
|
||||||
`visible` boolean NOT NULL DEFAULT '0' COMMENT '',
|
`visible` boolean NOT NULL DEFAULT '0' COMMENT '',
|
||||||
|
|
|
@ -113,17 +113,17 @@ table.bbcodes > * > tr > th {
|
||||||
<tr>
|
<tr>
|
||||||
<td>[bookmark]http://friendi.ca[/bookmark]<br><br>
|
<td>[bookmark]http://friendi.ca[/bookmark]<br><br>
|
||||||
#^[url]http://friendi.ca[/url]</td>
|
#^[url]http://friendi.ca[/url]</td>
|
||||||
<td><span class="oembed link"><h4>Friendica: <a href="http://friendi.ca" rel="oembed"></a><a href="http://friendi.ca" target="_blank">http://friendi.ca</a></h4></span></td>
|
<td><span class="oembed link"><h4>Friendica: <a href="http://friendi.ca" rel="oembed"></a><a href="http://friendi.ca" target="_blank" rel="noopener noreferrer">http://friendi.ca</a></h4></span></td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td>[bookmark=http://friendi.ca]Bookmark[/bookmark]<br><br>
|
<td>[bookmark=http://friendi.ca]Bookmark[/bookmark]<br><br>
|
||||||
#^[url=http://friendi.ca]Bookmark[/url]<br><br>
|
#^[url=http://friendi.ca]Bookmark[/url]<br><br>
|
||||||
#[url=http://friendi.ca]^[/url][url=http://friendi.ca]Bookmark[/url]</td>
|
#[url=http://friendi.ca]^[/url][url=http://friendi.ca]Bookmark[/url]</td>
|
||||||
<td><span class="oembed link"><h4>Friendica: <a href="http://friendi.ca" rel="oembed"></a><a href="http://friendi.ca" target="_blank">Bookmark</a></h4></span></td>
|
<td><span class="oembed link"><h4>Friendica: <a href="http://friendi.ca" rel="oembed"></a><a href="http://friendi.ca" target="_blank" rel="noopener noreferrer">Bookmark</a></h4></span></td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td>[url=/posts/f16d77b0630f0134740c0cc47a0ea02a]Diaspora post with GUID[/url]</td>
|
<td>[url=/posts/f16d77b0630f0134740c0cc47a0ea02a]Diaspora post with GUID[/url]</td>
|
||||||
<td><a href="/display/f16d77b0630f0134740c0cc47a0ea02a" target="_blank">Diaspora post with GUID</a></td>
|
<td><a href="/display/f16d77b0630f0134740c0cc47a0ea02a" target="_blank" rel="noopener noreferrer">Diaspora post with GUID</a></td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td>#Friendica</td>
|
<td>#Friendica</td>
|
||||||
|
|
|
@ -113,17 +113,17 @@ table.bbcodes > * > tr > th {
|
||||||
<tr>
|
<tr>
|
||||||
<td>[bookmark]http://friendi.ca[/bookmark]<br><br>
|
<td>[bookmark]http://friendi.ca[/bookmark]<br><br>
|
||||||
#^[url]http://friendi.ca[/url]</td>
|
#^[url]http://friendi.ca[/url]</td>
|
||||||
<td><span class="oembed link"><h4>Friendica: <a href="http://friendi.ca" rel="oembed"></a><a href="http://friendi.ca" target="_blank">http://friendi.ca</a></h4></span></td>
|
<td><span class="oembed link"><h4>Friendica: <a href="http://friendi.ca" rel="oembed"></a><a href="http://friendi.ca" target="_blank" rel="noopener noreferrer">http://friendi.ca</a></h4></span></td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td>[bookmark=http://friendi.ca]Lesezeichen[/bookmark]<br><br>
|
<td>[bookmark=http://friendi.ca]Lesezeichen[/bookmark]<br><br>
|
||||||
#^[url=http://friendi.ca]Lesezeichen[/url]<br><br>
|
#^[url=http://friendi.ca]Lesezeichen[/url]<br><br>
|
||||||
#[url=http://friendi.ca]^[/url][url=http://friendi.ca]Lesezeichen[/url]</td>
|
#[url=http://friendi.ca]^[/url][url=http://friendi.ca]Lesezeichen[/url]</td>
|
||||||
<td><span class="oembed link"><h4>Friendica: <a href="http://friendi.ca" rel="oembed"></a><a href="http://friendi.ca" target="_blank">Lesezeichen</a></h4></span></td>
|
<td><span class="oembed link"><h4>Friendica: <a href="http://friendi.ca" rel="oembed"></a><a href="http://friendi.ca" target="_blank" rel="noopener noreferrer">Lesezeichen</a></h4></span></td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td>[url=/posts/f16d77b0630f0134740c0cc47a0ea02a]Diaspora Beitrag mit GUID[/url]</td>
|
<td>[url=/posts/f16d77b0630f0134740c0cc47a0ea02a]Diaspora Beitrag mit GUID[/url]</td>
|
||||||
<td><a href="/display/f16d77b0630f0134740c0cc47a0ea02a" target="_blank">Diaspora Beitrag mit GUID</a></td>
|
<td><a href="/display/f16d77b0630f0134740c0cc47a0ea02a" target="_blank" rel="noopener noreferrer">Diaspora Beitrag mit GUID</a></td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td>#Friendica</td>
|
<td>#Friendica</td>
|
||||||
|
|
|
@ -25,13 +25,13 @@ In den ersten Zeilen wird Dir Dein Name und Deine aktuelle IP-Adresse angezeigt.
|
||||||
Rechts im Fenster siehst Du alle Teilnehmer des Chats.
|
Rechts im Fenster siehst Du alle Teilnehmer des Chats.
|
||||||
Unten hast Du ein Eingabefeld, um Beiträge zu schreiben.
|
Unten hast Du ein Eingabefeld, um Beiträge zu schreiben.
|
||||||
|
|
||||||
Weiter Informationen zu IRC findest Du zum Beispiel auf <a href="http://wiki.ubuntuusers.de/IRC" target="_blank">ubuntuusers.de</a>, in <a href="https://de.wikipedia.org/wiki/Internet_Relay_Chat" target="_blank">Wikipedia</a> oder bei <a href="http://www.irchelp.org/" target="_blank">icrhelp.org</a> (in Englisch).
|
Weiter Informationen zu IRC findest Du zum Beispiel auf <a href="http://wiki.ubuntuusers.de/IRC" target="_blank" rel="noopener noreferrer">ubuntuusers.de</a>, in <a href="https://de.wikipedia.org/wiki/Internet_Relay_Chat" target="_blank" rel="noopener noreferrer">Wikipedia</a> oder bei <a href="http://www.irchelp.org/" target="_blank" rel="noopener noreferrer">icrhelp.org</a> (in Englisch).
|
||||||
|
|
||||||
## Jappix Mini
|
## Jappix Mini
|
||||||
|
|
||||||
Das Jappix Mini Addon erlaubt das Erstellen einer Chatbox für Jabber/XMPP-Kontakte.
|
Das Jappix Mini Addon erlaubt das Erstellen einer Chatbox für Jabber/XMPP-Kontakte.
|
||||||
Ein Jabber/XMPP Account sollte vor der Installation bereits vorhanden sein.
|
Ein Jabber/XMPP Account sollte vor der Installation bereits vorhanden sein.
|
||||||
Die ausführliche Anleitung dazu und eine Kontrolle, ob Du nicht sogar schon über Deinen E-Mail Anbieter einen Jabber-Account hast, findest Du unter <a href="http://einfachjabber.de" target="_blank">einfachjabber.de</a>.
|
Die ausführliche Anleitung dazu und eine Kontrolle, ob Du nicht sogar schon über Deinen E-Mail Anbieter einen Jabber-Account hast, findest Du unter <a href="http://einfachjabber.de" target="_blank" rel="noopener noreferrer">einfachjabber.de</a>.
|
||||||
|
|
||||||
Einige Server zum Anmelden eines neuen Accounts:
|
Einige Server zum Anmelden eines neuen Accounts:
|
||||||
|
|
||||||
|
|
|
@ -26,4 +26,4 @@ Dies gilt vor allem für Übersetzungen, da wir hier möglicherweise nicht alle
|
||||||
Außerdem: **teste Deine Änderungen!** Vergiss nicht, dass eine simple Fehlerlösung einen anderen Fehler auslösen kann.
|
Außerdem: **teste Deine Änderungen!** Vergiss nicht, dass eine simple Fehlerlösung einen anderen Fehler auslösen kann.
|
||||||
Lass Deine Änderungen von einem erfahrenen Friendica-Entwickler gegenprüfen.
|
Lass Deine Änderungen von einem erfahrenen Friendica-Entwickler gegenprüfen.
|
||||||
|
|
||||||
Eine ausführliche Anleitung zu Git findest Du unter <a href="https://git-scm.com/book/de/v1" target="_blank">https://git-scm.com/book/de/v1</a>.
|
Eine ausführliche Anleitung zu Git findest Du unter <a href="https://git-scm.com/book/de/v1" target="_blank" rel="noopener noreferrer">https://git-scm.com/book/de/v1</a>.
|
||||||
|
|
|
@ -25,7 +25,6 @@
|
||||||
|
|
||||||
use Friendica\App;
|
use Friendica\App;
|
||||||
use Friendica\Content\ContactSelector;
|
use Friendica\Content\ContactSelector;
|
||||||
use Friendica\Content\Feature;
|
|
||||||
use Friendica\Content\Text\BBCode;
|
use Friendica\Content\Text\BBCode;
|
||||||
use Friendica\Content\Text\HTML;
|
use Friendica\Content\Text\HTML;
|
||||||
use Friendica\Core\Hook;
|
use Friendica\Core\Hook;
|
||||||
|
@ -42,7 +41,6 @@ use Friendica\Model\Item;
|
||||||
use Friendica\Model\Mail;
|
use Friendica\Model\Mail;
|
||||||
use Friendica\Model\Notify;
|
use Friendica\Model\Notify;
|
||||||
use Friendica\Model\Photo;
|
use Friendica\Model\Photo;
|
||||||
use Friendica\Model\Profile;
|
|
||||||
use Friendica\Model\User;
|
use Friendica\Model\User;
|
||||||
use Friendica\Model\UserItem;
|
use Friendica\Model\UserItem;
|
||||||
use Friendica\Network\FKOAuth1;
|
use Friendica\Network\FKOAuth1;
|
||||||
|
@ -785,7 +783,7 @@ function api_item_get_user(App $a, $item)
|
||||||
|
|
||||||
$author_user = $status_user;
|
$author_user = $status_user;
|
||||||
|
|
||||||
$status_user["protected"] = $item['private'] ?? 0;
|
$status_user["protected"] = isset($item['private']) && ($item['private'] == Item::PRIVATE);
|
||||||
|
|
||||||
if (($item['thr-parent'] ?? '') == ($item['uri'] ?? '')) {
|
if (($item['thr-parent'] ?? '') == ($item['uri'] ?? '')) {
|
||||||
$owner_user = api_get_user($a, $item['owner-id'] ?? null);
|
$owner_user = api_get_user($a, $item['owner-id'] ?? null);
|
||||||
|
@ -1344,7 +1342,7 @@ function api_get_last_status($ownerId, $uid)
|
||||||
'author-id'=> $ownerId,
|
'author-id'=> $ownerId,
|
||||||
'uid' => $uid,
|
'uid' => $uid,
|
||||||
'gravity' => [GRAVITY_PARENT, GRAVITY_COMMENT],
|
'gravity' => [GRAVITY_PARENT, GRAVITY_COMMENT],
|
||||||
'private' => false
|
'private' => [Item::PUBLIC, Item::UNLISTED]
|
||||||
];
|
];
|
||||||
|
|
||||||
$item = api_get_item($condition);
|
$item = api_get_item($condition);
|
||||||
|
@ -1734,8 +1732,8 @@ function api_statuses_public_timeline($type)
|
||||||
$start = max(0, ($page - 1) * $count);
|
$start = max(0, ($page - 1) * $count);
|
||||||
|
|
||||||
if ($exclude_replies && !$conversation_id) {
|
if ($exclude_replies && !$conversation_id) {
|
||||||
$condition = ["`gravity` IN (?, ?) AND `iid` > ? AND NOT `private` AND `wall` AND NOT `user`.`hidewall` AND NOT `author`.`hidden`",
|
$condition = ["`gravity` IN (?, ?) AND `iid` > ? AND `private` = ? AND `wall` AND NOT `author`.`hidden`",
|
||||||
GRAVITY_PARENT, GRAVITY_COMMENT, $since_id];
|
GRAVITY_PARENT, GRAVITY_COMMENT, $since_id, Item::PUBLIC];
|
||||||
|
|
||||||
if ($max_id > 0) {
|
if ($max_id > 0) {
|
||||||
$condition[0] .= " AND `thread`.`iid` <= ?";
|
$condition[0] .= " AND `thread`.`iid` <= ?";
|
||||||
|
@ -1747,8 +1745,8 @@ function api_statuses_public_timeline($type)
|
||||||
|
|
||||||
$r = Item::inArray($statuses);
|
$r = Item::inArray($statuses);
|
||||||
} else {
|
} else {
|
||||||
$condition = ["`gravity` IN (?, ?) AND `id` > ? AND NOT `private` AND `wall` AND NOT `user`.`hidewall` AND `item`.`origin` AND NOT `author`.`hidden`",
|
$condition = ["`gravity` IN (?, ?) AND `id` > ? AND `private` = ? AND `wall` AND `item`.`origin` AND NOT `author`.`hidden`",
|
||||||
GRAVITY_PARENT, GRAVITY_COMMENT, $since_id];
|
GRAVITY_PARENT, GRAVITY_COMMENT, $since_id, Item::PUBLIC];
|
||||||
|
|
||||||
if ($max_id > 0) {
|
if ($max_id > 0) {
|
||||||
$condition[0] .= " AND `item`.`id` <= ?";
|
$condition[0] .= " AND `item`.`id` <= ?";
|
||||||
|
@ -1813,8 +1811,8 @@ function api_statuses_networkpublic_timeline($type)
|
||||||
|
|
||||||
$start = max(0, ($page - 1) * $count);
|
$start = max(0, ($page - 1) * $count);
|
||||||
|
|
||||||
$condition = ["`uid` = 0 AND `gravity` IN (?, ?) AND `thread`.`iid` > ? AND NOT `private`",
|
$condition = ["`uid` = 0 AND `gravity` IN (?, ?) AND `thread`.`iid` > ? AND `private` = ?",
|
||||||
GRAVITY_PARENT, GRAVITY_COMMENT, $since_id];
|
GRAVITY_PARENT, GRAVITY_COMMENT, $since_id, Item::PUBLIC];
|
||||||
|
|
||||||
if ($max_id > 0) {
|
if ($max_id > 0) {
|
||||||
$condition[0] .= " AND `thread`.`iid` <= ?";
|
$condition[0] .= " AND `thread`.`iid` <= ?";
|
||||||
|
@ -2042,7 +2040,7 @@ function api_statuses_repeat($type)
|
||||||
Logger::log('API: api_statuses_repeat: '.$id);
|
Logger::log('API: api_statuses_repeat: '.$id);
|
||||||
|
|
||||||
$fields = ['body', 'title', 'attach', 'tag', 'author-name', 'author-link', 'author-avatar', 'guid', 'created', 'plink'];
|
$fields = ['body', 'title', 'attach', 'tag', 'author-name', 'author-link', 'author-avatar', 'guid', 'created', 'plink'];
|
||||||
$item = Item::selectFirst($fields, ['id' => $id, 'private' => false]);
|
$item = Item::selectFirst($fields, ['id' => $id, 'private' => [Item::PUBLIC, Item::UNLISTED]]);
|
||||||
|
|
||||||
if (DBA::isResult($item) && $item['body'] != "") {
|
if (DBA::isResult($item) && $item['body'] != "") {
|
||||||
if (strpos($item['body'], "[/share]") !== false) {
|
if (strpos($item['body'], "[/share]") !== false) {
|
||||||
|
@ -3007,7 +3005,7 @@ function api_format_item($item, $type = "json", $status_user = null, $author_use
|
||||||
'user' => $status_user,
|
'user' => $status_user,
|
||||||
'friendica_author' => $author_user,
|
'friendica_author' => $author_user,
|
||||||
'friendica_owner' => $owner_user,
|
'friendica_owner' => $owner_user,
|
||||||
'friendica_private' => $item['private'] == 1,
|
'friendica_private' => $item['private'] == Item::PRIVATE,
|
||||||
//'entities' => NULL,
|
//'entities' => NULL,
|
||||||
'statusnet_html' => $converted["html"],
|
'statusnet_html' => $converted["html"],
|
||||||
'statusnet_conversation_id' => $item['parent'],
|
'statusnet_conversation_id' => $item['parent'],
|
||||||
|
@ -5920,7 +5918,7 @@ function api_friendica_notification_seen($type)
|
||||||
$id = (!empty($_REQUEST['id']) ? intval($_REQUEST['id']) : 0);
|
$id = (!empty($_REQUEST['id']) ? intval($_REQUEST['id']) : 0);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
$notify = DI::notify()->getByID($id);
|
$notify = DI::notify()->getByID($id, api_user());
|
||||||
DI::notify()->setSeen(true, $notify);
|
DI::notify()->setSeen(true, $notify);
|
||||||
|
|
||||||
if ($notify->otype === Notify\ObjectType::ITEM) {
|
if ($notify->otype === Notify\ObjectType::ITEM) {
|
||||||
|
|
|
@ -579,12 +579,12 @@ function conversation(App $a, array $items, $mode, $update, $preview = false, $o
|
||||||
$items = $cb['items'];
|
$items = $cb['items'];
|
||||||
|
|
||||||
$conv_responses = [
|
$conv_responses = [
|
||||||
'like' => ['title' => DI::l10n()->t('Likes','title')],
|
'like' => [],
|
||||||
'dislike' => ['title' => DI::l10n()->t('Dislikes','title')],
|
'dislike' => [],
|
||||||
'attendyes' => ['title' => DI::l10n()->t('Attending','title')],
|
'attendyes' => [],
|
||||||
'attendno' => ['title' => DI::l10n()->t('Not attending','title')],
|
'attendno' => [],
|
||||||
'attendmaybe' => ['title' => DI::l10n()->t('Might attend','title')],
|
'attendmaybe' => [],
|
||||||
'announce' => ['title' => DI::l10n()->t('Reshares','title')]
|
'announce' => [],
|
||||||
];
|
];
|
||||||
|
|
||||||
if (DI::pConfig()->get(local_user(), 'system', 'hide_dislike')) {
|
if (DI::pConfig()->get(local_user(), 'system', 'hide_dislike')) {
|
||||||
|
@ -1572,56 +1572,3 @@ function render_location_dummy(array $item) {
|
||||||
return $item['coord'];
|
return $item['coord'];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function get_responses(array $conv_responses, array $response_verbs, array $item, Post $ob = null) {
|
|
||||||
$ret = [];
|
|
||||||
foreach ($response_verbs as $v) {
|
|
||||||
$ret[$v] = [];
|
|
||||||
$ret[$v]['count'] = $conv_responses[$v][$item['uri']] ?? 0;
|
|
||||||
$ret[$v]['list'] = $conv_responses[$v][$item['uri'] . '-l'] ?? [];
|
|
||||||
$ret[$v]['self'] = $conv_responses[$v][$item['uri'] . '-self'] ?? '0';
|
|
||||||
if (count($ret[$v]['list']) > MAX_LIKERS) {
|
|
||||||
$ret[$v]['list_part'] = array_slice($ret[$v]['list'], 0, MAX_LIKERS);
|
|
||||||
array_push($ret[$v]['list_part'], '<a href="#" data-toggle="modal" data-target="#' . $v . 'Modal-'
|
|
||||||
. (($ob) ? $ob->getId() : $item['id']) . '"><b>' . DI::l10n()->t('View all') . '</b></a>');
|
|
||||||
} else {
|
|
||||||
$ret[$v]['list_part'] = '';
|
|
||||||
}
|
|
||||||
$ret[$v]['button'] = get_response_button_text($v, $ret[$v]['count']);
|
|
||||||
$ret[$v]['title'] = $conv_responses[$v]['title'];
|
|
||||||
}
|
|
||||||
|
|
||||||
$count = 0;
|
|
||||||
foreach ($ret as $key) {
|
|
||||||
if ($key['count'] == true) {
|
|
||||||
$count++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
$ret['count'] = $count;
|
|
||||||
|
|
||||||
return $ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
function get_response_button_text($v, $count)
|
|
||||||
{
|
|
||||||
$return = '';
|
|
||||||
switch ($v) {
|
|
||||||
case 'like':
|
|
||||||
$return = DI::l10n()->tt('Like', 'Likes', $count);
|
|
||||||
break;
|
|
||||||
case 'dislike':
|
|
||||||
$return = DI::l10n()->tt('Dislike', 'Dislikes', $count);
|
|
||||||
break;
|
|
||||||
case 'attendyes':
|
|
||||||
$return = DI::l10n()->tt('Attending', 'Attending', $count);
|
|
||||||
break;
|
|
||||||
case 'attendno':
|
|
||||||
$return = DI::l10n()->tt('Not Attending', 'Not Attending', $count);
|
|
||||||
break;
|
|
||||||
case 'attendmaybe':
|
|
||||||
$return = DI::l10n()->tt('Undecided', 'Undecided', $count);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
return $return;
|
|
||||||
}
|
|
||||||
|
|
|
@ -70,7 +70,7 @@ function display_init(App $a)
|
||||||
|
|
||||||
// Is this item private but could be visible to the remove visitor?
|
// Is this item private but could be visible to the remove visitor?
|
||||||
if (!DBA::isResult($item) && remote_user()) {
|
if (!DBA::isResult($item) && remote_user()) {
|
||||||
$item = Item::selectFirst($fields, ['guid' => $a->argv[1], 'private' => 1, 'origin' => true]);
|
$item = Item::selectFirst($fields, ['guid' => $a->argv[1], 'private' => Item::PRIVATE, 'origin' => true]);
|
||||||
if (DBA::isResult($item)) {
|
if (DBA::isResult($item)) {
|
||||||
if (!Contact::isFollower(remote_user(), $item['uid'])) {
|
if (!Contact::isFollower(remote_user(), $item['uid'])) {
|
||||||
$item = null;
|
$item = null;
|
||||||
|
@ -82,14 +82,14 @@ function display_init(App $a)
|
||||||
|
|
||||||
// Is it an item with uid=0?
|
// Is it an item with uid=0?
|
||||||
if (!DBA::isResult($item)) {
|
if (!DBA::isResult($item)) {
|
||||||
$item = Item::selectFirstForUser(local_user(), $fields, ['guid' => $a->argv[1], 'private' => [0, 2], 'uid' => 0]);
|
$item = Item::selectFirstForUser(local_user(), $fields, ['guid' => $a->argv[1], 'private' => [Item::PUBLIC, Item::UNLISTED], 'uid' => 0]);
|
||||||
}
|
}
|
||||||
} elseif ($a->argc >= 3 && $nick == 'feed-item') {
|
} elseif ($a->argc >= 3 && $nick == 'feed-item') {
|
||||||
$item_id = $a->argv[2];
|
$item_id = $a->argv[2];
|
||||||
if (substr($item_id, -5) == '.atom') {
|
if (substr($item_id, -5) == '.atom') {
|
||||||
$item_id = substr($item_id, 0, -5);
|
$item_id = substr($item_id, 0, -5);
|
||||||
}
|
}
|
||||||
$item = Item::selectFirstForUser(local_user(), $fields, ['id' => $item_id, 'private' => [0, 2], 'uid' => 0]);
|
$item = Item::selectFirstForUser(local_user(), $fields, ['id' => $item_id, 'private' => [Item::PUBLIC, Item::UNLISTED], 'uid' => 0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!DBA::isResult($item)) {
|
if (!DBA::isResult($item)) {
|
||||||
|
@ -216,7 +216,7 @@ function display_content(App $a, $update = false, $update_uid = 0)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (($item_parent == 0) && remote_user()) {
|
if (($item_parent == 0) && remote_user()) {
|
||||||
$item = Item::selectFirst($fields, ['guid' => $a->argv[1], 'private' => 1, 'origin' => true]);
|
$item = Item::selectFirst($fields, ['guid' => $a->argv[1], 'private' => Item::PRIVATE, 'origin' => true]);
|
||||||
if (DBA::isResult($item) && Contact::isFollower(remote_user(), $item['uid'])) {
|
if (DBA::isResult($item) && Contact::isFollower(remote_user(), $item['uid'])) {
|
||||||
$item_id = $item["id"];
|
$item_id = $item["id"];
|
||||||
$item_parent = $item["parent"];
|
$item_parent = $item["parent"];
|
||||||
|
@ -225,7 +225,7 @@ function display_content(App $a, $update = false, $update_uid = 0)
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($item_parent == 0) {
|
if ($item_parent == 0) {
|
||||||
$condition = ['private' => [0, 2], 'guid' => $a->argv[1], 'uid' => 0];
|
$condition = ['private' => [Item::PUBLIC, Item::UNLISTED], 'guid' => $a->argv[1], 'uid' => 0];
|
||||||
$item = Item::selectFirstForUser(local_user(), $fields, $condition);
|
$item = Item::selectFirstForUser(local_user(), $fields, $condition);
|
||||||
if (DBA::isResult($item)) {
|
if (DBA::isResult($item)) {
|
||||||
$item_id = $item["id"];
|
$item_id = $item["id"];
|
||||||
|
@ -241,7 +241,7 @@ function display_content(App $a, $update = false, $update_uid = 0)
|
||||||
}
|
}
|
||||||
|
|
||||||
// We are displaying an "alternate" link if that post was public. See issue 2864
|
// We are displaying an "alternate" link if that post was public. See issue 2864
|
||||||
$is_public = Item::exists(['id' => $item_id, 'private' => [0, 2]]);
|
$is_public = Item::exists(['id' => $item_id, 'private' => [Item::PUBLIC, Item::UNLISTED]]);
|
||||||
if ($is_public) {
|
if ($is_public) {
|
||||||
// For the atom feed the nickname doesn't matter at all, we only need the item id.
|
// For the atom feed the nickname doesn't matter at all, we only need the item id.
|
||||||
$alternate = DI::baseUrl().'/display/feed-item/'.$item_id.'.atom';
|
$alternate = DI::baseUrl().'/display/feed-item/'.$item_id.'.atom';
|
||||||
|
|
|
@ -300,7 +300,13 @@ function item_post(App $a) {
|
||||||
|
|
||||||
$postopts = $_REQUEST['postopts'] ?? '';
|
$postopts = $_REQUEST['postopts'] ?? '';
|
||||||
|
|
||||||
$private = ((strlen($str_group_allow) || strlen($str_contact_allow) || strlen($str_group_deny) || strlen($str_contact_deny)) ? 1 : 0);
|
if (strlen($str_group_allow) || strlen($str_contact_allow) || strlen($str_group_deny) || strlen($str_contact_deny)) {
|
||||||
|
$private = Item::PRIVATE;
|
||||||
|
} elseif (DI::pConfig()->get($profile_uid, 'system', 'unlisted')) {
|
||||||
|
$private = Item::UNLISTED;
|
||||||
|
} else {
|
||||||
|
$private = Item::PUBLIC;
|
||||||
|
}
|
||||||
|
|
||||||
// If this is a comment, set the permissions from the parent.
|
// If this is a comment, set the permissions from the parent.
|
||||||
|
|
||||||
|
|
|
@ -66,7 +66,7 @@ function lockview_content(App $a)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isset($item['private'])
|
if (isset($item['private'])
|
||||||
&& $item['private'] == 1
|
&& $item['private'] == Item::PRIVATE
|
||||||
&& empty($item['allow_cid'])
|
&& empty($item['allow_cid'])
|
||||||
&& empty($item['allow_gid'])
|
&& empty($item['allow_gid'])
|
||||||
&& empty($item['deny_cid'])
|
&& empty($item['deny_cid'])
|
||||||
|
|
|
@ -204,13 +204,13 @@ function photos_post(App $a)
|
||||||
|
|
||||||
if (!DBA::isResult($r)) {
|
if (!DBA::isResult($r)) {
|
||||||
notice(DI::l10n()->t('Album not found.') . EOL);
|
notice(DI::l10n()->t('Album not found.') . EOL);
|
||||||
DI::baseUrl()->redirect($_SESSION['photo_return']);
|
DI::baseUrl()->redirect('photos/' . $a->data['user']['nickname'] . '/album');
|
||||||
return; // NOTREACHED
|
return; // NOTREACHED
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check if the user has responded to a delete confirmation query
|
// Check if the user has responded to a delete confirmation query
|
||||||
if (!empty($_REQUEST['canceled'])) {
|
if (!empty($_REQUEST['canceled'])) {
|
||||||
DI::baseUrl()->redirect($_SESSION['photo_return']);
|
DI::baseUrl()->redirect('photos/' . $a->data['user']['nickname'] . '/album/' . $a->argv[3]);
|
||||||
}
|
}
|
||||||
|
|
||||||
// RENAME photo album
|
// RENAME photo album
|
||||||
|
@ -267,7 +267,7 @@ function photos_post(App $a)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
DI::baseUrl()->redirect('photos/' . $a->argv[1]);
|
DI::baseUrl()->redirect('photos/' . $a->data['user']['nickname'] . '/album');
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($a->argc > 3 && $a->argv[2] === 'image') {
|
if ($a->argc > 3 && $a->argv[2] === 'image') {
|
||||||
|
@ -1372,7 +1372,6 @@ function photos_content(App $a)
|
||||||
$likebuttons = '';
|
$likebuttons = '';
|
||||||
$comments = '';
|
$comments = '';
|
||||||
$paginate = '';
|
$paginate = '';
|
||||||
$responses = '';
|
|
||||||
|
|
||||||
if (!empty($link_item['id']) && !empty($link_item['uri'])) {
|
if (!empty($link_item['id']) && !empty($link_item['uri'])) {
|
||||||
$cmnt_tpl = Renderer::getMarkupTemplate('comment_item.tpl');
|
$cmnt_tpl = Renderer::getMarkupTemplate('comment_item.tpl');
|
||||||
|
@ -1413,11 +1412,11 @@ function photos_content(App $a)
|
||||||
}
|
}
|
||||||
|
|
||||||
$conv_responses = [
|
$conv_responses = [
|
||||||
'like' => ['title' => DI::l10n()->t('Likes','title')],
|
'like' => [],
|
||||||
'dislike' => ['title' => DI::l10n()->t('Dislikes','title')],
|
'dislike' => [],
|
||||||
'attendyes' => ['title' => DI::l10n()->t('Attending','title')],
|
'attendyes' => [],
|
||||||
'attendno' => ['title' => DI::l10n()->t('Not attending','title')],
|
'attendno' => [],
|
||||||
'attendmaybe' => ['title' => DI::l10n()->t('Might attend','title')]
|
'attendmaybe' => []
|
||||||
];
|
];
|
||||||
|
|
||||||
if (DI::pConfig()->get(local_user(), 'system', 'hide_dislike')) {
|
if (DI::pConfig()->get(local_user(), 'system', 'hide_dislike')) {
|
||||||
|
@ -1460,7 +1459,6 @@ function photos_content(App $a)
|
||||||
foreach ($items as $item) {
|
foreach ($items as $item) {
|
||||||
$comment = '';
|
$comment = '';
|
||||||
$template = $tpl;
|
$template = $tpl;
|
||||||
$sparkle = '';
|
|
||||||
|
|
||||||
$activity = DI::activity();
|
$activity = DI::activity();
|
||||||
|
|
||||||
|
@ -1523,8 +1521,6 @@ function photos_content(App $a)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$responses = get_responses($conv_responses, ['like', 'dislike'], $link_item);
|
|
||||||
|
|
||||||
$paginate = $pager->renderFull($total);
|
$paginate = $pager->renderFull($total);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1544,7 +1540,6 @@ function photos_content(App $a)
|
||||||
'$likebuttons' => $likebuttons,
|
'$likebuttons' => $likebuttons,
|
||||||
'$like' => $like,
|
'$like' => $like,
|
||||||
'$dislike' => $dislike,
|
'$dislike' => $dislike,
|
||||||
'responses' => $responses,
|
|
||||||
'$comments' => $comments,
|
'$comments' => $comments,
|
||||||
'$paginate' => $paginate,
|
'$paginate' => $paginate,
|
||||||
]);
|
]);
|
||||||
|
|
|
@ -84,7 +84,7 @@ function poke_init(App $a)
|
||||||
$deny_gid = $item['deny_gid'];
|
$deny_gid = $item['deny_gid'];
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
$private = (!empty($_GET['private']) ? intval($_GET['private']) : 0);
|
$private = (!empty($_GET['private']) ? intval($_GET['private']) : Item::PUBLIC);
|
||||||
|
|
||||||
$allow_cid = ($private ? '<' . $target['id']. '>' : $a->user['allow_cid']);
|
$allow_cid = ($private ? '<' . $target['id']. '>' : $a->user['allow_cid']);
|
||||||
$allow_gid = ($private ? '' : $a->user['allow_gid']);
|
$allow_gid = ($private ? '' : $a->user['allow_gid']);
|
||||||
|
|
|
@ -84,18 +84,12 @@ function pubsubhubbub_init(App $a) {
|
||||||
|
|
||||||
// fetch user from database given the nickname
|
// fetch user from database given the nickname
|
||||||
$condition = ['nickname' => $nick, 'account_expired' => false, 'account_removed' => false];
|
$condition = ['nickname' => $nick, 'account_expired' => false, 'account_removed' => false];
|
||||||
$owner = DBA::selectFirst('user', ['uid', 'hidewall', 'nickname'], $condition);
|
$owner = DBA::selectFirst('user', ['uid', 'nickname'], $condition);
|
||||||
if (!DBA::isResult($owner)) {
|
if (!DBA::isResult($owner)) {
|
||||||
Logger::log('Local account not found: ' . $nick . ' - topic: ' . $hub_topic . ' - callback: ' . $hub_callback);
|
Logger::log('Local account not found: ' . $nick . ' - topic: ' . $hub_topic . ' - callback: ' . $hub_callback);
|
||||||
throw new \Friendica\Network\HTTPException\NotFoundException();
|
throw new \Friendica\Network\HTTPException\NotFoundException();
|
||||||
}
|
}
|
||||||
|
|
||||||
// abort if user's wall is supposed to be private
|
|
||||||
if ($owner['hidewall']) {
|
|
||||||
Logger::log('Local user ' . $nick . 'has chosen to hide wall, ignoring.');
|
|
||||||
throw new \Friendica\Network\HTTPException\ForbiddenException();
|
|
||||||
}
|
|
||||||
|
|
||||||
// get corresponding row from contact table
|
// get corresponding row from contact table
|
||||||
$condition = ['uid' => $owner['uid'], 'blocked' => false,
|
$condition = ['uid' => $owner['uid'], 'blocked' => false,
|
||||||
'pending' => false, 'self' => true];
|
'pending' => false, 'self' => true];
|
||||||
|
|
120
mod/regmod.php
120
mod/regmod.php
|
@ -1,120 +0,0 @@
|
||||||
<?php
|
|
||||||
/**
|
|
||||||
* @copyright Copyright (C) 2020, Friendica
|
|
||||||
*
|
|
||||||
* @license GNU AGPL version 3 or any later version
|
|
||||||
*
|
|
||||||
* This program is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU Affero General Public License as
|
|
||||||
* published by the Free Software Foundation, either version 3 of the
|
|
||||||
* License, or (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU Affero General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU Affero General Public License
|
|
||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
use Friendica\App;
|
|
||||||
use Friendica\Core\Worker;
|
|
||||||
use Friendica\Database\DBA;
|
|
||||||
use Friendica\DI;
|
|
||||||
use Friendica\Model\Register;
|
|
||||||
use Friendica\Model\User;
|
|
||||||
use Friendica\Module\Security\Login;
|
|
||||||
|
|
||||||
function user_allow($hash)
|
|
||||||
{
|
|
||||||
$register = Register::getByHash($hash);
|
|
||||||
if (!DBA::isResult($register)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
$user = User::getById($register['uid']);
|
|
||||||
if (!DBA::isResult($user)) {
|
|
||||||
exit();
|
|
||||||
}
|
|
||||||
|
|
||||||
Register::deleteByHash($hash);
|
|
||||||
|
|
||||||
DBA::update('user', ['blocked' => false, 'verified' => true], ['uid' => $register['uid']]);
|
|
||||||
|
|
||||||
$profile = DBA::selectFirst('profile', ['net-publish'], ['uid' => $register['uid']]);
|
|
||||||
|
|
||||||
if (DBA::isResult($profile) && $profile['net-publish'] && DI::config()->get('system', 'directory')) {
|
|
||||||
$url = DI::baseUrl() . '/profile/' . $user['nickname'];
|
|
||||||
Worker::add(PRIORITY_LOW, "Directory", $url);
|
|
||||||
}
|
|
||||||
|
|
||||||
$l10n = DI::l10n()->withLang($register['language']);
|
|
||||||
|
|
||||||
$res = User::sendRegisterOpenEmail(
|
|
||||||
$l10n,
|
|
||||||
$user,
|
|
||||||
DI::config()->get('config', 'sitename'),
|
|
||||||
DI::baseUrl()->get(),
|
|
||||||
($register['password'] ?? '') ?: 'Sent in a previous email'
|
|
||||||
);
|
|
||||||
|
|
||||||
if ($res) {
|
|
||||||
info(DI::l10n()->t('Account approved.') . EOL);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// This does not have to go through user_remove() and save the nickname
|
|
||||||
// permanently against re-registration, as the person was not yet
|
|
||||||
// allowed to have friends on this system
|
|
||||||
function user_deny($hash)
|
|
||||||
{
|
|
||||||
$register = Register::getByHash($hash);
|
|
||||||
if (!DBA::isResult($register)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
$user = User::getById($register['uid']);
|
|
||||||
if (!DBA::isResult($user)) {
|
|
||||||
exit();
|
|
||||||
}
|
|
||||||
|
|
||||||
DBA::delete('user', ['uid' => $register['uid']]);
|
|
||||||
|
|
||||||
Register::deleteByHash($register['hash']);
|
|
||||||
|
|
||||||
notice(DI::l10n()->t('Registration revoked for %s', $user['username']) . EOL);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
function regmod_content(App $a)
|
|
||||||
{
|
|
||||||
if (!local_user()) {
|
|
||||||
info(DI::l10n()->t('Please login.') . EOL);
|
|
||||||
return Login::form(DI::args()->getQueryString(), intval(DI::config()->get('config', 'register_policy')) === \Friendica\Module\Register::CLOSED ? 0 : 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!is_site_admin() || !empty($_SESSION['submanage'])) {
|
|
||||||
notice(DI::l10n()->t('Permission denied.') . EOL);
|
|
||||||
return '';
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($a->argc != 3) {
|
|
||||||
exit();
|
|
||||||
}
|
|
||||||
|
|
||||||
$cmd = $a->argv[1];
|
|
||||||
$hash = $a->argv[2];
|
|
||||||
|
|
||||||
if ($cmd === 'deny') {
|
|
||||||
user_deny($hash);
|
|
||||||
DI::baseUrl()->redirect('admin/users/');
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($cmd === 'allow') {
|
|
||||||
user_allow($hash);
|
|
||||||
DI::baseUrl()->redirect('admin/users/');
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -27,7 +27,6 @@ use Friendica\Core\ACL;
|
||||||
use Friendica\Core\Hook;
|
use Friendica\Core\Hook;
|
||||||
use Friendica\Core\Logger;
|
use Friendica\Core\Logger;
|
||||||
use Friendica\Core\Renderer;
|
use Friendica\Core\Renderer;
|
||||||
use Friendica\Core\Theme;
|
|
||||||
use Friendica\Core\Worker;
|
use Friendica\Core\Worker;
|
||||||
use Friendica\Database\DBA;
|
use Friendica\Database\DBA;
|
||||||
use Friendica\DI;
|
use Friendica\DI;
|
||||||
|
@ -252,6 +251,8 @@ function settings_post(App $a)
|
||||||
unlink($_FILES['importcontact-filename']['tmp_name']);
|
unlink($_FILES['importcontact-filename']['tmp_name']);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!empty($_POST['resend_relocate'])) {
|
if (!empty($_POST['resend_relocate'])) {
|
||||||
|
@ -317,6 +318,7 @@ function settings_post(App $a)
|
||||||
$cntunkmail = (!empty($_POST['cntunkmail']) ? intval($_POST['cntunkmail']) : 0);
|
$cntunkmail = (!empty($_POST['cntunkmail']) ? intval($_POST['cntunkmail']) : 0);
|
||||||
$hide_friends = (($_POST['hide-friends'] == 1) ? 1: 0);
|
$hide_friends = (($_POST['hide-friends'] == 1) ? 1: 0);
|
||||||
$hidewall = (($_POST['hidewall'] == 1) ? 1: 0);
|
$hidewall = (($_POST['hidewall'] == 1) ? 1: 0);
|
||||||
|
$unlisted = (($_POST['unlisted'] == 1) ? 1: 0);
|
||||||
|
|
||||||
$email_textonly = (($_POST['email_textonly'] == 1) ? 1 : 0);
|
$email_textonly = (($_POST['email_textonly'] == 1) ? 1 : 0);
|
||||||
$detailed_notif = (($_POST['detailed_notif'] == 1) ? 1 : 0);
|
$detailed_notif = (($_POST['detailed_notif'] == 1) ? 1 : 0);
|
||||||
|
@ -363,17 +365,17 @@ function settings_post(App $a)
|
||||||
|
|
||||||
if ($username != $a->user['username']) {
|
if ($username != $a->user['username']) {
|
||||||
if (strlen($username) > 40) {
|
if (strlen($username) > 40) {
|
||||||
$err .= DI::l10n()->t(' Please use a shorter name.');
|
$err .= DI::l10n()->t('Please use a shorter name.');
|
||||||
}
|
}
|
||||||
if (strlen($username) < 3) {
|
if (strlen($username) < 3) {
|
||||||
$err .= DI::l10n()->t(' Name too short.');
|
$err .= DI::l10n()->t('Name too short.');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($email != $a->user['email']) {
|
if ($email != $a->user['email']) {
|
||||||
// check for the correct password
|
// check for the correct password
|
||||||
if (!User::authenticate(intval(local_user()), $_POST['mpassword'])) {
|
if (!User::authenticate(intval(local_user()), $_POST['mpassword'])) {
|
||||||
$err .= DI::l10n()->t('Wrong Password') . EOL;
|
$err .= DI::l10n()->t('Wrong Password.');
|
||||||
$email = $a->user['email'];
|
$email = $a->user['email'];
|
||||||
}
|
}
|
||||||
// check the email is valid
|
// check the email is valid
|
||||||
|
@ -391,7 +393,7 @@ function settings_post(App $a)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (strlen($err)) {
|
if (strlen($err)) {
|
||||||
notice($err . EOL);
|
notice($err);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -414,6 +416,7 @@ function settings_post(App $a)
|
||||||
|
|
||||||
DI::pConfig()->set(local_user(), 'system', 'email_textonly', $email_textonly);
|
DI::pConfig()->set(local_user(), 'system', 'email_textonly', $email_textonly);
|
||||||
DI::pConfig()->set(local_user(), 'system', 'detailed_notif', $detailed_notif);
|
DI::pConfig()->set(local_user(), 'system', 'detailed_notif', $detailed_notif);
|
||||||
|
DI::pConfig()->set(local_user(), 'system', 'unlisted', $unlisted);
|
||||||
|
|
||||||
if ($page_flags == User::PAGE_FLAGS_PRVGROUP) {
|
if ($page_flags == User::PAGE_FLAGS_PRVGROUP) {
|
||||||
$hidewall = 1;
|
$hidewall = 1;
|
||||||
|
@ -597,7 +600,7 @@ function settings_content(App $a)
|
||||||
$arr[$fname] = [];
|
$arr[$fname] = [];
|
||||||
$arr[$fname][0] = $fdata[0];
|
$arr[$fname][0] = $fdata[0];
|
||||||
foreach (array_slice($fdata,1) as $f) {
|
foreach (array_slice($fdata,1) as $f) {
|
||||||
$arr[$fname][1][] = ['feature_' .$f[0], $f[1],((intval(Feature::isEnabled(local_user(), $f[0]))) ? "1" : ''), $f[2],[DI::l10n()->t('Off'), DI::l10n()->t('On')]];
|
$arr[$fname][1][] = ['feature_' . $f[0], $f[1], Feature::isEnabled(local_user(), $f[0]), $f[2]];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -836,6 +839,10 @@ function settings_content(App $a)
|
||||||
'$field' => ['hidewall', DI::l10n()->t('Hide your profile details from anonymous viewers?'), $a->user['hidewall'], DI::l10n()->t('Anonymous visitors will only see your profile picture, your display name and the nickname you are using on your profile page. Your public posts and replies will still be accessible by other means.')],
|
'$field' => ['hidewall', DI::l10n()->t('Hide your profile details from anonymous viewers?'), $a->user['hidewall'], DI::l10n()->t('Anonymous visitors will only see your profile picture, your display name and the nickname you are using on your profile page. Your public posts and replies will still be accessible by other means.')],
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
$unlisted = Renderer::replaceMacros($opt_tpl, [
|
||||||
|
'$field' => ['unlisted', DI::l10n()->t('Make public posts unlisted'), DI::pConfig()->get(local_user(), 'system', 'unlisted'), DI::l10n()->t('Your public posts will not appear on the community pages or in search results, nor be sent to relay servers. However they can still appear on public feeds on remote servers.')],
|
||||||
|
]);
|
||||||
|
|
||||||
$blockwall = Renderer::replaceMacros($opt_tpl, [
|
$blockwall = Renderer::replaceMacros($opt_tpl, [
|
||||||
'$field' => ['blockwall', DI::l10n()->t('Allow friends to post to your profile page?'), (intval($a->user['blockwall']) ? '0' : '1'), DI::l10n()->t('Your contacts may write posts on your profile wall. These posts will be distributed to your contacts')],
|
'$field' => ['blockwall', DI::l10n()->t('Allow friends to post to your profile page?'), (intval($a->user['blockwall']) ? '0' : '1'), DI::l10n()->t('Your contacts may write posts on your profile wall. These posts will be distributed to your contacts')],
|
||||||
]);
|
]);
|
||||||
|
@ -949,6 +956,7 @@ function settings_content(App $a)
|
||||||
'$profile_in_net_dir' => $profile_in_net_dir,
|
'$profile_in_net_dir' => $profile_in_net_dir,
|
||||||
'$hide_friends' => $hide_friends,
|
'$hide_friends' => $hide_friends,
|
||||||
'$hide_wall' => $hide_wall,
|
'$hide_wall' => $hide_wall,
|
||||||
|
'$unlisted' => $unlisted,
|
||||||
'$unkmail' => $unkmail,
|
'$unkmail' => $unkmail,
|
||||||
'$cntunkmail' => ['cntunkmail', DI::l10n()->t('Maximum private messages per day from unknown people:'), $cntunkmail , DI::l10n()->t("\x28to prevent spam abuse\x29")],
|
'$cntunkmail' => ['cntunkmail', DI::l10n()->t('Maximum private messages per day from unknown people:'), $cntunkmail , DI::l10n()->t("\x28to prevent spam abuse\x29")],
|
||||||
|
|
||||||
|
|
|
@ -34,7 +34,7 @@ function share_init(App $a) {
|
||||||
'guid', 'created', 'plink', 'title'];
|
'guid', 'created', 'plink', 'title'];
|
||||||
$item = Item::selectFirst($fields, ['id' => $post_id]);
|
$item = Item::selectFirst($fields, ['id' => $post_id]);
|
||||||
|
|
||||||
if (!DBA::isResult($item) || $item['private'] == 1) {
|
if (!DBA::isResult($item) || $item['private'] == Item::PRIVATE) {
|
||||||
exit();
|
exit();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -28,7 +28,7 @@ use Friendica\Module\Contact;
|
||||||
|
|
||||||
function update_contact_content(App $a)
|
function update_contact_content(App $a)
|
||||||
{
|
{
|
||||||
if ($_GET["force"] == 1) {
|
if (!empty($_GET['force']) || !DI::pConfig()->get(local_user(), 'system', 'no_auto_update')) {
|
||||||
$text = Contact::content([], true);
|
$text = Contact::content([], true);
|
||||||
} else {
|
} else {
|
||||||
$text = '';
|
$text = '';
|
||||||
|
|
|
@ -1,126 +0,0 @@
|
||||||
<?php
|
|
||||||
/**
|
|
||||||
* @copyright Copyright (C) 2020, Friendica
|
|
||||||
*
|
|
||||||
* @license GNU AGPL version 3 or any later version
|
|
||||||
*
|
|
||||||
* This program is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU Affero General Public License as
|
|
||||||
* published by the Free Software Foundation, either version 3 of the
|
|
||||||
* License, or (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU Affero General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU Affero General Public License
|
|
||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
namespace Friendica\Console;
|
|
||||||
|
|
||||||
use Friendica\App;
|
|
||||||
use Friendica\Core\L10n;
|
|
||||||
use Friendica\Database\Database;
|
|
||||||
use Friendica\Model\User;
|
|
||||||
use RuntimeException;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* tool to set a new password for a user
|
|
||||||
*
|
|
||||||
* With this tool, you can set a new password for a user
|
|
||||||
*/
|
|
||||||
class NewPassword extends \Asika\SimpleConsole\Console
|
|
||||||
{
|
|
||||||
protected $helpOptions = ['h', 'help', '?'];
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @var App\Mode
|
|
||||||
*/
|
|
||||||
private $appMode;
|
|
||||||
/**
|
|
||||||
* @var L10n
|
|
||||||
*/
|
|
||||||
private $l10n;
|
|
||||||
/**
|
|
||||||
* @var Database
|
|
||||||
*/
|
|
||||||
private $dba;
|
|
||||||
|
|
||||||
protected function getHelp()
|
|
||||||
{
|
|
||||||
$help = <<<HELP
|
|
||||||
console newpassword - Creates a new password for a given user
|
|
||||||
Usage
|
|
||||||
bin/console newpassword <nickname> [<password>] [-h|--help|-?] [-v]
|
|
||||||
|
|
||||||
Description
|
|
||||||
Creates a new password for a user without using the "forgot password" functionality.
|
|
||||||
|
|
||||||
Options
|
|
||||||
-h|--help|-? Show help information
|
|
||||||
-v Show more debug information.
|
|
||||||
HELP;
|
|
||||||
return $help;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function __construct(App\Mode $appMode, L10n $l10n, Database $dba, array $argv = null)
|
|
||||||
{
|
|
||||||
parent::__construct($argv);
|
|
||||||
|
|
||||||
$this->appMode = $appMode;
|
|
||||||
$this->l10n = $l10n;
|
|
||||||
$this->dba = $dba;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected function doExecute()
|
|
||||||
{
|
|
||||||
if ($this->getOption('v')) {
|
|
||||||
$this->out('Class: ' . __CLASS__);
|
|
||||||
$this->out('Arguments: ' . var_export($this->args, true));
|
|
||||||
$this->out('Options: ' . var_export($this->options, true));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (count($this->args) == 0) {
|
|
||||||
$this->out($this->getHelp());
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (count($this->args) > 2) {
|
|
||||||
throw new \Asika\SimpleConsole\CommandArgsException('Too many arguments');
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($this->appMode->isInstall()) {
|
|
||||||
throw new RuntimeException('Database isn\'t ready or populated yet');
|
|
||||||
}
|
|
||||||
|
|
||||||
$nick = $this->getArgument(0);
|
|
||||||
|
|
||||||
$user = $this->dba->selectFirst('user', ['uid'], ['nickname' => $nick]);
|
|
||||||
if (!$this->dba->isResult($user)) {
|
|
||||||
throw new RuntimeException($this->l10n->t('User not found'));
|
|
||||||
}
|
|
||||||
|
|
||||||
$password = $this->getArgument(1);
|
|
||||||
if (is_null($password)) {
|
|
||||||
$this->out($this->l10n->t('Enter new password: '), false);
|
|
||||||
$password = \Seld\CliPrompt\CliPrompt::hiddenPrompt(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
$result = User::updatePassword($user['uid'], $password);
|
|
||||||
|
|
||||||
if (!$this->dba->isResult($result)) {
|
|
||||||
throw new \Exception($this->l10n->t('Password update failed. Please try again.'));
|
|
||||||
}
|
|
||||||
|
|
||||||
$this->out($this->l10n->t('Password changed.'));
|
|
||||||
} catch (\Exception $e) {
|
|
||||||
throw new RuntimeException($e->getMessage(), $e->getCode(), $e);
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
|
423
src/Console/User.php
Normal file
423
src/Console/User.php
Normal file
|
@ -0,0 +1,423 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* @copyright Copyright (C) 2020, Friendica
|
||||||
|
*
|
||||||
|
* @license GNU AGPL version 3 or any later version
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Affero General Public License as
|
||||||
|
* published by the Free Software Foundation, either version 3 of the
|
||||||
|
* License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Affero General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Affero General Public License
|
||||||
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Friendica\Console;
|
||||||
|
|
||||||
|
use Console_Table;
|
||||||
|
use Friendica\App;
|
||||||
|
use Friendica\Content\Pager;
|
||||||
|
use Friendica\Core\L10n;
|
||||||
|
use Friendica\Database\Database;
|
||||||
|
use Friendica\Model\Register;
|
||||||
|
use Friendica\Model\User as UserModel;
|
||||||
|
use Friendica\Util\Temporal;
|
||||||
|
use RuntimeException;
|
||||||
|
use Seld\CliPrompt\CliPrompt;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* tool to manage users of the current node
|
||||||
|
*/
|
||||||
|
class User extends \Asika\SimpleConsole\Console
|
||||||
|
{
|
||||||
|
protected $helpOptions = ['h', 'help', '?'];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var App\Mode
|
||||||
|
*/
|
||||||
|
private $appMode;
|
||||||
|
/**
|
||||||
|
* @var L10n
|
||||||
|
*/
|
||||||
|
private $l10n;
|
||||||
|
/**
|
||||||
|
* @var Database
|
||||||
|
*/
|
||||||
|
private $dba;
|
||||||
|
|
||||||
|
protected function getHelp()
|
||||||
|
{
|
||||||
|
$help = <<<HELP
|
||||||
|
console user - Modify user settings per console commands.
|
||||||
|
Usage
|
||||||
|
bin/console user password <nickname> [<password>] [-h|--help|-?] [-v]
|
||||||
|
bin/console user add [<name> [<nickname> [<email> [<language>]]]] [-h|--help|-?] [-v]
|
||||||
|
bin/console user delete [<nickname>] [-q] [-h|--help|-?] [-v]
|
||||||
|
bin/console user allow [<nickname>] [-h|--help|-?] [-v]
|
||||||
|
bin/console user deny [<nickname>] [-h|--help|-?] [-v]
|
||||||
|
bin/console user block [<nickname>] [-h|--help|-?] [-v]
|
||||||
|
bin/console user unblock [<nickname>] [-h|--help|-?] [-v]
|
||||||
|
bin/console user list pending [-s|--start=0] [-c|--count=50] [-h|--help|-?] [-v]
|
||||||
|
bin/console user list removed [-s|--start=0] [-c|--count=50] [-h|--help|-?] [-v]
|
||||||
|
bin/console user list active [-s|--start=0] [-c|--count=50] [-h|--help|-?] [-v]
|
||||||
|
bin/console user list all [-s|--start=0] [-c|--count=50] [-h|--help|-?] [-v]
|
||||||
|
bin/console user search id <UID> [-h|--help|-?] [-v]
|
||||||
|
bin/console user search nick <nick> [-h|--help|-?] [-v]
|
||||||
|
bin/console user search mail <mail> [-h|--help|-?] [-v]
|
||||||
|
bin/console user search guid <GUID> [-h|--help|-?] [-v]
|
||||||
|
|
||||||
|
Description
|
||||||
|
Modify user settings per console commands.
|
||||||
|
|
||||||
|
Options
|
||||||
|
-h|--help|-? Show help information
|
||||||
|
-v Show more debug information.
|
||||||
|
-q Quiet mode (don't ask for a command).
|
||||||
|
HELP;
|
||||||
|
return $help;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function __construct(App\Mode $appMode, L10n $l10n, Database $dba, array $argv = null)
|
||||||
|
{
|
||||||
|
parent::__construct($argv);
|
||||||
|
|
||||||
|
$this->appMode = $appMode;
|
||||||
|
$this->l10n = $l10n;
|
||||||
|
$this->dba = $dba;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function doExecute()
|
||||||
|
{
|
||||||
|
if ($this->getOption('v')) {
|
||||||
|
$this->out('Class: ' . __CLASS__);
|
||||||
|
$this->out('Arguments: ' . var_export($this->args, true));
|
||||||
|
$this->out('Options: ' . var_export($this->options, true));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (count($this->args) == 0) {
|
||||||
|
$this->out($this->getHelp());
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($this->appMode->isInstall()) {
|
||||||
|
throw new RuntimeException('Database isn\'t ready or populated yet');
|
||||||
|
}
|
||||||
|
|
||||||
|
$command = $this->getArgument(0);
|
||||||
|
|
||||||
|
switch ($command) {
|
||||||
|
case 'password':
|
||||||
|
return $this->password();
|
||||||
|
case 'add':
|
||||||
|
return $this->addUser();
|
||||||
|
case 'allow':
|
||||||
|
return $this->pendingUser(true);
|
||||||
|
case 'deny':
|
||||||
|
return $this->pendingUser(false);
|
||||||
|
case 'block':
|
||||||
|
return $this->blockUser(true);
|
||||||
|
case 'unblock':
|
||||||
|
return $this->blockUser(false);
|
||||||
|
case 'delete':
|
||||||
|
return $this->deleteUser();
|
||||||
|
case 'list':
|
||||||
|
return $this->listUser();
|
||||||
|
case 'search':
|
||||||
|
return $this->searchUser();
|
||||||
|
default:
|
||||||
|
throw new \Asika\SimpleConsole\CommandArgsException('Wrong command.');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets a new password
|
||||||
|
*
|
||||||
|
* @return int Return code of this command
|
||||||
|
*
|
||||||
|
* @throws \Exception
|
||||||
|
*/
|
||||||
|
private function password()
|
||||||
|
{
|
||||||
|
$nick = $this->getArgument(1);
|
||||||
|
|
||||||
|
$user = $this->dba->selectFirst('user', ['uid'], ['nickname' => $nick]);
|
||||||
|
if (!$this->dba->isResult($user)) {
|
||||||
|
throw new RuntimeException($this->l10n->t('User not found'));
|
||||||
|
}
|
||||||
|
|
||||||
|
$password = $this->getArgument(2);
|
||||||
|
|
||||||
|
if (is_null($password)) {
|
||||||
|
$this->out($this->l10n->t('Enter new password: '), false);
|
||||||
|
$password = CliPrompt::hiddenPrompt(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
$result = UserModel::updatePassword($user['uid'], $password);
|
||||||
|
|
||||||
|
if (!$this->dba->isResult($result)) {
|
||||||
|
throw new \Exception($this->l10n->t('Password update failed. Please try again.'));
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->out($this->l10n->t('Password changed.'));
|
||||||
|
} catch (\Exception $e) {
|
||||||
|
throw new RuntimeException($e->getMessage(), $e->getCode(), $e);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds a new user based on given console arguments
|
||||||
|
*
|
||||||
|
* @return bool True, if the command was successful
|
||||||
|
* @throws \ErrorException
|
||||||
|
* @throws \Friendica\Network\HTTPException\InternalServerErrorException
|
||||||
|
* @throws \ImagickException
|
||||||
|
*/
|
||||||
|
private function addUser()
|
||||||
|
{
|
||||||
|
$name = $this->getArgument(1);
|
||||||
|
$nick = $this->getArgument(2);
|
||||||
|
$email = $this->getArgument(3);
|
||||||
|
$lang = $this->getArgument(4);
|
||||||
|
|
||||||
|
if (empty($name)) {
|
||||||
|
$this->out($this->l10n->t('Enter user name: '));
|
||||||
|
$name = CliPrompt::prompt();
|
||||||
|
if (empty($name)) {
|
||||||
|
throw new RuntimeException('A name must be set.');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (empty($nick)) {
|
||||||
|
$this->out($this->l10n->t('Enter user nickname: '));
|
||||||
|
$nick = CliPrompt::prompt();
|
||||||
|
if (empty($nick)) {
|
||||||
|
throw new RuntimeException('A nick name must be set.');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (empty($email)) {
|
||||||
|
$this->out($this->l10n->t('Enter user email address: '));
|
||||||
|
$email = CliPrompt::prompt();
|
||||||
|
if (empty($email)) {
|
||||||
|
throw new RuntimeException('A email address must be set.');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (empty($lang)) {
|
||||||
|
$this->out($this->l10n->t('Enter a language (optional): '));
|
||||||
|
$lang = CliPrompt::prompt();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (empty($lang)) {
|
||||||
|
return UserModel::createMinimal($name, $email, $nick);
|
||||||
|
} else {
|
||||||
|
return UserModel::createMinimal($name, $email, $nick, $lang);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Allows or denys a user based on it's nickname
|
||||||
|
*
|
||||||
|
* @param bool $allow True, if the pending user is allowed, false if denies
|
||||||
|
*
|
||||||
|
* @return bool True, if allow was successful
|
||||||
|
* @throws \Friendica\Network\HTTPException\InternalServerErrorException
|
||||||
|
*/
|
||||||
|
private function pendingUser(bool $allow = true)
|
||||||
|
{
|
||||||
|
$nick = $this->getArgument(1);
|
||||||
|
|
||||||
|
if (!$nick) {
|
||||||
|
$this->out($this->l10n->t('Enter user nickname: '));
|
||||||
|
$nick = CliPrompt::prompt();
|
||||||
|
if (empty($nick)) {
|
||||||
|
throw new RuntimeException('A nick name must be set.');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$user = $this->dba->selectFirst('user', ['uid'], ['nickname' => $nick]);
|
||||||
|
if (empty($user)) {
|
||||||
|
throw new RuntimeException($this->l10n->t('User not found'));
|
||||||
|
}
|
||||||
|
|
||||||
|
$pending = Register::getPendingForUser($user['uid'] ?? 0);
|
||||||
|
if (empty($pending)) {
|
||||||
|
throw new RuntimeException($this->l10n->t('User is not pending.'));
|
||||||
|
}
|
||||||
|
|
||||||
|
return ($allow) ? UserModel::allow($pending['hash']) : UserModel::deny($pending['hash']);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Blocks/unblocks a user
|
||||||
|
*
|
||||||
|
* @param bool $block True, if the given user should get blocked
|
||||||
|
*
|
||||||
|
* @return bool True, if the command was successful
|
||||||
|
* @throws \Exception
|
||||||
|
*/
|
||||||
|
private function blockUser(bool $block = true)
|
||||||
|
{
|
||||||
|
$nick = $this->getArgument(1);
|
||||||
|
|
||||||
|
if (!$nick) {
|
||||||
|
$this->out($this->l10n->t('Enter user nickname: '));
|
||||||
|
$nick = CliPrompt::prompt();
|
||||||
|
if (empty($nick)) {
|
||||||
|
throw new RuntimeException('A nick name must be set.');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$user = $this->dba->selectFirst('user', ['uid'], ['nickname' => $nick]);
|
||||||
|
if (empty($user)) {
|
||||||
|
throw new RuntimeException($this->l10n->t('User not found'));
|
||||||
|
}
|
||||||
|
|
||||||
|
return $block ? UserModel::block($user['uid'] ?? 0) : UserModel::block($user['uid'] ?? 0, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Deletes a user
|
||||||
|
*
|
||||||
|
* @return bool True, if the delete was successful
|
||||||
|
* @throws \Exception
|
||||||
|
*/
|
||||||
|
private function deleteUser()
|
||||||
|
{
|
||||||
|
$nick = $this->getArgument(1);
|
||||||
|
|
||||||
|
if (!$nick) {
|
||||||
|
$this->out($this->l10n->t('Enter user nickname: '));
|
||||||
|
$nick = CliPrompt::prompt();
|
||||||
|
if (empty($nick)) {
|
||||||
|
throw new RuntimeException('A nick name must be set.');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$user = $this->dba->selectFirst('user', ['uid'], ['nickname' => $nick]);
|
||||||
|
if (empty($user)) {
|
||||||
|
throw new RuntimeException($this->l10n->t('User not found'));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!$this->getOption('q')) {
|
||||||
|
$this->out($this->l10n->t('Type "yes" to delete %s', $nick));
|
||||||
|
if (CliPrompt::prompt() !== 'yes') {
|
||||||
|
throw new RuntimeException('Delete abort.');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return UserModel::remove($user['uid'] ?? -1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* List users of the current node
|
||||||
|
*
|
||||||
|
* @return bool True, if the command was successful
|
||||||
|
*/
|
||||||
|
private function listUser()
|
||||||
|
{
|
||||||
|
$subCmd = $this->getArgument(1);
|
||||||
|
$start = $this->getOption(['s', 'start'], 0);
|
||||||
|
$count = $this->getOption(['c', 'count'], Pager::ITEMS_PER_PAGE);
|
||||||
|
|
||||||
|
$table = new Console_Table();
|
||||||
|
|
||||||
|
switch ($subCmd) {
|
||||||
|
case 'pending':
|
||||||
|
$table->setHeaders(['Nick', 'Name', 'URL', 'E-Mail', 'Register Date', 'Comment']);
|
||||||
|
$pending = Register::getPending($start, $count);
|
||||||
|
foreach ($pending as $contact) {
|
||||||
|
$table->addRow([
|
||||||
|
$contact['nick'],
|
||||||
|
$contact['name'],
|
||||||
|
$contact['url'],
|
||||||
|
$contact['email'],
|
||||||
|
Temporal::getRelativeDate($contact['created']),
|
||||||
|
$contact['note'],
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
$this->out($table->getTable());
|
||||||
|
return true;
|
||||||
|
case 'all':
|
||||||
|
case 'active':
|
||||||
|
case 'removed':
|
||||||
|
$table->setHeaders(['Nick', 'Name', 'URL', 'E-Mail', 'Register', 'Login', 'Last Item']);
|
||||||
|
$contacts = UserModel::getList($start, $count, $subCmd);
|
||||||
|
foreach ($contacts as $contact) {
|
||||||
|
$table->addRow([
|
||||||
|
$contact['nick'],
|
||||||
|
$contact['name'],
|
||||||
|
$contact['url'],
|
||||||
|
$contact['email'],
|
||||||
|
Temporal::getRelativeDate($contact['created']),
|
||||||
|
Temporal::getRelativeDate($contact['login_date']),
|
||||||
|
Temporal::getRelativeDate($contact['lastitem_date']),
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
$this->out($table->getTable());
|
||||||
|
return true;
|
||||||
|
default:
|
||||||
|
$this->out($this->getHelp());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a user based on search parameter
|
||||||
|
*
|
||||||
|
* @return bool True, if the command was successful
|
||||||
|
*/
|
||||||
|
private function searchUser()
|
||||||
|
{
|
||||||
|
$fields = [
|
||||||
|
'uid',
|
||||||
|
'guid',
|
||||||
|
'username',
|
||||||
|
'nickname',
|
||||||
|
'email',
|
||||||
|
'register_date',
|
||||||
|
'login_date',
|
||||||
|
'verified',
|
||||||
|
'blocked',
|
||||||
|
];
|
||||||
|
|
||||||
|
$subCmd = $this->getArgument(1);
|
||||||
|
$param = $this->getArgument(2);
|
||||||
|
|
||||||
|
$table = new Console_Table();
|
||||||
|
$table->setHeaders(['UID', 'GUID', 'Name', 'Nick', 'E-Mail', 'Register', 'Login', 'Verified', 'Blocked']);
|
||||||
|
|
||||||
|
switch ($subCmd) {
|
||||||
|
case 'id':
|
||||||
|
$user = UserModel::getById($param, $fields);
|
||||||
|
break;
|
||||||
|
case 'guid':
|
||||||
|
$user = UserModel::getByGuid($param, $fields);
|
||||||
|
break;
|
||||||
|
case 'email':
|
||||||
|
$user = UserModel::getByEmail($param, $fields);
|
||||||
|
break;
|
||||||
|
case 'nick':
|
||||||
|
$user = UserModel::getByNickname($param, $fields);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
$this->out($this->getHelp());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
$table->addRow($user);
|
||||||
|
$this->out($table->getTable());
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
|
@ -57,7 +57,7 @@ class BoundariesPager extends Pager
|
||||||
$this->last_item_id = $last_item_id;
|
$this->last_item_id = $last_item_id;
|
||||||
|
|
||||||
$parsed = parse_url($this->getBaseQueryString());
|
$parsed = parse_url($this->getBaseQueryString());
|
||||||
if ($parsed) {
|
if (!empty($parsed['query'])) {
|
||||||
parse_str($parsed['query'], $queryParameters);
|
parse_str($parsed['query'], $queryParameters);
|
||||||
|
|
||||||
$this->first_page = !($queryParameters['since_id'] ?? null) && !($queryParameters['max_id'] ?? null);
|
$this->first_page = !($queryParameters['since_id'] ?? null) && !($queryParameters['max_id'] ?? null);
|
||||||
|
|
|
@ -30,10 +30,13 @@ use Friendica\Util\Strings;
|
||||||
*/
|
*/
|
||||||
class Pager
|
class Pager
|
||||||
{
|
{
|
||||||
|
/** @var int Default count of items per page */
|
||||||
|
const ITEMS_PER_PAGE = 50;
|
||||||
|
|
||||||
/** @var integer */
|
/** @var integer */
|
||||||
private $page = 1;
|
private $page = 1;
|
||||||
/** @var integer */
|
/** @var integer */
|
||||||
protected $itemsPerPage = 50;
|
protected $itemsPerPage = self::ITEMS_PER_PAGE;
|
||||||
/** @var string */
|
/** @var string */
|
||||||
protected $baseQueryString = '';
|
protected $baseQueryString = '';
|
||||||
|
|
||||||
|
|
|
@ -634,12 +634,12 @@ class BBCode
|
||||||
|
|
||||||
if (!empty($data['title']) && !empty($data['url'])) {
|
if (!empty($data['title']) && !empty($data['url'])) {
|
||||||
if (!empty($data['image']) && empty($data['text']) && ($data['type'] == 'photo')) {
|
if (!empty($data['image']) && empty($data['text']) && ($data['type'] == 'photo')) {
|
||||||
$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']);
|
$return .= sprintf('<a href="%s" target="_blank" rel="noopener noreferrer"><img src="%s" alt="" title="%s" class="attachment-image" /></a>', $data['url'], self::proxyUrl($data['image'], $simplehtml), $data['title']);
|
||||||
} else {
|
} else {
|
||||||
if (!empty($data['image'])) {
|
if (!empty($data['image'])) {
|
||||||
$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']);
|
$return .= sprintf('<a href="%s" target="_blank" rel="noopener noreferrer"><img src="%s" alt="" title="%s" class="attachment-image" /></a><br />', $data['url'], self::proxyUrl($data['image'], $simplehtml), $data['title']);
|
||||||
} elseif (!empty($data['preview'])) {
|
} elseif (!empty($data['preview'])) {
|
||||||
$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']);
|
$return .= sprintf('<a href="%s" target="_blank" rel="noopener noreferrer"><img src="%s" alt="" title="%s" class="attachment-preview" /></a><br />', $data['url'], self::proxyUrl($data['preview'], $simplehtml), $data['title']);
|
||||||
}
|
}
|
||||||
$return .= sprintf('<h4><a href="%s">%s</a></h4>', $data['url'], $data['title']);
|
$return .= sprintf('<h4><a href="%s">%s</a></h4>', $data['url'], $data['title']);
|
||||||
}
|
}
|
||||||
|
@ -732,7 +732,7 @@ class BBCode
|
||||||
*/
|
*/
|
||||||
private static function convertUrlForActivityPub($url)
|
private static function convertUrlForActivityPub($url)
|
||||||
{
|
{
|
||||||
$html = '<a href="%s" target="_blank">%s</a>';
|
$html = '<a href="%s" target="_blank" rel="noopener noreferrer">%s</a>';
|
||||||
return sprintf($html, $url, self::getStyledURL($url));
|
return sprintf($html, $url, self::getStyledURL($url));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -975,7 +975,8 @@ class BBCode
|
||||||
Contact::getIdForURL($attributes['profile'], 0, true, $default);
|
Contact::getIdForURL($attributes['profile'], 0, true, $default);
|
||||||
|
|
||||||
$author_contact = Contact::getDetailsByURL($attributes['profile']);
|
$author_contact = Contact::getDetailsByURL($attributes['profile']);
|
||||||
$author_contact['addr'] = ($author_contact['addr'] ?? '') ?: Protocol::getAddrFromProfileUrl($attributes['profile']);
|
$author_contact['url'] = ($author_contact['url'] ?? $attributes['profile']);
|
||||||
|
$author_contact['addr'] = ($author_contact['addr'] ?? '') ?: Protocol::getAddrFromProfileUrl($attributes['profile']);
|
||||||
|
|
||||||
$attributes['author'] = ($author_contact['name'] ?? '') ?: $attributes['author'];
|
$attributes['author'] = ($author_contact['name'] ?? '') ?: $attributes['author'];
|
||||||
$attributes['avatar'] = ($author_contact['micro'] ?? '') ?: $attributes['avatar'];
|
$attributes['avatar'] = ($author_contact['micro'] ?? '') ?: $attributes['avatar'];
|
||||||
|
@ -1038,7 +1039,7 @@ class BBCode
|
||||||
break;
|
break;
|
||||||
case 4:
|
case 4:
|
||||||
$headline = '<p><b>' . html_entity_decode('♲ ', ENT_QUOTES, 'UTF-8');
|
$headline = '<p><b>' . html_entity_decode('♲ ', ENT_QUOTES, 'UTF-8');
|
||||||
$headline .= DI::l10n()->t('<a href="%1$s" target="_blank">%2$s</a> %3$s', $attributes['link'], $mention, $attributes['posted']);
|
$headline .= DI::l10n()->t('<a href="%1$s" target="_blank" rel="noopener noreferrer">%2$s</a> %3$s', $attributes['link'], $mention, $attributes['posted']);
|
||||||
$headline .= ':</b></p>' . "\n";
|
$headline .= ':</b></p>' . "\n";
|
||||||
|
|
||||||
$text = ($is_quote_share? '<hr />' : '') . $headline . '<blockquote class="shared_content">' . trim($content) . '</blockquote>' . "\n";
|
$text = ($is_quote_share? '<hr />' : '') . $headline . '<blockquote class="shared_content">' . trim($content) . '</blockquote>' . "\n";
|
||||||
|
@ -1636,9 +1637,9 @@ class BBCode
|
||||||
$text = preg_replace_callback("/\[audio\](.*?)\[\/audio\]/ism", $try_oembed_callback, $text);
|
$text = preg_replace_callback("/\[audio\](.*?)\[\/audio\]/ism", $try_oembed_callback, $text);
|
||||||
} else {
|
} else {
|
||||||
$text = preg_replace("/\[video\](.*?)\[\/video\]/ism",
|
$text = preg_replace("/\[video\](.*?)\[\/video\]/ism",
|
||||||
'<a href="$1" target="_blank">$1</a>', $text);
|
'<a href="$1" target="_blank" rel="noopener noreferrer">$1</a>', $text);
|
||||||
$text = preg_replace("/\[audio\](.*?)\[\/audio\]/ism",
|
$text = preg_replace("/\[audio\](.*?)\[\/audio\]/ism",
|
||||||
'<a href="$1" target="_blank">$1</a>', $text);
|
'<a href="$1" target="_blank" rel="noopener noreferrer">$1</a>', $text);
|
||||||
}
|
}
|
||||||
|
|
||||||
// html5 video and audio
|
// html5 video and audio
|
||||||
|
@ -1665,7 +1666,7 @@ class BBCode
|
||||||
$text = preg_replace("/\[youtube\]([A-Za-z0-9\-_=]+)(.*?)\[\/youtube\]/ism", '<iframe width="' . $a->videowidth . '" height="' . $a->videoheight . '" src="https://www.youtube.com/embed/$1" frameborder="0" ></iframe>', $text);
|
$text = preg_replace("/\[youtube\]([A-Za-z0-9\-_=]+)(.*?)\[\/youtube\]/ism", '<iframe width="' . $a->videowidth . '" height="' . $a->videoheight . '" src="https://www.youtube.com/embed/$1" frameborder="0" ></iframe>', $text);
|
||||||
} else {
|
} else {
|
||||||
$text = preg_replace("/\[youtube\]([A-Za-z0-9\-_=]+)(.*?)\[\/youtube\]/ism",
|
$text = preg_replace("/\[youtube\]([A-Za-z0-9\-_=]+)(.*?)\[\/youtube\]/ism",
|
||||||
'<a href="https://www.youtube.com/watch?v=$1" target="_blank">https://www.youtube.com/watch?v=$1</a>', $text);
|
'<a href="https://www.youtube.com/watch?v=$1" target="_blank" rel="noopener noreferrer">https://www.youtube.com/watch?v=$1</a>', $text);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($try_oembed) {
|
if ($try_oembed) {
|
||||||
|
@ -1680,7 +1681,7 @@ class BBCode
|
||||||
$text = preg_replace("/\[vimeo\]([0-9]+)(.*?)\[\/vimeo\]/ism", '<iframe width="' . $a->videowidth . '" height="' . $a->videoheight . '" src="https://player.vimeo.com/video/$1" frameborder="0" ></iframe>', $text);
|
$text = preg_replace("/\[vimeo\]([0-9]+)(.*?)\[\/vimeo\]/ism", '<iframe width="' . $a->videowidth . '" height="' . $a->videoheight . '" src="https://player.vimeo.com/video/$1" frameborder="0" ></iframe>', $text);
|
||||||
} else {
|
} else {
|
||||||
$text = preg_replace("/\[vimeo\]([0-9]+)(.*?)\[\/vimeo\]/ism",
|
$text = preg_replace("/\[vimeo\]([0-9]+)(.*?)\[\/vimeo\]/ism",
|
||||||
'<a href="https://vimeo.com/$1" target="_blank">https://vimeo.com/$1</a>', $text);
|
'<a href="https://vimeo.com/$1" target="_blank" rel="noopener noreferrer">https://vimeo.com/$1</a>', $text);
|
||||||
}
|
}
|
||||||
|
|
||||||
// oembed tag
|
// oembed tag
|
||||||
|
@ -1801,17 +1802,17 @@ class BBCode
|
||||||
. '</a>';
|
. '</a>';
|
||||||
}, $text);
|
}, $text);
|
||||||
|
|
||||||
// We need no target="_blank" for local links
|
// We need no target="_blank" rel="noopener noreferrer" for local links
|
||||||
// convert links start with DI::baseUrl() as local link without the target="_blank" attribute
|
// convert links start with DI::baseUrl() as local link without the target="_blank" rel="noopener noreferrer" attribute
|
||||||
$escapedBaseUrl = preg_quote(DI::baseUrl(), '/');
|
$escapedBaseUrl = preg_quote(DI::baseUrl(), '/');
|
||||||
$text = preg_replace("/\[url\](".$escapedBaseUrl.".*?)\[\/url\]/ism", '<a href="$1">$1</a>', $text);
|
$text = preg_replace("/\[url\](".$escapedBaseUrl.".*?)\[\/url\]/ism", '<a href="$1">$1</a>', $text);
|
||||||
$text = preg_replace("/\[url\=(".$escapedBaseUrl.".*?)\](.*?)\[\/url\]/ism", '<a href="$1">$2</a>', $text);
|
$text = preg_replace("/\[url\=(".$escapedBaseUrl.".*?)\](.*?)\[\/url\]/ism", '<a href="$1">$2</a>', $text);
|
||||||
|
|
||||||
$text = preg_replace("/\[url\](.*?)\[\/url\]/ism", '<a href="$1" target="_blank">$1</a>', $text);
|
$text = preg_replace("/\[url\](.*?)\[\/url\]/ism", '<a href="$1" target="_blank" rel="noopener noreferrer">$1</a>', $text);
|
||||||
$text = preg_replace("/\[url\=(.*?)\](.*?)\[\/url\]/ism", '<a href="$1" target="_blank">$2</a>', $text);
|
$text = preg_replace("/\[url\=(.*?)\](.*?)\[\/url\]/ism", '<a href="$1" target="_blank" rel="noopener noreferrer">$2</a>', $text);
|
||||||
|
|
||||||
// Red compatibility, though the link can't be authenticated on Friendica
|
// Red compatibility, though the link can't be authenticated on Friendica
|
||||||
$text = preg_replace("/\[zrl\=(.*?)\](.*?)\[\/zrl\]/ism", '<a href="$1" target="_blank">$2</a>', $text);
|
$text = preg_replace("/\[zrl\=(.*?)\](.*?)\[\/zrl\]/ism", '<a href="$1" target="_blank" rel="noopener noreferrer">$2</a>', $text);
|
||||||
|
|
||||||
|
|
||||||
// we may need to restrict this further if it picks up too many strays
|
// we may need to restrict this further if it picks up too many strays
|
||||||
|
@ -2004,8 +2005,6 @@ class BBCode
|
||||||
*/
|
*/
|
||||||
public static function toMarkdown($text, $for_diaspora = true)
|
public static function toMarkdown($text, $for_diaspora = true)
|
||||||
{
|
{
|
||||||
$a = DI::app();
|
|
||||||
|
|
||||||
$original_text = $text;
|
$original_text = $text;
|
||||||
|
|
||||||
// Since Diaspora is creating a summary for links, this function removes them before posting
|
// Since Diaspora is creating a summary for links, this function removes them before posting
|
||||||
|
|
|
@ -943,7 +943,7 @@ class HTML
|
||||||
*/
|
*/
|
||||||
public static function toLink($s)
|
public static function toLink($s)
|
||||||
{
|
{
|
||||||
$s = preg_replace("/(https?\:\/\/[a-zA-Z0-9\:\/\-\?\&\;\.\=\_\~\#\'\%\$\!\+]*)/", ' <a href="$1" target="_blank">$1</a>', $s);
|
$s = preg_replace("/(https?\:\/\/[a-zA-Z0-9\:\/\-\?\&\;\.\=\_\~\#\'\%\$\!\+]*)/", ' <a href="$1" target="_blank" rel="noopener noreferrer">$1</a>', $s);
|
||||||
$s = preg_replace("/\<(.*?)(src|href)=(.*?)\&\;(.*?)\>/ism", '<$1$2=$3&$4>', $s);
|
$s = preg_replace("/\<(.*?)(src|href)=(.*?)\&\;(.*?)\>/ism", '<$1$2=$3&$4>', $s);
|
||||||
return $s;
|
return $s;
|
||||||
}
|
}
|
||||||
|
|
|
@ -53,6 +53,8 @@ class Markdown
|
||||||
return $url;
|
return $url;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
$text = self::convertDiasporaMentionsToHtml($text);
|
||||||
|
|
||||||
$html = $MarkdownParser->transform($text);
|
$html = $MarkdownParser->transform($text);
|
||||||
|
|
||||||
DI::profiler()->saveTimestamp($stamp1, "parser", System::callstack());
|
DI::profiler()->saveTimestamp($stamp1, "parser", System::callstack());
|
||||||
|
@ -61,35 +63,42 @@ class Markdown
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Callback function to replace a Diaspora style mention in a mention for Friendica
|
* Replace Diaspora-style mentions in a text since they trip the Markdown parser autolinker.
|
||||||
*
|
*
|
||||||
* @param array $match Matching values for the callback
|
* @param string $text
|
||||||
* [1] = mention type (@ or !)
|
* @return string
|
||||||
* [2] = name (optional)
|
|
||||||
* [3] = address
|
|
||||||
* @return string Replaced mention
|
|
||||||
* @throws \Friendica\Network\HTTPException\InternalServerErrorException
|
|
||||||
* @throws \ImagickException
|
|
||||||
*/
|
*/
|
||||||
private static function diasporaMention2BBCodeCallback($match)
|
private static function convertDiasporaMentionsToHtml(string $text)
|
||||||
{
|
{
|
||||||
if ($match[3] == '') {
|
return preg_replace_callback(
|
||||||
return;
|
'/([@!]){(?:([^}]+?); ?)?([^} ]+)}/',
|
||||||
}
|
/*
|
||||||
|
* Matching values for the callback
|
||||||
|
* [1] = mention type (@ or !)
|
||||||
|
* [2] = name (optional)
|
||||||
|
* [3] = profile URL
|
||||||
|
*/
|
||||||
|
function ($matches) {
|
||||||
|
if ($matches[3] == '') {
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
|
||||||
$data = Contact::getDetailsByAddr($match[3]);
|
$data = Contact::getDetailsByAddr($matches[3]);
|
||||||
|
|
||||||
if (empty($data)) {
|
if (empty($data)) {
|
||||||
return;
|
return '';
|
||||||
}
|
}
|
||||||
|
|
||||||
$name = $match[2];
|
$name = $matches[2];
|
||||||
|
|
||||||
if ($name == '') {
|
if ($name == '') {
|
||||||
$name = $data['name'];
|
$name = $data['name'];
|
||||||
}
|
}
|
||||||
|
|
||||||
return $match[1] . '[url=' . $data['url'] . ']' . $name . '[/url]';
|
return $matches[1] . '<a href="' . $data['url'] . '">' . $name . '</a>';
|
||||||
|
},
|
||||||
|
$text
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -110,9 +119,6 @@ class Markdown
|
||||||
|
|
||||||
$s = self::convert($s);
|
$s = self::convert($s);
|
||||||
|
|
||||||
$regexp = "/([@!])\{(?:([^\}]+?); ?)?([^\} ]+)\}/";
|
|
||||||
$s = preg_replace_callback($regexp, ['self', 'diasporaMention2BBCodeCallback'], $s);
|
|
||||||
|
|
||||||
$s = HTML::toBBCode($s);
|
$s = HTML::toBBCode($s);
|
||||||
|
|
||||||
// protect the recycle symbol from turning into a tag, but without unescaping angles and naked ampersands
|
// protect the recycle symbol from turning into a tag, but without unescaping angles and naked ampersands
|
||||||
|
|
|
@ -57,7 +57,7 @@ Commands:
|
||||||
autoinstall Starts automatic installation of friendica based on values from htconfig.php
|
autoinstall Starts automatic installation of friendica based on values from htconfig.php
|
||||||
lock Edit site locks
|
lock Edit site locks
|
||||||
maintenance Set maintenance mode for this node
|
maintenance Set maintenance mode for this node
|
||||||
newpassword Set a new password for a given user
|
user User management
|
||||||
php2po Generate a messages.po file from a strings.php file
|
php2po Generate a messages.po file from a strings.php file
|
||||||
po2php Generate a strings.php file from a messages.po file
|
po2php Generate a strings.php file from a messages.po file
|
||||||
typo Checks for parse errors in Friendica files
|
typo Checks for parse errors in Friendica files
|
||||||
|
@ -85,7 +85,7 @@ HELP;
|
||||||
'autoinstall' => Friendica\Console\AutomaticInstallation::class,
|
'autoinstall' => Friendica\Console\AutomaticInstallation::class,
|
||||||
'lock' => Friendica\Console\Lock::class,
|
'lock' => Friendica\Console\Lock::class,
|
||||||
'maintenance' => Friendica\Console\Maintenance::class,
|
'maintenance' => Friendica\Console\Maintenance::class,
|
||||||
'newpassword' => Friendica\Console\NewPassword::class,
|
'user' => Friendica\Console\User::class,
|
||||||
'php2po' => Friendica\Console\PhpToPo::class,
|
'php2po' => Friendica\Console\PhpToPo::class,
|
||||||
'po2php' => Friendica\Console\PoToPhp::class,
|
'po2php' => Friendica\Console\PoToPhp::class,
|
||||||
'typo' => Friendica\Console\Typo::class,
|
'typo' => Friendica\Console\Typo::class,
|
||||||
|
|
|
@ -33,6 +33,9 @@ use Psr\Log\LoggerInterface;
|
||||||
*/
|
*/
|
||||||
class L10n
|
class L10n
|
||||||
{
|
{
|
||||||
|
/** @var string The default language */
|
||||||
|
const DEFAULT = 'en';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A string indicating the current language used for translation:
|
* A string indicating the current language used for translation:
|
||||||
* - Two-letter ISO 639-1 code.
|
* - Two-letter ISO 639-1 code.
|
||||||
|
@ -64,7 +67,7 @@ class L10n
|
||||||
$this->dba = $dba;
|
$this->dba = $dba;
|
||||||
$this->logger = $logger;
|
$this->logger = $logger;
|
||||||
|
|
||||||
$this->loadTranslationTable(L10n::detectLanguage($server, $get, $config->get('system', 'language', 'en')));
|
$this->loadTranslationTable(L10n::detectLanguage($server, $get, $config->get('system', 'language', self::DEFAULT)));
|
||||||
$this->setSessionVariable($session);
|
$this->setSessionVariable($session);
|
||||||
$this->setLangFromSession($session);
|
$this->setLangFromSession($session);
|
||||||
}
|
}
|
||||||
|
@ -158,7 +161,7 @@ class L10n
|
||||||
*
|
*
|
||||||
* @return string The two-letter language code
|
* @return string The two-letter language code
|
||||||
*/
|
*/
|
||||||
public static function detectLanguage(array $server, array $get, string $sysLang = 'en')
|
public static function detectLanguage(array $server, array $get, string $sysLang = self::DEFAULT)
|
||||||
{
|
{
|
||||||
$lang_variable = $server['HTTP_ACCEPT_LANGUAGE'] ?? null;
|
$lang_variable = $server['HTTP_ACCEPT_LANGUAGE'] ?? null;
|
||||||
|
|
||||||
|
|
|
@ -98,7 +98,7 @@ class Theme
|
||||||
$comment_lines = explode("\n", $matches[0]);
|
$comment_lines = explode("\n", $matches[0]);
|
||||||
foreach ($comment_lines as $comment_line) {
|
foreach ($comment_lines as $comment_line) {
|
||||||
$comment_line = trim($comment_line, "\t\n\r */");
|
$comment_line = trim($comment_line, "\t\n\r */");
|
||||||
if ($comment_line != "") {
|
if (strpos($comment_line, ':') !== false) {
|
||||||
list($key, $value) = array_map("trim", explode(":", $comment_line, 2));
|
list($key, $value) = array_map("trim", explode(":", $comment_line, 2));
|
||||||
$key = strtolower($key);
|
$key = strtolower($key);
|
||||||
if ($key == "author") {
|
if ($key == "author") {
|
||||||
|
|
|
@ -1037,6 +1037,7 @@ class Contact
|
||||||
}
|
}
|
||||||
|
|
||||||
if (DBA::isResult($r)) {
|
if (DBA::isResult($r)) {
|
||||||
|
$authoritativeResult = true;
|
||||||
// If there is more than one entry we filter out the connector networks
|
// If there is more than one entry we filter out the connector networks
|
||||||
if (count($r) > 1) {
|
if (count($r) > 1) {
|
||||||
foreach ($r as $id => $result) {
|
foreach ($r as $id => $result) {
|
||||||
|
@ -1070,6 +1071,7 @@ class Contact
|
||||||
$profile["bd"] = DBA::NULL_DATE;
|
$profile["bd"] = DBA::NULL_DATE;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
$authoritativeResult = false;
|
||||||
$profile = $default;
|
$profile = $default;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1106,7 +1108,11 @@ class Contact
|
||||||
$profile["birthday"] = DBA::NULL_DATE;
|
$profile["birthday"] = DBA::NULL_DATE;
|
||||||
}
|
}
|
||||||
|
|
||||||
$cache[$url][$uid] = $profile;
|
// Only cache the result if it came from the DB since this method is used in widely different contexts
|
||||||
|
// @see display_fetch_author for an example of $default parameter diverging from the DB result
|
||||||
|
if ($authoritativeResult) {
|
||||||
|
$cache[$url][$uid] = $profile;
|
||||||
|
}
|
||||||
|
|
||||||
return $profile;
|
return $profile;
|
||||||
}
|
}
|
||||||
|
|
|
@ -113,6 +113,10 @@ class Item
|
||||||
Activity::FOLLOW,
|
Activity::FOLLOW,
|
||||||
Activity::ANNOUNCE];
|
Activity::ANNOUNCE];
|
||||||
|
|
||||||
|
const PUBLIC = 0;
|
||||||
|
const PRIVATE = 1;
|
||||||
|
const UNLISTED = 2;
|
||||||
|
|
||||||
private static $legacy_mode = null;
|
private static $legacy_mode = null;
|
||||||
|
|
||||||
public static function isLegacyMode()
|
public static function isLegacyMode()
|
||||||
|
@ -1112,6 +1116,7 @@ class Item
|
||||||
*/
|
*/
|
||||||
public static function deleteById($item_id, $priority = PRIORITY_HIGH)
|
public static function deleteById($item_id, $priority = PRIORITY_HIGH)
|
||||||
{
|
{
|
||||||
|
Logger::notice('Delete item by id', ['id' => $item_id, 'callstack' => System::callstack()]);
|
||||||
// locate item to be deleted
|
// locate item to be deleted
|
||||||
$fields = ['id', 'uri', 'uid', 'parent', 'parent-uri', 'origin',
|
$fields = ['id', 'uri', 'uid', 'parent', 'parent-uri', 'origin',
|
||||||
'deleted', 'file', 'resource-id', 'event-id', 'attach',
|
'deleted', 'file', 'resource-id', 'event-id', 'attach',
|
||||||
|
@ -1541,7 +1546,7 @@ class Item
|
||||||
$item['allow_gid'] = trim($item['allow_gid'] ?? '');
|
$item['allow_gid'] = trim($item['allow_gid'] ?? '');
|
||||||
$item['deny_cid'] = trim($item['deny_cid'] ?? '');
|
$item['deny_cid'] = trim($item['deny_cid'] ?? '');
|
||||||
$item['deny_gid'] = trim($item['deny_gid'] ?? '');
|
$item['deny_gid'] = trim($item['deny_gid'] ?? '');
|
||||||
$item['private'] = intval($item['private'] ?? 0);
|
$item['private'] = intval($item['private'] ?? self::PUBLIC);
|
||||||
$item['body'] = trim($item['body'] ?? '');
|
$item['body'] = trim($item['body'] ?? '');
|
||||||
$item['tag'] = trim($item['tag'] ?? '');
|
$item['tag'] = trim($item['tag'] ?? '');
|
||||||
$item['attach'] = trim($item['attach'] ?? '');
|
$item['attach'] = trim($item['attach'] ?? '');
|
||||||
|
@ -1737,8 +1742,8 @@ class Item
|
||||||
* The original author commented, but as this is a comment, the permissions
|
* The original author commented, but as this is a comment, the permissions
|
||||||
* weren't fixed up so it will still show the comment as private unless we fix it here.
|
* weren't fixed up so it will still show the comment as private unless we fix it here.
|
||||||
*/
|
*/
|
||||||
if ((intval($parent['forum_mode']) == 1) && $parent['private']) {
|
if ((intval($parent['forum_mode']) == 1) && ($parent['private'] != self::PUBLIC)) {
|
||||||
$item['private'] = 0;
|
$item['private'] = self::PUBLIC;
|
||||||
}
|
}
|
||||||
|
|
||||||
// If its a post that originated here then tag the thread as "mention"
|
// If its a post that originated here then tag the thread as "mention"
|
||||||
|
@ -1808,7 +1813,7 @@ class Item
|
||||||
|
|
||||||
// ACL settings
|
// ACL settings
|
||||||
if (strlen($allow_cid) || strlen($allow_gid) || strlen($deny_cid) || strlen($deny_gid)) {
|
if (strlen($allow_cid) || strlen($allow_gid) || strlen($deny_cid) || strlen($deny_gid)) {
|
||||||
$private = 1;
|
$private = self::PRIVATE;
|
||||||
} else {
|
} else {
|
||||||
$private = $item['private'];
|
$private = $item['private'];
|
||||||
}
|
}
|
||||||
|
@ -1934,7 +1939,7 @@ class Item
|
||||||
|
|
||||||
if ($entries > 1) {
|
if ($entries > 1) {
|
||||||
// There are duplicates. We delete our just created entry.
|
// There are duplicates. We delete our just created entry.
|
||||||
Logger::log('Duplicated post occurred. uri = ' . $item['uri'] . ' uid = ' . $item['uid']);
|
Logger::notice('Delete duplicated item', ['id' => $current_post, 'uri' => $item['uri'], 'uid' => $item['uid']]);
|
||||||
|
|
||||||
// Yes, we could do a rollback here - but we are having many users with MyISAM.
|
// Yes, we could do a rollback here - but we are having many users with MyISAM.
|
||||||
DBA::delete('item', ['id' => $current_post]);
|
DBA::delete('item', ['id' => $current_post]);
|
||||||
|
@ -2217,7 +2222,7 @@ class Item
|
||||||
// Only distribute public items from native networks
|
// Only distribute public items from native networks
|
||||||
$condition = ['id' => $itemid, 'uid' => 0,
|
$condition = ['id' => $itemid, 'uid' => 0,
|
||||||
'network' => array_merge(Protocol::FEDERATED ,['']),
|
'network' => array_merge(Protocol::FEDERATED ,['']),
|
||||||
'visible' => true, 'deleted' => false, 'moderated' => false, 'private' => false];
|
'visible' => true, 'deleted' => false, 'moderated' => false, 'private' => [self::PUBLIC, self::UNLISTED]];
|
||||||
$item = self::selectFirst(self::ITEM_FIELDLIST, $condition);
|
$item = self::selectFirst(self::ITEM_FIELDLIST, $condition);
|
||||||
if (!DBA::isResult($item)) {
|
if (!DBA::isResult($item)) {
|
||||||
return;
|
return;
|
||||||
|
@ -2367,7 +2372,7 @@ class Item
|
||||||
}
|
}
|
||||||
|
|
||||||
// Is it a visible public post?
|
// Is it a visible public post?
|
||||||
if (!$item["visible"] || $item["deleted"] || $item["moderated"] || $item["private"]) {
|
if (!$item["visible"] || $item["deleted"] || $item["moderated"] || ($item["private"] == Item::PRIVATE)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2558,7 +2563,7 @@ class Item
|
||||||
Contact::unmarkForArchival($contact);
|
Contact::unmarkForArchival($contact);
|
||||||
}
|
}
|
||||||
|
|
||||||
$update = (!$arr['private'] && ((($arr['author-link'] ?? '') === ($arr['owner-link'] ?? '')) || ($arr["parent-uri"] === $arr["uri"])));
|
$update = (($arr['private'] != self::PRIVATE) && ((($arr['author-link'] ?? '') === ($arr['owner-link'] ?? '')) || ($arr["parent-uri"] === $arr["uri"])));
|
||||||
|
|
||||||
// Is it a forum? Then we don't care about the rules from above
|
// Is it a forum? Then we don't care about the rules from above
|
||||||
if (!$update && in_array($arr["network"], [Protocol::ACTIVITYPUB, Protocol::DFRN]) && ($arr["parent-uri"] === $arr["uri"])) {
|
if (!$update && in_array($arr["network"], [Protocol::ACTIVITYPUB, Protocol::DFRN]) && ($arr["parent-uri"] === $arr["uri"])) {
|
||||||
|
@ -2572,7 +2577,7 @@ class Item
|
||||||
['id' => $arr['contact-id']]);
|
['id' => $arr['contact-id']]);
|
||||||
}
|
}
|
||||||
// Now do the same for the system wide contacts with uid=0
|
// Now do the same for the system wide contacts with uid=0
|
||||||
if (!$arr['private']) {
|
if ($arr['private'] != self::PRIVATE) {
|
||||||
DBA::update('contact', ['success_update' => $arr['received'], 'last-item' => $arr['received']],
|
DBA::update('contact', ['success_update' => $arr['received'], 'last-item' => $arr['received']],
|
||||||
['id' => $arr['owner-id']]);
|
['id' => $arr['owner-id']]);
|
||||||
|
|
||||||
|
@ -2717,9 +2722,7 @@ class Item
|
||||||
if (!$mention) {
|
if (!$mention) {
|
||||||
if (($community_page || $prvgroup) &&
|
if (($community_page || $prvgroup) &&
|
||||||
!$item['wall'] && !$item['origin'] && ($item['id'] == $item['parent'])) {
|
!$item['wall'] && !$item['origin'] && ($item['id'] == $item['parent'])) {
|
||||||
// mmh.. no mention.. community page or private group... no wall.. no origin.. top-post (not a comment)
|
Logger::notice('Delete private group/communiy top-level item without mention', ['id' => $item_id]);
|
||||||
// delete it!
|
|
||||||
Logger::log("no-mention top-level post to community or private group. delete.");
|
|
||||||
DBA::delete('item', ['id' => $item_id]);
|
DBA::delete('item', ['id' => $item_id]);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -2753,7 +2756,7 @@ class Item
|
||||||
|
|
||||||
// also reset all the privacy bits to the forum default permissions
|
// also reset all the privacy bits to the forum default permissions
|
||||||
|
|
||||||
$private = ($user['allow_cid'] || $user['allow_gid'] || $user['deny_cid'] || $user['deny_gid']) ? 1 : 0;
|
$private = ($user['allow_cid'] || $user['allow_gid'] || $user['deny_cid'] || $user['deny_gid']) ? self::PRIVATE : self::PUBLIC;
|
||||||
|
|
||||||
$psid = PermissionSet::getIdFromACL(
|
$psid = PermissionSet::getIdFromACL(
|
||||||
$user['uid'],
|
$user['uid'],
|
||||||
|
@ -2800,7 +2803,7 @@ class Item
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (($contact['network'] != Protocol::FEED) && $datarray['private']) {
|
if (($contact['network'] != Protocol::FEED) && ($datarray['private'] == self::PRIVATE)) {
|
||||||
Logger::log('Not public', Logger::DEBUG);
|
Logger::log('Not public', Logger::DEBUG);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -2838,7 +2841,7 @@ class Item
|
||||||
$urlpart = parse_url($datarray2['author-link']);
|
$urlpart = parse_url($datarray2['author-link']);
|
||||||
$datarray["app"] = $urlpart["host"];
|
$datarray["app"] = $urlpart["host"];
|
||||||
} else {
|
} else {
|
||||||
$datarray['private'] = 0;
|
$datarray['private'] = self::PUBLIC;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3367,7 +3370,7 @@ class Item
|
||||||
$condition = ["`uri` = ? AND NOT `deleted` AND NOT (`uid` IN (?, 0))", $itemuri, $item["uid"]];
|
$condition = ["`uri` = ? AND NOT `deleted` AND NOT (`uid` IN (?, 0))", $itemuri, $item["uid"]];
|
||||||
if (!self::exists($condition)) {
|
if (!self::exists($condition)) {
|
||||||
DBA::delete('item', ['uri' => $itemuri, 'uid' => 0]);
|
DBA::delete('item', ['uri' => $itemuri, 'uid' => 0]);
|
||||||
Logger::log("deleteThread: Deleted shadow for item ".$itemuri, Logger::DEBUG);
|
Logger::debug('Deleted shadow item', ['id' => $itemid, 'uri' => $itemuri]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3382,7 +3385,7 @@ class Item
|
||||||
*
|
*
|
||||||
* default permissions - anonymous user
|
* default permissions - anonymous user
|
||||||
*/
|
*/
|
||||||
$sql = " AND NOT `item`.`private`";
|
$sql = sprintf(" AND `item`.`private` != %d", self::PRIVATE);
|
||||||
|
|
||||||
// Profile owner - everything is visible
|
// Profile owner - everything is visible
|
||||||
if ($local_user && ($local_user == $owner_id)) {
|
if ($local_user && ($local_user == $owner_id)) {
|
||||||
|
@ -3398,12 +3401,12 @@ class Item
|
||||||
$set = PermissionSet::get($owner_id, $remote_user);
|
$set = PermissionSet::get($owner_id, $remote_user);
|
||||||
|
|
||||||
if (!empty($set)) {
|
if (!empty($set)) {
|
||||||
$sql_set = " OR (`item`.`private` IN (1,2) AND `item`.`wall` AND `item`.`psid` IN (" . implode(',', $set) . "))";
|
$sql_set = sprintf(" OR (`item`.`private` = %d AND `item`.`wall` AND `item`.`psid` IN (", self::PRIVATE) . implode(',', $set) . "))";
|
||||||
} else {
|
} else {
|
||||||
$sql_set = '';
|
$sql_set = '';
|
||||||
}
|
}
|
||||||
|
|
||||||
$sql = " AND (NOT `item`.`private`" . $sql_set . ")";
|
$sql = sprintf(" AND (`item`.`private` != %d", self::PRIVATE) . $sql_set . ")";
|
||||||
}
|
}
|
||||||
|
|
||||||
return $sql;
|
return $sql;
|
||||||
|
@ -3505,7 +3508,7 @@ class Item
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((local_user() == $item['uid']) && ($item['private'] == 1) && ($item['contact-id'] != $app->contact['id']) && ($item['network'] == Protocol::DFRN)) {
|
if ((local_user() == $item['uid']) && ($item['private'] == self::PRIVATE) && ($item['contact-id'] != $app->contact['id']) && ($item['network'] == Protocol::DFRN)) {
|
||||||
$img_url = 'redir/' . $item['contact-id'] . '?url=' . urlencode($mtch[1]);
|
$img_url = 'redir/' . $item['contact-id'] . '?url=' . urlencode($mtch[1]);
|
||||||
$item['body'] = str_replace($mtch[0], '[img]' . $img_url . '[/img]', $item['body']);
|
$item['body'] = str_replace($mtch[0], '[img]' . $img_url . '[/img]', $item['body']);
|
||||||
}
|
}
|
||||||
|
@ -3630,7 +3633,7 @@ class Item
|
||||||
$title .= ' ' . $mtch[2] . ' ' . DI::l10n()->t('bytes');
|
$title .= ' ' . $mtch[2] . ' ' . DI::l10n()->t('bytes');
|
||||||
|
|
||||||
$icon = '<div class="attachtype icon s22 type-' . $filetype . ' subtype-' . $filesubtype . '"></div>';
|
$icon = '<div class="attachtype icon s22 type-' . $filetype . ' subtype-' . $filesubtype . '"></div>';
|
||||||
$as .= '<a href="' . strip_tags($the_url) . '" title="' . $title . '" class="attachlink" target="_blank" >' . $icon . '</a>';
|
$as .= '<a href="' . strip_tags($the_url) . '" title="' . $title . '" class="attachlink" target="_blank" rel="noopener noreferrer" >' . $icon . '</a>';
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($as != '') {
|
if ($as != '') {
|
||||||
|
@ -3683,7 +3686,7 @@ class Item
|
||||||
$ret["title"] = DI::l10n()->t('link to source');
|
$ret["title"] = DI::l10n()->t('link to source');
|
||||||
}
|
}
|
||||||
|
|
||||||
} elseif (!empty($item['plink']) && ($item['private'] != 1)) {
|
} elseif (!empty($item['plink']) && ($item['private'] != self::PRIVATE)) {
|
||||||
$ret = [
|
$ret = [
|
||||||
'href' => $item['plink'],
|
'href' => $item['plink'],
|
||||||
'orig' => $item['plink'],
|
'orig' => $item['plink'],
|
||||||
|
|
|
@ -330,7 +330,8 @@ class Profile
|
||||||
|
|
||||||
if (!$local_user_is_self && $show_connect) {
|
if (!$local_user_is_self && $show_connect) {
|
||||||
if (!$visitor_is_authenticated) {
|
if (!$visitor_is_authenticated) {
|
||||||
if (!empty($profile['nickname'])) {
|
// Remote follow is only available for local profiles
|
||||||
|
if (!empty($profile['nickname']) && strpos($profile_url, DI::baseUrl()->get()) === 0) {
|
||||||
$follow_link = 'remote_follow/' . $profile['nickname'];
|
$follow_link = 'remote_follow/' . $profile['nickname'];
|
||||||
}
|
}
|
||||||
} elseif ($profile_is_native) {
|
} elseif ($profile_is_native) {
|
||||||
|
|
|
@ -21,6 +21,7 @@
|
||||||
|
|
||||||
namespace Friendica\Model;
|
namespace Friendica\Model;
|
||||||
|
|
||||||
|
use Friendica\Content\Pager;
|
||||||
use Friendica\Database\DBA;
|
use Friendica\Database\DBA;
|
||||||
use Friendica\Util\DateTimeFormat;
|
use Friendica\Util\DateTimeFormat;
|
||||||
use Friendica\Util\Strings;
|
use Friendica\Util\Strings;
|
||||||
|
@ -33,21 +34,46 @@ class Register
|
||||||
/**
|
/**
|
||||||
* Return the list of pending registrations
|
* Return the list of pending registrations
|
||||||
*
|
*
|
||||||
|
* @param int $start Start count (Default is 0)
|
||||||
|
* @param int $count Count of the items per page (Default is @see Pager::ITEMS_PER_PAGE)
|
||||||
|
*
|
||||||
* @return array
|
* @return array
|
||||||
* @throws \Exception
|
* @throws \Exception
|
||||||
*/
|
*/
|
||||||
public static function getPending()
|
public static function getPending($start = 0, $count = Pager::ITEMS_PER_PAGE)
|
||||||
{
|
{
|
||||||
$stmt = DBA::p(
|
$stmt = DBA::p(
|
||||||
"SELECT `register`.*, `contact`.`name`, `contact`.`url`, `contact`.`micro`, `user`.`email`
|
"SELECT `register`.*, `contact`.`name`, `contact`.`url`, `contact`.`micro`, `user`.`email`, `contact`.`nick`
|
||||||
FROM `register`
|
FROM `register`
|
||||||
INNER JOIN `contact` ON `register`.`uid` = `contact`.`uid`
|
INNER JOIN `contact` ON `register`.`uid` = `contact`.`uid`
|
||||||
INNER JOIN `user` ON `register`.`uid` = `user`.`uid`"
|
INNER JOIN `user` ON `register`.`uid` = `user`.`uid`
|
||||||
|
LIMIT ?, ?", $start, $count
|
||||||
);
|
);
|
||||||
|
|
||||||
return DBA::toArray($stmt);
|
return DBA::toArray($stmt);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the pending user based on a given user id
|
||||||
|
*
|
||||||
|
* @param int $uid The user id
|
||||||
|
*
|
||||||
|
* @return array The pending user information
|
||||||
|
*
|
||||||
|
* @throws \Exception
|
||||||
|
*/
|
||||||
|
public static function getPendingForUser(int $uid)
|
||||||
|
{
|
||||||
|
return DBA::fetchFirst(
|
||||||
|
"SELECT `register`.*, `contact`.`name`, `contact`.`url`, `contact`.`micro`, `user`.`email`
|
||||||
|
FROM `register`
|
||||||
|
INNER JOIN `contact` ON `register`.`uid` = `contact`.`uid`
|
||||||
|
INNER JOIN `user` ON `register`.`uid` = `user`.`uid`
|
||||||
|
WHERE `register`.uid = ?",
|
||||||
|
$uid
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the pending registration count
|
* Returns the pending registration count
|
||||||
*
|
*
|
||||||
|
|
|
@ -82,7 +82,7 @@ class Term
|
||||||
WHERE `thread`.`visible`
|
WHERE `thread`.`visible`
|
||||||
AND NOT `thread`.`deleted`
|
AND NOT `thread`.`deleted`
|
||||||
AND NOT `thread`.`moderated`
|
AND NOT `thread`.`moderated`
|
||||||
AND NOT `thread`.`private`
|
AND `thread`.`private` = ?
|
||||||
AND t.`uid` = 0
|
AND t.`uid` = 0
|
||||||
AND t.`otype` = ?
|
AND t.`otype` = ?
|
||||||
AND t.`type` = ?
|
AND t.`type` = ?
|
||||||
|
@ -91,6 +91,7 @@ class Term
|
||||||
GROUP BY `term`
|
GROUP BY `term`
|
||||||
ORDER BY `score` DESC
|
ORDER BY `score` DESC
|
||||||
LIMIT ?",
|
LIMIT ?",
|
||||||
|
Item::PUBLIC,
|
||||||
Term::OBJECT_TYPE_POST,
|
Term::OBJECT_TYPE_POST,
|
||||||
Term::HASHTAG,
|
Term::HASHTAG,
|
||||||
$period,
|
$period,
|
||||||
|
@ -122,11 +123,10 @@ class Term
|
||||||
FROM `term` t
|
FROM `term` t
|
||||||
JOIN `item` i ON i.`id` = t.`oid` AND i.`uid` = t.`uid`
|
JOIN `item` i ON i.`id` = t.`oid` AND i.`uid` = t.`uid`
|
||||||
JOIN `thread` ON `thread`.`iid` = i.`id`
|
JOIN `thread` ON `thread`.`iid` = i.`id`
|
||||||
JOIN `user` ON `user`.`uid` = `thread`.`uid` AND NOT `user`.`hidewall`
|
|
||||||
WHERE `thread`.`visible`
|
WHERE `thread`.`visible`
|
||||||
AND NOT `thread`.`deleted`
|
AND NOT `thread`.`deleted`
|
||||||
AND NOT `thread`.`moderated`
|
AND NOT `thread`.`moderated`
|
||||||
AND NOT `thread`.`private`
|
AND `thread`.`private` = ?
|
||||||
AND `thread`.`wall`
|
AND `thread`.`wall`
|
||||||
AND `thread`.`origin`
|
AND `thread`.`origin`
|
||||||
AND t.`otype` = ?
|
AND t.`otype` = ?
|
||||||
|
@ -136,6 +136,7 @@ class Term
|
||||||
GROUP BY `term`
|
GROUP BY `term`
|
||||||
ORDER BY `score` DESC
|
ORDER BY `score` DESC
|
||||||
LIMIT ?",
|
LIMIT ?",
|
||||||
|
Item::PUBLIC,
|
||||||
Term::OBJECT_TYPE_POST,
|
Term::OBJECT_TYPE_POST,
|
||||||
Term::HASHTAG,
|
Term::HASHTAG,
|
||||||
$period,
|
$period,
|
||||||
|
@ -462,13 +463,13 @@ class Term
|
||||||
$item['body'] = str_replace($orig_tag, $tag['url'], $item['body']);
|
$item['body'] = str_replace($orig_tag, $tag['url'], $item['body']);
|
||||||
}
|
}
|
||||||
|
|
||||||
$return['hashtags'][] = $prefix . '<a href="' . $tag['url'] . '" target="_blank">' . htmlspecialchars($tag['term']) . '</a>';
|
$return['hashtags'][] = $prefix . '<a href="' . $tag['url'] . '" target="_blank" rel="noopener noreferrer">' . htmlspecialchars($tag['term']) . '</a>';
|
||||||
$return['tags'][] = $prefix . '<a href="' . $tag['url'] . '" target="_blank">' . htmlspecialchars($tag['term']) . '</a>';
|
$return['tags'][] = $prefix . '<a href="' . $tag['url'] . '" target="_blank" rel="noopener noreferrer">' . htmlspecialchars($tag['term']) . '</a>';
|
||||||
break;
|
break;
|
||||||
case self::MENTION:
|
case self::MENTION:
|
||||||
$tag['url'] = Contact::magicLink($tag['url']);
|
$tag['url'] = Contact::magicLink($tag['url']);
|
||||||
$return['mentions'][] = $prefix . '<a href="' . $tag['url'] . '" target="_blank">' . htmlspecialchars($tag['term']) . '</a>';
|
$return['mentions'][] = $prefix . '<a href="' . $tag['url'] . '" target="_blank" rel="noopener noreferrer">' . htmlspecialchars($tag['term']) . '</a>';
|
||||||
$return['tags'][] = $prefix . '<a href="' . $tag['url'] . '" target="_blank">' . htmlspecialchars($tag['term']) . '</a>';
|
$return['tags'][] = $prefix . '<a href="' . $tag['url'] . '" target="_blank" rel="noopener noreferrer">' . htmlspecialchars($tag['term']) . '</a>';
|
||||||
break;
|
break;
|
||||||
case self::IMPLICIT_MENTION:
|
case self::IMPLICIT_MENTION:
|
||||||
$return['implicit_mentions'][] = $prefix . $tag['term'];
|
$return['implicit_mentions'][] = $prefix . $tag['term'];
|
||||||
|
|
|
@ -23,7 +23,9 @@ namespace Friendica\Model;
|
||||||
|
|
||||||
use DivineOmega\PasswordExposed;
|
use DivineOmega\PasswordExposed;
|
||||||
use Exception;
|
use Exception;
|
||||||
|
use Friendica\Content\Pager;
|
||||||
use Friendica\Core\Hook;
|
use Friendica\Core\Hook;
|
||||||
|
use Friendica\Core\L10n;
|
||||||
use Friendica\Core\Logger;
|
use Friendica\Core\Logger;
|
||||||
use Friendica\Core\Protocol;
|
use Friendica\Core\Protocol;
|
||||||
use Friendica\Core\System;
|
use Friendica\Core\System;
|
||||||
|
@ -31,6 +33,7 @@ use Friendica\Core\Worker;
|
||||||
use Friendica\Database\DBA;
|
use Friendica\Database\DBA;
|
||||||
use Friendica\DI;
|
use Friendica\DI;
|
||||||
use Friendica\Model\TwoFactor\AppSpecificPassword;
|
use Friendica\Model\TwoFactor\AppSpecificPassword;
|
||||||
|
use Friendica\Network\HTTPException\InternalServerErrorException;
|
||||||
use Friendica\Object\Image;
|
use Friendica\Object\Image;
|
||||||
use Friendica\Util\Crypto;
|
use Friendica\Util\Crypto;
|
||||||
use Friendica\Util\DateTimeFormat;
|
use Friendica\Util\DateTimeFormat;
|
||||||
|
@ -279,7 +282,7 @@ class User
|
||||||
* @param string $network network name
|
* @param string $network network name
|
||||||
*
|
*
|
||||||
* @return int group id
|
* @return int group id
|
||||||
* @throws \Friendica\Network\HTTPException\InternalServerErrorException
|
* @throws InternalServerErrorException
|
||||||
*/
|
*/
|
||||||
public static function getDefaultGroup($uid, $network = '')
|
public static function getDefaultGroup($uid, $network = '')
|
||||||
{
|
{
|
||||||
|
@ -556,7 +559,7 @@ class User
|
||||||
*
|
*
|
||||||
* @param string $nickname The nickname that should be checked
|
* @param string $nickname The nickname that should be checked
|
||||||
* @return boolean True is the nickname is blocked on the node
|
* @return boolean True is the nickname is blocked on the node
|
||||||
* @throws \Friendica\Network\HTTPException\InternalServerErrorException
|
* @throws InternalServerErrorException
|
||||||
*/
|
*/
|
||||||
public static function isNicknameBlocked($nickname)
|
public static function isNicknameBlocked($nickname)
|
||||||
{
|
{
|
||||||
|
@ -593,7 +596,7 @@ class User
|
||||||
* @param array $data
|
* @param array $data
|
||||||
* @return array
|
* @return array
|
||||||
* @throws \ErrorException
|
* @throws \ErrorException
|
||||||
* @throws \Friendica\Network\HTTPException\InternalServerErrorException
|
* @throws InternalServerErrorException
|
||||||
* @throws \ImagickException
|
* @throws \ImagickException
|
||||||
* @throws Exception
|
* @throws Exception
|
||||||
*/
|
*/
|
||||||
|
@ -880,6 +883,166 @@ class User
|
||||||
return $return;
|
return $return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets block state for a given user
|
||||||
|
*
|
||||||
|
* @param int $uid The user id
|
||||||
|
* @param bool $block Block state (default is true)
|
||||||
|
*
|
||||||
|
* @return bool True, if successfully blocked
|
||||||
|
|
||||||
|
* @throws Exception
|
||||||
|
*/
|
||||||
|
public static function block(int $uid, bool $block = true)
|
||||||
|
{
|
||||||
|
return DBA::update('user', ['blocked' => $block], ['uid' => $uid]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Allows a registration based on a hash
|
||||||
|
*
|
||||||
|
* @param string $hash
|
||||||
|
*
|
||||||
|
* @return bool True, if the allow was successful
|
||||||
|
*
|
||||||
|
* @throws InternalServerErrorException
|
||||||
|
* @throws Exception
|
||||||
|
*/
|
||||||
|
public static function allow(string $hash)
|
||||||
|
{
|
||||||
|
$register = Register::getByHash($hash);
|
||||||
|
if (!DBA::isResult($register)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
$user = User::getById($register['uid']);
|
||||||
|
if (!DBA::isResult($user)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
Register::deleteByHash($hash);
|
||||||
|
|
||||||
|
DBA::update('user', ['blocked' => false, 'verified' => true], ['uid' => $register['uid']]);
|
||||||
|
|
||||||
|
$profile = DBA::selectFirst('profile', ['net-publish'], ['uid' => $register['uid']]);
|
||||||
|
|
||||||
|
if (DBA::isResult($profile) && $profile['net-publish'] && DI::config()->get('system', 'directory')) {
|
||||||
|
$url = DI::baseUrl() . '/profile/' . $user['nickname'];
|
||||||
|
Worker::add(PRIORITY_LOW, "Directory", $url);
|
||||||
|
}
|
||||||
|
|
||||||
|
$l10n = DI::l10n()->withLang($register['language']);
|
||||||
|
|
||||||
|
return User::sendRegisterOpenEmail(
|
||||||
|
$l10n,
|
||||||
|
$user,
|
||||||
|
DI::config()->get('config', 'sitename'),
|
||||||
|
DI::baseUrl()->get(),
|
||||||
|
($register['password'] ?? '') ?: 'Sent in a previous email'
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Denys a pending registration
|
||||||
|
*
|
||||||
|
* @param string $hash The hash of the pending user
|
||||||
|
*
|
||||||
|
* This does not have to go through user_remove() and save the nickname
|
||||||
|
* permanently against re-registration, as the person was not yet
|
||||||
|
* allowed to have friends on this system
|
||||||
|
*
|
||||||
|
* @return bool True, if the deny was successfull
|
||||||
|
* @throws Exception
|
||||||
|
*/
|
||||||
|
public static function deny(string $hash)
|
||||||
|
{
|
||||||
|
$register = Register::getByHash($hash);
|
||||||
|
if (!DBA::isResult($register)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
$user = User::getById($register['uid']);
|
||||||
|
if (!DBA::isResult($user)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return DBA::delete('user', ['uid' => $register['uid']]) &&
|
||||||
|
Register::deleteByHash($register['hash']);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new user based on a minimal set and sends an email to this user
|
||||||
|
*
|
||||||
|
* @param string $name The user's name
|
||||||
|
* @param string $email The user's email address
|
||||||
|
* @param string $nick The user's nick name
|
||||||
|
* @param string $lang The user's language (default is english)
|
||||||
|
*
|
||||||
|
* @return bool True, if the user was created successfully
|
||||||
|
* @throws InternalServerErrorException
|
||||||
|
* @throws \ErrorException
|
||||||
|
* @throws \ImagickException
|
||||||
|
*/
|
||||||
|
public static function createMinimal(string $name, string $email, string $nick, string $lang = L10n::DEFAULT)
|
||||||
|
{
|
||||||
|
if (empty($name) ||
|
||||||
|
empty($email) ||
|
||||||
|
empty($nick)) {
|
||||||
|
throw new InternalServerErrorException('Invalid arguments.');
|
||||||
|
}
|
||||||
|
|
||||||
|
$result = self::create([
|
||||||
|
'username' => $name,
|
||||||
|
'email' => $email,
|
||||||
|
'nickname' => $nick,
|
||||||
|
'verified' => 1,
|
||||||
|
'language' => $lang
|
||||||
|
]);
|
||||||
|
|
||||||
|
$user = $result['user'];
|
||||||
|
$preamble = Strings::deindent(DI::l10n()->t('
|
||||||
|
Dear %1$s,
|
||||||
|
the administrator of %2$s has set up an account for you.'));
|
||||||
|
$body = Strings::deindent(DI::l10n()->t('
|
||||||
|
The login details are as follows:
|
||||||
|
|
||||||
|
Site Location: %1$s
|
||||||
|
Login Name: %2$s
|
||||||
|
Password: %3$s
|
||||||
|
|
||||||
|
You may change your password from your account "Settings" page after logging
|
||||||
|
in.
|
||||||
|
|
||||||
|
Please take a few moments to review the other account settings on that page.
|
||||||
|
|
||||||
|
You may also wish to add some basic information to your default profile
|
||||||
|
(on the "Profiles" page) so that other people can easily find you.
|
||||||
|
|
||||||
|
We recommend setting your full name, adding a profile photo,
|
||||||
|
adding some profile "keywords" (very useful in making new friends) - and
|
||||||
|
perhaps what country you live in; if you do not wish to be more specific
|
||||||
|
than that.
|
||||||
|
|
||||||
|
We fully respect your right to privacy, and none of these items are necessary.
|
||||||
|
If you are new and do not know anybody here, they may help
|
||||||
|
you to make some new and interesting friends.
|
||||||
|
|
||||||
|
If you ever want to delete your account, you can do so at %1$s/removeme
|
||||||
|
|
||||||
|
Thank you and welcome to %4$s.'));
|
||||||
|
|
||||||
|
$preamble = sprintf($preamble, $user['username'], DI::config()->get('config', 'sitename'));
|
||||||
|
$body = sprintf($body, DI::baseUrl()->get(), $user['nickname'], $result['password'], DI::config()->get('config', 'sitename'));
|
||||||
|
|
||||||
|
$email = DI::emailer()
|
||||||
|
->newSystemMail()
|
||||||
|
->withMessage(DI::l10n()->t('Registration details for %s', DI::config()->get('config', 'sitename')), $preamble, $body)
|
||||||
|
->forUser($user)
|
||||||
|
->withRecipient($user['email'])
|
||||||
|
->build();
|
||||||
|
return DI::emailer()->send($email);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sends pending registration confirmation email
|
* Sends pending registration confirmation email
|
||||||
*
|
*
|
||||||
|
@ -888,7 +1051,7 @@ class User
|
||||||
* @param string $siteurl
|
* @param string $siteurl
|
||||||
* @param string $password Plaintext password
|
* @param string $password Plaintext password
|
||||||
* @return NULL|boolean from notification() and email() inherited
|
* @return NULL|boolean from notification() and email() inherited
|
||||||
* @throws \Friendica\Network\HTTPException\InternalServerErrorException
|
* @throws InternalServerErrorException
|
||||||
*/
|
*/
|
||||||
public static function sendRegisterPendingEmail($user, $sitename, $siteurl, $password)
|
public static function sendRegisterPendingEmail($user, $sitename, $siteurl, $password)
|
||||||
{
|
{
|
||||||
|
@ -931,7 +1094,7 @@ class User
|
||||||
* @param string $password Plaintext password
|
* @param string $password Plaintext password
|
||||||
*
|
*
|
||||||
* @return NULL|boolean from notification() and email() inherited
|
* @return NULL|boolean from notification() and email() inherited
|
||||||
* @throws \Friendica\Network\HTTPException\InternalServerErrorException
|
* @throws InternalServerErrorException
|
||||||
*/
|
*/
|
||||||
public static function sendRegisterOpenEmail(\Friendica\Core\L10n $l10n, $user, $sitename, $siteurl, $password)
|
public static function sendRegisterOpenEmail(\Friendica\Core\L10n $l10n, $user, $sitename, $siteurl, $password)
|
||||||
{
|
{
|
||||||
|
@ -988,11 +1151,11 @@ class User
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param object $uid user to remove
|
* @param int $uid user to remove
|
||||||
* @return bool
|
* @return bool
|
||||||
* @throws \Friendica\Network\HTTPException\InternalServerErrorException
|
* @throws InternalServerErrorException
|
||||||
*/
|
*/
|
||||||
public static function remove($uid)
|
public static function remove(int $uid)
|
||||||
{
|
{
|
||||||
if (!$uid) {
|
if (!$uid) {
|
||||||
return false;
|
return false;
|
||||||
|
@ -1154,4 +1317,47 @@ class User
|
||||||
|
|
||||||
return $statistics;
|
return $statistics;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get all users of the current node
|
||||||
|
*
|
||||||
|
* @param int $start Start count (Default is 0)
|
||||||
|
* @param int $count Count of the items per page (Default is @see Pager::ITEMS_PER_PAGE)
|
||||||
|
* @param string $type The type of users, which should get (all, bocked, removed)
|
||||||
|
* @param string $order Order of the user list (Default is 'contact.name')
|
||||||
|
* @param string $order_direction Order direction (Default is ASC)
|
||||||
|
*
|
||||||
|
* @return array The list of the users
|
||||||
|
* @throws Exception
|
||||||
|
*/
|
||||||
|
public static function getList($start = 0, $count = Pager::ITEMS_PER_PAGE, $type = 'all', $order = 'contact.name', $order_direction = '+')
|
||||||
|
{
|
||||||
|
$sql_order = '`' . str_replace('.', '`.`', $order) . '`';
|
||||||
|
$sql_order_direction = ($order_direction === '+') ? 'ASC' : 'DESC';
|
||||||
|
|
||||||
|
switch ($type) {
|
||||||
|
case 'active':
|
||||||
|
$sql_extra = 'AND `user`.`blocked` = 0';
|
||||||
|
break;
|
||||||
|
case 'blocked':
|
||||||
|
$sql_extra = 'AND `user`.`blocked` = 1';
|
||||||
|
break;
|
||||||
|
case 'removed':
|
||||||
|
$sql_extra = 'AND `user`.`account_removed` = 1';
|
||||||
|
break;
|
||||||
|
case 'all':
|
||||||
|
default:
|
||||||
|
$sql_extra = '';
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
$usersStmt = DBA::p("SELECT `user`.*, `contact`.`name`, `contact`.`url`, `contact`.`micro`, `user`.`account_expired`, `contact`.`last-item` AS `lastitem_date`, `contact`.`nick`, `contact`.`created`
|
||||||
|
FROM `user`
|
||||||
|
INNER JOIN `contact` ON `contact`.`uid` = `user`.`uid` AND `contact`.`self`
|
||||||
|
WHERE `user`.`verified` $sql_extra
|
||||||
|
ORDER BY $sql_order $sql_order_direction LIMIT ?, ?", $start, $count
|
||||||
|
);
|
||||||
|
|
||||||
|
return DBA::toArray($usersStmt);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -73,8 +73,8 @@ class Features extends BaseAdmin
|
||||||
foreach (array_slice($fdata, 1) as $f) {
|
foreach (array_slice($fdata, 1) as $f) {
|
||||||
$set = DI::config()->get('feature', $f[0], $f[3]);
|
$set = DI::config()->get('feature', $f[0], $f[3]);
|
||||||
$arr[$fname][1][] = [
|
$arr[$fname][1][] = [
|
||||||
['feature_' . $f[0], $f[1], $set, $f[2], [DI::l10n()->t('Off'), DI::l10n()->t('On')]],
|
['feature_' . $f[0], $f[1], $set, $f[2]],
|
||||||
['featurelock_' . $f[0], DI::l10n()->t('Lock feature %s', $f[1]), (($f[4] !== false) ? "1" : ''), '', [DI::l10n()->t('Off'), DI::l10n()->t('On')]]
|
['featurelock_' . $f[0], DI::l10n()->t('Lock feature %s', $f[1]), $f[4], '']
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -60,7 +60,7 @@ class Tos extends BaseAdmin
|
||||||
'$title' => DI::l10n()->t('Administration'),
|
'$title' => DI::l10n()->t('Administration'),
|
||||||
'$page' => DI::l10n()->t('Terms of Service'),
|
'$page' => DI::l10n()->t('Terms of Service'),
|
||||||
'$displaytos' => ['displaytos', DI::l10n()->t('Display Terms of Service'), DI::config()->get('system', 'tosdisplay'), DI::l10n()->t('Enable the Terms of Service page. If this is enabled a link to the terms will be added to the registration form and the general information page.')],
|
'$displaytos' => ['displaytos', DI::l10n()->t('Display Terms of Service'), DI::config()->get('system', 'tosdisplay'), DI::l10n()->t('Enable the Terms of Service page. If this is enabled a link to the terms will be added to the registration form and the general information page.')],
|
||||||
'$displayprivstatement' => ['displayprivstatement', DI::l10n()->t('Display Privacy Statement'), DI::config()->get('system', 'tosprivstatement'), DI::l10n()->t('Show some informations regarding the needed information to operate the node according e.g. to <a href="%s" target="_blank">EU-GDPR</a>.', 'https://en.wikipedia.org/wiki/General_Data_Protection_Regulation')],
|
'$displayprivstatement' => ['displayprivstatement', DI::l10n()->t('Display Privacy Statement'), DI::config()->get('system', 'tosprivstatement'), DI::l10n()->t('Show some informations regarding the needed information to operate the node according e.g. to <a href="%s" target="_blank" rel="noopener noreferrer">EU-GDPR</a>.', 'https://en.wikipedia.org/wiki/General_Data_Protection_Regulation')],
|
||||||
'$preview' => DI::l10n()->t('Privacy Statement Preview'),
|
'$preview' => DI::l10n()->t('Privacy Statement Preview'),
|
||||||
'$privtext' => $tos->privacy_complete,
|
'$privtext' => $tos->privacy_complete,
|
||||||
'$tostext' => ['tostext', DI::l10n()->t('The Terms of Service'), DI::config()->get('system', 'tostext'), DI::l10n()->t('Enter the Terms of Service for your node here. You can use BBCode. Headers of sections should be [h2] and below.')],
|
'$tostext' => ['tostext', DI::l10n()->t('The Terms of Service'), DI::config()->get('system', 'tostext'), DI::l10n()->t('Enter the Terms of Service for your node here. You can use BBCode. Headers of sections should be [h2] and below.')],
|
||||||
|
|
|
@ -28,7 +28,6 @@ use Friendica\DI;
|
||||||
use Friendica\Model\Register;
|
use Friendica\Model\Register;
|
||||||
use Friendica\Model\User;
|
use Friendica\Model\User;
|
||||||
use Friendica\Module\BaseAdmin;
|
use Friendica\Module\BaseAdmin;
|
||||||
use Friendica\Util\Strings;
|
|
||||||
use Friendica\Util\Temporal;
|
use Friendica\Util\Temporal;
|
||||||
|
|
||||||
class Users extends BaseAdmin
|
class Users extends BaseAdmin
|
||||||
|
@ -48,71 +47,24 @@ class Users extends BaseAdmin
|
||||||
|
|
||||||
if ($nu_name !== '' && $nu_email !== '' && $nu_nickname !== '') {
|
if ($nu_name !== '' && $nu_email !== '' && $nu_nickname !== '') {
|
||||||
try {
|
try {
|
||||||
$result = User::create([
|
User::createMinimal($nu_name, $nu_email, $nu_nickname, $nu_language);
|
||||||
'username' => $nu_name,
|
|
||||||
'email' => $nu_email,
|
|
||||||
'nickname' => $nu_nickname,
|
|
||||||
'verified' => 1,
|
|
||||||
'language' => $nu_language
|
|
||||||
]);
|
|
||||||
} catch (\Exception $ex) {
|
} catch (\Exception $ex) {
|
||||||
notice($ex->getMessage());
|
notice($ex->getMessage());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
$user = $result['user'];
|
|
||||||
$preamble = Strings::deindent(DI::l10n()->t('
|
|
||||||
Dear %1$s,
|
|
||||||
the administrator of %2$s has set up an account for you.'));
|
|
||||||
$body = Strings::deindent(DI::l10n()->t('
|
|
||||||
The login details are as follows:
|
|
||||||
|
|
||||||
Site Location: %1$s
|
|
||||||
Login Name: %2$s
|
|
||||||
Password: %3$s
|
|
||||||
|
|
||||||
You may change your password from your account "Settings" page after logging
|
|
||||||
in.
|
|
||||||
|
|
||||||
Please take a few moments to review the other account settings on that page.
|
|
||||||
|
|
||||||
You may also wish to add some basic information to your default profile
|
|
||||||
(on the "Profiles" page) so that other people can easily find you.
|
|
||||||
|
|
||||||
We recommend setting your full name, adding a profile photo,
|
|
||||||
adding some profile "keywords" (very useful in making new friends) - and
|
|
||||||
perhaps what country you live in; if you do not wish to be more specific
|
|
||||||
than that.
|
|
||||||
|
|
||||||
We fully respect your right to privacy, and none of these items are necessary.
|
|
||||||
If you are new and do not know anybody here, they may help
|
|
||||||
you to make some new and interesting friends.
|
|
||||||
|
|
||||||
If you ever want to delete your account, you can do so at %1$s/removeme
|
|
||||||
|
|
||||||
Thank you and welcome to %4$s.'));
|
|
||||||
|
|
||||||
$preamble = sprintf($preamble, $user['username'], DI::config()->get('config', 'sitename'));
|
|
||||||
$body = sprintf($body, DI::baseUrl()->get(), $user['nickname'], $result['password'], DI::config()->get('config', 'sitename'));
|
|
||||||
|
|
||||||
$email = DI::emailer()
|
|
||||||
->newSystemMail()
|
|
||||||
->withMessage(DI::l10n()->t('Registration details for %s', DI::config()->get('config', 'sitename')), $preamble, $body)
|
|
||||||
->forUser($user)
|
|
||||||
->withRecipient($user['email'])
|
|
||||||
->build();
|
|
||||||
return DI::emailer()->send($email);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!empty($_POST['page_users_block'])) {
|
if (!empty($_POST['page_users_block'])) {
|
||||||
// @TODO Move this to Model\User:block($users);
|
foreach ($users as $uid) {
|
||||||
DBA::update('user', ['blocked' => 1], ['uid' => $users]);
|
User::block($uid);
|
||||||
|
}
|
||||||
notice(DI::l10n()->tt('%s user blocked', '%s users blocked', count($users)));
|
notice(DI::l10n()->tt('%s user blocked', '%s users blocked', count($users)));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!empty($_POST['page_users_unblock'])) {
|
if (!empty($_POST['page_users_unblock'])) {
|
||||||
// @TODO Move this to Model\User:unblock($users);
|
foreach ($users as $uid) {
|
||||||
DBA::update('user', ['blocked' => 0], ['uid' => $users]);
|
User::block($uid, false);
|
||||||
|
}
|
||||||
notice(DI::l10n()->tt('%s user unblocked', '%s users unblocked', count($users)));
|
notice(DI::l10n()->tt('%s user unblocked', '%s users unblocked', count($users)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -129,17 +81,17 @@ class Users extends BaseAdmin
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!empty($_POST['page_users_approve'])) {
|
if (!empty($_POST['page_users_approve'])) {
|
||||||
require_once 'mod/regmod.php';
|
|
||||||
foreach ($pending as $hash) {
|
foreach ($pending as $hash) {
|
||||||
user_allow($hash);
|
User::allow($hash);
|
||||||
}
|
}
|
||||||
|
notice(DI::l10n()->tt('%s user approved', '%s users approved', count($pending)));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!empty($_POST['page_users_deny'])) {
|
if (!empty($_POST['page_users_deny'])) {
|
||||||
require_once 'mod/regmod.php';
|
|
||||||
foreach ($pending as $hash) {
|
foreach ($pending as $hash) {
|
||||||
user_deny($hash);
|
User::deny($hash);
|
||||||
}
|
}
|
||||||
|
notice(DI::l10n()->tt('%s registration revoked', '%s registrations revoked', count($pending)));
|
||||||
}
|
}
|
||||||
|
|
||||||
DI::baseUrl()->redirect('admin/users');
|
DI::baseUrl()->redirect('admin/users');
|
||||||
|
@ -176,16 +128,24 @@ class Users extends BaseAdmin
|
||||||
break;
|
break;
|
||||||
case 'block':
|
case 'block':
|
||||||
parent::checkFormSecurityTokenRedirectOnError('/admin/users', 'admin_users', 't');
|
parent::checkFormSecurityTokenRedirectOnError('/admin/users', 'admin_users', 't');
|
||||||
// @TODO Move this to Model\User:block([$uid]);
|
User::block($uid);
|
||||||
DBA::update('user', ['blocked' => 1], ['uid' => $uid]);
|
|
||||||
notice(DI::l10n()->t('User "%s" blocked', $user['username']));
|
notice(DI::l10n()->t('User "%s" blocked', $user['username']));
|
||||||
break;
|
break;
|
||||||
case 'unblock':
|
case 'unblock':
|
||||||
parent::checkFormSecurityTokenRedirectOnError('/admin/users', 'admin_users', 't');
|
parent::checkFormSecurityTokenRedirectOnError('/admin/users', 'admin_users', 't');
|
||||||
// @TODO Move this to Model\User:unblock([$uid]);
|
User::block($uid, false);
|
||||||
DBA::update('user', ['blocked' => 0], ['uid' => $uid]);
|
|
||||||
notice(DI::l10n()->t('User "%s" unblocked', $user['username']));
|
notice(DI::l10n()->t('User "%s" unblocked', $user['username']));
|
||||||
break;
|
break;
|
||||||
|
case 'allow':
|
||||||
|
parent::checkFormSecurityTokenRedirectOnError('/admin/users', 'admin_users', 't');
|
||||||
|
User::allow(Register::getPendingForUser($uid)['hash'] ?? '');
|
||||||
|
notice(DI::l10n()->t('Account approved.'));
|
||||||
|
break;
|
||||||
|
case 'deny':
|
||||||
|
parent::checkFormSecurityTokenRedirectOnError('/admin/users', 'admin_users', 't');
|
||||||
|
User::deny(Register::getPendingForUser($uid)['hash'] ?? '');
|
||||||
|
notice(DI::l10n()->t('Registration revoked'));
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
DI::baseUrl()->redirect('admin/users');
|
DI::baseUrl()->redirect('admin/users');
|
||||||
|
@ -196,7 +156,6 @@ class Users extends BaseAdmin
|
||||||
|
|
||||||
$pager = new Pager(DI::l10n(), DI::args()->getQueryString(), 100);
|
$pager = new Pager(DI::l10n(), DI::args()->getQueryString(), 100);
|
||||||
|
|
||||||
// @TODO Move below block to Model\User::getUsers($start, $count, $order = 'contact.name', $order_direction = '+')
|
|
||||||
$valid_orders = [
|
$valid_orders = [
|
||||||
'contact.name',
|
'contact.name',
|
||||||
'user.email',
|
'user.email',
|
||||||
|
@ -219,16 +178,8 @@ class Users extends BaseAdmin
|
||||||
$order = $new_order;
|
$order = $new_order;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
$sql_order = '`' . str_replace('.', '`.`', $order) . '`';
|
|
||||||
$sql_order_direction = ($order_direction === '+') ? 'ASC' : 'DESC';
|
|
||||||
|
|
||||||
$usersStmt = DBA::p("SELECT `user`.*, `contact`.`name`, `contact`.`url`, `contact`.`micro`, `user`.`account_expired`, `contact`.`last-item` AS `lastitem_date`
|
$users = User::getList($pager->getStart(), $pager->getItemsPerPage(), 'all', $order, $order_direction);
|
||||||
FROM `user`
|
|
||||||
INNER JOIN `contact` ON `contact`.`uid` = `user`.`uid` AND `contact`.`self`
|
|
||||||
WHERE `user`.`verified`
|
|
||||||
ORDER BY $sql_order $sql_order_direction LIMIT ?, ?", $pager->getStart(), $pager->getItemsPerPage()
|
|
||||||
);
|
|
||||||
$users = DBA::toArray($usersStmt);
|
|
||||||
|
|
||||||
$adminlist = explode(',', str_replace(' ', '', DI::config()->get('config', 'admin_email')));
|
$adminlist = explode(',', str_replace(' ', '', DI::config()->get('config', 'admin_email')));
|
||||||
$_setup_users = function ($e) use ($adminlist) {
|
$_setup_users = function ($e) use ($adminlist) {
|
||||||
|
@ -283,7 +234,7 @@ class Users extends BaseAdmin
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$th_users = array_map(null, [DI::l10n()->t('Name'), DI::l10n()->t('Email'), DI::l10n()->t('Register date'), DI::l10n()->t('Last login'), DI::l10n()->t('Last item'), DI::l10n()->t('Type')], $valid_orders);
|
$th_users = array_map(null, [DI::l10n()->t('Name'), DI::l10n()->t('Email'), DI::l10n()->t('Register date'), DI::l10n()->t('Last login'), DI::l10n()->t('Last public item'), DI::l10n()->t('Type')], $valid_orders);
|
||||||
|
|
||||||
$t = Renderer::getMarkupTemplate('admin/users.tpl');
|
$t = Renderer::getMarkupTemplate('admin/users.tpl');
|
||||||
$o = Renderer::replaceMacros($t, [
|
$o = Renderer::replaceMacros($t, [
|
||||||
|
@ -308,7 +259,7 @@ class Users extends BaseAdmin
|
||||||
|
|
||||||
'$h_users' => DI::l10n()->t('Users'),
|
'$h_users' => DI::l10n()->t('Users'),
|
||||||
'$h_newuser' => DI::l10n()->t('New User'),
|
'$h_newuser' => DI::l10n()->t('New User'),
|
||||||
'$th_deleted' => [DI::l10n()->t('Name'), DI::l10n()->t('Email'), DI::l10n()->t('Register date'), DI::l10n()->t('Last login'), DI::l10n()->t('Last item'), DI::l10n()->t('Permanent deletion')],
|
'$th_deleted' => [DI::l10n()->t('Name'), DI::l10n()->t('Email'), DI::l10n()->t('Register date'), DI::l10n()->t('Last login'), DI::l10n()->t('Last public item'), DI::l10n()->t('Permanent deletion')],
|
||||||
'$th_users' => $th_users,
|
'$th_users' => $th_users,
|
||||||
'$order_users' => $order,
|
'$order_users' => $order,
|
||||||
'$order_direction_users' => $order_direction,
|
'$order_direction_users' => $order_direction,
|
||||||
|
|
|
@ -280,58 +280,33 @@ class Community extends BaseModule
|
||||||
$r = false;
|
$r = false;
|
||||||
|
|
||||||
if (self::$content == 'local') {
|
if (self::$content == 'local') {
|
||||||
$values = [];
|
|
||||||
|
|
||||||
$sql_accounttype = '';
|
|
||||||
$sql_boundaries = '';
|
|
||||||
if (!is_null(self::$accounttype)) {
|
if (!is_null(self::$accounttype)) {
|
||||||
$sql_accounttype = " AND `user`.`account-type` = ?";
|
$condition = ["`wall` AND `origin` AND `private` = ? AND `owner`.`contact-type` = ?", Item::PUBLIC, self::$accounttype];
|
||||||
$values[] = [self::$accounttype];
|
} else {
|
||||||
|
$condition = ["`wall` AND `origin` AND `private` = ?", Item::PUBLIC];
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isset($since_id)) {
|
|
||||||
$sql_boundaries .= " AND `thread`.`commented` > ?";
|
|
||||||
$values[] = $since_id;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (isset($max_id)) {
|
|
||||||
$sql_boundaries .= " AND `thread`.`commented` < ?";
|
|
||||||
$values[] = $max_id;
|
|
||||||
}
|
|
||||||
|
|
||||||
$values[] = $itemspage;
|
|
||||||
|
|
||||||
/// @todo Use "unsearchable" here as well (instead of "hidewall")
|
|
||||||
$r = DBA::p("SELECT `item`.`uri`, `author`.`url` AS `author-link`, `thread`.`commented` FROM `thread`
|
|
||||||
STRAIGHT_JOIN `user` ON `user`.`uid` = `thread`.`uid` AND NOT `user`.`hidewall`
|
|
||||||
STRAIGHT_JOIN `item` ON `item`.`id` = `thread`.`iid`
|
|
||||||
STRAIGHT_JOIN `contact` AS `author` ON `author`.`id`=`item`.`author-id`
|
|
||||||
WHERE `thread`.`visible` AND NOT `thread`.`deleted` AND NOT `thread`.`moderated`
|
|
||||||
AND NOT `thread`.`private` AND `thread`.`wall` AND `thread`.`origin`
|
|
||||||
$sql_accounttype
|
|
||||||
$sql_boundaries
|
|
||||||
ORDER BY `thread`.`commented` DESC
|
|
||||||
LIMIT ?", $values);
|
|
||||||
} elseif (self::$content == 'global') {
|
} elseif (self::$content == 'global') {
|
||||||
if (!is_null(self::$accounttype)) {
|
if (!is_null(self::$accounttype)) {
|
||||||
$condition = ["`uid` = ? AND NOT `author`.`unsearchable` AND NOT `owner`.`unsearchable` AND `owner`.`contact-type` = ?", 0, self::$accounttype];
|
$condition = ["`uid` = ? AND `private` = ? AND `owner`.`contact-type` = ?", 0, Item::PUBLIC, self::$accounttype];
|
||||||
} else {
|
} else {
|
||||||
$condition = ["`uid` = ? AND NOT `author`.`unsearchable` AND NOT `owner`.`unsearchable`", 0];
|
$condition = ["`uid` = ? AND `private` = ?", 0, Item::PUBLIC];
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
if (isset($max_id)) {
|
return [];
|
||||||
$condition[0] .= " AND `commented` < ?";
|
|
||||||
$condition[] = $max_id;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (isset($since_id)) {
|
|
||||||
$condition[0] .= " AND `commented` > ?";
|
|
||||||
$condition[] = $since_id;
|
|
||||||
}
|
|
||||||
|
|
||||||
$r = Item::selectThreadForUser(0, ['uri', 'commented'], $condition, ['order' => ['commented' => true], 'limit' => $itemspage]);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (isset($max_id)) {
|
||||||
|
$condition[0] .= " AND `commented` < ?";
|
||||||
|
$condition[] = $max_id;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isset($since_id)) {
|
||||||
|
$condition[0] .= " AND `commented` > ?";
|
||||||
|
$condition[] = $since_id;
|
||||||
|
}
|
||||||
|
|
||||||
|
$r = Item::selectThreadForUser(0, ['uri', 'commented', 'author-link'], $condition, ['order' => ['commented' => true], 'limit' => $itemspage]);
|
||||||
|
|
||||||
return DBA::toArray($r);
|
return DBA::toArray($r);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -54,7 +54,7 @@ class Fetch extends BaseModule
|
||||||
'uid', 'title', 'body', 'guid', 'contact-id', 'private', 'created', 'received', 'app', 'location', 'coord', 'network',
|
'uid', 'title', 'body', 'guid', 'contact-id', 'private', 'created', 'received', 'app', 'location', 'coord', 'network',
|
||||||
'event-id', 'resource-id', 'author-link', 'author-avatar', 'author-name', 'plink', 'owner-link', 'attach'
|
'event-id', 'resource-id', 'author-link', 'author-avatar', 'author-name', 'plink', 'owner-link', 'attach'
|
||||||
];
|
];
|
||||||
$condition = ['wall' => true, 'private' => false, 'guid' => $guid, 'network' => [Protocol::DFRN, Protocol::DIASPORA]];
|
$condition = ['wall' => true, 'private' => [Item::PUBLIC, Item::UNLISTED], 'guid' => $guid, 'network' => [Protocol::DFRN, Protocol::DIASPORA]];
|
||||||
$item = Item::selectFirst($fields, $condition);
|
$item = Item::selectFirst($fields, $condition);
|
||||||
if (empty($item)) {
|
if (empty($item)) {
|
||||||
$condition = ['guid' => $guid, 'network' => [Protocol::DFRN, Protocol::DIASPORA]];
|
$condition = ['guid' => $guid, 'network' => [Protocol::DFRN, Protocol::DIASPORA]];
|
||||||
|
|
|
@ -24,6 +24,7 @@ namespace Friendica\Module\Notifications;
|
||||||
use Friendica\BaseModule;
|
use Friendica\BaseModule;
|
||||||
use Friendica\Core\System;
|
use Friendica\Core\System;
|
||||||
use Friendica\DI;
|
use Friendica\DI;
|
||||||
|
use Friendica\Module\Security\Login;
|
||||||
use Friendica\Network\HTTPException;
|
use Friendica\Network\HTTPException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -31,15 +32,21 @@ use Friendica\Network\HTTPException;
|
||||||
*/
|
*/
|
||||||
class Notification extends BaseModule
|
class Notification extends BaseModule
|
||||||
{
|
{
|
||||||
public static function init(array $parameters = [])
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*
|
||||||
|
* @throws HTTPException\InternalServerErrorException
|
||||||
|
* @throws HTTPException\NotFoundException
|
||||||
|
* @throws HTTPException\UnauthorizedException
|
||||||
|
* @throws \ImagickException
|
||||||
|
* @throws \Exception
|
||||||
|
*/
|
||||||
|
public static function post(array $parameters = [])
|
||||||
{
|
{
|
||||||
if (!local_user()) {
|
if (!local_user()) {
|
||||||
throw new HTTPException\UnauthorizedException(DI::l10n()->t('Permission denied.'));
|
throw new HTTPException\UnauthorizedException(DI::l10n()->t('Permission denied.'));
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
public static function post(array $parameters = [])
|
|
||||||
{
|
|
||||||
$request_id = $parameters['id'] ?? false;
|
$request_id = $parameters['id'] ?? false;
|
||||||
|
|
||||||
if ($request_id) {
|
if ($request_id) {
|
||||||
|
@ -58,9 +65,17 @@ class Notification extends BaseModule
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*
|
||||||
|
* @throws HTTPException\UnauthorizedException
|
||||||
|
*/
|
||||||
public static function rawContent(array $parameters = [])
|
public static function rawContent(array $parameters = [])
|
||||||
{
|
{
|
||||||
// @TODO: Replace with parameter from router
|
if (!local_user()) {
|
||||||
|
throw new HTTPException\UnauthorizedException(DI::l10n()->t('Permission denied.'));
|
||||||
|
}
|
||||||
|
|
||||||
if (DI::args()->get(1) === 'mark' && DI::args()->get(2) === 'all') {
|
if (DI::args()->get(1) === 'mark' && DI::args()->get(2) === 'all') {
|
||||||
try {
|
try {
|
||||||
$success = DI::notify()->setSeen();
|
$success = DI::notify()->setSeen();
|
||||||
|
@ -74,31 +89,36 @@ class Notification extends BaseModule
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*
|
||||||
* Redirect to the notifications main page or to the url for the chosen notifications
|
* Redirect to the notifications main page or to the url for the chosen notifications
|
||||||
*
|
*
|
||||||
* @return string|void
|
* @throws HTTPException\NotFoundException In case the notification is either not existing or is not for this user
|
||||||
* @throws HTTPException\InternalServerErrorException
|
* @throws HTTPException\InternalServerErrorException
|
||||||
|
* @throws \Exception
|
||||||
*/
|
*/
|
||||||
public static function content(array $parameters = [])
|
public static function content(array $parameters = [])
|
||||||
{
|
{
|
||||||
|
if (!local_user()) {
|
||||||
|
notice(DI::l10n()->t('You must be logged in to show this page.'));
|
||||||
|
return Login::form();
|
||||||
|
}
|
||||||
|
|
||||||
$request_id = $parameters['id'] ?? false;
|
$request_id = $parameters['id'] ?? false;
|
||||||
|
|
||||||
if ($request_id) {
|
if ($request_id) {
|
||||||
try {
|
$notify = DI::notify()->getByID($request_id, local_user());
|
||||||
$notify = DI::notify()->getByID($request_id);
|
DI::notify()->setSeen(true, $notify);
|
||||||
DI::notify()->setSeen(true, $notify);
|
|
||||||
|
|
||||||
if (!empty($notify->link)) {
|
if (!empty($notify->link)) {
|
||||||
System::externalRedirect($notify->link);
|
System::externalRedirect($notify->link);
|
||||||
}
|
|
||||||
|
|
||||||
} catch (HTTPException\NotFoundException $e) {
|
|
||||||
info(DI::l10n()->t('Invalid notification.'));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
DI::baseUrl()->redirect();
|
DI::baseUrl()->redirect();
|
||||||
}
|
}
|
||||||
|
|
||||||
DI::baseUrl()->redirect('notifications/system');
|
DI::baseUrl()->redirect('notifications/system');
|
||||||
|
|
||||||
|
throw new HTTPException\InternalServerErrorException('Invalid situation.');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -49,11 +49,11 @@ class Objects extends BaseModule
|
||||||
|
|
||||||
// At first we try the original post with that guid
|
// At first we try the original post with that guid
|
||||||
// @TODO: Replace with parameter from router
|
// @TODO: Replace with parameter from router
|
||||||
$item = Item::selectFirst(['id'], ['guid' => $a->argv[1], 'origin' => true, 'private' => false]);
|
$item = Item::selectFirst(['id'], ['guid' => $a->argv[1], 'origin' => true, 'private' => [item::PRIVATE, Item::UNLISTED]]);
|
||||||
if (!DBA::isResult($item)) {
|
if (!DBA::isResult($item)) {
|
||||||
// If no original post could be found, it could possibly be a forum post, there we remove the "origin" field.
|
// If no original post could be found, it could possibly be a forum post, there we remove the "origin" field.
|
||||||
// @TODO: Replace with parameter from router
|
// @TODO: Replace with parameter from router
|
||||||
$item = Item::selectFirst(['id', 'author-link'], ['guid' => $a->argv[1], 'private' => false]);
|
$item = Item::selectFirst(['id', 'author-link'], ['guid' => $a->argv[1], 'private' => [item::PRIVATE, Item::UNLISTED]]);
|
||||||
if (!DBA::isResult($item) || !strstr($item['author-link'], DI::baseUrl()->get())) {
|
if (!DBA::isResult($item) || !strstr($item['author-link'], DI::baseUrl()->get())) {
|
||||||
throw new \Friendica\Network\HTTPException\NotFoundException();
|
throw new \Friendica\Network\HTTPException\NotFoundException();
|
||||||
}
|
}
|
||||||
|
|
|
@ -197,7 +197,7 @@ class Display extends BaseSettings
|
||||||
'$itemspage_network' => ['itemspage_network' , DI::l10n()->t('Number of items to display per page:'), $itemspage_network, DI::l10n()->t('Maximum of 100 items')],
|
'$itemspage_network' => ['itemspage_network' , DI::l10n()->t('Number of items to display per page:'), $itemspage_network, DI::l10n()->t('Maximum of 100 items')],
|
||||||
'$itemspage_mobile_network' => ['itemspage_mobile_network', DI::l10n()->t('Number of items to display per page when viewed from mobile device:'), $itemspage_mobile_network, DI::l10n()->t('Maximum of 100 items')],
|
'$itemspage_mobile_network' => ['itemspage_mobile_network', DI::l10n()->t('Number of items to display per page when viewed from mobile device:'), $itemspage_mobile_network, DI::l10n()->t('Maximum of 100 items')],
|
||||||
'$ajaxint' => ['browser_update' , DI::l10n()->t('Update browser every xx seconds'), $browser_update, DI::l10n()->t('Minimum of 10 seconds. Enter -1 to disable it.')],
|
'$ajaxint' => ['browser_update' , DI::l10n()->t('Update browser every xx seconds'), $browser_update, DI::l10n()->t('Minimum of 10 seconds. Enter -1 to disable it.')],
|
||||||
'$no_auto_update' => ['no_auto_update' , DI::l10n()->t('Automatic updates only at the top of the network page'), $no_auto_update, DI::l10n()->t('When disabled, the network page is updated all the time, which could be confusing while reading.')],
|
'$no_auto_update' => ['no_auto_update' , DI::l10n()->t('Automatic updates only at the top of the post stream pages'), $no_auto_update, DI::l10n()->t('Auto update may add new posts at the top of the post stream pages, which can affect the scroll position and perturb normal reading if it happens anywhere else the top of the page.')],
|
||||||
'$nosmile' => ['nosmile' , DI::l10n()->t('Don\'t show emoticons'), $nosmile, DI::l10n()->t('Normally emoticons are replaced with matching symbols. This setting disables this behaviour.')],
|
'$nosmile' => ['nosmile' , DI::l10n()->t('Don\'t show emoticons'), $nosmile, DI::l10n()->t('Normally emoticons are replaced with matching symbols. This setting disables this behaviour.')],
|
||||||
'$infinite_scroll' => ['infinite_scroll' , DI::l10n()->t('Infinite scroll'), $infinite_scroll, DI::l10n()->t('Automatic fetch new items when reaching the page end.')],
|
'$infinite_scroll' => ['infinite_scroll' , DI::l10n()->t('Infinite scroll'), $infinite_scroll, DI::l10n()->t('Automatic fetch new items when reaching the page end.')],
|
||||||
'$no_smart_threading' => ['no_smart_threading' , DI::l10n()->t('Disable Smart Threading'), $no_smart_threading, DI::l10n()->t('Disable the automatic suppression of extraneous thread indentation.')],
|
'$no_smart_threading' => ['no_smart_threading' , DI::l10n()->t('Disable Smart Threading'), $no_smart_threading, DI::l10n()->t('Disable the automatic suppression of extraneous thread indentation.')],
|
||||||
|
|
|
@ -37,7 +37,10 @@ class Community extends CommunityModule
|
||||||
{
|
{
|
||||||
self::parseRequest($parameters);
|
self::parseRequest($parameters);
|
||||||
|
|
||||||
$o = conversation(DI::app(), self::getItems(), 'community', true, false, 'commented', local_user());
|
$o = '';
|
||||||
|
if (!empty($_GET['force']) || !DI::pConfig()->get(local_user(), 'system', 'no_auto_update')) {
|
||||||
|
$o = conversation(DI::app(), self::getItems(), 'community', true, false, 'commented', local_user());
|
||||||
|
}
|
||||||
|
|
||||||
System::htmlUpdateExit($o);
|
System::htmlUpdateExit($o);
|
||||||
}
|
}
|
||||||
|
|
|
@ -42,8 +42,6 @@ class Profile extends BaseModule
|
||||||
throw new ForbiddenException();
|
throw new ForbiddenException();
|
||||||
}
|
}
|
||||||
|
|
||||||
$o = '';
|
|
||||||
|
|
||||||
$profile_uid = intval($_GET['p'] ?? 0);
|
$profile_uid = intval($_GET['p'] ?? 0);
|
||||||
|
|
||||||
// Ensure we've got a profile owner if updating.
|
// Ensure we've got a profile owner if updating.
|
||||||
|
@ -57,6 +55,12 @@ class Profile extends BaseModule
|
||||||
throw new ForbiddenException(DI::l10n()->t('Access to this profile has been restricted.'));
|
throw new ForbiddenException(DI::l10n()->t('Access to this profile has been restricted.'));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$o = '';
|
||||||
|
|
||||||
|
if (empty($_GET['force']) && DI::pConfig()->get(local_user(), 'system', 'no_auto_update')) {
|
||||||
|
System::htmlUpdateExit($o);
|
||||||
|
}
|
||||||
|
|
||||||
// Get permissions SQL - if $remote_contact is true, our remote user has been pre-verified and we already have fetched his/her groups
|
// Get permissions SQL - if $remote_contact is true, our remote user has been pre-verified and we already have fetched his/her groups
|
||||||
$sql_extra = Item::getPermissionsSQLByUserId($a->profile['uid']);
|
$sql_extra = Item::getPermissionsSQLByUserId($a->profile['uid']);
|
||||||
|
|
||||||
|
|
|
@ -170,12 +170,12 @@ class Post
|
||||||
|
|
||||||
$conv = $this->getThread();
|
$conv = $this->getThread();
|
||||||
|
|
||||||
$lock = ((($item['private'] == 1) || (($item['uid'] == local_user()) && (strlen($item['allow_cid']) || strlen($item['allow_gid'])
|
$lock = ((($item['private'] == Item::PRIVATE) || (($item['uid'] == local_user()) && (strlen($item['allow_cid']) || strlen($item['allow_gid'])
|
||||||
|| strlen($item['deny_cid']) || strlen($item['deny_gid']))))
|
|| strlen($item['deny_cid']) || strlen($item['deny_gid']))))
|
||||||
? DI::l10n()->t('Private Message')
|
? DI::l10n()->t('Private Message')
|
||||||
: false);
|
: false);
|
||||||
|
|
||||||
$shareable = in_array($conv->getProfileOwner(), [0, local_user()]) && $item['private'] != 1;
|
$shareable = in_array($conv->getProfileOwner(), [0, local_user()]) && $item['private'] != Item::PRIVATE;
|
||||||
|
|
||||||
$edpost = false;
|
$edpost = false;
|
||||||
|
|
||||||
|
@ -272,10 +272,12 @@ class Post
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$responses = get_responses($conv_responses, $response_verbs, $item, $this);
|
$responses = [];
|
||||||
|
foreach ($response_verbs as $value => $verb) {
|
||||||
foreach ($response_verbs as $value => $verbs) {
|
$responses[$verb] = [
|
||||||
$responses[$verbs]['output'] = !empty($conv_responses[$verbs][$item['uri']]) ? format_like($conv_responses[$verbs][$item['uri']], $conv_responses[$verbs][$item['uri'] . '-l'], $verbs, $item['uri']) : '';
|
'self' => $conv_responses[$verb][$item['uri'] . '-self'] ?? 0,
|
||||||
|
'output' => !empty($conv_responses[$verb][$item['uri']]) ? format_like($conv_responses[$verb][$item['uri']], $conv_responses[$verb][$item['uri'] . '-l'], $verb, $item['uri']) : '',
|
||||||
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -34,6 +34,7 @@ use Friendica\Util\Security;
|
||||||
*/
|
*/
|
||||||
class Thread
|
class Thread
|
||||||
{
|
{
|
||||||
|
/** @var Post[] */
|
||||||
private $parents = [];
|
private $parents = [];
|
||||||
private $mode = null;
|
private $mode = null;
|
||||||
private $writable = false;
|
private $writable = false;
|
||||||
|
|
|
@ -29,6 +29,7 @@ use Friendica\Database\DBA;
|
||||||
use Friendica\DI;
|
use Friendica\DI;
|
||||||
use Friendica\Model\APContact;
|
use Friendica\Model\APContact;
|
||||||
use Friendica\Model\Contact;
|
use Friendica\Model\Contact;
|
||||||
|
use Friendica\Model\Conversation;
|
||||||
use Friendica\Model\Event;
|
use Friendica\Model\Event;
|
||||||
use Friendica\Model\Item;
|
use Friendica\Model\Item;
|
||||||
use Friendica\Model\Mail;
|
use Friendica\Model\Mail;
|
||||||
|
@ -375,7 +376,7 @@ class Processor
|
||||||
Logger::warning('Unknown parent item.', ['uri' => $item['thr-parent']]);
|
Logger::warning('Unknown parent item.', ['uri' => $item['thr-parent']]);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if ($item_private && !$parent['private']) {
|
if ($item_private && ($parent['private'] == Item::PRIVATE)) {
|
||||||
Logger::warning('Item is private but the parent is not. Dropping.', ['item-uri' => $item['uri'], 'thr-parent' => $item['thr-parent']]);
|
Logger::warning('Item is private but the parent is not. Dropping.', ['item-uri' => $item['uri'], 'thr-parent' => $item['thr-parent']]);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -442,12 +443,26 @@ class Processor
|
||||||
}
|
}
|
||||||
|
|
||||||
$item['network'] = Protocol::ACTIVITYPUB;
|
$item['network'] = Protocol::ACTIVITYPUB;
|
||||||
$item['private'] = !in_array(0, $activity['receiver']);
|
|
||||||
$item['author-link'] = $activity['author'];
|
$item['author-link'] = $activity['author'];
|
||||||
$item['author-id'] = Contact::getIdForURL($activity['author'], 0, true);
|
$item['author-id'] = Contact::getIdForURL($activity['author'], 0, true);
|
||||||
$item['owner-link'] = $activity['actor'];
|
$item['owner-link'] = $activity['actor'];
|
||||||
$item['owner-id'] = Contact::getIdForURL($activity['actor'], 0, true);
|
$item['owner-id'] = Contact::getIdForURL($activity['actor'], 0, true);
|
||||||
|
|
||||||
|
if (in_array(0, $activity['receiver']) && !empty($activity['unlisted'])) {
|
||||||
|
$item['private'] = Item::UNLISTED;
|
||||||
|
} elseif (in_array(0, $activity['receiver'])) {
|
||||||
|
$item['private'] = Item::PUBLIC;
|
||||||
|
} else {
|
||||||
|
$item['private'] = Item::PRIVATE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!empty($activity['raw'])) {
|
||||||
|
$item['source'] = $activity['raw'];
|
||||||
|
$item['protocol'] = Conversation::PARCEL_ACTIVITYPUB;
|
||||||
|
$item['conversation-href'] = $activity['context'] ?? '';
|
||||||
|
$item['conversation-uri'] = $activity['conversation'] ?? '';
|
||||||
|
}
|
||||||
|
|
||||||
$isForum = false;
|
$isForum = false;
|
||||||
|
|
||||||
if (!empty($activity['thread-completion'])) {
|
if (!empty($activity['thread-completion'])) {
|
||||||
|
@ -490,6 +505,10 @@ class Processor
|
||||||
$stored = false;
|
$stored = false;
|
||||||
|
|
||||||
foreach ($activity['receiver'] as $receiver) {
|
foreach ($activity['receiver'] as $receiver) {
|
||||||
|
if ($receiver == -1) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
$item['uid'] = $receiver;
|
$item['uid'] = $receiver;
|
||||||
|
|
||||||
if ($isForum) {
|
if ($isForum) {
|
||||||
|
@ -539,7 +558,7 @@ class Processor
|
||||||
}
|
}
|
||||||
|
|
||||||
// Store send a follow request for every reshare - but only when the item had been stored
|
// Store send a follow request for every reshare - but only when the item had been stored
|
||||||
if ($stored && !$item['private'] && ($item['gravity'] == GRAVITY_PARENT) && ($item['author-link'] != $item['owner-link'])) {
|
if ($stored && ($item['private'] != Item::PRIVATE) && ($item['gravity'] == GRAVITY_PARENT) && ($item['author-link'] != $item['owner-link'])) {
|
||||||
$author = APContact::getByURL($item['owner-link'], false);
|
$author = APContact::getByURL($item['owner-link'], false);
|
||||||
// We send automatic follow requests for reshared messages. (We don't need though for forum posts)
|
// We send automatic follow requests for reshared messages. (We don't need though for forum posts)
|
||||||
if ($author['type'] != 'Group') {
|
if ($author['type'] != 'Group') {
|
||||||
|
|
|
@ -28,7 +28,6 @@ use Friendica\Core\Logger;
|
||||||
use Friendica\Core\Protocol;
|
use Friendica\Core\Protocol;
|
||||||
use Friendica\Model\Contact;
|
use Friendica\Model\Contact;
|
||||||
use Friendica\Model\APContact;
|
use Friendica\Model\APContact;
|
||||||
use Friendica\Model\Conversation;
|
|
||||||
use Friendica\Model\Item;
|
use Friendica\Model\Item;
|
||||||
use Friendica\Model\User;
|
use Friendica\Model\User;
|
||||||
use Friendica\Protocol\Activity;
|
use Friendica\Protocol\Activity;
|
||||||
|
@ -306,33 +305,6 @@ class Receiver
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Store the unprocessed data into the conversation table
|
|
||||||
* This has to be done outside the regular function,
|
|
||||||
* since we store everything - not only item posts.
|
|
||||||
*
|
|
||||||
* @param array $activity Array with activity data
|
|
||||||
* @param string $body The raw message
|
|
||||||
* @throws \Exception
|
|
||||||
*/
|
|
||||||
private static function storeConversation($activity, $body)
|
|
||||||
{
|
|
||||||
if (empty($body) || empty($activity['id'])) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
$conversation = [
|
|
||||||
'protocol' => Conversation::PARCEL_ACTIVITYPUB,
|
|
||||||
'item-uri' => $activity['id'],
|
|
||||||
'reply-to-uri' => $activity['reply-to-id'] ?? '',
|
|
||||||
'conversation-href' => $activity['context'] ?? '',
|
|
||||||
'conversation-uri' => $activity['conversation'] ?? '',
|
|
||||||
'source' => $body,
|
|
||||||
'received' => DateTimeFormat::utcNow()];
|
|
||||||
|
|
||||||
DBA::insert('conversation', $conversation, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Processes the activity object
|
* Processes the activity object
|
||||||
*
|
*
|
||||||
|
@ -383,9 +355,8 @@ class Receiver
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Only store content related stuff - and no announces, since they possibly overwrite the original content
|
if (!empty($body)) {
|
||||||
if (in_array($object_data['object_type'], self::CONTENT_TYPES) && ($type != 'as:Announce')) {
|
$object_data['raw'] = $body;
|
||||||
self::storeConversation($object_data, $body);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Internal flag for thread completion. See Processor.php
|
// Internal flag for thread completion. See Processor.php
|
||||||
|
@ -509,14 +480,15 @@ class Receiver
|
||||||
/**
|
/**
|
||||||
* Fetch the receiver list from an activity array
|
* Fetch the receiver list from an activity array
|
||||||
*
|
*
|
||||||
* @param array $activity
|
* @param array $activity
|
||||||
* @param string $actor
|
* @param string $actor
|
||||||
* @param array $tags
|
* @param array $tags
|
||||||
|
* @param boolean $fetch_unlisted
|
||||||
*
|
*
|
||||||
* @return array with receivers (user id)
|
* @return array with receivers (user id)
|
||||||
* @throws \Exception
|
* @throws \Exception
|
||||||
*/
|
*/
|
||||||
private static function getReceivers($activity, $actor, $tags = [])
|
private static function getReceivers($activity, $actor, $tags = [], $fetch_unlisted = false)
|
||||||
{
|
{
|
||||||
$receivers = [];
|
$receivers = [];
|
||||||
|
|
||||||
|
@ -554,6 +526,11 @@ class Receiver
|
||||||
$receivers['uid:0'] = 0;
|
$receivers['uid:0'] = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Add receiver "-1" for unlisted posts
|
||||||
|
if ($fetch_unlisted && ($receiver == self::PUBLIC_COLLECTION) && ($element == 'as:cc')) {
|
||||||
|
$receivers['uid:-1'] = -1;
|
||||||
|
}
|
||||||
|
|
||||||
if (($receiver == self::PUBLIC_COLLECTION) && !empty($actor)) {
|
if (($receiver == self::PUBLIC_COLLECTION) && !empty($actor)) {
|
||||||
// This will most likely catch all OStatus connections to Mastodon
|
// This will most likely catch all OStatus connections to Mastodon
|
||||||
$condition = ['alias' => [$actor, Strings::normaliseLink($actor)], 'rel' => [Contact::SHARING, Contact::FRIEND]
|
$condition = ['alias' => [$actor, Strings::normaliseLink($actor)], 'rel' => [Contact::SHARING, Contact::FRIEND]
|
||||||
|
@ -1025,7 +1002,9 @@ class Receiver
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$object_data['receiver'] = self::getReceivers($object, $object_data['actor'], $object_data['tags']);
|
$object_data['receiver'] = self::getReceivers($object, $object_data['actor'], $object_data['tags'], true);
|
||||||
|
$object_data['unlisted'] = in_array(-1, $object_data['receiver']);
|
||||||
|
unset($object_data['receiver']['uid:-1']);
|
||||||
|
|
||||||
// Common object data:
|
// Common object data:
|
||||||
|
|
||||||
|
|
|
@ -173,7 +173,7 @@ class Transmitter
|
||||||
$public_contact = Contact::getIdForURL($owner['url'], 0, true);
|
$public_contact = Contact::getIdForURL($owner['url'], 0, true);
|
||||||
|
|
||||||
$condition = ['uid' => 0, 'contact-id' => $public_contact, 'author-id' => $public_contact,
|
$condition = ['uid' => 0, 'contact-id' => $public_contact, 'author-id' => $public_contact,
|
||||||
'private' => false, 'gravity' => [GRAVITY_PARENT, GRAVITY_COMMENT],
|
'private' => [Item::PUBLIC, Item::UNLISTED], 'gravity' => [GRAVITY_PARENT, GRAVITY_COMMENT],
|
||||||
'deleted' => false, 'visible' => true, 'moderated' => false];
|
'deleted' => false, 'visible' => true, 'moderated' => false];
|
||||||
$count = DBA::count('item', $condition);
|
$count = DBA::count('item', $condition);
|
||||||
|
|
||||||
|
@ -264,7 +264,7 @@ class Transmitter
|
||||||
$data['name'] = $contact['name'];
|
$data['name'] = $contact['name'];
|
||||||
$data['vcard:hasAddress'] = ['@type' => 'vcard:Home', 'vcard:country-name' => $profile['country-name'],
|
$data['vcard:hasAddress'] = ['@type' => 'vcard:Home', 'vcard:country-name' => $profile['country-name'],
|
||||||
'vcard:region' => $profile['region'], 'vcard:locality' => $profile['locality']];
|
'vcard:region' => $profile['region'], 'vcard:locality' => $profile['locality']];
|
||||||
$data['summary'] = $contact['about'];
|
$data['summary'] = BBCode::convert($contact['about'], false);
|
||||||
$data['url'] = $contact['url'];
|
$data['url'] = $contact['url'];
|
||||||
$data['manuallyApprovesFollowers'] = in_array($user['page-flags'], [User::PAGE_FLAGS_NORMAL, User::PAGE_FLAGS_PRVGROUP]);
|
$data['manuallyApprovesFollowers'] = in_array($user['page-flags'], [User::PAGE_FLAGS_NORMAL, User::PAGE_FLAGS_PRVGROUP]);
|
||||||
$data['publicKey'] = ['id' => $contact['url'] . '#main-key',
|
$data['publicKey'] = ['id' => $contact['url'] . '#main-key',
|
||||||
|
@ -401,7 +401,7 @@ class Transmitter
|
||||||
|
|
||||||
$terms = Term::tagArrayFromItemId($item['id'], [Term::MENTION, Term::IMPLICIT_MENTION]);
|
$terms = Term::tagArrayFromItemId($item['id'], [Term::MENTION, Term::IMPLICIT_MENTION]);
|
||||||
|
|
||||||
if (!$item['private']) {
|
if ($item['private'] != Item::PRIVATE) {
|
||||||
// Directly mention the original author upon a quoted reshare.
|
// Directly mention the original author upon a quoted reshare.
|
||||||
// Else just ensure that the original author receives the reshare.
|
// Else just ensure that the original author receives the reshare.
|
||||||
$announce = self::getAnnounceArray($item);
|
$announce = self::getAnnounceArray($item);
|
||||||
|
@ -413,7 +413,12 @@ class Transmitter
|
||||||
|
|
||||||
$data = array_merge($data, self::fetchPermissionBlockFromConversation($item));
|
$data = array_merge($data, self::fetchPermissionBlockFromConversation($item));
|
||||||
|
|
||||||
$data['to'][] = ActivityPub::PUBLIC_COLLECTION;
|
// Check if the item is completely public or unlisted
|
||||||
|
if ($item['private'] == Item::PUBLIC) {
|
||||||
|
$data['to'][] = ActivityPub::PUBLIC_COLLECTION;
|
||||||
|
} else {
|
||||||
|
$data['cc'][] = ActivityPub::PUBLIC_COLLECTION;
|
||||||
|
}
|
||||||
|
|
||||||
foreach ($terms as $term) {
|
foreach ($terms as $term) {
|
||||||
$profile = APContact::getByURL($term['url'], false);
|
$profile = APContact::getByURL($term['url'], false);
|
||||||
|
@ -467,13 +472,13 @@ class Transmitter
|
||||||
$data['to'][] = $profile['url'];
|
$data['to'][] = $profile['url'];
|
||||||
} else {
|
} else {
|
||||||
$data['cc'][] = $profile['url'];
|
$data['cc'][] = $profile['url'];
|
||||||
if (!$item['private'] && !empty($actor_profile['followers'])) {
|
if (($item['private'] != Item::PRIVATE) && $item['private'] && !empty($actor_profile['followers'])) {
|
||||||
$data['cc'][] = $actor_profile['followers'];
|
$data['cc'][] = $actor_profile['followers'];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// Public thread parent post always are directed to the followers
|
// Public thread parent post always are directed to the followers
|
||||||
if (!$item['private'] && !$forum_mode) {
|
if (($item['private'] != Item::PRIVATE) && !$forum_mode) {
|
||||||
$data['cc'][] = $actor_profile['followers'];
|
$data['cc'][] = $actor_profile['followers'];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -182,7 +182,7 @@ class DFRN
|
||||||
|
|
||||||
// default permissions - anonymous user
|
// default permissions - anonymous user
|
||||||
|
|
||||||
$sql_extra = " AND NOT `item`.`private` ";
|
$sql_extra = sprintf(" AND `item`.`private` != %s ", Item::PRIVATE);
|
||||||
|
|
||||||
$r = q(
|
$r = q(
|
||||||
"SELECT `contact`.*, `user`.`nickname`, `user`.`timezone`, `user`.`page-flags`, `user`.`account-type`
|
"SELECT `contact`.*, `user`.`nickname`, `user`.`timezone`, `user`.`page-flags`, `user`.`account-type`
|
||||||
|
@ -234,7 +234,7 @@ class DFRN
|
||||||
if (!empty($set)) {
|
if (!empty($set)) {
|
||||||
$sql_extra = " AND `item`.`psid` IN (" . implode(',', $set) .")";
|
$sql_extra = " AND `item`.`psid` IN (" . implode(',', $set) .")";
|
||||||
} else {
|
} else {
|
||||||
$sql_extra = " AND NOT `item`.`private`";
|
$sql_extra = sprintf(" AND `item`.`private` != %s", Item::PRIVATE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -332,7 +332,7 @@ class DFRN
|
||||||
if ($public_feed) {
|
if ($public_feed) {
|
||||||
$type = 'html';
|
$type = 'html';
|
||||||
// catch any email that's in a public conversation and make sure it doesn't leak
|
// catch any email that's in a public conversation and make sure it doesn't leak
|
||||||
if ($item['private']) {
|
if ($item['private'] == Item::PRIVATE) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -955,7 +955,7 @@ class DFRN
|
||||||
$entry->setAttribute("xmlns:statusnet", ActivityNamespace::STATUSNET);
|
$entry->setAttribute("xmlns:statusnet", ActivityNamespace::STATUSNET);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($item['private']) {
|
if ($item['private'] == Item::PRIVATE) {
|
||||||
$body = Item::fixPrivatePhotos($item['body'], $owner['uid'], $item, $cid);
|
$body = Item::fixPrivatePhotos($item['body'], $owner['uid'], $item, $cid);
|
||||||
} else {
|
} else {
|
||||||
$body = $item['body'];
|
$body = $item['body'];
|
||||||
|
@ -1050,7 +1050,9 @@ class DFRN
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($item['private']) {
|
if ($item['private']) {
|
||||||
XML::addElement($doc, $entry, "dfrn:private", ($item['private'] ? $item['private'] : 1));
|
// Friendica versions prior to 2020.3 can't handle "unlisted" properly. So we can only transmit public and private
|
||||||
|
XML::addElement($doc, $entry, "dfrn:private", ($item['private'] == Item::PRIVATE ? Item::PRIVATE : Item::PUBLIC));
|
||||||
|
XML::addElement($doc, $entry, "dfrn:unlisted", $item['private'] == Item::UNLISTED);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($item['extid']) {
|
if ($item['extid']) {
|
||||||
|
@ -2404,6 +2406,11 @@ class DFRN
|
||||||
|
|
||||||
$item["private"] = XML::getFirstNodeValue($xpath, "dfrn:private/text()", $entry);
|
$item["private"] = XML::getFirstNodeValue($xpath, "dfrn:private/text()", $entry);
|
||||||
|
|
||||||
|
$unlisted = XML::getFirstNodeValue($xpath, "dfrn:unlisted/text()", $entry);
|
||||||
|
if (!empty($unlisted) && ($item['private'] != Item::PRIVATE)) {
|
||||||
|
$item['private'] = Item::UNLISTED;
|
||||||
|
}
|
||||||
|
|
||||||
$item["extid"] = XML::getFirstNodeValue($xpath, "dfrn:extid/text()", $entry);
|
$item["extid"] = XML::getFirstNodeValue($xpath, "dfrn:extid/text()", $entry);
|
||||||
|
|
||||||
if (XML::getFirstNodeValue($xpath, "dfrn:bookmark/text()", $entry) == "true") {
|
if (XML::getFirstNodeValue($xpath, "dfrn:bookmark/text()", $entry) == "true") {
|
||||||
|
|
|
@ -2211,7 +2211,7 @@ class Diaspora
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
$item = Item::selectFirst(['id'], ['guid' => $parent_guid, 'origin' => true, 'private' => false]);
|
$item = Item::selectFirst(['id'], ['guid' => $parent_guid, 'origin' => true, 'private' => [Item::PUBLIC, Item::UNLISTED]]);
|
||||||
if (!DBA::isResult($item)) {
|
if (!DBA::isResult($item)) {
|
||||||
Logger::log('Item not found, no origin or private: '.$parent_guid);
|
Logger::log('Item not found, no origin or private: '.$parent_guid);
|
||||||
return false;
|
return false;
|
||||||
|
@ -2523,7 +2523,7 @@ class Diaspora
|
||||||
// Do we already have this item?
|
// Do we already have this item?
|
||||||
$fields = ['body', 'title', 'attach', 'tag', 'app', 'created', 'object-type', 'uri', 'guid',
|
$fields = ['body', 'title', 'attach', 'tag', 'app', 'created', 'object-type', 'uri', 'guid',
|
||||||
'author-name', 'author-link', 'author-avatar'];
|
'author-name', 'author-link', 'author-avatar'];
|
||||||
$condition = ['guid' => $guid, 'visible' => true, 'deleted' => false, 'private' => false];
|
$condition = ['guid' => $guid, 'visible' => true, 'deleted' => false, 'private' => [Item::PUBLIC, Item::UNLISTED]];
|
||||||
$item = Item::selectFirst($fields, $condition);
|
$item = Item::selectFirst($fields, $condition);
|
||||||
|
|
||||||
if (DBA::isResult($item)) {
|
if (DBA::isResult($item)) {
|
||||||
|
@ -2567,7 +2567,7 @@ class Diaspora
|
||||||
if ($stored) {
|
if ($stored) {
|
||||||
$fields = ['body', 'title', 'attach', 'tag', 'app', 'created', 'object-type', 'uri', 'guid',
|
$fields = ['body', 'title', 'attach', 'tag', 'app', 'created', 'object-type', 'uri', 'guid',
|
||||||
'author-name', 'author-link', 'author-avatar'];
|
'author-name', 'author-link', 'author-avatar'];
|
||||||
$condition = ['guid' => $guid, 'visible' => true, 'deleted' => false, 'private' => false];
|
$condition = ['guid' => $guid, 'visible' => true, 'deleted' => false, 'private' => [Item::PUBLIC, Item::UNLISTED]];
|
||||||
$item = Item::selectFirst($fields, $condition);
|
$item = Item::selectFirst($fields, $condition);
|
||||||
|
|
||||||
if (DBA::isResult($item)) {
|
if (DBA::isResult($item)) {
|
||||||
|
@ -2711,7 +2711,7 @@ class Diaspora
|
||||||
$datarray["app"] = $original_item["app"];
|
$datarray["app"] = $original_item["app"];
|
||||||
|
|
||||||
$datarray["plink"] = self::plink($author, $guid);
|
$datarray["plink"] = self::plink($author, $guid);
|
||||||
$datarray["private"] = (($public == "false") ? 1 : 0);
|
$datarray["private"] = (($public == "false") ? Item::PRIVATE : Item::PUBLIC);
|
||||||
$datarray["changed"] = $datarray["created"] = $datarray["edited"] = $created_at;
|
$datarray["changed"] = $datarray["created"] = $datarray["edited"] = $created_at;
|
||||||
|
|
||||||
$datarray["object-type"] = $original_item["object-type"];
|
$datarray["object-type"] = $original_item["object-type"];
|
||||||
|
@ -2941,7 +2941,7 @@ class Diaspora
|
||||||
}
|
}
|
||||||
|
|
||||||
$datarray["plink"] = self::plink($author, $guid);
|
$datarray["plink"] = self::plink($author, $guid);
|
||||||
$datarray["private"] = (($public == "false") ? 1 : 0);
|
$datarray["private"] = (($public == "false") ? Item::PRIVATE : Item::PUBLIC);
|
||||||
$datarray["changed"] = $datarray["created"] = $datarray["edited"] = $created_at;
|
$datarray["changed"] = $datarray["created"] = $datarray["edited"] = $created_at;
|
||||||
|
|
||||||
if (isset($address["address"])) {
|
if (isset($address["address"])) {
|
||||||
|
@ -3245,7 +3245,7 @@ class Diaspora
|
||||||
private static function sendParticipation(array $contact, array $item)
|
private static function sendParticipation(array $contact, array $item)
|
||||||
{
|
{
|
||||||
// Don't send notifications for private postings
|
// Don't send notifications for private postings
|
||||||
if ($item['private']) {
|
if ($item['private'] == Item::PRIVATE) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3536,12 +3536,12 @@ class Diaspora
|
||||||
|
|
||||||
$myaddr = self::myHandle($owner);
|
$myaddr = self::myHandle($owner);
|
||||||
|
|
||||||
$public = ($item["private"] ? "false" : "true");
|
$public = ($item["private"] == Item::PRIVATE ? "false" : "true");
|
||||||
$created = DateTimeFormat::utc($item['received'], DateTimeFormat::ATOM);
|
$created = DateTimeFormat::utc($item['received'], DateTimeFormat::ATOM);
|
||||||
$edited = DateTimeFormat::utc($item["edited"] ?? $item["created"], DateTimeFormat::ATOM);
|
$edited = DateTimeFormat::utc($item["edited"] ?? $item["created"], DateTimeFormat::ATOM);
|
||||||
|
|
||||||
// Detect a share element and do a reshare
|
// Detect a share element and do a reshare
|
||||||
if (!$item['private'] && ($ret = self::isReshare($item["body"]))) {
|
if (($item['private'] != Item::PRIVATE) && ($ret = self::isReshare($item["body"]))) {
|
||||||
$message = ["author" => $myaddr,
|
$message = ["author" => $myaddr,
|
||||||
"guid" => $item["guid"],
|
"guid" => $item["guid"],
|
||||||
"created_at" => $created,
|
"created_at" => $created,
|
||||||
|
@ -4135,8 +4135,7 @@ class Diaspora
|
||||||
$dob = DateTimeFormat::utc($year . '-' . $month . '-'. $day, 'Y-m-d');
|
$dob = DateTimeFormat::utc($year . '-' . $month . '-'. $day, 'Y-m-d');
|
||||||
}
|
}
|
||||||
|
|
||||||
$about = $profile['about'];
|
$about = BBCode::toMarkdown($profile['about']);
|
||||||
$about = strip_tags(BBCode::convert($about));
|
|
||||||
|
|
||||||
$location = Profile::formatLocation($profile);
|
$location = Profile::formatLocation($profile);
|
||||||
$tags = '';
|
$tags = '';
|
||||||
|
|
|
@ -220,7 +220,7 @@ class Feed {
|
||||||
$header["wall"] = 0;
|
$header["wall"] = 0;
|
||||||
$header["origin"] = 0;
|
$header["origin"] = 0;
|
||||||
$header["gravity"] = GRAVITY_PARENT;
|
$header["gravity"] = GRAVITY_PARENT;
|
||||||
$header["private"] = 2;
|
$header["private"] = Item::PUBLIC;
|
||||||
$header["verb"] = Activity::POST;
|
$header["verb"] = Activity::POST;
|
||||||
$header["object-type"] = Activity\ObjectType::NOTE;
|
$header["object-type"] = Activity\ObjectType::NOTE;
|
||||||
|
|
||||||
|
|
|
@ -1682,7 +1682,7 @@ class OStatus
|
||||||
|
|
||||||
$entry = self::entryHeader($doc, $owner, $item, $toplevel);
|
$entry = self::entryHeader($doc, $owner, $item, $toplevel);
|
||||||
|
|
||||||
$condition = ['uid' => $owner["uid"], 'guid' => $repeated_guid, 'private' => false,
|
$condition = ['uid' => $owner["uid"], 'guid' => $repeated_guid, 'private' => [Item::PUBLIC, Item::UNLISTED],
|
||||||
'network' => [Protocol::DFRN, Protocol::DIASPORA, Protocol::OSTATUS]];
|
'network' => [Protocol::DFRN, Protocol::DIASPORA, Protocol::OSTATUS]];
|
||||||
$repeated_item = Item::selectFirst([], $condition);
|
$repeated_item = Item::selectFirst([], $condition);
|
||||||
if (!DBA::isResult($repeated_item)) {
|
if (!DBA::isResult($repeated_item)) {
|
||||||
|
@ -1827,7 +1827,7 @@ class OStatus
|
||||||
{
|
{
|
||||||
$item["id"] = $item["parent"] = 0;
|
$item["id"] = $item["parent"] = 0;
|
||||||
$item["created"] = $item["edited"] = date("c");
|
$item["created"] = $item["edited"] = date("c");
|
||||||
$item["private"] = true;
|
$item["private"] = Item::PRIVATE;
|
||||||
|
|
||||||
$contact = Probe::uri($item['follow']);
|
$contact = Probe::uri($item['follow']);
|
||||||
|
|
||||||
|
@ -2120,7 +2120,7 @@ class OStatus
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!$item["private"] && !$feed_mode) {
|
if (($item['private'] != Item::PRIVATE) && !$feed_mode) {
|
||||||
XML::addElement($doc, $entry, "link", "", ["rel" => "ostatus:attention",
|
XML::addElement($doc, $entry, "link", "", ["rel" => "ostatus:attention",
|
||||||
"href" => "http://activityschema.org/collection/public"]);
|
"href" => "http://activityschema.org/collection/public"]);
|
||||||
XML::addElement($doc, $entry, "link", "", ["rel" => "mentioned",
|
XML::addElement($doc, $entry, "link", "", ["rel" => "mentioned",
|
||||||
|
@ -2212,8 +2212,8 @@ class OStatus
|
||||||
$authorid = Contact::getIdForURL($owner["url"], 0, true);
|
$authorid = Contact::getIdForURL($owner["url"], 0, true);
|
||||||
|
|
||||||
$condition = ["`uid` = ? AND `received` > ? AND NOT `deleted`
|
$condition = ["`uid` = ? AND `received` > ? AND NOT `deleted`
|
||||||
AND NOT `private` AND `visible` AND `wall` AND `parent-network` IN (?, ?)",
|
AND `private` != ? AND `visible` AND `wall` AND `parent-network` IN (?, ?)",
|
||||||
$owner["uid"], $check_date, Protocol::OSTATUS, Protocol::DFRN];
|
$owner["uid"], $check_date, Item::PRIVATE, Protocol::OSTATUS, Protocol::DFRN];
|
||||||
|
|
||||||
if ($filter === 'comments') {
|
if ($filter === 'comments') {
|
||||||
$condition[0] .= " AND `object-type` = ? ";
|
$condition[0] .= " AND `object-type` = ? ";
|
||||||
|
|
|
@ -23,9 +23,9 @@ namespace Friendica\Repository;
|
||||||
|
|
||||||
use Exception;
|
use Exception;
|
||||||
use Friendica\BaseRepository;
|
use Friendica\BaseRepository;
|
||||||
|
use Friendica\Collection;
|
||||||
use Friendica\Core\Hook;
|
use Friendica\Core\Hook;
|
||||||
use Friendica\Model;
|
use Friendica\Model;
|
||||||
use Friendica\Collection;
|
|
||||||
use Friendica\Network\HTTPException\InternalServerErrorException;
|
use Friendica\Network\HTTPException\InternalServerErrorException;
|
||||||
use Friendica\Network\HTTPException\NotFoundException;
|
use Friendica\Network\HTTPException\NotFoundException;
|
||||||
use Friendica\Util\DateTimeFormat;
|
use Friendica\Util\DateTimeFormat;
|
||||||
|
@ -61,14 +61,17 @@ class Notify extends BaseRepository
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {@inheritDoc}
|
* Return one notify instance based on ID / UID
|
||||||
|
*
|
||||||
|
* @param int $id The ID of the notify instance
|
||||||
|
* @param int $uid The user ID, bound to this notify instance (= security check)
|
||||||
*
|
*
|
||||||
* @return Model\Notify
|
* @return Model\Notify
|
||||||
* @throws NotFoundException
|
* @throws NotFoundException
|
||||||
*/
|
*/
|
||||||
public function getByID(int $id)
|
public function getByID(int $id, int $uid)
|
||||||
{
|
{
|
||||||
return $this->selectFirst(['id' => $id, 'uid' => local_user()]);
|
return $this->selectFirst(['id' => $id, 'uid' => $uid]);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -122,7 +122,9 @@ class JsonLD
|
||||||
'ostatus' => (object)['@id' => 'http://ostatus.org#', '@type' => '@id'],
|
'ostatus' => (object)['@id' => 'http://ostatus.org#', '@type' => '@id'],
|
||||||
'dc' => (object)['@id' => 'http://purl.org/dc/terms/', '@type' => '@id'],
|
'dc' => (object)['@id' => 'http://purl.org/dc/terms/', '@type' => '@id'],
|
||||||
'toot' => (object)['@id' => 'http://joinmastodon.org/ns#', '@type' => '@id'],
|
'toot' => (object)['@id' => 'http://joinmastodon.org/ns#', '@type' => '@id'],
|
||||||
'litepub' => (object)['@id' => 'http://litepub.social/ns#', '@type' => '@id']];
|
'litepub' => (object)['@id' => 'http://litepub.social/ns#', '@type' => '@id'],
|
||||||
|
'sc' => (object)['@id' => 'http://schema.org#', '@type' => '@id'],
|
||||||
|
'pt' => (object)['@id' => 'https://joinpeertube.org/ns#', '@type' => '@id']];
|
||||||
|
|
||||||
// Preparation for adding possibly missing content to the context
|
// Preparation for adding possibly missing content to the context
|
||||||
if (!empty($json['@context']) && is_string($json['@context'])) {
|
if (!empty($json['@context']) && is_string($json['@context'])) {
|
||||||
|
|
|
@ -107,6 +107,7 @@ class DBClean {
|
||||||
Logger::log("found global item orphans: ".$count);
|
Logger::log("found global item orphans: ".$count);
|
||||||
while ($orphan = DBA::fetch($r)) {
|
while ($orphan = DBA::fetch($r)) {
|
||||||
$last_id = $orphan["id"];
|
$last_id = $orphan["id"];
|
||||||
|
Logger::notice('Delete global orphan item', ['id' => $orphan["id"]]);
|
||||||
DBA::delete('item', ['id' => $orphan["id"]]);
|
DBA::delete('item', ['id' => $orphan["id"]]);
|
||||||
}
|
}
|
||||||
Worker::add(PRIORITY_MEDIUM, 'DBClean', 1, $last_id);
|
Worker::add(PRIORITY_MEDIUM, 'DBClean', 1, $last_id);
|
||||||
|
@ -129,6 +130,7 @@ class DBClean {
|
||||||
Logger::log("found item orphans without parents: ".$count);
|
Logger::log("found item orphans without parents: ".$count);
|
||||||
while ($orphan = DBA::fetch($r)) {
|
while ($orphan = DBA::fetch($r)) {
|
||||||
$last_id = $orphan["id"];
|
$last_id = $orphan["id"];
|
||||||
|
Logger::notice('Delete orphan item', ['id' => $orphan["id"]]);
|
||||||
DBA::delete('item', ['id' => $orphan["id"]]);
|
DBA::delete('item', ['id' => $orphan["id"]]);
|
||||||
}
|
}
|
||||||
Worker::add(PRIORITY_MEDIUM, 'DBClean', 2, $last_id);
|
Worker::add(PRIORITY_MEDIUM, 'DBClean', 2, $last_id);
|
||||||
|
@ -326,6 +328,7 @@ class DBClean {
|
||||||
Logger::log("found global item entries from expired threads: ".$count);
|
Logger::log("found global item entries from expired threads: ".$count);
|
||||||
while ($orphan = DBA::fetch($r)) {
|
while ($orphan = DBA::fetch($r)) {
|
||||||
$last_id = $orphan["id"];
|
$last_id = $orphan["id"];
|
||||||
|
Logger::notice('Delete expired thread item', ['id' => $orphan["id"]]);
|
||||||
DBA::delete('item', ['id' => $orphan["id"]]);
|
DBA::delete('item', ['id' => $orphan["id"]]);
|
||||||
}
|
}
|
||||||
Worker::add(PRIORITY_MEDIUM, 'DBClean', 9, $last_id);
|
Worker::add(PRIORITY_MEDIUM, 'DBClean', 9, $last_id);
|
||||||
|
|
|
@ -176,7 +176,7 @@ class Delivery
|
||||||
&& empty($parent['allow_gid'])
|
&& empty($parent['allow_gid'])
|
||||||
&& empty($parent['deny_cid'])
|
&& empty($parent['deny_cid'])
|
||||||
&& empty($parent['deny_gid'])
|
&& empty($parent['deny_gid'])
|
||||||
&& !$parent["private"]) {
|
&& ($parent["private"] != Model\Item::PRIVATE)) {
|
||||||
$public_message = true;
|
$public_message = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -45,6 +45,7 @@ class Expire
|
||||||
$condition = ["`deleted` AND `changed` < UTC_TIMESTAMP() - INTERVAL 60 DAY"];
|
$condition = ["`deleted` AND `changed` < UTC_TIMESTAMP() - INTERVAL 60 DAY"];
|
||||||
$rows = DBA::select('item', ['id'], $condition);
|
$rows = DBA::select('item', ['id'], $condition);
|
||||||
while ($row = DBA::fetch($rows)) {
|
while ($row = DBA::fetch($rows)) {
|
||||||
|
Logger::notice('Delete expired item', ['id' => $row["id"]]);
|
||||||
DBA::delete('item', ['id' => $row['id']]);
|
DBA::delete('item', ['id' => $row['id']]);
|
||||||
}
|
}
|
||||||
DBA::close($rows);
|
DBA::close($rows);
|
||||||
|
|
|
@ -151,6 +151,8 @@ class Notifier
|
||||||
// If this is a public conversation, notify the feed hub
|
// If this is a public conversation, notify the feed hub
|
||||||
$public_message = true;
|
$public_message = true;
|
||||||
|
|
||||||
|
$unlisted = false;
|
||||||
|
|
||||||
// Do a PuSH
|
// Do a PuSH
|
||||||
$push_notify = false;
|
$push_notify = false;
|
||||||
|
|
||||||
|
@ -183,6 +185,8 @@ class Notifier
|
||||||
Logger::info('Threaded comment', ['diaspora_delivery' => (int)$diaspora_delivery]);
|
Logger::info('Threaded comment', ['diaspora_delivery' => (int)$diaspora_delivery]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$unlisted = $target_item['private'] == Item::UNLISTED;
|
||||||
|
|
||||||
// This is IMPORTANT!!!!
|
// This is IMPORTANT!!!!
|
||||||
|
|
||||||
// We will only send a "notify owner to relay" or followup message if the referenced post
|
// We will only send a "notify owner to relay" or followup message if the referenced post
|
||||||
|
@ -245,8 +249,7 @@ class Notifier
|
||||||
|
|
||||||
Logger::info('Followup', ['target' => $target_id, 'guid' => $target_item['guid'], 'to' => $parent['contact-id']]);
|
Logger::info('Followup', ['target' => $target_id, 'guid' => $target_item['guid'], 'to' => $parent['contact-id']]);
|
||||||
|
|
||||||
//if (!$target_item['private'] && $target_item['wall'] &&
|
if (($target_item['private'] != Item::PRIVATE) &&
|
||||||
if (!$target_item['private'] &&
|
|
||||||
(strlen($target_item['allow_cid'].$target_item['allow_gid'].
|
(strlen($target_item['allow_cid'].$target_item['allow_gid'].
|
||||||
$target_item['deny_cid'].$target_item['deny_gid']) == 0))
|
$target_item['deny_cid'].$target_item['deny_gid']) == 0))
|
||||||
$push_notify = true;
|
$push_notify = true;
|
||||||
|
@ -410,7 +413,7 @@ class Notifier
|
||||||
if ($public_message && !in_array($cmd, [Delivery::MAIL, Delivery::SUGGESTION]) && !$followup) {
|
if ($public_message && !in_array($cmd, [Delivery::MAIL, Delivery::SUGGESTION]) && !$followup) {
|
||||||
$relay_list = [];
|
$relay_list = [];
|
||||||
|
|
||||||
if ($diaspora_delivery) {
|
if ($diaspora_delivery && !$unlisted) {
|
||||||
$batch_delivery = true;
|
$batch_delivery = true;
|
||||||
|
|
||||||
$relay_list_stmt = DBA::p(
|
$relay_list_stmt = DBA::p(
|
||||||
|
|
|
@ -657,11 +657,11 @@ class OnePoll
|
||||||
$datarray['owner-avatar'] = $contact['photo'];
|
$datarray['owner-avatar'] = $contact['photo'];
|
||||||
|
|
||||||
if ($datarray['parent-uri'] === $datarray['uri']) {
|
if ($datarray['parent-uri'] === $datarray['uri']) {
|
||||||
$datarray['private'] = 1;
|
$datarray['private'] = Item::PRIVATE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!DI::pConfig()->get($importer_uid, 'system', 'allow_public_email_replies')) {
|
if (!DI::pConfig()->get($importer_uid, 'system', 'allow_public_email_replies')) {
|
||||||
$datarray['private'] = 1;
|
$datarray['private'] = Item::PRIVATE;
|
||||||
$datarray['allow_cid'] = '<' . $contact['id'] . '>';
|
$datarray['allow_cid'] = '<' . $contact['id'] . '>';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -21,6 +21,7 @@
|
||||||
|
|
||||||
namespace Friendica\Worker;
|
namespace Friendica\Worker;
|
||||||
|
|
||||||
|
use Friendica\Core\Logger;
|
||||||
use Friendica\Database\DBA;
|
use Friendica\Database\DBA;
|
||||||
use Friendica\Core\Protocol;
|
use Friendica\Core\Protocol;
|
||||||
use Friendica\Model\Item;
|
use Friendica\Model\Item;
|
||||||
|
@ -42,6 +43,7 @@ class RemoveContact {
|
||||||
do {
|
do {
|
||||||
$items = Item::select(['id'], $condition, ['limit' => 100]);
|
$items = Item::select(['id'], $condition, ['limit' => 100]);
|
||||||
while ($item = Item::fetch($items)) {
|
while ($item = Item::fetch($items)) {
|
||||||
|
Logger::notice('Delete removed contact item', ['id' => $item["id"]]);
|
||||||
DBA::delete('item', ['id' => $item['id']]);
|
DBA::delete('item', ['id' => $item['id']]);
|
||||||
}
|
}
|
||||||
DBA::close($items);
|
DBA::close($items);
|
||||||
|
|
|
@ -51,7 +51,7 @@
|
||||||
use Friendica\Database\DBA;
|
use Friendica\Database\DBA;
|
||||||
|
|
||||||
if (!defined('DB_UPDATE_VERSION')) {
|
if (!defined('DB_UPDATE_VERSION')) {
|
||||||
define('DB_UPDATE_VERSION', 1333);
|
define('DB_UPDATE_VERSION', 1334);
|
||||||
}
|
}
|
||||||
|
|
||||||
return [
|
return [
|
||||||
|
@ -647,7 +647,7 @@ return [
|
||||||
"extid" => ["type" => "varchar(255)", "not null" => "1", "default" => "", "comment" => ""],
|
"extid" => ["type" => "varchar(255)", "not null" => "1", "default" => "", "comment" => ""],
|
||||||
"post-type" => ["type" => "tinyint unsigned", "not null" => "1", "default" => "0", "comment" => "Post type (personal note, bookmark, ...)"],
|
"post-type" => ["type" => "tinyint unsigned", "not null" => "1", "default" => "0", "comment" => "Post type (personal note, bookmark, ...)"],
|
||||||
"global" => ["type" => "boolean", "not null" => "1", "default" => "0", "comment" => ""],
|
"global" => ["type" => "boolean", "not null" => "1", "default" => "0", "comment" => ""],
|
||||||
"private" => ["type" => "boolean", "not null" => "1", "default" => "0", "comment" => "distribution is restricted"],
|
"private" => ["type" => "tinyint unsigned", "not null" => "1", "default" => "0", "comment" => "0=public, 1=private, 2=unlisted"],
|
||||||
"visible" => ["type" => "boolean", "not null" => "1", "default" => "0", "comment" => ""],
|
"visible" => ["type" => "boolean", "not null" => "1", "default" => "0", "comment" => ""],
|
||||||
"moderated" => ["type" => "boolean", "not null" => "1", "default" => "0", "comment" => ""],
|
"moderated" => ["type" => "boolean", "not null" => "1", "default" => "0", "comment" => ""],
|
||||||
"deleted" => ["type" => "boolean", "not null" => "1", "default" => "0", "comment" => "item has been deleted"],
|
"deleted" => ["type" => "boolean", "not null" => "1", "default" => "0", "comment" => "item has been deleted"],
|
||||||
|
@ -1294,7 +1294,7 @@ return [
|
||||||
"received" => ["type" => "datetime", "not null" => "1", "default" => DBA::NULL_DATETIME, "comment" => ""],
|
"received" => ["type" => "datetime", "not null" => "1", "default" => DBA::NULL_DATETIME, "comment" => ""],
|
||||||
"changed" => ["type" => "datetime", "not null" => "1", "default" => DBA::NULL_DATETIME, "comment" => ""],
|
"changed" => ["type" => "datetime", "not null" => "1", "default" => DBA::NULL_DATETIME, "comment" => ""],
|
||||||
"wall" => ["type" => "boolean", "not null" => "1", "default" => "0", "comment" => ""],
|
"wall" => ["type" => "boolean", "not null" => "1", "default" => "0", "comment" => ""],
|
||||||
"private" => ["type" => "boolean", "not null" => "1", "default" => "0", "comment" => ""],
|
"private" => ["type" => "tinyint unsigned", "not null" => "1", "default" => "0", "comment" => "0=public, 1=private, 2=unlisted"],
|
||||||
"pubmail" => ["type" => "boolean", "not null" => "1", "default" => "0", "comment" => ""],
|
"pubmail" => ["type" => "boolean", "not null" => "1", "default" => "0", "comment" => ""],
|
||||||
"moderated" => ["type" => "boolean", "not null" => "1", "default" => "0", "comment" => ""],
|
"moderated" => ["type" => "boolean", "not null" => "1", "default" => "0", "comment" => ""],
|
||||||
"visible" => ["type" => "boolean", "not null" => "1", "default" => "0", "comment" => ""],
|
"visible" => ["type" => "boolean", "not null" => "1", "default" => "0", "comment" => ""],
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
<p>I recently released a PHP package that makes executing commands over SSH super simple. You can also upload/download files via SCP.</p><p><a href="https://github.com/DivineOmega/php-ssh-connection" rel="nofollow noopener" target="_blank"><span class="invisible">https://</span><span class="ellipsis">github.com/DivineOmega/php-ssh</span><span class="invisible">-connection</span></a></p><p><a href="https://mastodon.xyz/tags/php" class="mention hashtag" rel="tag">#<span>php</span></a> <a href="https://mastodon.xyz/tags/opensource" class="mention hashtag" rel="tag">#<span>opensource</span></a> <a href="https://mastodon.xyz/tags/webdev" class="mention hashtag" rel="tag">#<span>webdev</span></a> <a href="https://mastodon.xyz/tags/ssh" class="mention hashtag" rel="tag">#<span>ssh</span></a> <a href="https://mastodon.xyz/tags/devops" class="mention hashtag" rel="tag">#<span>DevOps</span></a></p>
|
<p>I recently released a PHP package that makes executing commands over SSH super simple. You can also upload/download files via SCP.</p><p><a href="https://github.com/DivineOmega/php-ssh-connection" target="_blank" rel="noopener noreferrer"><span class="invisible">https://</span><span class="ellipsis">github.com/DivineOmega/php-ssh</span><span class="invisible">-connection</span></a></p><p><a href="https://mastodon.xyz/tags/php" class="mention hashtag" rel="tag">#<span>php</span></a> <a href="https://mastodon.xyz/tags/opensource" class="mention hashtag" rel="tag">#<span>opensource</span></a> <a href="https://mastodon.xyz/tags/webdev" class="mention hashtag" rel="tag">#<span>webdev</span></a> <a href="https://mastodon.xyz/tags/ssh" class="mention hashtag" rel="tag">#<span>ssh</span></a> <a href="https://mastodon.xyz/tags/devops" class="mention hashtag" rel="tag">#<span>DevOps</span></a></p>
|
|
@ -164,7 +164,7 @@ class BBCodeTest extends MockedTest
|
||||||
public function testAutoLinking($data, $assertHTML)
|
public function testAutoLinking($data, $assertHTML)
|
||||||
{
|
{
|
||||||
$output = BBCode::convert($data);
|
$output = BBCode::convert($data);
|
||||||
$assert = '<a href="' . $data . '" target="_blank">' . $data . '</a>';
|
$assert = '<a href="' . $data . '" target="_blank" rel="noopener noreferrer">' . $data . '</a>';
|
||||||
if ($assertHTML) {
|
if ($assertHTML) {
|
||||||
$this->assertEquals($assert, $output);
|
$this->assertEquals($assert, $output);
|
||||||
} else {
|
} else {
|
||||||
|
@ -176,21 +176,21 @@ class BBCodeTest extends MockedTest
|
||||||
{
|
{
|
||||||
return [
|
return [
|
||||||
'bug-7271-condensed-space' => [
|
'bug-7271-condensed-space' => [
|
||||||
'expectedHtml' => '<ul class="listdecimal" style="list-style-type: decimal;"><li> <a href="http://example.com/" target="_blank">http://example.com/</a></li></ul>',
|
'expectedHtml' => '<ul class="listdecimal" style="list-style-type: decimal;"><li> <a href="http://example.com/" target="_blank" rel="noopener noreferrer">http://example.com/</a></li></ul>',
|
||||||
'text' => '[ol][*] http://example.com/[/ol]',
|
'text' => '[ol][*] http://example.com/[/ol]',
|
||||||
],
|
],
|
||||||
'bug-7271-condensed-nospace' => [
|
'bug-7271-condensed-nospace' => [
|
||||||
'expectedHtml' => '<ul class="listdecimal" style="list-style-type: decimal;"><li><a href="http://example.com/" target="_blank">http://example.com/</a></li></ul>',
|
'expectedHtml' => '<ul class="listdecimal" style="list-style-type: decimal;"><li><a href="http://example.com/" target="_blank" rel="noopener noreferrer">http://example.com/</a></li></ul>',
|
||||||
'text' => '[ol][*]http://example.com/[/ol]',
|
'text' => '[ol][*]http://example.com/[/ol]',
|
||||||
],
|
],
|
||||||
'bug-7271-indented-space' => [
|
'bug-7271-indented-space' => [
|
||||||
'expectedHtml' => '<ul class="listbullet" style="list-style-type: circle;"><li> <a href="http://example.com/" target="_blank">http://example.com/</a></li></ul>',
|
'expectedHtml' => '<ul class="listbullet" style="list-style-type: circle;"><li> <a href="http://example.com/" target="_blank" rel="noopener noreferrer">http://example.com/</a></li></ul>',
|
||||||
'text' => '[ul]
|
'text' => '[ul]
|
||||||
[*] http://example.com/
|
[*] http://example.com/
|
||||||
[/ul]',
|
[/ul]',
|
||||||
],
|
],
|
||||||
'bug-7271-indented-nospace' => [
|
'bug-7271-indented-nospace' => [
|
||||||
'expectedHtml' => '<ul class="listbullet" style="list-style-type: circle;"><li><a href="http://example.com/" target="_blank">http://example.com/</a></li></ul>',
|
'expectedHtml' => '<ul class="listbullet" style="list-style-type: circle;"><li><a href="http://example.com/" target="_blank" rel="noopener noreferrer">http://example.com/</a></li></ul>',
|
||||||
'text' => '[ul]
|
'text' => '[ul]
|
||||||
[*]http://example.com/
|
[*]http://example.com/
|
||||||
[/ul]',
|
[/ul]',
|
||||||
|
|
|
@ -35,8 +35,8 @@
|
||||||
<td class="email">{{$u.email}}</td>
|
<td class="email">{{$u.email}}</td>
|
||||||
<td class="checkbox"><input type="checkbox" class="pending_ckbx" id="id_pending_{{$u.hash}}" name="pending[]" value="{{$u.hash}}" /></td>
|
<td class="checkbox"><input type="checkbox" class="pending_ckbx" id="id_pending_{{$u.hash}}" name="pending[]" value="{{$u.hash}}" /></td>
|
||||||
<td class="tools">
|
<td class="tools">
|
||||||
<a href="{{$baseurl}}/regmod/allow/{{$u.hash}}" title='{{$approve}}'><span class='icon like'></span></a>
|
<a href="{{$baseurl}}/admin/users/allow/{{$u.uid}}?t={{$form_security_token}}" title='{{$approve}}'><span class='icon like'></span></a>
|
||||||
<a href="{{$baseurl}}/regmod/deny/{{$u.hash}}" title='{{$deny}}'><span class='icon dislike'></span></a>
|
<a href="{{$baseurl}}/admin/users/deny/{{$u.uid}}?t={{$form_security_token}}" title='{{$deny}}'><span class='icon dislike'></span></a>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
|
|
||||||
{{if $event.item.author_name}}<a href="{{$event.item.author_link}}" ><img src="{{$event.item.author_avatar}}" height="32" width="32" />{{$event.item.author_name}}</a>{{/if}}
|
{{if $event.item.author_name}}<a href="{{$event.item.author_link}}" ><img src="{{$event.item.author_avatar}}" height="32" width="32" />{{$event.item.author_name}}</a>{{/if}}
|
||||||
{{$event.html nofilter}}
|
{{$event.html nofilter}}
|
||||||
{{if $event.item.plink}}<a href="{{$event.plink.0}}" title="{{$event.plink.1}}" target="_blank" class="plink-event-link icon s22 remote-link"></a>{{/if}}
|
{{if $event.item.plink}}<a href="{{$event.plink.0}}" title="{{$event.plink.1}}" target="_blank" rel="noopener noreferrer" class="plink-event-link icon s22 remote-link"></a>{{/if}}
|
||||||
{{if $event.edit}}<a href="{{$event.edit.0}}" title="{{$event.edit.1}}" class="edit-event-link icon s22 pencil"></a>{{/if}}
|
{{if $event.edit}}<a href="{{$event.edit.0}}" title="{{$event.edit.1}}" class="edit-event-link icon s22 pencil"></a>{{/if}}
|
||||||
{{if $event.copy}}<a href="{{$event.copy.0}}" title="{{$event.copy.1}}" class="copy-event-link icon s22 copy"></a>{{/if}}
|
{{if $event.copy}}<a href="{{$event.copy.0}}" title="{{$event.copy.1}}" class="copy-event-link icon s22 copy"></a>{{/if}}
|
||||||
{{if $event.drop}}<a href="{{$event.drop.0}}" onclick="return confirmDelete();" title="{{$event.drop.1}}" class="drop-event-link icon s22 delete"></a>{{/if}}
|
{{if $event.drop}}<a href="{{$event.drop.0}}" onclick="return confirmDelete();" title="{{$event.drop.1}}" class="drop-event-link icon s22 delete"></a>{{/if}}
|
||||||
|
|
|
@ -17,7 +17,7 @@
|
||||||
{{if $event.is_first}}<hr /><a name="link-{{$event.j}}" ><div class="event-list-date">{{$event.d}}</div></a>{{/if}}
|
{{if $event.is_first}}<hr /><a name="link-{{$event.j}}" ><div class="event-list-date">{{$event.d}}</div></a>{{/if}}
|
||||||
{{if $event.item.author_name}}<a href="{{$event.item.author_link}}" ><img src="{{$event.item.author_avatar}}" height="32" width="32" />{{$event.item.author_name}}</a>{{/if}}
|
{{if $event.item.author_name}}<a href="{{$event.item.author_link}}" ><img src="{{$event.item.author_avatar}}" height="32" width="32" />{{$event.item.author_name}}</a>{{/if}}
|
||||||
{{$event.html nofilter}}
|
{{$event.html nofilter}}
|
||||||
{{if $event.item.plink}}<a href="{{$event.plink.0}}" title="{{$event.plink.1}}" target="_blank" class="plink-event-link icon s22 remote-link"></a>{{/if}}
|
{{if $event.item.plink}}<a href="{{$event.plink.0}}" title="{{$event.plink.1}}" target="_blank" rel="noopener noreferrer" class="plink-event-link icon s22 remote-link"></a>{{/if}}
|
||||||
{{if $event.edit}}<a href="{{$event.edit.0}}" title="{{$event.edit.1}}" class="edit-event-link icon s22 pencil"></a>{{/if}}
|
{{if $event.edit}}<a href="{{$event.edit.0}}" title="{{$event.edit.1}}" class="edit-event-link icon s22 pencil"></a>{{/if}}
|
||||||
</div>
|
</div>
|
||||||
<div class="clear"></div>
|
<div class="clear"></div>
|
||||||
|
|
|
@ -1,8 +1,5 @@
|
||||||
<h3 id="photo-album-title">{{$album}}</h3>
|
<h3 id="photo-album-title">{{$album}}</h3>
|
||||||
|
|
||||||
{{if $edit}}
|
|
||||||
<div id="album-edit-link"><a href="{{$edit.1}}" title="{{$edit.0}}">{{$edit.0}}</a></div>
|
|
||||||
{{/if}}
|
|
||||||
{{if $edit}}
|
{{if $edit}}
|
||||||
<div id="album-edit-link"><a href="{{$edit.1}}" title="{{$edit.0}}">{{$edit.0}}</a></div>
|
<div id="album-edit-link"><a href="{{$edit.1}}" title="{{$edit.0}}">{{$edit.0}}</a></div>
|
||||||
{{/if}}
|
{{/if}}
|
||||||
|
|
|
@ -41,7 +41,7 @@
|
||||||
|
|
||||||
{{if $updated}}<div class="updated" style="display:none;">{{$updated}}</div>{{/if}}
|
{{if $updated}}<div class="updated" style="display:none;">{{$updated}}</div>{{/if}}
|
||||||
|
|
||||||
{{if $homepage}}<dl class="homepage"><dt class="homepage-label">{{$homepage}}</dt><dd class="homepage-url u-url"><a href="{{$profile.homepage}}" rel="me" target="_blank">{{$profile.homepage}}</a></dd></dl>{{/if}}
|
{{if $homepage}}<dl class="homepage"><dt class="homepage-label">{{$homepage}}</dt><dd class="homepage-url u-url"><a href="{{$profile.homepage}}" rel="me" target="_blank" rel="noopener noreferrer">{{$profile.homepage}}</a></dd></dl>{{/if}}
|
||||||
|
|
||||||
{{if $about}}<dl class="about"><dt class="about-label">{{$about}}</dt><dd class="x-network">{{$profile.about nofilter}}</dd></dl>{{/if}}
|
{{if $about}}<dl class="about"><dt class="about-label">{{$about}}</dt><dd class="x-network">{{$profile.about nofilter}}</dd></dl>{{/if}}
|
||||||
|
|
||||||
|
|
|
@ -53,6 +53,8 @@
|
||||||
|
|
||||||
{{$hide_wall nofilter}}
|
{{$hide_wall nofilter}}
|
||||||
|
|
||||||
|
{{$unlisted nofilter}}
|
||||||
|
|
||||||
{{$blockwall nofilter}}
|
{{$blockwall nofilter}}
|
||||||
|
|
||||||
{{$blocktags nofilter}}
|
{{$blocktags nofilter}}
|
||||||
|
|
|
@ -1,12 +1,12 @@
|
||||||
<div class="shared-wrapper">
|
<div class="shared-wrapper">
|
||||||
<div class="shared_header">
|
<div class="shared_header">
|
||||||
{{if $avatar}}
|
{{if $avatar}}
|
||||||
<a href="{{$profile}}" target="_blank" class="shared-userinfo">
|
<a href="{{$profile}}" target="_blank" rel="noopener noreferrer" class="shared-userinfo">
|
||||||
<img src="{{$avatar}}" height="32" width="32">
|
<img src="{{$avatar}}" height="32" width="32">
|
||||||
</a>
|
</a>
|
||||||
{{/if}}
|
{{/if}}
|
||||||
<div><a href="{{$profile}}" target="_blank" class="shared-wall-item-name"><span class="shared-author">{{$author}}</span></a></div>
|
<div><a href="{{$profile}}" target="_blank" rel="noopener noreferrer" class="shared-wall-item-name"><span class="shared-author">{{$author}}</span></a></div>
|
||||||
<div class="shared-wall-item-ago"><small><a href="{{$link}}" target="_blank"><span class="shared-time">{{$posted}}</a></a></small></div>
|
<div class="shared-wall-item-ago"><small><a href="{{$link}}" target="_blank" rel="noopener noreferrer"><span class="shared-time">{{$posted}}</a></a></small></div>
|
||||||
</div>
|
</div>
|
||||||
<blockquote class="shared_content">{{$content nofilter}}</blockquote>
|
<blockquote class="shared_content">{{$content nofilter}}</blockquote>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -84,10 +84,10 @@
|
||||||
</div>
|
</div>
|
||||||
{{/if}}
|
{{/if}}
|
||||||
{{if $item.remote_comment}}
|
{{if $item.remote_comment}}
|
||||||
<div class="wall-item-links-wrapper"><a href="{{$item.remote_comment.2}}" title="{{$item.remote_comment.0}}" target="_blank" class="icon remote-link{{$item.sparkle}} u-url"></a></div>
|
<div class="wall-item-links-wrapper"><a href="{{$item.remote_comment.2}}" title="{{$item.remote_comment.0}}" target="_blank" rel="noopener noreferrer" class="icon remote-link{{$item.sparkle}} u-url"></a></div>
|
||||||
{{/if}}
|
{{/if}}
|
||||||
{{if $item.plink}}
|
{{if $item.plink}}
|
||||||
<div class="wall-item-links-wrapper"><a href="{{$item.plink.href}}" title="{{$item.plink.title}}" target="_blank" class="icon remote-link{{$item.sparkle}} u-url"></a></div>
|
<div class="wall-item-links-wrapper"><a href="{{$item.plink.href}}" title="{{$item.plink.title}}" target="_blank" rel="noopener noreferrer" class="icon remote-link{{$item.sparkle}} u-url"></a></div>
|
||||||
{{/if}}
|
{{/if}}
|
||||||
{{if $item.edpost}}
|
{{if $item.edpost}}
|
||||||
<a class="editpost icon pencil" href="{{$item.edpost.0}}" title="{{$item.edpost.1}}"></a>
|
<a class="editpost icon pencil" href="{{$item.edpost.0}}" title="{{$item.edpost.1}}"></a>
|
||||||
|
|
|
@ -24,7 +24,7 @@ function showHideForumlist() {
|
||||||
{{if $forum.id <= $visible_forums}}
|
{{if $forum.id <= $visible_forums}}
|
||||||
<li class="forum-widget-entry forum-{{$forum.cid}}" id="forum-widget-entry-{{$forum.id}}" role="menuitem">
|
<li class="forum-widget-entry forum-{{$forum.cid}}" id="forum-widget-entry-{{$forum.id}}" role="menuitem">
|
||||||
<span class="notify badge pull-right"></span>
|
<span class="notify badge pull-right"></span>
|
||||||
<a href="{{$forum.external_url}}" title="{{$forum.link_desc}}" class="label sparkle" target="_blank">
|
<a href="{{$forum.external_url}}" title="{{$forum.link_desc}}" class="label sparkle" target="_blank" rel="noopener noreferrer">
|
||||||
<img class="forumlist-img" src="{{$forum.micro}}" alt="{{$forum.link_desc}}" />
|
<img class="forumlist-img" src="{{$forum.micro}}" alt="{{$forum.link_desc}}" />
|
||||||
</a>
|
</a>
|
||||||
<a class="forum-widget-link {{if $forum.selected}}forum-selected{{/if}}" id="forum-widget-link-{{$forum.id}}" href="{{$forum.url}}" >{{$forum.name}}</a>
|
<a class="forum-widget-link {{if $forum.selected}}forum-selected{{/if}}" id="forum-widget-link-{{$forum.id}}" href="{{$forum.url}}" >{{$forum.name}}</a>
|
||||||
|
@ -34,7 +34,7 @@ function showHideForumlist() {
|
||||||
{{if $forum.id > $visible_forums}}
|
{{if $forum.id > $visible_forums}}
|
||||||
<li class="forum-widget-entry forum-{{$forum.cid}}" id="forum-widget-entry-extended-{{$forum.id}}" role="menuitem" style="display: none;">
|
<li class="forum-widget-entry forum-{{$forum.cid}}" id="forum-widget-entry-extended-{{$forum.id}}" role="menuitem" style="display: none;">
|
||||||
<span class="notify badge pull-right"></span>
|
<span class="notify badge pull-right"></span>
|
||||||
<a href="{{$forum.external_url}}" title="{{$forum.link_desc}}" class="label sparkle" target="_blank">
|
<a href="{{$forum.external_url}}" title="{{$forum.link_desc}}" class="label sparkle" target="_blank" rel="noopener noreferrer">
|
||||||
<img class="forumlist-img" src="{{$forum.micro}}" alt="{{$forum.link_desc}}" />
|
<img class="forumlist-img" src="{{$forum.micro}}" alt="{{$forum.link_desc}}" />
|
||||||
</a>
|
</a>
|
||||||
<a class="forum-widget-link {{if $forum.selected}}forum-selected{{/if}}" id="forum-widget-link-{{$forum.id}}" href="{{$forum.url}}" >{{$forum.name}}</a>
|
<a class="forum-widget-link {{if $forum.selected}}forum-selected{{/if}}" id="forum-widget-link-{{$forum.id}}" href="{{$forum.url}}" >{{$forum.name}}</a>
|
||||||
|
|
|
@ -49,8 +49,8 @@
|
||||||
<td>{{$u.name}}</td>
|
<td>{{$u.name}}</td>
|
||||||
<td>{{$u.email}}</td>
|
<td>{{$u.email}}</td>
|
||||||
<td>
|
<td>
|
||||||
<a href="{{$baseurl}}/regmod/allow/{{$u.hash}}" class="admin-settings-action-link" title="{{$approve}}"><i class="fa fa-check" aria-hidden="true"></i></a>
|
<a href="{{$baseurl}}/admin/users/allow/{{$u.uid}}?t={{$form_security_token}}" class="admin-settings-action-link" title="{{$approve}}"><i class="fa fa-check" aria-hidden="true"></i></a>
|
||||||
<a href="{{$baseurl}}/regmod/deny/{{$u.hash}}" class="admin-settings-action-link" title="{{$deny}}"><i class="fa fa-trash-o" aria-hidden="true"></i></a>
|
<a href="{{$baseurl}}/admin/users/deny/{{$u.uid}}?t={{$form_security_token}}" class="admin-settings-action-link" title="{{$deny}}"><i class="fa fa-trash-o" aria-hidden="true"></i></a>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
{{if $u.note}}
|
{{if $u.note}}
|
||||||
|
|
|
@ -94,7 +94,7 @@
|
||||||
{{if $profile.xmpp}}
|
{{if $profile.xmpp}}
|
||||||
<div class="xmpp">
|
<div class="xmpp">
|
||||||
<span class="xmpp-label icon"><i class="fa fa-comments"></i></span>
|
<span class="xmpp-label icon"><i class="fa fa-comments"></i></span>
|
||||||
<span class="xmpp-data"><a href="xmpp:{{$profile.xmpp}}" rel="me" target="_blank">{{include file="sub/punct_wrap.tpl" text=$profile.xmpp}}</a></span>
|
<span class="xmpp-data"><a href="xmpp:{{$profile.xmpp}}" rel="me" target="_blank" rel="noopener noreferrer">{{include file="sub/punct_wrap.tpl" text=$profile.xmpp}}</a></span>
|
||||||
</div>
|
</div>
|
||||||
{{/if}}
|
{{/if}}
|
||||||
|
|
||||||
|
@ -107,7 +107,7 @@
|
||||||
{{if $homepage}}
|
{{if $homepage}}
|
||||||
<div class="homepage detail">
|
<div class="homepage detail">
|
||||||
<span class="homepage-label icon"><i class="fa fa-external-link-square"></i></span>
|
<span class="homepage-label icon"><i class="fa fa-external-link-square"></i></span>
|
||||||
<span class="homepage-url u-url"><a href="{{$profile.homepage}}" rel="me" target="_blank">{{include file="sub/punct_wrap.tpl" text=$profile.homepage}}</a></span>
|
<span class="homepage-url u-url"><a href="{{$profile.homepage}}" rel="me" target="_blank" rel="noopener noreferrer">{{include file="sub/punct_wrap.tpl" text=$profile.homepage}}</a></span>
|
||||||
</div>
|
</div>
|
||||||
{{/if}}
|
{{/if}}
|
||||||
|
|
||||||
|
|
|
@ -11,65 +11,18 @@
|
||||||
<div class="media">
|
<div class="media">
|
||||||
{{* Put additional actions in a top-right dropdown menu *}}
|
{{* Put additional actions in a top-right dropdown menu *}}
|
||||||
|
|
||||||
<ul class="nav nav-pills preferences">
|
<div class="preferences">
|
||||||
{{if $item.network_icon != ""}}
|
{{if $item.network_icon != ""}}
|
||||||
<li><span class="wall-item-network"><i class="fa fa-{{$item.network_icon}}" title="{{$item.network_name}}" aria-hidden="true"></i></span></li>
|
<span class="wall-item-network"><i class="fa fa-{{$item.network_icon}}" title="{{$item.network_name}}" aria-hidden="true"></i></span>
|
||||||
{{else}}
|
{{else}}
|
||||||
<li><span class="wall-item-network" title="{{$item.app}}">{{$item.network_name}}</span></li>
|
<span class="wall-item-network" title="{{$item.app}}">{{$item.network_name}}</span>
|
||||||
{{/if}}
|
{{/if}}
|
||||||
|
{{if $item.plink}} {{*link to the original source of the item *}}
|
||||||
{{if $item.plink || $item.star || $item.drop.dropping || $item.edpost || $item.subthread}}
|
<a href="{{$item.plink.href}}" class="plink u-url" aria-label="{{$item.plink.title}}" title="{{$item.plink.title}}">
|
||||||
<li class="dropdown">
|
<i class="fa fa-external-link"></i>
|
||||||
<button type="button" class="btn-link dropdown-toggle" data-toggle="dropdown" id="dropdownMenuTools-{{$item.id}}" aria-haspopup="true" aria-expanded="false"><i class="fa fa-angle-down" aria-hidden="true"></i></button>
|
</a>
|
||||||
|
{{/if}}
|
||||||
<ul class="dropdown-menu pull-right" role="menu" aria-labelledby="dropdownMenuTools-{{$item.id}}">
|
</div>
|
||||||
{{if $item.plink}} {{*link to the original source of the item *}}
|
|
||||||
<li role="menuitem">
|
|
||||||
<a title="{{$item.plink.title}}" href="{{$item.plink.href}}" class="navicon plink"><i class="fa fa-external-link" aria-hidden="true"></i> {{$item.plink.title}}</a>
|
|
||||||
</li>
|
|
||||||
{{/if}}
|
|
||||||
|
|
||||||
{{if $item.edpost}} {{* edit the posting *}}
|
|
||||||
<li role="menuitem">
|
|
||||||
<button type="button" href="{{$item.edpost.0}}" title="{{$item.edpost.1}}" class="btn-link navicon pencil"><i class="fa fa-pencil" aria-hidden="true"></i> {{$item.edpost.1}}</button>
|
|
||||||
</li>
|
|
||||||
{{/if}}
|
|
||||||
|
|
||||||
{{if $item.tagger}} {{* tag the post *}}
|
|
||||||
<li role="menuitem">
|
|
||||||
<button type="button" id="tagger-{{$item.id}}" onclick="itemTag({{$item.id}});" class="btn-link {{$item.tagger.class}}" title="{{$item.tagger.add}}"><i class="fa fa-tag" aria-hidden="true"></i> {{$item.tagger.add}}</button>
|
|
||||||
</li>
|
|
||||||
{{/if}}
|
|
||||||
|
|
||||||
{{if $item.filer}}
|
|
||||||
<li role="menuitem">
|
|
||||||
<button type="button" id="filer-{{$item.id}}" onclick="itemFiler({{$item.id}});" class="btn-link filer-item filer-icon" title="{{$item.filer}}"><i class="fa fa-folder" aria-hidden="true"></i> {{$item.filer}}</button>
|
|
||||||
</li>
|
|
||||||
{{/if}}
|
|
||||||
|
|
||||||
{{if $item.star}}
|
|
||||||
<li role="menuitem">
|
|
||||||
<button type="button" id="star-{{$item.id}}" onclick="dostar({{$item.id}});" class="btn-link {{$item.star.classdo}}" title="{{$item.star.do}}"><i class="fa fa-star-o" aria-hidden="true"></i> {{$item.star.do}}</button>
|
|
||||||
<button type="button" id="unstar-{{$item.id}}" onclick="dostar({{$item.id}});" class="btn-link {{$item.star.classundo}}" title="{{$item.star.undo}}"><i class="fa fa-star" aria-hidden="true"></i> {{$item.star.undo}}</button>
|
|
||||||
</li>
|
|
||||||
{{/if}}
|
|
||||||
|
|
||||||
{{if $item.subthread}}
|
|
||||||
<li role="menuitem">
|
|
||||||
<button type="button" id="subthread-{{$item.id}}" onclick="{{$item.subthread.action}}" class="btn-link" title="{{$item.subthread.title}}"><i class="fa fa-plus" aria-hidden="true"></i> {{$item.subthread.title}}</button>
|
|
||||||
</li>
|
|
||||||
{{/if}}
|
|
||||||
|
|
||||||
{{if $item.drop.dropping}}
|
|
||||||
<li role="separator" class="divider"></li>
|
|
||||||
<li role="menuitem">
|
|
||||||
<button type="button" class="btn-link navicon delete" onclick="dropItem('item/drop/{{$item.id}}', 'item-{{$item.guid}}');" title="{{$item.drop.delete}}"><i class="fa fa-trash" aria-hidden="true"></i> {{$item.drop.delete}}</button>
|
|
||||||
</li>
|
|
||||||
{{/if}}
|
|
||||||
</ul>
|
|
||||||
</li>
|
|
||||||
{{/if}}
|
|
||||||
</ul>
|
|
||||||
|
|
||||||
{{* The avatar picture and the photo-menu *}}
|
{{* The avatar picture and the photo-menu *}}
|
||||||
<div class="dropdown pull-left"><!-- Dropdown -->
|
<div class="dropdown pull-left"><!-- Dropdown -->
|
||||||
|
@ -219,7 +172,76 @@
|
||||||
<button type="button" class="btn btn-default" id="share-{{$item.id}}" title="{{$item.vote.share.0}}" onclick="jotShare({{$item.id}});"><i class="fa fa-retweet" aria-hidden="true"></i> {{$item.vote.share.0}}</button>
|
<button type="button" class="btn btn-default" id="share-{{$item.id}}" title="{{$item.vote.share.0}}" onclick="jotShare({{$item.id}});"><i class="fa fa-retweet" aria-hidden="true"></i> {{$item.vote.share.0}}</button>
|
||||||
{{/if}}
|
{{/if}}
|
||||||
{{/if}}
|
{{/if}}
|
||||||
|
|
||||||
|
|
||||||
|
{{* Put additional actions in a dropdown menu *}}
|
||||||
|
{{if $item.edpost || $item.tagger || $item.filer || $item.pin || $item.star || $item.subthread || $item.ignore || $item.drop.dropping}}
|
||||||
|
<span role="presentation" class="separator"></span>
|
||||||
|
<span class="more-links btn-group{{if $item.thread_level > 1}} dropup{{/if}}">
|
||||||
|
<button type="button" class="btn-link dropdown-toggle" data-toggle="dropdown" id="dropdownMenuOptions-{{$item.id}}" aria-haspopup="true" aria-expanded="false" title="{{$item.menu}}"><i class="fa fa-ellipsis-h" aria-hidden="true"></i> {{$item.menu}}</button>
|
||||||
|
<ul class="dropdown-menu dropdown-menu-right" role="menu" aria-labelledby="dropdownMenuOptions-{{$item.id}}">
|
||||||
|
{{if $item.edpost}} {{* edit the posting *}}
|
||||||
|
<li role="menuitem">
|
||||||
|
<a href="javascript:editpost('{{$item.edpost.0}}?mode=none');" title="{{$item.edpost.1}}" class="btn-link navicon pencil"><i class="fa fa-pencil" aria-hidden="true"></i> {{$item.edpost.1}}</a>
|
||||||
|
</li>
|
||||||
|
{{/if}}
|
||||||
|
|
||||||
|
{{if $item.tagger}} {{* tag the post *}}
|
||||||
|
<li role="menuitem">
|
||||||
|
<a id="tagger-{{$item.id}}" href="javascript:itemTag({{$item.id}});" class="btn-link {{$item.tagger.class}}" title="{{$item.tagger.add}}"><i class="fa fa-tag" aria-hidden="true"></i> {{$item.tagger.add}}</a>
|
||||||
|
</li>
|
||||||
|
{{/if}}
|
||||||
|
|
||||||
|
{{if $item.filer}}
|
||||||
|
<li role="menuitem">
|
||||||
|
<a id="filer-{{$item.id}}" href="javascript:itemFiler({{$item.id}});" class="btn-link filer-item filer-icon" title="{{$item.filer}}"><i class="fa fa-folder" aria-hidden="true"></i> {{$item.filer}}</a>
|
||||||
|
</li>
|
||||||
|
{{/if}}
|
||||||
|
|
||||||
|
{{if $item.pin}}
|
||||||
|
<li role="menuitem">
|
||||||
|
<a id="pin-{{$item.id}}" href="javascript:dopin({{$item.id}});" class="btn-link {{$item.pin.classdo}}" title="{{$item.pin.do}}"><i class="fa fa-circle-o" aria-hidden="true"></i> {{$item.pin.do}}</a>
|
||||||
|
<a id="unpin-{{$item.id}}" href="javascript:dopin({{$item.id}});" class="btn-link {{$item.pin.classundo}}" title="{{$item.pin.undo}}"><i class="fa fa-dot-circle-o" aria-hidden="true"></i> {{$item.pin.undo}}</a>
|
||||||
|
</li>
|
||||||
|
{{/if}}
|
||||||
|
|
||||||
|
{{if $item.star}}
|
||||||
|
<li role="menuitem">
|
||||||
|
<a id="star-{{$item.id}}" href="javascript:dostar({{$item.id}});" class="btn-link {{$item.star.classdo}}" title="{{$item.star.do}}"><i class="fa fa-star-o" aria-hidden="true"></i> {{$item.star.do}}</a>
|
||||||
|
<a id="unstar-{{$item.id}}" href="javascript:dostar({{$item.id}});" class="btn-link {{$item.star.classundo}}" title="{{$item.star.undo}}"><i class="fa fa-star" aria-hidden="true"></i> {{$item.star.undo}}</a>
|
||||||
|
</li>
|
||||||
|
{{/if}}
|
||||||
|
|
||||||
|
{{if $item.subthread}}
|
||||||
|
<li role="menuitem">
|
||||||
|
<a id="subthread-{{$item.id}}" href="javascript:{{$item.subthread.action}}" class="btn-link" title="{{$item.subthread.title}}"><i class="fa fa-plus" aria-hidden="true"></i> {{$item.subthread.title}}</a>
|
||||||
|
</li>
|
||||||
|
{{/if}}
|
||||||
|
|
||||||
|
{{if ($item.edpost || $item.tagger || $item.filer || $item.pin || $item.star || $item.subthread) && ($item.ignore || $item.drop.dropping)}}
|
||||||
|
<li role="separator" class="divider"></li>
|
||||||
|
{{/if}}
|
||||||
|
|
||||||
|
{{if $item.ignore}}
|
||||||
|
<li role="menuitem">
|
||||||
|
<a id="ignore-{{$item.id}}" href="javascript:doignore({{$item.id}});" class="btn-link {{$item.ignore.classdo}}" title="{{$item.ignore.do}}"><i class="fa fa-eye-slash" aria-hidden="true"></i> {{$item.ignore.do}}</a>
|
||||||
|
</li>
|
||||||
|
<li role="menuitem">
|
||||||
|
<a id="unignore-{{$item.id}}" href="javascript:doignore({{$item.id}});" class="btn-link {{$item.ignore.classundo}}" title="{{$item.ignore.undo}}"><i class="fa fa-eye" aria-hidden="true"></i> {{$item.ignore.undo}}</a>
|
||||||
|
</li>
|
||||||
|
{{/if}}
|
||||||
|
|
||||||
|
{{if $item.drop.dropping}}
|
||||||
|
<li role="menuitem">
|
||||||
|
<a class="btn-link navicon delete" href="javascript:dropItem('item/drop/{{$item.id}}/{{$item.return}}', 'item-{{$item.guid}}');" title="{{$item.drop.delete}}"><i class="fa fa-trash" aria-hidden="true"></i> {{$item.drop.delete}}</a>
|
||||||
|
</li>
|
||||||
|
{{/if}}
|
||||||
|
</ul>
|
||||||
|
<img id="like-rotator-{{$item.id}}" class="like-rotator" src="images/rotator.gif" alt="{{$item.wait}}" title="{{$item.wait}}" style="display: none;" />
|
||||||
|
</span>
|
||||||
|
{{else}}
|
||||||
<img id="like-rotator-{{$item.id}}" class="like-rotator" src="images/rotator.gif" alt="{{$item.wait}}" title="{{$item.wait}}" style="display: none;" />
|
<img id="like-rotator-{{$item.id}}" class="like-rotator" src="images/rotator.gif" alt="{{$item.wait}}" title="{{$item.wait}}" style="display: none;" />
|
||||||
|
{{/if}}
|
||||||
</span>
|
</span>
|
||||||
|
|
||||||
|
|
||||||
|
@ -242,7 +264,7 @@
|
||||||
</span>
|
</span>
|
||||||
</p><!--./wall-item-actions-->
|
</p><!--./wall-item-actions-->
|
||||||
|
|
||||||
{{* Display likes, dislike and attendance stats *}}
|
{{* Display likes, dislike and attendance stats *}}
|
||||||
{{if $item.responses}}
|
{{if $item.responses}}
|
||||||
<div class="wall-item-responses">
|
<div class="wall-item-responses">
|
||||||
{{foreach $item.responses as $verb=>$response}}
|
{{foreach $item.responses as $verb=>$response}}
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
|
|
||||||
{{$nickname_block nofilter}}
|
{{$nickname_block nofilter}}
|
||||||
|
|
||||||
<form action="settings" id="settings-form" method="post" autocomplete="off" >
|
<form action="settings" id="settings-form" method="post" autocomplete="off" enctype="multipart/form-data">
|
||||||
<input type='hidden' name='form_security_token' value='{{$form_security_token}}'>
|
<input type='hidden' name='form_security_token' value='{{$form_security_token}}'>
|
||||||
|
|
||||||
{{* We organize the settings in collapsable panel-groups *}}
|
{{* We organize the settings in collapsable panel-groups *}}
|
||||||
|
@ -89,6 +89,8 @@
|
||||||
|
|
||||||
{{$hide_wall nofilter}}
|
{{$hide_wall nofilter}}
|
||||||
|
|
||||||
|
{{$unlisted nofilter}}
|
||||||
|
|
||||||
{{$blockwall nofilter}}
|
{{$blockwall nofilter}}
|
||||||
|
|
||||||
{{$blocktags nofilter}}
|
{{$blocktags nofilter}}
|
||||||
|
|
|
@ -35,8 +35,8 @@
|
||||||
<td class="email">{{$u.email}}</td>
|
<td class="email">{{$u.email}}</td>
|
||||||
<td class="checkbox"><input type="checkbox" class="pending_ckbx" id="id_pending_{{$u.hash}}" name="pending[]" value="{{$u.hash}}" /></td>
|
<td class="checkbox"><input type="checkbox" class="pending_ckbx" id="id_pending_{{$u.hash}}" name="pending[]" value="{{$u.hash}}" /></td>
|
||||||
<td class="tools">
|
<td class="tools">
|
||||||
<a href="{{$baseurl}}/regmod/allow/{{$u.hash}}" title='{{$approve}}'><span class='icon like'></span></a>
|
<a href="{{$baseurl}}/admin/users/allow/{{$u.uid}}?t={{$form_security_token}}" title='{{$approve}}'><span class='icon like'></span></a>
|
||||||
<a href="{{$baseurl}}/regmod/deny/{{$u.hash}}" title='{{$deny}}'><span class='icon dislike'></span></a>
|
<a href="{{$baseurl}}/admin/users/deny/{{$u.uid}}?t={{$form_security_token}}" title='{{$deny}}'><span class='icon dislike'></span></a>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
|
|
|
@ -13,7 +13,7 @@
|
||||||
{{if $event.is_first}}<hr /><a name="link-{{$event.j}}" ><div class="event-list-date">{{$event.d}}</div></a>{{/if}}
|
{{if $event.is_first}}<hr /><a name="link-{{$event.j}}" ><div class="event-list-date">{{$event.d}}</div></a>{{/if}}
|
||||||
{{if $event.item.author_name}}<a href="{{$event.item.author_link}}" ><img src="{{$event.item.author_avatar}}" height="32" width="32" />{{$event.item.author_name}}</a>{{/if}}
|
{{if $event.item.author_name}}<a href="{{$event.item.author_link}}" ><img src="{{$event.item.author_avatar}}" height="32" width="32" />{{$event.item.author_name}}</a>{{/if}}
|
||||||
{{$event.html nofilter}}
|
{{$event.html nofilter}}
|
||||||
{{if $event.item.plink}}<a href="{{$event.plink.0}}" title="{{$event.plink.1}}" target="_blank" class="plink-event-link icon s22 remote-link"></a>{{/if}}
|
{{if $event.item.plink}}<a href="{{$event.plink.0}}" title="{{$event.plink.1}}" target="_blank" rel="noopener noreferrer" class="plink-event-link icon s22 remote-link"></a>{{/if}}
|
||||||
{{if $event.edit}}<a href="{{$event.edit.0}}" title="{{$event.edit.1}}" class="edit-event-link icon s22 pencil"></a>{{/if}}
|
{{if $event.edit}}<a href="{{$event.edit.0}}" title="{{$event.edit.1}}" class="edit-event-link icon s22 pencil"></a>{{/if}}
|
||||||
</div>
|
</div>
|
||||||
<div class="clear"></div>
|
<div class="clear"></div>
|
||||||
|
|
|
@ -21,7 +21,7 @@ function showHideForumlist() {
|
||||||
{{if $forum.id <= $visible_forums}}
|
{{if $forum.id <= $visible_forums}}
|
||||||
<li class="forum-widget-entry forum-{{$forum.cid}} tool {{if $forum.selected}}selected{{/if}}" id="forum-widget-entry-{{$forum.id}}" role="menuitem">
|
<li class="forum-widget-entry forum-{{$forum.cid}} tool {{if $forum.selected}}selected{{/if}}" id="forum-widget-entry-{{$forum.id}}" role="menuitem">
|
||||||
<span class="notify badge pull-right"></span>
|
<span class="notify badge pull-right"></span>
|
||||||
<a href="{{$forum.external_url}}" title="{{$forum.link_desc}}" class="label sparkle" target="_blank">
|
<a href="{{$forum.external_url}}" title="{{$forum.link_desc}}" class="label sparkle" target="_blank" rel="noopener noreferrer">
|
||||||
<img class="forumlist-img" src="{{$forum.micro}}" alt="{{$forum.link_desc}}" />
|
<img class="forumlist-img" src="{{$forum.micro}}" alt="{{$forum.link_desc}}" />
|
||||||
</a>
|
</a>
|
||||||
<a class="forum-widget-link" id="forum-widget-link-{{$forum.id}}" href="{{$forum.url}}" >{{$forum.name}}</a>
|
<a class="forum-widget-link" id="forum-widget-link-{{$forum.id}}" href="{{$forum.url}}" >{{$forum.name}}</a>
|
||||||
|
@ -31,7 +31,7 @@ function showHideForumlist() {
|
||||||
{{if $forum.id > $visible_forums}}
|
{{if $forum.id > $visible_forums}}
|
||||||
<li class="forum-widget-entry forum-{{$forum.cid}} tool {{if $forum.selected}}selected{{/if}}" id="forum-widget-entry-extended-{{$forum.id}}" role="menuitem" style="display: none;">
|
<li class="forum-widget-entry forum-{{$forum.cid}} tool {{if $forum.selected}}selected{{/if}}" id="forum-widget-entry-extended-{{$forum.id}}" role="menuitem" style="display: none;">
|
||||||
<span class="notify badge pull-right"></span>
|
<span class="notify badge pull-right"></span>
|
||||||
<a href="{{$forum.external_url}}" title="{{$forum.link_desc}}" class="label sparkle" target="_blank">
|
<a href="{{$forum.external_url}}" title="{{$forum.link_desc}}" class="label sparkle" target="_blank" rel="noopener noreferrer">
|
||||||
<img class="forumlist-img" src="{{$forum.micro}}" alt="{{$forum.link_desc}}" />
|
<img class="forumlist-img" src="{{$forum.micro}}" alt="{{$forum.link_desc}}" />
|
||||||
</a>
|
</a>
|
||||||
<a class="forum-widget-link" id="forum-widget-link-{{$forum.id}}" href="{{$forum.url}}" >{{$forum.name}}</a>
|
<a class="forum-widget-link" id="forum-widget-link-{{$forum.id}}" href="{{$forum.url}}" >{{$forum.name}}</a>
|
||||||
|
|
|
@ -48,7 +48,7 @@
|
||||||
|
|
||||||
{{if $updated}}<div class="updated" style="display:none;">{{$updated}}</div>{{/if}}
|
{{if $updated}}<div class="updated" style="display:none;">{{$updated}}</div>{{/if}}
|
||||||
|
|
||||||
{{if $homepage}}<dl class="homepage"><dt class="homepage-label">{{$homepage}}</dt><dd class="homepage-url"><a href="{{$profile.homepage}}" class="u-url" rel="me" target="_blank">{{$profile.homepage}}</a></dd></dl>{{/if}}
|
{{if $homepage}}<dl class="homepage"><dt class="homepage-label">{{$homepage}}</dt><dd class="homepage-url"><a href="{{$profile.homepage}}" class="u-url" rel="me" target="_blank" rel="noopener noreferrer">{{$profile.homepage}}</a></dd></dl>{{/if}}
|
||||||
|
|
||||||
{{if $about}}<dl class="about"><dt class="about-label">{{$about}}</dt><dd class="x-network">{{$profile.about nofilter}}</dd></dl>{{/if}}
|
{{if $about}}<dl class="about"><dt class="about-label">{{$about}}</dt><dd class="x-network">{{$profile.about nofilter}}</dd></dl>{{/if}}
|
||||||
|
|
||||||
|
|
|
@ -21,7 +21,7 @@ function showHideForumlist() {
|
||||||
{{if $forum.id <= $visible_forums}}
|
{{if $forum.id <= $visible_forums}}
|
||||||
<li class="forum-widget-entry forum-{{$forum.cid}}" id="forum-widget-entry-{{$forum.id}}" role="menuitem">
|
<li class="forum-widget-entry forum-{{$forum.cid}}" id="forum-widget-entry-{{$forum.id}}" role="menuitem">
|
||||||
<span class="notify badge pull-right"></span>
|
<span class="notify badge pull-right"></span>
|
||||||
<a href="{{$forum.external_url}}" title="{{$forum.link_desc}}" class="label sparkle" target="_blank">
|
<a href="{{$forum.external_url}}" title="{{$forum.link_desc}}" class="label sparkle" target="_blank" rel="noopener noreferrer">
|
||||||
<img class="forumlist-img" src="{{$forum.micro}}" alt="{{$forum.link_desc}}" />
|
<img class="forumlist-img" src="{{$forum.micro}}" alt="{{$forum.link_desc}}" />
|
||||||
</a>
|
</a>
|
||||||
<a class="forum-widget-link {{if $forum.selected}}forum-selected{{/if}}" id="forum-widget-link-{{$forum.id}}" href="{{$forum.url}}" >{{$forum.name}}</a>
|
<a class="forum-widget-link {{if $forum.selected}}forum-selected{{/if}}" id="forum-widget-link-{{$forum.id}}" href="{{$forum.url}}" >{{$forum.name}}</a>
|
||||||
|
@ -31,7 +31,7 @@ function showHideForumlist() {
|
||||||
{{if $forum.id > $visible_forums}}
|
{{if $forum.id > $visible_forums}}
|
||||||
<li class="forum-widget-entry forum-{{$forum.cid}}" id="forum-widget-entry-extended-{{$forum.id}}" role="menuitem" style="display: none;">
|
<li class="forum-widget-entry forum-{{$forum.cid}}" id="forum-widget-entry-extended-{{$forum.id}}" role="menuitem" style="display: none;">
|
||||||
<span class="notify badge pull-right"></span>
|
<span class="notify badge pull-right"></span>
|
||||||
<a href="{{$forum.external_url}}" title="{{$forum.link_desc}}" class="label sparkle" target="_blank">
|
<a href="{{$forum.external_url}}" title="{{$forum.link_desc}}" class="label sparkle" target="_blank" rel="noopener noreferrer">
|
||||||
<img class="forumlist-img" src="{{$forum.micro}}" alt="{{$forum.link_desc}}" />
|
<img class="forumlist-img" src="{{$forum.micro}}" alt="{{$forum.link_desc}}" />
|
||||||
</a>
|
</a>
|
||||||
<a class="forum-widget-link {{if $forum.selected}}forum-selected{{/if}}" id="forum-widget-link-{{$forum.id}}" href="{{$forum.url}}" >{{$forum.name}}</a>
|
<a class="forum-widget-link {{if $forum.selected}}forum-selected{{/if}}" id="forum-widget-link-{{$forum.id}}" href="{{$forum.url}}" >{{$forum.name}}</a>
|
||||||
|
|
Loading…
Reference in a new issue