mirror of
https://github.com/friendica/friendica
synced 2026-01-18 01:58:41 +01:00
Merge branch '2020.06-rc' into stable
This commit is contained in:
commit
dc42dbb68a
302 changed files with 78831 additions and 76304 deletions
|
|
@ -8,7 +8,7 @@ php:
|
|||
|
||||
services:
|
||||
- mysql
|
||||
- redis-server
|
||||
- redis
|
||||
- memcached
|
||||
env:
|
||||
- MYSQL_HOST=localhost MYSQL_PORT=3306 MYSQL_USERNAME=travis MYSQL_PASSWORD="" MYSQL_DATABASE=test
|
||||
|
|
|
|||
64
CHANGELOG
64
CHANGELOG
|
|
@ -1,3 +1,61 @@
|
|||
Version 2020.07 (2020-07-12)
|
||||
Friendica Core:
|
||||
Update to the translations: DE, EN GB, EN US, FR, ET, NL, PL, RU, ZH-CN [translation teams]
|
||||
Updates to the themes (frio, vier) [MrPetovan]
|
||||
Updated the shipped composer version, and the dependency list [annando, MrPetovan, tobiasd]
|
||||
Updates to the documentation [MrPetovan]
|
||||
General code refactoring and enhancements [AlfredSK, annando, MrPetovan]
|
||||
Replace charged terms with "allowlist", "denylist" and "blocklist" [MrPetovan]
|
||||
Enhanced the comment distribution in threads that involve diaspora*, AP and DFRN actors [annando]
|
||||
Enhanced the profile probing mechanism [annando, MrPetovan]
|
||||
Enhanced the post update process of the database [annando]
|
||||
Enhanced the database performance [annando]
|
||||
Enhanced ActivityPub attachment handling [MrPetovan]
|
||||
Enhanced security of redirections [annando]
|
||||
Enhanced database performance [annando]
|
||||
Enhanced the handling of BBCode [pre] tags [MrPetovan]
|
||||
Enhanced Markdown to BBCode conversion [MrPetovan]
|
||||
Enhanced the speed of the network page [annando]
|
||||
Fixed a problem recognising logins via the API [MrPetovan]
|
||||
Fixed a problem with handling local diaspora* URLs [MrPetovan]
|
||||
Fixed a problem with implicit mentions [annando]
|
||||
Fixed a problem with the password reset token security [lynn-stephenson]
|
||||
Fixed a problem with receiving non-public posts via ActivityPub [annando]
|
||||
Fixed a problem with the photo endpoint of the API [MrPetovan]
|
||||
Fixed a problem with pressing the ESC key in the frio-theme [MrPetovan]
|
||||
Fixed a problem with the display if post categories [annando]
|
||||
Fixed a problem with validation of feeds [annando]
|
||||
Fixed a problem that prevented AP activities being fetched sometimes [annando]
|
||||
Renamed the -q option of the console user delete command to -y [MrPetovan]
|
||||
Added notification count to page title [MrPetovan]
|
||||
Added handling of relative URLs during feed detection [MrPetovan]
|
||||
Added entities [nupplaphil]
|
||||
|
||||
Friendica Addons:
|
||||
Update to the translations (EN GB, NB NO, NL, PL, RU, ZH CN) [translation teams]
|
||||
blockbot:
|
||||
The list of accepted user agents was enhanced [annando]
|
||||
Diaspora*:
|
||||
Enhanced conntector settings [MrPetovan]
|
||||
PHP Mailer SMTP:
|
||||
Updated phpmailer version [dependabot]
|
||||
showmore_dyn:
|
||||
New addon to collapse long post depending on their actual height [wiwie]
|
||||
twitter:
|
||||
Enhaceed the handling of mobile twitter URLs [annando]
|
||||
Enhanced the handling of quoted tweets [MrPetovan]
|
||||
added HTML error code handling [MrPetovan]
|
||||
various:
|
||||
enhancements to the probe mechanism [MrPetovan]
|
||||
|
||||
Closed Issues:
|
||||
3084, 3884, 8287, 8314, 8374, 8400, 8425, 8432, 8458, 8470, 8477,
|
||||
8482, 8488, 8489, 8490, 8493, 8495, 8498, 8511, 8517, 8523, 8527,
|
||||
8551, 8553, 8560, 8564, 8565, 8568, 8578, 8586, 8593, 8606, 8610,
|
||||
8612, 8626, 8664, 8672, 8683, 8685, 8691, 8694, 8702, 8709, 8714,
|
||||
8717, 8722, 8726, 8732, 8736, 8743, 8744, 8746, 8756, 8766, 8769,
|
||||
8781, 8800, 8807, 8808, 8827, 8829, 8836, 8844, 8846, 8857, 8866
|
||||
|
||||
Version 2020.03 "Red Hot Poker" (2020-03-30)
|
||||
Friendica Core:
|
||||
Updates to the translations (DE, FR, JA, NL, PL, RU, ZH-CN) [translation teams]
|
||||
|
|
@ -52,7 +110,7 @@ Version 2020.03 "Red Hot Poker" (2020-03-30)
|
|||
Update to the translations (CS, DE, FR, PL, RU, ZH-CN) [translation teams]
|
||||
General code refactoring and enhancements [AndyHee, annando, MrPetovan, nupplaphil]
|
||||
blockbot:
|
||||
Ensure that good agents are whitelisted [valvin1]
|
||||
Ensure that good agents are allowlisted [valvin1]
|
||||
markdown:
|
||||
Addon to use Markdown while composing a posting was added [annando]
|
||||
showmore:
|
||||
|
|
@ -902,7 +960,7 @@ Version 3.5.3 (2017-10-05)
|
|||
Updates to the documentation [tobiasd]
|
||||
Code revision and refactoring [Hypolite]
|
||||
pumpio, twitter bridges adopted to new background mechanism [annando]
|
||||
Leistungsschutzrecht has a new source list, and a whitelist [annando]
|
||||
Leistungsschutzrecht has a new source list, and an allowlist [annando]
|
||||
retriever marked unsupported due to unwanted side-effects [annando]
|
||||
Unicode emoji added [annando]
|
||||
Enhancement to the general content filter [annando]
|
||||
|
|
@ -1364,7 +1422,7 @@ Version 3.3.1 (2014-11-06)
|
|||
Set default location to empty for new users. Suppress warning on user creation (issue #1193) (fabrixxm)
|
||||
Correctly build urls with queries (issue #1190) (fabrixxm)
|
||||
Optionally use keywords in feed as post tags with "remote self" (annando)
|
||||
A blacklist of keywords to not use can be defined (annando)
|
||||
A denylist of keywords to not use can be defined (annando)
|
||||
"remote self" works also with Friendica and Diaspora contacts (annando)
|
||||
Show exact post time after 12 hours (FX7)
|
||||
Optionally redirect from non-SSL to SSL (annando)
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@ Aditoo
|
|||
AgnesElisa
|
||||
Albert
|
||||
Alberto Díaz Tormo
|
||||
Aleksandr "M.O.Z.G" Dikov
|
||||
Alex
|
||||
Alexander An
|
||||
Alexander Fortin
|
||||
|
|
@ -131,6 +132,7 @@ julia.domagalska
|
|||
Julio Cova
|
||||
Karel
|
||||
Karolina
|
||||
Keenan Pepper
|
||||
Keith Fernie
|
||||
Klaus Weidenbach
|
||||
Koyu Berteon
|
||||
|
|
@ -141,8 +143,10 @@ Leberwurscht
|
|||
Leonard Lausen
|
||||
Lionel Triay
|
||||
loma-one
|
||||
loma1
|
||||
Lorem Ipsum
|
||||
Ludovic Grossard
|
||||
Lynn Stephenson
|
||||
maase2
|
||||
Magdalena Gazda
|
||||
Mai Anh Nguyen
|
||||
|
|
@ -231,6 +235,7 @@ St John Karp
|
|||
Stanislav N.
|
||||
Steffen K9
|
||||
StefOfficiel
|
||||
steve jobs
|
||||
Sveinn í Felli
|
||||
Sven Anders
|
||||
Sylke Vicious
|
||||
|
|
|
|||
2
VERSION
2
VERSION
|
|
@ -1 +1 @@
|
|||
2020.03
|
||||
2020.06-rc
|
||||
|
|
|
|||
Binary file not shown.
|
|
@ -32,7 +32,7 @@ case "$MODE" in
|
|||
mkdir -p "$FULLPATH/../addon/$ADDONNAME/lang/C"
|
||||
OUTFILE="$FULLPATH/../addon/$ADDONNAME/lang/C/messages.po"
|
||||
FINDSTARTDIR="."
|
||||
FINDOPTS=
|
||||
FINDOPTS="-path ./vendor -prune -or"
|
||||
;;
|
||||
'single')
|
||||
FULLPATH=$PWD
|
||||
|
|
@ -40,7 +40,7 @@ case "$MODE" in
|
|||
mkdir -p "$FULLPATH/lang/C"
|
||||
OUTFILE="$FULLPATH/lang/C/messages.po"
|
||||
FINDSTARTDIR="."
|
||||
FINDOPTS=
|
||||
FINDOPTS="-path ./vendor -prune -or"
|
||||
echo "Extract strings for single addon '$ADDONNAME'"
|
||||
;;
|
||||
'default')
|
||||
|
|
@ -48,7 +48,7 @@ case "$MODE" in
|
|||
OUTFILE="$FULLPATH/../view/lang/C/messages.po"
|
||||
FINDSTARTDIR="."
|
||||
# skip addon folder
|
||||
FINDOPTS="( -wholename */addon -or -wholename */addons -or -wholename */addons-extra -or -wholename */smarty3 ) -prune -o"
|
||||
FINDOPTS="( -path ./addon -or -path ./addons -or -path ./addons-extra -or -path ./tests -or -path ./view/lang -or -path ./view/smarty3 -or -path ./vendor ) -prune -or"
|
||||
|
||||
F9KVERSION=$(cat ./VERSION);
|
||||
echo "Friendica version $F9KVERSION"
|
||||
|
|
@ -58,44 +58,54 @@ esac
|
|||
|
||||
KEYWORDS="-k -kt -ktt:1,2"
|
||||
|
||||
echo "extract strings to $OUTFILE.."
|
||||
echo "Extract strings to $OUTFILE.."
|
||||
rm "$OUTFILE"; touch "$OUTFILE"
|
||||
for f in $(find "$FINDSTARTDIR" $FINDOPTS -name "*.php" -type f)
|
||||
|
||||
find_result=$(find "$FINDSTARTDIR" $FINDOPTS -name "*.php" -type f)
|
||||
|
||||
total_files=$(wc -l <<< "${find_result}")
|
||||
|
||||
for file in $find_result
|
||||
do
|
||||
if [ ! -d "$f" ]
|
||||
((count++))
|
||||
echo -ne " \r"
|
||||
echo -ne "Reading file $count/$total_files..."
|
||||
|
||||
# On Windows, find still outputs the name of pruned folders
|
||||
if [ ! -d "$file" ]
|
||||
then
|
||||
xgettext $KEYWORDS -j -o "$OUTFILE" --from-code=UTF-8 "$f"
|
||||
xgettext $KEYWORDS -j -o "$OUTFILE" --from-code=UTF-8 "$file" || exit 1
|
||||
sed -i "s/CHARSET/UTF-8/g" "$OUTFILE"
|
||||
fi
|
||||
done
|
||||
echo -ne "\n"
|
||||
|
||||
echo "setup base info.."
|
||||
case "$MODE" in
|
||||
echo "Interpolate metadata.."
|
||||
|
||||
sed -i "s/^\"Plural-Forms.*$//g" "$OUTFILE"
|
||||
|
||||
case "$MODE" in
|
||||
'addon'|'single')
|
||||
sed -i "s/SOME DESCRIPTIVE TITLE./ADDON $ADDONNAME/g" "$OUTFILE"
|
||||
sed -i "s/YEAR THE PACKAGE'S COPYRIGHT HOLDER//g" "$OUTFILE"
|
||||
sed -i "s/FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.//g" "$OUTFILE"
|
||||
sed -i "s/PACKAGE VERSION//g" "$OUTFILE"
|
||||
sed -i "s/PACKAGE/Friendica $ADDONNAME addon/g" "$OUTFILE"
|
||||
sed -i "s/CHARSET/UTF-8/g" "$OUTFILE"
|
||||
sed -i "s/^\"Plural-Forms.*$//g" "$OUTFILE"
|
||||
;;
|
||||
'default')
|
||||
sed -i "s/SOME DESCRIPTIVE TITLE./FRIENDICA Distributed Social Network/g" "$OUTFILE"
|
||||
sed -i "s/YEAR THE PACKAGE'S COPYRIGHT HOLDER/2010, 2011, 2012, 2013 the Friendica Project/g" "$OUTFILE"
|
||||
sed -i "s/YEAR THE PACKAGE'S COPYRIGHT HOLDER/2010-$(date +%Y) the Friendica Project/g" "$OUTFILE"
|
||||
sed -i "s/FIRST AUTHOR <EMAIL@ADDRESS>, YEAR./Mike Macgirvin, 2010/g" "$OUTFILE"
|
||||
sed -i "s/PACKAGE VERSION/$F9KVERSION/g" "$OUTFILE"
|
||||
sed -i "s/PACKAGE/Friendica/g" "$OUTFILE"
|
||||
sed -i "s/CHARSET/UTF-8/g" "$OUTFILE"
|
||||
sed -i "s/^\"Plural-Forms.*$//g" "$OUTFILE"
|
||||
;;
|
||||
esac
|
||||
|
||||
if [ "" != "$1" -a "$MODE" == "default" ]
|
||||
then
|
||||
UPDATEFILE="$(readlink -f ${FULLPATH}/$1)"
|
||||
echo "merging new strings to $UPDATEFILE.."
|
||||
echo "Merging new strings to $UPDATEFILE.."
|
||||
msgmerge -U $OUTFILE $UPDATEFILE
|
||||
fi
|
||||
|
||||
echo "done."
|
||||
echo "Done."
|
||||
|
|
|
|||
26
boot.php
26
boot.php
|
|
@ -33,13 +33,12 @@ use Friendica\Database\DBA;
|
|||
use Friendica\DI;
|
||||
use Friendica\Model\Contact;
|
||||
use Friendica\Model\Notify;
|
||||
use Friendica\Model\Term;
|
||||
use Friendica\Util\BasePath;
|
||||
use Friendica\Util\DateTimeFormat;
|
||||
|
||||
define('FRIENDICA_PLATFORM', 'Friendica');
|
||||
define('FRIENDICA_CODENAME', 'Red Hot Poker');
|
||||
define('FRIENDICA_VERSION', '2020.03');
|
||||
define('FRIENDICA_VERSION', '2020.06-rc');
|
||||
define('DFRN_PROTOCOL_VERSION', '2.23');
|
||||
define('NEW_UPDATE_ROUTINE_VERSION', 1170);
|
||||
|
||||
|
|
@ -178,29 +177,6 @@ define('NOTIFY_SHARE', Notify\Type::SHARE);
|
|||
define('NOTIFY_SYSTEM', Notify\Type::SYSTEM);
|
||||
/* @}*/
|
||||
|
||||
|
||||
/** @deprecated since 2019.03, use Term::UNKNOWN instead */
|
||||
define('TERM_UNKNOWN', Term::UNKNOWN);
|
||||
/** @deprecated since 2019.03, use Term::HASHTAG instead */
|
||||
define('TERM_HASHTAG', Term::HASHTAG);
|
||||
/** @deprecated since 2019.03, use Term::MENTION instead */
|
||||
define('TERM_MENTION', Term::MENTION);
|
||||
/** @deprecated since 2019.03, use Term::CATEGORY instead */
|
||||
define('TERM_CATEGORY', Term::CATEGORY);
|
||||
/** @deprecated since 2019.03, use Term::PCATEGORY instead */
|
||||
define('TERM_PCATEGORY', Term::PCATEGORY);
|
||||
/** @deprecated since 2019.03, use Term::FILE instead */
|
||||
define('TERM_FILE', Term::FILE);
|
||||
/** @deprecated since 2019.03, use Term::SAVEDSEARCH instead */
|
||||
define('TERM_SAVEDSEARCH', Term::SAVEDSEARCH);
|
||||
/** @deprecated since 2019.03, use Term::CONVERSATION instead */
|
||||
define('TERM_CONVERSATION', Term::CONVERSATION);
|
||||
|
||||
/** @deprecated since 2019.03, use Term::OBJECT_TYPE_POST instead */
|
||||
define('TERM_OBJ_POST', Term::OBJECT_TYPE_POST);
|
||||
/** @deprecated since 2019.03, use Term::OBJECT_TYPE_PHOTO instead */
|
||||
define('TERM_OBJ_PHOTO', Term::OBJECT_TYPE_PHOTO);
|
||||
|
||||
/**
|
||||
* @name Gravity
|
||||
*
|
||||
|
|
|
|||
|
|
@ -92,6 +92,9 @@
|
|||
}
|
||||
},
|
||||
"config": {
|
||||
"platform": {
|
||||
"php": "7.0"
|
||||
},
|
||||
"autoloader-suffix": "Friendica",
|
||||
"optimize-autoloader": true,
|
||||
"preferred-install": "dist",
|
||||
|
|
|
|||
587
composer.lock
generated
587
composer.lock
generated
|
|
@ -4,7 +4,7 @@
|
|||
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
||||
"This file is @generated automatically"
|
||||
],
|
||||
"content-hash": "b3a7490d8f103ef40431848a26fcc2a6",
|
||||
"content-hash": "ded67f7e680a122d0cd3512c2738be97",
|
||||
"packages": [
|
||||
{
|
||||
"name": "asika/simple-console",
|
||||
|
|
@ -87,16 +87,16 @@
|
|||
},
|
||||
{
|
||||
"name": "bower-asset/Chart-js",
|
||||
"version": "v2.8.0",
|
||||
"version": "v2.9.3",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/chartjs/Chart.js.git",
|
||||
"reference": "947d8a7ccfbfc76dd9d384ea75436fa4a7aeefb1"
|
||||
"reference": "06f73dc3590084b2c464bf08189c7aee2b6b92d2"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/chartjs/Chart.js/zipball/947d8a7ccfbfc76dd9d384ea75436fa4a7aeefb1",
|
||||
"reference": "947d8a7ccfbfc76dd9d384ea75436fa4a7aeefb1",
|
||||
"url": "https://api.github.com/repos/chartjs/Chart.js/zipball/06f73dc3590084b2c464bf08189c7aee2b6b92d2",
|
||||
"reference": "06f73dc3590084b2c464bf08189c7aee2b6b92d2",
|
||||
"shasum": ""
|
||||
},
|
||||
"type": "bower-asset-library",
|
||||
|
|
@ -115,20 +115,20 @@
|
|||
"MIT"
|
||||
],
|
||||
"description": "Simple HTML5 charts using the canvas element.",
|
||||
"time": "2019-03-14T13:03:00+00:00"
|
||||
"time": "2019-11-14T18:37:30+00:00"
|
||||
},
|
||||
{
|
||||
"name": "bower-asset/base64",
|
||||
"version": "1.0.2",
|
||||
"version": "1.1.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/davidchambers/Base64.js.git",
|
||||
"reference": "10f0e9990dab0a73009fc106ff2b88102a0a13cf"
|
||||
"reference": "660b299aa4854843fd35d42b30eda9273125b9da"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/davidchambers/Base64.js/zipball/10f0e9990dab0a73009fc106ff2b88102a0a13cf",
|
||||
"reference": "10f0e9990dab0a73009fc106ff2b88102a0a13cf",
|
||||
"url": "https://api.github.com/repos/davidchambers/Base64.js/zipball/660b299aa4854843fd35d42b30eda9273125b9da",
|
||||
"reference": "660b299aa4854843fd35d42b30eda9273125b9da",
|
||||
"shasum": ""
|
||||
},
|
||||
"type": "bower-asset-library",
|
||||
|
|
@ -146,7 +146,7 @@
|
|||
"WTFPL"
|
||||
],
|
||||
"description": "Base64 encoding and decoding",
|
||||
"time": "2019-02-12T17:19:36+00:00"
|
||||
"time": "2019-11-02T20:07:47+00:00"
|
||||
},
|
||||
{
|
||||
"name": "bower-asset/dompurify",
|
||||
|
|
@ -239,16 +239,16 @@
|
|||
},
|
||||
{
|
||||
"name": "bower-asset/vue",
|
||||
"version": "v2.6.10",
|
||||
"version": "v2.6.11",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/vuejs/vue.git",
|
||||
"reference": "e90cc60c4718a69e2c919275a999b7370141f3bf"
|
||||
"reference": "ec78fc8b6d03e59da669be1adf4b4b5abf670a34"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/vuejs/vue/zipball/e90cc60c4718a69e2c919275a999b7370141f3bf",
|
||||
"reference": "e90cc60c4718a69e2c919275a999b7370141f3bf",
|
||||
"url": "https://api.github.com/repos/vuejs/vue/zipball/ec78fc8b6d03e59da669be1adf4b4b5abf670a34",
|
||||
"reference": "ec78fc8b6d03e59da669be1adf4b4b5abf670a34",
|
||||
"shasum": ""
|
||||
},
|
||||
"type": "bower-asset-library"
|
||||
|
|
@ -394,21 +394,24 @@
|
|||
},
|
||||
{
|
||||
"name": "ezyang/htmlpurifier",
|
||||
"version": "v4.7.0",
|
||||
"version": "v4.12.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/ezyang/htmlpurifier.git",
|
||||
"reference": "ae1828d955112356f7677c465f94f7deb7d27a40"
|
||||
"reference": "a617e55bc62a87eec73bd456d146d134ad716f03"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/ezyang/htmlpurifier/zipball/ae1828d955112356f7677c465f94f7deb7d27a40",
|
||||
"reference": "ae1828d955112356f7677c465f94f7deb7d27a40",
|
||||
"url": "https://api.github.com/repos/ezyang/htmlpurifier/zipball/a617e55bc62a87eec73bd456d146d134ad716f03",
|
||||
"reference": "a617e55bc62a87eec73bd456d146d134ad716f03",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=5.2"
|
||||
},
|
||||
"require-dev": {
|
||||
"simpletest/simpletest": "dev-master#72de02a7b80c6bb8864ef9bf66d41d2f58f826bd"
|
||||
},
|
||||
"type": "library",
|
||||
"autoload": {
|
||||
"psr-0": {
|
||||
|
|
@ -420,7 +423,7 @@
|
|||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"LGPL"
|
||||
"LGPL-2.1-or-later"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
|
|
@ -434,7 +437,7 @@
|
|||
"keywords": [
|
||||
"html"
|
||||
],
|
||||
"time": "2015-08-05T01:03:42+00:00"
|
||||
"time": "2019-10-28T03:44:26+00:00"
|
||||
},
|
||||
{
|
||||
"name": "friendica/json-ld",
|
||||
|
|
@ -541,27 +544,29 @@
|
|||
},
|
||||
{
|
||||
"name": "guzzlehttp/guzzle",
|
||||
"version": "6.3.3",
|
||||
"version": "6.5.5",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/guzzle/guzzle.git",
|
||||
"reference": "407b0cb880ace85c9b63c5f9551db498cb2d50ba"
|
||||
"reference": "9d4290de1cfd701f38099ef7e183b64b4b7b0c5e"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/guzzle/guzzle/zipball/407b0cb880ace85c9b63c5f9551db498cb2d50ba",
|
||||
"reference": "407b0cb880ace85c9b63c5f9551db498cb2d50ba",
|
||||
"url": "https://api.github.com/repos/guzzle/guzzle/zipball/9d4290de1cfd701f38099ef7e183b64b4b7b0c5e",
|
||||
"reference": "9d4290de1cfd701f38099ef7e183b64b4b7b0c5e",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"ext-json": "*",
|
||||
"guzzlehttp/promises": "^1.0",
|
||||
"guzzlehttp/psr7": "^1.4",
|
||||
"php": ">=5.5"
|
||||
"guzzlehttp/psr7": "^1.6.1",
|
||||
"php": ">=5.5",
|
||||
"symfony/polyfill-intl-idn": "^1.17.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"ext-curl": "*",
|
||||
"phpunit/phpunit": "^4.8.35 || ^5.7 || ^6.4 || ^7.0",
|
||||
"psr/log": "^1.0"
|
||||
"psr/log": "^1.1"
|
||||
},
|
||||
"suggest": {
|
||||
"psr/log": "Required for using the Log middleware"
|
||||
|
|
@ -569,16 +574,16 @@
|
|||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "6.3-dev"
|
||||
"dev-master": "6.5-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"files": [
|
||||
"src/functions_include.php"
|
||||
],
|
||||
"psr-4": {
|
||||
"GuzzleHttp\\": "src/"
|
||||
}
|
||||
},
|
||||
"files": [
|
||||
"src/functions_include.php"
|
||||
]
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
|
|
@ -602,7 +607,7 @@
|
|||
"rest",
|
||||
"web service"
|
||||
],
|
||||
"time": "2018-04-22T15:46:56+00:00"
|
||||
"time": "2020-06-16T21:01:06+00:00"
|
||||
},
|
||||
{
|
||||
"name": "guzzlehttp/promises",
|
||||
|
|
@ -792,16 +797,16 @@
|
|||
},
|
||||
{
|
||||
"name": "level-2/dice",
|
||||
"version": "4.0.1",
|
||||
"version": "4.0.2",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/Level-2/Dice.git",
|
||||
"reference": "e631f110f0520294fec902814c61cac26566023c"
|
||||
"reference": "b9336d9200d0165c31e982374dc5d8d2552807bc"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/Level-2/Dice/zipball/e631f110f0520294fec902814c61cac26566023c",
|
||||
"reference": "e631f110f0520294fec902814c61cac26566023c",
|
||||
"url": "https://api.github.com/repos/Level-2/Dice/zipball/b9336d9200d0165c31e982374dc5d8d2552807bc",
|
||||
"reference": "b9336d9200d0165c31e982374dc5d8d2552807bc",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
|
|
@ -834,7 +839,7 @@
|
|||
"di",
|
||||
"ioc"
|
||||
],
|
||||
"time": "2019-05-01T12:55:36+00:00"
|
||||
"time": "2020-01-28T13:47:49+00:00"
|
||||
},
|
||||
{
|
||||
"name": "lightopenid/lightopenid",
|
||||
|
|
@ -871,21 +876,24 @@
|
|||
},
|
||||
{
|
||||
"name": "michelf/php-markdown",
|
||||
"version": "1.8.0",
|
||||
"version": "1.9.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/michelf/php-markdown.git",
|
||||
"reference": "01ab082b355bf188d907b9929cd99b2923053495"
|
||||
"reference": "c83178d49e372ca967d1a8c77ae4e051b3a3c75c"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/michelf/php-markdown/zipball/01ab082b355bf188d907b9929cd99b2923053495",
|
||||
"reference": "01ab082b355bf188d907b9929cd99b2923053495",
|
||||
"url": "https://api.github.com/repos/michelf/php-markdown/zipball/c83178d49e372ca967d1a8c77ae4e051b3a3c75c",
|
||||
"reference": "c83178d49e372ca967d1a8c77ae4e051b3a3c75c",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=5.3.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpunit/phpunit": ">=4.3 <5.8"
|
||||
},
|
||||
"type": "library",
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
|
|
@ -913,7 +921,7 @@
|
|||
"keywords": [
|
||||
"markdown"
|
||||
],
|
||||
"time": "2018-01-15T00:49:33+00:00"
|
||||
"time": "2019-12-02T02:32:27+00:00"
|
||||
},
|
||||
{
|
||||
"name": "mobiledetect/mobiledetectlib",
|
||||
|
|
@ -969,16 +977,16 @@
|
|||
},
|
||||
{
|
||||
"name": "monolog/monolog",
|
||||
"version": "1.25.1",
|
||||
"version": "1.25.4",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/Seldaek/monolog.git",
|
||||
"reference": "70e65a5470a42cfec1a7da00d30edb6e617e8dcf"
|
||||
"reference": "3022efff205e2448b560c833c6fbbf91c3139168"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/Seldaek/monolog/zipball/70e65a5470a42cfec1a7da00d30edb6e617e8dcf",
|
||||
"reference": "70e65a5470a42cfec1a7da00d30edb6e617e8dcf",
|
||||
"url": "https://api.github.com/repos/Seldaek/monolog/zipball/3022efff205e2448b560c833c6fbbf91c3139168",
|
||||
"reference": "3022efff205e2448b560c833c6fbbf91c3139168",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
|
|
@ -992,11 +1000,10 @@
|
|||
"aws/aws-sdk-php": "^2.4.9 || ^3.0",
|
||||
"doctrine/couchdb": "~1.0@dev",
|
||||
"graylog2/gelf-php": "~1.0",
|
||||
"jakub-onderka/php-parallel-lint": "0.9",
|
||||
"php-amqplib/php-amqplib": "~2.4",
|
||||
"php-console/php-console": "^3.1.3",
|
||||
"php-parallel-lint/php-parallel-lint": "^1.0",
|
||||
"phpunit/phpunit": "~4.5",
|
||||
"phpunit/phpunit-mock-objects": "2.3.0",
|
||||
"ruflin/elastica": ">=0.90 <3.0",
|
||||
"sentry/sentry": "^0.13",
|
||||
"swiftmailer/swiftmailer": "^5.3|^6.0"
|
||||
|
|
@ -1043,7 +1050,7 @@
|
|||
"logging",
|
||||
"psr-3"
|
||||
],
|
||||
"time": "2019-09-06T13:49:17+00:00"
|
||||
"time": "2020-05-22T07:31:27+00:00"
|
||||
},
|
||||
{
|
||||
"name": "nikic/fast-route",
|
||||
|
|
@ -1271,11 +1278,11 @@
|
|||
},
|
||||
{
|
||||
"name": "npm-asset/fullcalendar",
|
||||
"version": "3.10.1",
|
||||
"version": "3.10.2",
|
||||
"dist": {
|
||||
"type": "tar",
|
||||
"url": "https://registry.npmjs.org/fullcalendar/-/fullcalendar-3.10.1.tgz",
|
||||
"shasum": "cca3f9a2656a7e978a3f3facb7f35934a91185db"
|
||||
"url": "https://registry.npmjs.org/fullcalendar/-/fullcalendar-3.10.2.tgz",
|
||||
"shasum": "9b1ba84bb02803621b761d1bba91a4f18affafb7"
|
||||
},
|
||||
"type": "npm-asset-library",
|
||||
"extra": {
|
||||
|
|
@ -1313,7 +1320,7 @@
|
|||
"full-sized",
|
||||
"jquery-plugin"
|
||||
],
|
||||
"time": "2019-08-10T16:05:46+00:00"
|
||||
"time": "2020-05-19T03:44:55+00:00"
|
||||
},
|
||||
{
|
||||
"name": "npm-asset/imagesloaded",
|
||||
|
|
@ -1647,11 +1654,11 @@
|
|||
},
|
||||
{
|
||||
"name": "npm-asset/moment",
|
||||
"version": "2.24.0",
|
||||
"version": "2.26.0",
|
||||
"dist": {
|
||||
"type": "tar",
|
||||
"url": "https://registry.npmjs.org/moment/-/moment-2.24.0.tgz",
|
||||
"shasum": "0d055d53f5052aa653c9f6eb68bb5d12bf5c2b5b"
|
||||
"url": "https://registry.npmjs.org/moment/-/moment-2.26.0.tgz",
|
||||
"shasum": "5e1f82c6bafca6e83e808b30c8705eed0dcbd39a"
|
||||
},
|
||||
"type": "npm-asset-library",
|
||||
"extra": {
|
||||
|
|
@ -1665,8 +1672,12 @@
|
|||
"url": "git+https://github.com/moment/moment.git"
|
||||
},
|
||||
"npm-asset-scripts": {
|
||||
"typescript-test": "tsc --project typing-tests",
|
||||
"ts3.1-typescript-test": "cross-env node_modules/typescript3/bin/tsc --project ts3.1-typing-tests",
|
||||
"typescript-test": "cross-env node_modules/typescript/bin/tsc --project typing-tests",
|
||||
"test": "grunt test",
|
||||
"eslint": "eslint Gruntfile.js tasks src",
|
||||
"prettier-check": "prettier --check Gruntfile.js tasks src",
|
||||
"prettier-fmt": "prettier --write Gruntfile.js tasks src",
|
||||
"coverage": "nyc npm test && nyc report",
|
||||
"coveralls": "nyc npm test && nyc report --reporter=text-lcov | coveralls"
|
||||
},
|
||||
|
|
@ -1709,7 +1720,7 @@
|
|||
}
|
||||
],
|
||||
"description": "Parse, validate, manipulate, and display dates",
|
||||
"homepage": "http://momentjs.com",
|
||||
"homepage": "https://momentjs.com",
|
||||
"keywords": [
|
||||
"date",
|
||||
"ender",
|
||||
|
|
@ -1721,7 +1732,65 @@
|
|||
"time",
|
||||
"validate"
|
||||
],
|
||||
"time": "2019-01-21T21:10:34+00:00"
|
||||
"time": "2020-05-20T06:46:22+00:00"
|
||||
},
|
||||
{
|
||||
"name": "npm-asset/perfect-scrollbar",
|
||||
"version": "0.6.16",
|
||||
"dist": {
|
||||
"type": "tar",
|
||||
"url": "https://registry.npmjs.org/perfect-scrollbar/-/perfect-scrollbar-0.6.16.tgz",
|
||||
"shasum": "b1d61a5245cf3962bb9a8407a3fc669d923212fc"
|
||||
},
|
||||
"type": "npm-asset-library",
|
||||
"extra": {
|
||||
"npm-asset-bugs": {
|
||||
"url": "https://github.com/noraesae/perfect-scrollbar/issues"
|
||||
},
|
||||
"npm-asset-files": [
|
||||
"dist",
|
||||
"src",
|
||||
"index.js",
|
||||
"jquery.js",
|
||||
"perfect-scrollbar.d.ts"
|
||||
],
|
||||
"npm-asset-main": "./index.js",
|
||||
"npm-asset-directories": [],
|
||||
"npm-asset-repository": {
|
||||
"type": "git",
|
||||
"url": "git+https://github.com/noraesae/perfect-scrollbar.git"
|
||||
},
|
||||
"npm-asset-scripts": {
|
||||
"test": "gulp",
|
||||
"before-deploy": "gulp && gulp compress",
|
||||
"release": "rm -rf dist && gulp && npm publish"
|
||||
},
|
||||
"npm-asset-engines": {
|
||||
"node": ">= 0.12.0"
|
||||
}
|
||||
},
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Hyunje Jun",
|
||||
"email": "me@noraesae.net"
|
||||
},
|
||||
{
|
||||
"name": "Hyunje Jun",
|
||||
"email": "me@noraesae.net"
|
||||
}
|
||||
],
|
||||
"description": "Minimalistic but perfect custom scrollbar plugin",
|
||||
"homepage": "https://github.com/noraesae/perfect-scrollbar#readme",
|
||||
"keywords": [
|
||||
"frontend",
|
||||
"jquery-plugin",
|
||||
"scroll",
|
||||
"scrollbar"
|
||||
],
|
||||
"time": "2017-01-10T01:03:05+00:00"
|
||||
},
|
||||
{
|
||||
"name": "npm-asset/perfect-scrollbar",
|
||||
|
|
@ -1783,16 +1852,16 @@
|
|||
},
|
||||
{
|
||||
"name": "npm-asset/php-date-formatter",
|
||||
"version": "v1.3.5",
|
||||
"version": "v1.3.6",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/kartik-v/php-date-formatter.git",
|
||||
"reference": "d842e1c4e6a8d6108017b726321c305bb5ae4fb5"
|
||||
"reference": "514a53660b0d69439236fd3cbc3f41512adb00a0"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/kartik-v/php-date-formatter/zipball/d842e1c4e6a8d6108017b726321c305bb5ae4fb5",
|
||||
"reference": "d842e1c4e6a8d6108017b726321c305bb5ae4fb5",
|
||||
"url": "https://api.github.com/repos/kartik-v/php-date-formatter/zipball/514a53660b0d69439236fd3cbc3f41512adb00a0",
|
||||
"reference": "514a53660b0d69439236fd3cbc3f41512adb00a0",
|
||||
"shasum": ""
|
||||
},
|
||||
"type": "npm-asset-library",
|
||||
|
|
@ -1817,7 +1886,7 @@
|
|||
],
|
||||
"description": "A Javascript datetime formatting and manipulation library using PHP date-time formats.",
|
||||
"homepage": "https://github.com/kartik-v/php-date-formatter",
|
||||
"time": "2018-07-13T06:56:46+00:00"
|
||||
"time": "2020-04-14T10:16:32+00:00"
|
||||
},
|
||||
{
|
||||
"name": "npm-asset/typeahead.js",
|
||||
|
|
@ -1873,16 +1942,16 @@
|
|||
},
|
||||
{
|
||||
"name": "paragonie/certainty",
|
||||
"version": "v2.5.0",
|
||||
"version": "v2.6.1",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/paragonie/certainty.git",
|
||||
"reference": "cc39b91595e577fdff6128d7ce787892bd117274"
|
||||
"reference": "b0068bc1e5605bd2ebe1ba906f2426d5df123944"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/paragonie/certainty/zipball/cc39b91595e577fdff6128d7ce787892bd117274",
|
||||
"reference": "cc39b91595e577fdff6128d7ce787892bd117274",
|
||||
"url": "https://api.github.com/repos/paragonie/certainty/zipball/b0068bc1e5605bd2ebe1ba906f2426d5df123944",
|
||||
"reference": "b0068bc1e5605bd2ebe1ba906f2426d5df123944",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
|
|
@ -1891,7 +1960,7 @@
|
|||
"guzzlehttp/guzzle": "^6",
|
||||
"paragonie/constant_time_encoding": "^1|^2",
|
||||
"paragonie/sodium_compat": "^1.11",
|
||||
"php": "^5.5|^7"
|
||||
"php": "^5.5|^7|^8"
|
||||
},
|
||||
"require-dev": {
|
||||
"composer/composer": "^1",
|
||||
|
|
@ -1931,28 +2000,28 @@
|
|||
"ssl",
|
||||
"tls"
|
||||
],
|
||||
"time": "2019-09-27T22:26:33+00:00"
|
||||
"time": "2020-01-02T00:55:01+00:00"
|
||||
},
|
||||
{
|
||||
"name": "paragonie/constant_time_encoding",
|
||||
"version": "v2.2.3",
|
||||
"version": "v2.3.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/paragonie/constant_time_encoding.git",
|
||||
"reference": "55af0dc01992b4d0da7f6372e2eac097bbbaffdb"
|
||||
"reference": "47a1cedd2e4d52688eb8c96469c05ebc8fd28fa2"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/paragonie/constant_time_encoding/zipball/55af0dc01992b4d0da7f6372e2eac097bbbaffdb",
|
||||
"reference": "55af0dc01992b4d0da7f6372e2eac097bbbaffdb",
|
||||
"url": "https://api.github.com/repos/paragonie/constant_time_encoding/zipball/47a1cedd2e4d52688eb8c96469c05ebc8fd28fa2",
|
||||
"reference": "47a1cedd2e4d52688eb8c96469c05ebc8fd28fa2",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": "^7"
|
||||
"php": "^7|^8"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpunit/phpunit": "^6|^7",
|
||||
"vimeo/psalm": "^1|^2"
|
||||
"vimeo/psalm": "^1|^2|^3"
|
||||
},
|
||||
"type": "library",
|
||||
"autoload": {
|
||||
|
|
@ -1993,7 +2062,7 @@
|
|||
"hex2bin",
|
||||
"rfc4648"
|
||||
],
|
||||
"time": "2019-01-03T20:26:31+00:00"
|
||||
"time": "2019-11-06T19:20:29+00:00"
|
||||
},
|
||||
{
|
||||
"name": "paragonie/hidden-string",
|
||||
|
|
@ -2091,16 +2160,16 @@
|
|||
},
|
||||
{
|
||||
"name": "paragonie/sodium_compat",
|
||||
"version": "v1.11.1",
|
||||
"version": "v1.13.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/paragonie/sodium_compat.git",
|
||||
"reference": "a9f968bc99485f85f9303a8524c3485a7e87bc15"
|
||||
"reference": "bbade402cbe84c69b718120911506a3aa2bae653"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/paragonie/sodium_compat/zipball/a9f968bc99485f85f9303a8524c3485a7e87bc15",
|
||||
"reference": "a9f968bc99485f85f9303a8524c3485a7e87bc15",
|
||||
"url": "https://api.github.com/repos/paragonie/sodium_compat/zipball/bbade402cbe84c69b718120911506a3aa2bae653",
|
||||
"reference": "bbade402cbe84c69b718120911506a3aa2bae653",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
|
|
@ -2108,7 +2177,7 @@
|
|||
"php": "^5.2.4|^5.3|^5.4|^5.5|^5.6|^7|^8"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpunit/phpunit": "^3|^4|^5"
|
||||
"phpunit/phpunit": "^3|^4|^5|^6|^7"
|
||||
},
|
||||
"suggest": {
|
||||
"ext-libsodium": "PHP < 7.0: Better performance, password hashing (Argon2i), secure memory management (memzero), and better security.",
|
||||
|
|
@ -2169,7 +2238,7 @@
|
|||
"secret-key cryptography",
|
||||
"side-channel resistant"
|
||||
],
|
||||
"time": "2019-09-12T12:05:58+00:00"
|
||||
"time": "2020-03-20T21:48:09+00:00"
|
||||
},
|
||||
{
|
||||
"name": "pear/console_table",
|
||||
|
|
@ -2228,20 +2297,20 @@
|
|||
},
|
||||
{
|
||||
"name": "pear/text_languagedetect",
|
||||
"version": "v1.0.0",
|
||||
"version": "v1.0.1",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/pear/Text_LanguageDetect.git",
|
||||
"reference": "bb9ff6f4970f686fac59081e916b456021fe7ba6"
|
||||
"reference": "9e253f26cef9a9066f53f200cc3e0684018cb5b5"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/pear/Text_LanguageDetect/zipball/bb9ff6f4970f686fac59081e916b456021fe7ba6",
|
||||
"reference": "bb9ff6f4970f686fac59081e916b456021fe7ba6",
|
||||
"url": "https://api.github.com/repos/pear/Text_LanguageDetect/zipball/9e253f26cef9a9066f53f200cc3e0684018cb5b5",
|
||||
"reference": "9e253f26cef9a9066f53f200cc3e0684018cb5b5",
|
||||
"shasum": ""
|
||||
},
|
||||
"require-dev": {
|
||||
"phpunit/phpunit": "*"
|
||||
"phpunit/phpunit": "8.*|9.*"
|
||||
},
|
||||
"suggest": {
|
||||
"ext-mbstring": "May require the mbstring PHP extension"
|
||||
|
|
@ -2268,7 +2337,7 @@
|
|||
],
|
||||
"description": "Identify human languages from text samples",
|
||||
"homepage": "http://pear.php.net/package/Text_LanguageDetect",
|
||||
"time": "2017-03-02T16:14:08+00:00"
|
||||
"time": "2020-05-17T12:19:40+00:00"
|
||||
},
|
||||
{
|
||||
"name": "pragmarx/google2fa",
|
||||
|
|
@ -2600,16 +2669,16 @@
|
|||
},
|
||||
{
|
||||
"name": "psr/log",
|
||||
"version": "1.1.0",
|
||||
"version": "1.1.3",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/php-fig/log.git",
|
||||
"reference": "6c001f1daafa3a3ac1d8ff69ee4db8e799a654dd"
|
||||
"reference": "0f73288fd15629204f9d42b7055f72dacbe811fc"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/php-fig/log/zipball/6c001f1daafa3a3ac1d8ff69ee4db8e799a654dd",
|
||||
"reference": "6c001f1daafa3a3ac1d8ff69ee4db8e799a654dd",
|
||||
"url": "https://api.github.com/repos/php-fig/log/zipball/0f73288fd15629204f9d42b7055f72dacbe811fc",
|
||||
"reference": "0f73288fd15629204f9d42b7055f72dacbe811fc",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
|
|
@ -2618,7 +2687,7 @@
|
|||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "1.0.x-dev"
|
||||
"dev-master": "1.1.x-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
|
|
@ -2643,7 +2712,7 @@
|
|||
"psr",
|
||||
"psr-3"
|
||||
],
|
||||
"time": "2018-11-20T15:27:04+00:00"
|
||||
"time": "2020-03-23T09:12:05+00:00"
|
||||
},
|
||||
{
|
||||
"name": "ralouphie/getallheaders",
|
||||
|
|
@ -2735,21 +2804,25 @@
|
|||
},
|
||||
{
|
||||
"name": "smarty/smarty",
|
||||
"version": "v3.1.33",
|
||||
"version": "v3.1.36",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/smarty-php/smarty.git",
|
||||
"reference": "dd55b23121e55a3b4f1af90a707a6c4e5969530f"
|
||||
"reference": "fd148f7ade295014fff77f89ee3d5b20d9d55451"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/smarty-php/smarty/zipball/dd55b23121e55a3b4f1af90a707a6c4e5969530f",
|
||||
"reference": "dd55b23121e55a3b4f1af90a707a6c4e5969530f",
|
||||
"url": "https://api.github.com/repos/smarty-php/smarty/zipball/fd148f7ade295014fff77f89ee3d5b20d9d55451",
|
||||
"reference": "fd148f7ade295014fff77f89ee3d5b20d9d55451",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=5.2"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpunit/phpunit": "6.4.1",
|
||||
"smarty/smarty-lexer": "^3.1"
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
|
|
@ -2757,8 +2830,8 @@
|
|||
}
|
||||
},
|
||||
"autoload": {
|
||||
"files": [
|
||||
"libs/bootstrap.php"
|
||||
"classmap": [
|
||||
"libs/"
|
||||
]
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
|
|
@ -2784,20 +2857,141 @@
|
|||
"keywords": [
|
||||
"templating"
|
||||
],
|
||||
"time": "2018-09-12T20:54:16+00:00"
|
||||
"time": "2020-04-14T14:44:26+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/polyfill-php56",
|
||||
"version": "v1.12.0",
|
||||
"name": "symfony/polyfill-intl-idn",
|
||||
"version": "v1.17.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/polyfill-php56.git",
|
||||
"reference": "0e3b212e96a51338639d8ce175c046d7729c3403"
|
||||
"url": "https://github.com/symfony/polyfill-intl-idn.git",
|
||||
"reference": "3bff59ea7047e925be6b7f2059d60af31bb46d6a"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/polyfill-php56/zipball/0e3b212e96a51338639d8ce175c046d7729c3403",
|
||||
"reference": "0e3b212e96a51338639d8ce175c046d7729c3403",
|
||||
"url": "https://api.github.com/repos/symfony/polyfill-intl-idn/zipball/3bff59ea7047e925be6b7f2059d60af31bb46d6a",
|
||||
"reference": "3bff59ea7047e925be6b7f2059d60af31bb46d6a",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=5.3.3",
|
||||
"symfony/polyfill-mbstring": "^1.3",
|
||||
"symfony/polyfill-php72": "^1.10"
|
||||
},
|
||||
"suggest": {
|
||||
"ext-intl": "For best performance"
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "1.17-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Symfony\\Polyfill\\Intl\\Idn\\": ""
|
||||
},
|
||||
"files": [
|
||||
"bootstrap.php"
|
||||
]
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Laurent Bassin",
|
||||
"email": "laurent@bassin.info"
|
||||
},
|
||||
{
|
||||
"name": "Symfony Community",
|
||||
"homepage": "https://symfony.com/contributors"
|
||||
}
|
||||
],
|
||||
"description": "Symfony polyfill for intl's idn_to_ascii and idn_to_utf8 functions",
|
||||
"homepage": "https://symfony.com",
|
||||
"keywords": [
|
||||
"compatibility",
|
||||
"idn",
|
||||
"intl",
|
||||
"polyfill",
|
||||
"portable",
|
||||
"shim"
|
||||
],
|
||||
"time": "2020-05-12T16:47:27+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/polyfill-mbstring",
|
||||
"version": "v1.17.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/polyfill-mbstring.git",
|
||||
"reference": "fa79b11539418b02fc5e1897267673ba2c19419c"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/fa79b11539418b02fc5e1897267673ba2c19419c",
|
||||
"reference": "fa79b11539418b02fc5e1897267673ba2c19419c",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=5.3.3"
|
||||
},
|
||||
"suggest": {
|
||||
"ext-mbstring": "For best performance"
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "1.17-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Symfony\\Polyfill\\Mbstring\\": ""
|
||||
},
|
||||
"files": [
|
||||
"bootstrap.php"
|
||||
]
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Nicolas Grekas",
|
||||
"email": "p@tchwork.com"
|
||||
},
|
||||
{
|
||||
"name": "Symfony Community",
|
||||
"homepage": "https://symfony.com/contributors"
|
||||
}
|
||||
],
|
||||
"description": "Symfony polyfill for the Mbstring extension",
|
||||
"homepage": "https://symfony.com",
|
||||
"keywords": [
|
||||
"compatibility",
|
||||
"mbstring",
|
||||
"polyfill",
|
||||
"portable",
|
||||
"shim"
|
||||
],
|
||||
"time": "2020-05-12T16:47:27+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/polyfill-php56",
|
||||
"version": "v1.17.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/polyfill-php56.git",
|
||||
"reference": "e3c8c138280cdfe4b81488441555583aa1984e23"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/polyfill-php56/zipball/e3c8c138280cdfe4b81488441555583aa1984e23",
|
||||
"reference": "e3c8c138280cdfe4b81488441555583aa1984e23",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
|
|
@ -2807,7 +3001,7 @@
|
|||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "1.12-dev"
|
||||
"dev-master": "1.17-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
|
|
@ -2840,20 +3034,20 @@
|
|||
"portable",
|
||||
"shim"
|
||||
],
|
||||
"time": "2019-08-06T08:03:45+00:00"
|
||||
"time": "2020-05-12T16:47:27+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/polyfill-util",
|
||||
"version": "v1.12.0",
|
||||
"name": "symfony/polyfill-php72",
|
||||
"version": "v1.17.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/polyfill-util.git",
|
||||
"reference": "4317de1386717b4c22caed7725350a8887ab205c"
|
||||
"url": "https://github.com/symfony/polyfill-php72.git",
|
||||
"reference": "f048e612a3905f34931127360bdd2def19a5e582"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/polyfill-util/zipball/4317de1386717b4c22caed7725350a8887ab205c",
|
||||
"reference": "4317de1386717b4c22caed7725350a8887ab205c",
|
||||
"url": "https://api.github.com/repos/symfony/polyfill-php72/zipball/f048e612a3905f34931127360bdd2def19a5e582",
|
||||
"reference": "f048e612a3905f34931127360bdd2def19a5e582",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
|
|
@ -2862,7 +3056,62 @@
|
|||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "1.12-dev"
|
||||
"dev-master": "1.17-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Symfony\\Polyfill\\Php72\\": ""
|
||||
},
|
||||
"files": [
|
||||
"bootstrap.php"
|
||||
]
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Nicolas Grekas",
|
||||
"email": "p@tchwork.com"
|
||||
},
|
||||
{
|
||||
"name": "Symfony Community",
|
||||
"homepage": "https://symfony.com/contributors"
|
||||
}
|
||||
],
|
||||
"description": "Symfony polyfill backporting some PHP 7.2+ features to lower PHP versions",
|
||||
"homepage": "https://symfony.com",
|
||||
"keywords": [
|
||||
"compatibility",
|
||||
"polyfill",
|
||||
"portable",
|
||||
"shim"
|
||||
],
|
||||
"time": "2020-05-12T16:47:27+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/polyfill-util",
|
||||
"version": "v1.17.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/polyfill-util.git",
|
||||
"reference": "4afb4110fc037752cf0ce9869f9ab8162c4e20d7"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/polyfill-util/zipball/4afb4110fc037752cf0ce9869f9ab8162c4e20d7",
|
||||
"reference": "4afb4110fc037752cf0ce9869f9ab8162c4e20d7",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=5.3.3"
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "1.17-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
|
|
@ -2892,7 +3141,7 @@
|
|||
"polyfill",
|
||||
"shim"
|
||||
],
|
||||
"time": "2019-08-06T08:03:45+00:00"
|
||||
"time": "2020-05-12T16:14:59+00:00"
|
||||
}
|
||||
],
|
||||
"packages-dev": [
|
||||
|
|
@ -3097,16 +3346,16 @@
|
|||
},
|
||||
{
|
||||
"name": "mikey179/vfsstream",
|
||||
"version": "v1.6.7",
|
||||
"version": "v1.6.8",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/bovigo/vfsStream.git",
|
||||
"reference": "2b544ac3a21bcc4dde5d90c4ae8d06f4319055fb"
|
||||
"reference": "231c73783ebb7dd9ec77916c10037eff5a2b6efe"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/bovigo/vfsStream/zipball/2b544ac3a21bcc4dde5d90c4ae8d06f4319055fb",
|
||||
"reference": "2b544ac3a21bcc4dde5d90c4ae8d06f4319055fb",
|
||||
"url": "https://api.github.com/repos/bovigo/vfsStream/zipball/231c73783ebb7dd9ec77916c10037eff5a2b6efe",
|
||||
"reference": "231c73783ebb7dd9ec77916c10037eff5a2b6efe",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
|
|
@ -3139,20 +3388,20 @@
|
|||
],
|
||||
"description": "Virtual file system to mock the real file system in unit tests.",
|
||||
"homepage": "http://vfs.bovigo.org/",
|
||||
"time": "2019-08-01T01:38:37+00:00"
|
||||
"time": "2019-10-30T15:31:00+00:00"
|
||||
},
|
||||
{
|
||||
"name": "mockery/mockery",
|
||||
"version": "1.2.3",
|
||||
"version": "1.3.1",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/mockery/mockery.git",
|
||||
"reference": "4eff936d83eb809bde2c57a3cea0ee9643769031"
|
||||
"reference": "f69bbde7d7a75d6b2862d9ca8fab1cd28014b4be"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/mockery/mockery/zipball/4eff936d83eb809bde2c57a3cea0ee9643769031",
|
||||
"reference": "4eff936d83eb809bde2c57a3cea0ee9643769031",
|
||||
"url": "https://api.github.com/repos/mockery/mockery/zipball/f69bbde7d7a75d6b2862d9ca8fab1cd28014b4be",
|
||||
"reference": "f69bbde7d7a75d6b2862d9ca8fab1cd28014b4be",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
|
|
@ -3166,7 +3415,7 @@
|
|||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "1.0.x-dev"
|
||||
"dev-master": "1.3.x-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
|
|
@ -3204,7 +3453,7 @@
|
|||
"test double",
|
||||
"testing"
|
||||
],
|
||||
"time": "2019-08-07T15:01:07+00:00"
|
||||
"time": "2019-12-26T09:49:15+00:00"
|
||||
},
|
||||
{
|
||||
"name": "myclabs/deep-copy",
|
||||
|
|
@ -3399,33 +3648,33 @@
|
|||
},
|
||||
{
|
||||
"name": "phpspec/prophecy",
|
||||
"version": "1.8.1",
|
||||
"version": "v1.10.3",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/phpspec/prophecy.git",
|
||||
"reference": "1927e75f4ed19131ec9bcc3b002e07fb1173ee76"
|
||||
"reference": "451c3cd1418cf640de218914901e51b064abb093"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/phpspec/prophecy/zipball/1927e75f4ed19131ec9bcc3b002e07fb1173ee76",
|
||||
"reference": "1927e75f4ed19131ec9bcc3b002e07fb1173ee76",
|
||||
"url": "https://api.github.com/repos/phpspec/prophecy/zipball/451c3cd1418cf640de218914901e51b064abb093",
|
||||
"reference": "451c3cd1418cf640de218914901e51b064abb093",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"doctrine/instantiator": "^1.0.2",
|
||||
"php": "^5.3|^7.0",
|
||||
"phpdocumentor/reflection-docblock": "^2.0|^3.0.2|^4.0",
|
||||
"sebastian/comparator": "^1.1|^2.0|^3.0",
|
||||
"sebastian/recursion-context": "^1.0|^2.0|^3.0"
|
||||
"phpdocumentor/reflection-docblock": "^2.0|^3.0.2|^4.0|^5.0",
|
||||
"sebastian/comparator": "^1.2.3|^2.0|^3.0|^4.0",
|
||||
"sebastian/recursion-context": "^1.0|^2.0|^3.0|^4.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpspec/phpspec": "^2.5|^3.2",
|
||||
"phpspec/phpspec": "^2.5 || ^3.2",
|
||||
"phpunit/phpunit": "^4.8.35 || ^5.7 || ^6.5 || ^7.1"
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "1.8.x-dev"
|
||||
"dev-master": "1.10.x-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
|
|
@ -3458,7 +3707,7 @@
|
|||
"spy",
|
||||
"stub"
|
||||
],
|
||||
"time": "2019-06-13T12:50:23+00:00"
|
||||
"time": "2020-03-05T15:02:03+00:00"
|
||||
},
|
||||
{
|
||||
"name": "phpunit/php-code-coverage",
|
||||
|
|
@ -4366,16 +4615,16 @@
|
|||
},
|
||||
{
|
||||
"name": "symfony/polyfill-ctype",
|
||||
"version": "v1.12.0",
|
||||
"version": "v1.17.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/polyfill-ctype.git",
|
||||
"reference": "550ebaac289296ce228a706d0867afc34687e3f4"
|
||||
"reference": "e94c8b1bbe2bc77507a1056cdb06451c75b427f9"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/550ebaac289296ce228a706d0867afc34687e3f4",
|
||||
"reference": "550ebaac289296ce228a706d0867afc34687e3f4",
|
||||
"url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/e94c8b1bbe2bc77507a1056cdb06451c75b427f9",
|
||||
"reference": "e94c8b1bbe2bc77507a1056cdb06451c75b427f9",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
|
|
@ -4387,7 +4636,7 @@
|
|||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "1.12-dev"
|
||||
"dev-master": "1.17-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
|
|
@ -4420,31 +4669,27 @@
|
|||
"polyfill",
|
||||
"portable"
|
||||
],
|
||||
"time": "2019-08-06T08:03:45+00:00"
|
||||
"time": "2020-05-12T16:14:59+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/yaml",
|
||||
"version": "v3.4.32",
|
||||
"version": "v3.3.6",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/yaml.git",
|
||||
"reference": "768f817446da74a776a31eea335540f9dcb53942"
|
||||
"reference": "ddc23324e6cfe066f3dd34a37ff494fa80b617ed"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/yaml/zipball/768f817446da74a776a31eea335540f9dcb53942",
|
||||
"reference": "768f817446da74a776a31eea335540f9dcb53942",
|
||||
"url": "https://api.github.com/repos/symfony/yaml/zipball/ddc23324e6cfe066f3dd34a37ff494fa80b617ed",
|
||||
"reference": "ddc23324e6cfe066f3dd34a37ff494fa80b617ed",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": "^5.5.9|>=7.0.8",
|
||||
"symfony/polyfill-ctype": "~1.8"
|
||||
},
|
||||
"conflict": {
|
||||
"symfony/console": "<3.4"
|
||||
"php": ">=5.5.9"
|
||||
},
|
||||
"require-dev": {
|
||||
"symfony/console": "~3.4|~4.0"
|
||||
"symfony/console": "~2.8|~3.0"
|
||||
},
|
||||
"suggest": {
|
||||
"symfony/console": "For validating YAML files using the lint command"
|
||||
|
|
@ -4452,7 +4697,7 @@
|
|||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "3.4-dev"
|
||||
"dev-master": "3.3-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
|
|
@ -4479,35 +4724,34 @@
|
|||
],
|
||||
"description": "Symfony Yaml Component",
|
||||
"homepage": "https://symfony.com",
|
||||
"time": "2019-09-10T10:38:46+00:00"
|
||||
"time": "2017-07-23T12:43:26+00:00"
|
||||
},
|
||||
{
|
||||
"name": "webmozart/assert",
|
||||
"version": "1.5.0",
|
||||
"version": "1.9.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/webmozart/assert.git",
|
||||
"reference": "88e6d84706d09a236046d686bbea96f07b3a34f4"
|
||||
"reference": "9dc4f203e36f2b486149058bade43c851dd97451"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/webmozart/assert/zipball/88e6d84706d09a236046d686bbea96f07b3a34f4",
|
||||
"reference": "88e6d84706d09a236046d686bbea96f07b3a34f4",
|
||||
"url": "https://api.github.com/repos/webmozart/assert/zipball/9dc4f203e36f2b486149058bade43c851dd97451",
|
||||
"reference": "9dc4f203e36f2b486149058bade43c851dd97451",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": "^5.3.3 || ^7.0",
|
||||
"symfony/polyfill-ctype": "^1.8"
|
||||
},
|
||||
"conflict": {
|
||||
"phpstan/phpstan": "<0.12.20",
|
||||
"vimeo/psalm": "<3.9.1"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpunit/phpunit": "^4.8.36 || ^7.5.13"
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "1.3-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Webmozart\\Assert\\": "src/"
|
||||
|
|
@ -4529,7 +4773,7 @@
|
|||
"check",
|
||||
"validate"
|
||||
],
|
||||
"time": "2019-08-24T08:43:50+00:00"
|
||||
"time": "2020-06-16T10:16:42+00:00"
|
||||
}
|
||||
],
|
||||
"aliases": [],
|
||||
|
|
@ -4554,5 +4798,8 @@
|
|||
"ext-simplexml": "*",
|
||||
"ext-xml": "*"
|
||||
},
|
||||
"platform-dev": []
|
||||
"platform-dev": [],
|
||||
"platform-overrides": {
|
||||
"php": "7.0"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
735
database.sql
735
database.sql
|
|
@ -1,9 +1,186 @@
|
|||
-- ------------------------------------------
|
||||
-- Friendica 2020.03-rc (Dalmatian Bellflower)
|
||||
-- DB_UPDATE_VERSION 1338
|
||||
-- Friendica 2020.06-dev (Red Hot Poker)
|
||||
-- DB_UPDATE_VERSION 1353
|
||||
-- ------------------------------------------
|
||||
|
||||
|
||||
--
|
||||
-- TABLE gserver
|
||||
--
|
||||
CREATE TABLE IF NOT EXISTS `gserver` (
|
||||
`id` int unsigned NOT NULL auto_increment COMMENT 'sequential ID',
|
||||
`url` varchar(255) NOT NULL DEFAULT '' COMMENT '',
|
||||
`nurl` varchar(255) NOT NULL DEFAULT '' COMMENT '',
|
||||
`version` varchar(255) NOT NULL DEFAULT '' COMMENT '',
|
||||
`site_name` varchar(255) NOT NULL DEFAULT '' COMMENT '',
|
||||
`info` text COMMENT '',
|
||||
`register_policy` tinyint NOT NULL DEFAULT 0 COMMENT '',
|
||||
`registered-users` int unsigned NOT NULL DEFAULT 0 COMMENT 'Number of registered users',
|
||||
`directory-type` tinyint DEFAULT 0 COMMENT 'Type of directory service (Poco, Mastodon)',
|
||||
`poco` varchar(255) NOT NULL DEFAULT '' COMMENT '',
|
||||
`noscrape` varchar(255) NOT NULL DEFAULT '' COMMENT '',
|
||||
`network` char(4) NOT NULL DEFAULT '' COMMENT '',
|
||||
`platform` varchar(255) NOT NULL DEFAULT '' COMMENT '',
|
||||
`relay-subscribe` boolean NOT NULL DEFAULT '0' COMMENT 'Has the server subscribed to the relay system',
|
||||
`relay-scope` varchar(10) NOT NULL DEFAULT '' COMMENT 'The scope of messages that the server wants to get',
|
||||
`detection-method` tinyint unsigned COMMENT 'Method that had been used to detect that server',
|
||||
`created` datetime NOT NULL DEFAULT '0001-01-01 00:00:00' COMMENT '',
|
||||
`last_poco_query` datetime DEFAULT '0001-01-01 00:00:00' COMMENT '',
|
||||
`last_contact` datetime DEFAULT '0001-01-01 00:00:00' COMMENT '',
|
||||
`last_failure` datetime DEFAULT '0001-01-01 00:00:00' COMMENT '',
|
||||
PRIMARY KEY(`id`),
|
||||
UNIQUE INDEX `nurl` (`nurl`(190))
|
||||
) DEFAULT COLLATE utf8mb4_general_ci COMMENT='Global servers';
|
||||
|
||||
--
|
||||
-- TABLE clients
|
||||
--
|
||||
CREATE TABLE IF NOT EXISTS `clients` (
|
||||
`client_id` varchar(20) NOT NULL COMMENT '',
|
||||
`pw` varchar(20) NOT NULL DEFAULT '' COMMENT '',
|
||||
`redirect_uri` varchar(200) NOT NULL DEFAULT '' COMMENT '',
|
||||
`name` text COMMENT '',
|
||||
`icon` text COMMENT '',
|
||||
`uid` mediumint unsigned NOT NULL DEFAULT 0 COMMENT 'User id',
|
||||
PRIMARY KEY(`client_id`)
|
||||
) DEFAULT COLLATE utf8mb4_general_ci COMMENT='OAuth usage';
|
||||
|
||||
--
|
||||
-- TABLE contact
|
||||
--
|
||||
CREATE TABLE IF NOT EXISTS `contact` (
|
||||
`id` int unsigned NOT NULL auto_increment COMMENT 'sequential ID',
|
||||
`uid` mediumint unsigned NOT NULL DEFAULT 0 COMMENT 'Owner User id',
|
||||
`created` datetime NOT NULL DEFAULT '0001-01-01 00:00:00' COMMENT '',
|
||||
`updated` datetime DEFAULT '0001-01-01 00:00:00' COMMENT 'Date of last contact update',
|
||||
`self` boolean NOT NULL DEFAULT '0' COMMENT '1 if the contact is the user him/her self',
|
||||
`remote_self` boolean NOT NULL DEFAULT '0' COMMENT '',
|
||||
`rel` tinyint unsigned NOT NULL DEFAULT 0 COMMENT 'The kind of the relation between the user and the contact',
|
||||
`duplex` boolean NOT NULL DEFAULT '0' COMMENT '',
|
||||
`network` char(4) NOT NULL DEFAULT '' COMMENT 'Network of the contact',
|
||||
`protocol` char(4) NOT NULL DEFAULT '' COMMENT 'Protocol of the contact',
|
||||
`name` varchar(255) NOT NULL DEFAULT '' COMMENT 'Name that this contact is known by',
|
||||
`nick` varchar(255) NOT NULL DEFAULT '' COMMENT 'Nick- and user name of the contact',
|
||||
`location` varchar(255) DEFAULT '' COMMENT '',
|
||||
`about` text COMMENT '',
|
||||
`keywords` text COMMENT 'public keywords (interests) of the contact',
|
||||
`gender` varchar(32) NOT NULL DEFAULT '' COMMENT 'Deprecated',
|
||||
`xmpp` varchar(255) NOT NULL DEFAULT '' COMMENT '',
|
||||
`attag` varchar(255) NOT NULL DEFAULT '' COMMENT '',
|
||||
`avatar` varchar(255) NOT NULL DEFAULT '' COMMENT '',
|
||||
`photo` varchar(255) DEFAULT '' COMMENT 'Link to the profile photo of the contact',
|
||||
`thumb` varchar(255) DEFAULT '' COMMENT 'Link to the profile photo (thumb size)',
|
||||
`micro` varchar(255) DEFAULT '' COMMENT 'Link to the profile photo (micro size)',
|
||||
`site-pubkey` text COMMENT '',
|
||||
`issued-id` varchar(255) NOT NULL DEFAULT '' COMMENT '',
|
||||
`dfrn-id` varchar(255) NOT NULL DEFAULT '' COMMENT '',
|
||||
`url` varchar(255) NOT NULL DEFAULT '' COMMENT '',
|
||||
`nurl` varchar(255) NOT NULL DEFAULT '' COMMENT '',
|
||||
`addr` varchar(255) NOT NULL DEFAULT '' COMMENT '',
|
||||
`alias` varchar(255) NOT NULL DEFAULT '' COMMENT '',
|
||||
`pubkey` text COMMENT 'RSA public key 4096 bit',
|
||||
`prvkey` text COMMENT 'RSA private key 4096 bit',
|
||||
`batch` varchar(255) NOT NULL DEFAULT '' COMMENT '',
|
||||
`request` varchar(255) COMMENT '',
|
||||
`notify` varchar(255) COMMENT '',
|
||||
`poll` varchar(255) COMMENT '',
|
||||
`confirm` varchar(255) COMMENT '',
|
||||
`subscribe` varchar(255) COMMENT '',
|
||||
`poco` varchar(255) COMMENT '',
|
||||
`aes_allow` boolean NOT NULL DEFAULT '0' COMMENT '',
|
||||
`ret-aes` boolean NOT NULL DEFAULT '0' COMMENT '',
|
||||
`usehub` boolean NOT NULL DEFAULT '0' COMMENT '',
|
||||
`subhub` boolean NOT NULL DEFAULT '0' COMMENT '',
|
||||
`hub-verify` varchar(255) NOT NULL DEFAULT '' COMMENT '',
|
||||
`last-update` datetime NOT NULL DEFAULT '0001-01-01 00:00:00' COMMENT 'Date of the last try to update the contact info',
|
||||
`success_update` datetime NOT NULL DEFAULT '0001-01-01 00:00:00' COMMENT 'Date of the last successful contact update',
|
||||
`failure_update` datetime NOT NULL DEFAULT '0001-01-01 00:00:00' COMMENT 'Date of the last failed update',
|
||||
`name-date` datetime NOT NULL DEFAULT '0001-01-01 00:00:00' COMMENT '',
|
||||
`uri-date` datetime NOT NULL DEFAULT '0001-01-01 00:00:00' COMMENT '',
|
||||
`avatar-date` datetime NOT NULL DEFAULT '0001-01-01 00:00:00' COMMENT '',
|
||||
`term-date` datetime NOT NULL DEFAULT '0001-01-01 00:00:00' COMMENT '',
|
||||
`last-item` datetime NOT NULL DEFAULT '0001-01-01 00:00:00' COMMENT 'date of the last post',
|
||||
`priority` tinyint unsigned NOT NULL DEFAULT 0 COMMENT '',
|
||||
`blocked` boolean NOT NULL DEFAULT '1' COMMENT 'Node-wide block status',
|
||||
`block_reason` text COMMENT 'Node-wide block reason',
|
||||
`readonly` boolean NOT NULL DEFAULT '0' COMMENT 'posts of the contact are readonly',
|
||||
`writable` boolean NOT NULL DEFAULT '0' COMMENT '',
|
||||
`forum` boolean NOT NULL DEFAULT '0' COMMENT 'contact is a forum',
|
||||
`prv` boolean NOT NULL DEFAULT '0' COMMENT 'contact is a private group',
|
||||
`contact-type` tinyint NOT NULL DEFAULT 0 COMMENT '',
|
||||
`hidden` boolean NOT NULL DEFAULT '0' COMMENT '',
|
||||
`archive` boolean NOT NULL DEFAULT '0' COMMENT '',
|
||||
`pending` boolean NOT NULL DEFAULT '1' COMMENT '',
|
||||
`deleted` boolean NOT NULL DEFAULT '0' COMMENT 'Contact has been deleted',
|
||||
`rating` tinyint NOT NULL DEFAULT 0 COMMENT '',
|
||||
`unsearchable` boolean NOT NULL DEFAULT '0' COMMENT 'Contact prefers to not be searchable',
|
||||
`sensitive` boolean NOT NULL DEFAULT '0' COMMENT 'Contact posts sensitive content',
|
||||
`baseurl` varchar(255) DEFAULT '' COMMENT 'baseurl of the contact',
|
||||
`gsid` int unsigned COMMENT 'Global Server ID',
|
||||
`reason` text COMMENT '',
|
||||
`closeness` tinyint unsigned NOT NULL DEFAULT 99 COMMENT '',
|
||||
`info` mediumtext COMMENT '',
|
||||
`profile-id` int unsigned COMMENT 'Deprecated',
|
||||
`bdyear` varchar(4) NOT NULL DEFAULT '' COMMENT '',
|
||||
`bd` date NOT NULL DEFAULT '0001-01-01' COMMENT '',
|
||||
`notify_new_posts` boolean NOT NULL DEFAULT '0' COMMENT '',
|
||||
`fetch_further_information` tinyint unsigned NOT NULL DEFAULT 0 COMMENT '',
|
||||
`ffi_keyword_denylist` text COMMENT '',
|
||||
PRIMARY KEY(`id`),
|
||||
INDEX `uid_name` (`uid`,`name`(190)),
|
||||
INDEX `self_uid` (`self`,`uid`),
|
||||
INDEX `alias_uid` (`alias`(32),`uid`),
|
||||
INDEX `pending_uid` (`pending`,`uid`),
|
||||
INDEX `blocked_uid` (`blocked`,`uid`),
|
||||
INDEX `uid_rel_network_poll` (`uid`,`rel`,`network`,`poll`(64),`archive`),
|
||||
INDEX `uid_network_batch` (`uid`,`network`,`batch`(64)),
|
||||
INDEX `addr_uid` (`addr`(32),`uid`),
|
||||
INDEX `nurl_uid` (`nurl`(32),`uid`),
|
||||
INDEX `nick_uid` (`nick`(32),`uid`),
|
||||
INDEX `dfrn-id` (`dfrn-id`(64)),
|
||||
INDEX `issued-id` (`issued-id`(64)),
|
||||
INDEX `gsid` (`gsid`),
|
||||
FOREIGN KEY (`gsid`) REFERENCES `gserver` (`id`) ON UPDATE RESTRICT ON DELETE RESTRICT
|
||||
) DEFAULT COLLATE utf8mb4_general_ci COMMENT='contact table';
|
||||
|
||||
--
|
||||
-- TABLE item-uri
|
||||
--
|
||||
CREATE TABLE IF NOT EXISTS `item-uri` (
|
||||
`id` int unsigned NOT NULL auto_increment,
|
||||
`uri` varbinary(255) NOT NULL COMMENT 'URI of an item',
|
||||
`guid` varbinary(255) COMMENT 'A unique identifier for an item',
|
||||
PRIMARY KEY(`id`),
|
||||
UNIQUE INDEX `uri` (`uri`),
|
||||
INDEX `guid` (`guid`)
|
||||
) DEFAULT COLLATE utf8mb4_general_ci COMMENT='URI and GUID for items';
|
||||
|
||||
--
|
||||
-- TABLE permissionset
|
||||
--
|
||||
CREATE TABLE IF NOT EXISTS `permissionset` (
|
||||
`id` int unsigned NOT NULL auto_increment COMMENT 'sequential ID',
|
||||
`uid` mediumint unsigned NOT NULL DEFAULT 0 COMMENT 'Owner id of this permission set',
|
||||
`allow_cid` mediumtext COMMENT 'Access Control - list of allowed contact.id \'<19><78>\'',
|
||||
`allow_gid` mediumtext COMMENT 'Access Control - list of allowed groups',
|
||||
`deny_cid` mediumtext COMMENT 'Access Control - list of denied contact.id',
|
||||
`deny_gid` mediumtext COMMENT 'Access Control - list of denied groups',
|
||||
PRIMARY KEY(`id`),
|
||||
INDEX `uid_allow_cid_allow_gid_deny_cid_deny_gid` (`allow_cid`(50),`allow_gid`(30),`deny_cid`(50),`deny_gid`(30))
|
||||
) DEFAULT COLLATE utf8mb4_general_ci COMMENT='';
|
||||
|
||||
--
|
||||
-- TABLE tag
|
||||
--
|
||||
CREATE TABLE IF NOT EXISTS `tag` (
|
||||
`id` int unsigned NOT NULL auto_increment COMMENT '',
|
||||
`name` varchar(96) NOT NULL DEFAULT '' COMMENT '',
|
||||
`url` varbinary(255) NOT NULL DEFAULT '' COMMENT '',
|
||||
PRIMARY KEY(`id`),
|
||||
UNIQUE INDEX `type_name_url` (`name`,`url`),
|
||||
INDEX `url` (`url`)
|
||||
) DEFAULT COLLATE utf8mb4_general_ci COMMENT='tags and mentions';
|
||||
|
||||
--
|
||||
-- TABLE 2fa_app_specific_password
|
||||
--
|
||||
|
|
@ -64,7 +241,9 @@ CREATE TABLE IF NOT EXISTS `apcontact` (
|
|||
`addr` varchar(255) COMMENT '',
|
||||
`alias` varchar(255) COMMENT '',
|
||||
`pubkey` text COMMENT '',
|
||||
`subscribe` varchar(255) COMMENT '',
|
||||
`baseurl` varchar(255) COMMENT 'baseurl of the ap contact',
|
||||
`gsid` int unsigned COMMENT 'Global Server ID',
|
||||
`generator` varchar(255) COMMENT 'Name of the contact\'s system',
|
||||
`following_count` int unsigned DEFAULT 0 COMMENT 'Number of following contacts',
|
||||
`followers_count` int unsigned DEFAULT 0 COMMENT 'Number of followers',
|
||||
|
|
@ -73,7 +252,9 @@ CREATE TABLE IF NOT EXISTS `apcontact` (
|
|||
PRIMARY KEY(`url`),
|
||||
INDEX `addr` (`addr`(32)),
|
||||
INDEX `alias` (`alias`(190)),
|
||||
INDEX `url` (`followers`(190))
|
||||
INDEX `followers` (`followers`(190)),
|
||||
INDEX `gsid` (`gsid`),
|
||||
FOREIGN KEY (`gsid`) REFERENCES `gserver` (`id`) ON UPDATE RESTRICT ON DELETE RESTRICT
|
||||
) DEFAULT COLLATE utf8mb4_general_ci COMMENT='ActivityPub compatible contacts - used in the ActivityPub implementation';
|
||||
|
||||
--
|
||||
|
|
@ -107,7 +288,9 @@ CREATE TABLE IF NOT EXISTS `auth_codes` (
|
|||
`redirect_uri` varchar(200) NOT NULL DEFAULT '' COMMENT '',
|
||||
`expires` int NOT NULL DEFAULT 0 COMMENT '',
|
||||
`scope` varchar(250) NOT NULL DEFAULT '' COMMENT '',
|
||||
PRIMARY KEY(`id`)
|
||||
PRIMARY KEY(`id`),
|
||||
INDEX `client_id` (`client_id`),
|
||||
FOREIGN KEY (`client_id`) REFERENCES `clients` (`client_id`) ON UPDATE RESTRICT ON DELETE CASCADE
|
||||
) DEFAULT COLLATE utf8mb4_general_ci COMMENT='OAuth usage';
|
||||
|
||||
--
|
||||
|
|
@ -135,19 +318,6 @@ CREATE TABLE IF NOT EXISTS `challenge` (
|
|||
PRIMARY KEY(`id`)
|
||||
) DEFAULT COLLATE utf8mb4_general_ci COMMENT='';
|
||||
|
||||
--
|
||||
-- TABLE clients
|
||||
--
|
||||
CREATE TABLE IF NOT EXISTS `clients` (
|
||||
`client_id` varchar(20) NOT NULL COMMENT '',
|
||||
`pw` varchar(20) NOT NULL DEFAULT '' COMMENT '',
|
||||
`redirect_uri` varchar(200) NOT NULL DEFAULT '' COMMENT '',
|
||||
`name` text COMMENT '',
|
||||
`icon` text COMMENT '',
|
||||
`uid` mediumint unsigned NOT NULL DEFAULT 0 COMMENT 'User id',
|
||||
PRIMARY KEY(`client_id`)
|
||||
) DEFAULT COLLATE utf8mb4_general_ci COMMENT='OAuth usage';
|
||||
|
||||
--
|
||||
-- TABLE config
|
||||
--
|
||||
|
|
@ -160,100 +330,6 @@ CREATE TABLE IF NOT EXISTS `config` (
|
|||
UNIQUE INDEX `cat_k` (`cat`,`k`)
|
||||
) DEFAULT COLLATE utf8mb4_general_ci COMMENT='main configuration storage';
|
||||
|
||||
--
|
||||
-- TABLE contact
|
||||
--
|
||||
CREATE TABLE IF NOT EXISTS `contact` (
|
||||
`id` int unsigned NOT NULL auto_increment COMMENT 'sequential ID',
|
||||
`uid` mediumint unsigned NOT NULL DEFAULT 0 COMMENT 'Owner User id',
|
||||
`created` datetime NOT NULL DEFAULT '0001-01-01 00:00:00' COMMENT '',
|
||||
`updated` datetime DEFAULT '0001-01-01 00:00:00' COMMENT 'Date of last contact update',
|
||||
`self` boolean NOT NULL DEFAULT '0' COMMENT '1 if the contact is the user him/her self',
|
||||
`remote_self` boolean NOT NULL DEFAULT '0' COMMENT '',
|
||||
`rel` tinyint unsigned NOT NULL DEFAULT 0 COMMENT 'The kind of the relation between the user and the contact',
|
||||
`duplex` boolean NOT NULL DEFAULT '0' COMMENT '',
|
||||
`network` char(4) NOT NULL DEFAULT '' COMMENT 'Network of the contact',
|
||||
`protocol` char(4) NOT NULL DEFAULT '' COMMENT 'Protocol of the contact',
|
||||
`name` varchar(255) NOT NULL DEFAULT '' COMMENT 'Name that this contact is known by',
|
||||
`nick` varchar(255) NOT NULL DEFAULT '' COMMENT 'Nick- and user name of the contact',
|
||||
`location` varchar(255) DEFAULT '' COMMENT '',
|
||||
`about` text COMMENT '',
|
||||
`keywords` text COMMENT 'public keywords (interests) of the contact',
|
||||
`gender` varchar(32) NOT NULL DEFAULT '' COMMENT 'Deprecated',
|
||||
`xmpp` varchar(255) NOT NULL DEFAULT '' COMMENT '',
|
||||
`attag` varchar(255) NOT NULL DEFAULT '' COMMENT '',
|
||||
`avatar` varchar(255) NOT NULL DEFAULT '' COMMENT '',
|
||||
`photo` varchar(255) DEFAULT '' COMMENT 'Link to the profile photo of the contact',
|
||||
`thumb` varchar(255) DEFAULT '' COMMENT 'Link to the profile photo (thumb size)',
|
||||
`micro` varchar(255) DEFAULT '' COMMENT 'Link to the profile photo (micro size)',
|
||||
`site-pubkey` text COMMENT '',
|
||||
`issued-id` varchar(255) NOT NULL DEFAULT '' COMMENT '',
|
||||
`dfrn-id` varchar(255) NOT NULL DEFAULT '' COMMENT '',
|
||||
`url` varchar(255) NOT NULL DEFAULT '' COMMENT '',
|
||||
`nurl` varchar(255) NOT NULL DEFAULT '' COMMENT '',
|
||||
`addr` varchar(255) NOT NULL DEFAULT '' COMMENT '',
|
||||
`alias` varchar(255) NOT NULL DEFAULT '' COMMENT '',
|
||||
`pubkey` text COMMENT 'RSA public key 4096 bit',
|
||||
`prvkey` text COMMENT 'RSA private key 4096 bit',
|
||||
`batch` varchar(255) NOT NULL DEFAULT '' COMMENT '',
|
||||
`request` varchar(255) COMMENT '',
|
||||
`notify` varchar(255) COMMENT '',
|
||||
`poll` varchar(255) COMMENT '',
|
||||
`confirm` varchar(255) COMMENT '',
|
||||
`poco` varchar(255) COMMENT '',
|
||||
`aes_allow` boolean NOT NULL DEFAULT '0' COMMENT '',
|
||||
`ret-aes` boolean NOT NULL DEFAULT '0' COMMENT '',
|
||||
`usehub` boolean NOT NULL DEFAULT '0' COMMENT '',
|
||||
`subhub` boolean NOT NULL DEFAULT '0' COMMENT '',
|
||||
`hub-verify` varchar(255) NOT NULL DEFAULT '' COMMENT '',
|
||||
`last-update` datetime NOT NULL DEFAULT '0001-01-01 00:00:00' COMMENT 'Date of the last try to update the contact info',
|
||||
`success_update` datetime NOT NULL DEFAULT '0001-01-01 00:00:00' COMMENT 'Date of the last successful contact update',
|
||||
`failure_update` datetime NOT NULL DEFAULT '0001-01-01 00:00:00' COMMENT 'Date of the last failed update',
|
||||
`name-date` datetime NOT NULL DEFAULT '0001-01-01 00:00:00' COMMENT '',
|
||||
`uri-date` datetime NOT NULL DEFAULT '0001-01-01 00:00:00' COMMENT '',
|
||||
`avatar-date` datetime NOT NULL DEFAULT '0001-01-01 00:00:00' COMMENT '',
|
||||
`term-date` datetime NOT NULL DEFAULT '0001-01-01 00:00:00' COMMENT '',
|
||||
`last-item` datetime NOT NULL DEFAULT '0001-01-01 00:00:00' COMMENT 'date of the last post',
|
||||
`priority` tinyint unsigned NOT NULL DEFAULT 0 COMMENT '',
|
||||
`blocked` boolean NOT NULL DEFAULT '1' COMMENT 'Node-wide block status',
|
||||
`block_reason` text COMMENT 'Node-wide block reason',
|
||||
`readonly` boolean NOT NULL DEFAULT '0' COMMENT 'posts of the contact are readonly',
|
||||
`writable` boolean NOT NULL DEFAULT '0' COMMENT '',
|
||||
`forum` boolean NOT NULL DEFAULT '0' COMMENT 'contact is a forum',
|
||||
`prv` boolean NOT NULL DEFAULT '0' COMMENT 'contact is a private group',
|
||||
`contact-type` tinyint NOT NULL DEFAULT 0 COMMENT '',
|
||||
`hidden` boolean NOT NULL DEFAULT '0' COMMENT '',
|
||||
`archive` boolean NOT NULL DEFAULT '0' COMMENT '',
|
||||
`pending` boolean NOT NULL DEFAULT '1' COMMENT '',
|
||||
`deleted` boolean NOT NULL DEFAULT '0' COMMENT 'Contact has been deleted',
|
||||
`rating` tinyint NOT NULL DEFAULT 0 COMMENT '',
|
||||
`unsearchable` boolean NOT NULL DEFAULT '0' COMMENT 'Contact prefers to not be searchable',
|
||||
`sensitive` boolean NOT NULL DEFAULT '0' COMMENT 'Contact posts sensitive content',
|
||||
`baseurl` varchar(255) DEFAULT '' COMMENT 'baseurl of the contact',
|
||||
`reason` text COMMENT '',
|
||||
`closeness` tinyint unsigned NOT NULL DEFAULT 99 COMMENT '',
|
||||
`info` mediumtext COMMENT '',
|
||||
`profile-id` int unsigned COMMENT 'Deprecated',
|
||||
`bdyear` varchar(4) NOT NULL DEFAULT '' COMMENT '',
|
||||
`bd` date NOT NULL DEFAULT '0001-01-01' COMMENT '',
|
||||
`notify_new_posts` boolean NOT NULL DEFAULT '0' COMMENT '',
|
||||
`fetch_further_information` tinyint unsigned NOT NULL DEFAULT 0 COMMENT '',
|
||||
`ffi_keyword_blacklist` text COMMENT '',
|
||||
PRIMARY KEY(`id`),
|
||||
INDEX `uid_name` (`uid`,`name`(190)),
|
||||
INDEX `self_uid` (`self`,`uid`),
|
||||
INDEX `alias_uid` (`alias`(32),`uid`),
|
||||
INDEX `pending_uid` (`pending`,`uid`),
|
||||
INDEX `blocked_uid` (`blocked`,`uid`),
|
||||
INDEX `uid_rel_network_poll` (`uid`,`rel`,`network`,`poll`(64),`archive`),
|
||||
INDEX `uid_network_batch` (`uid`,`network`,`batch`(64)),
|
||||
INDEX `addr_uid` (`addr`(32),`uid`),
|
||||
INDEX `nurl_uid` (`nurl`(32),`uid`),
|
||||
INDEX `nick_uid` (`nick`(32),`uid`),
|
||||
INDEX `dfrn-id` (`dfrn-id`(64)),
|
||||
INDEX `issued-id` (`issued-id`(64))
|
||||
) DEFAULT COLLATE utf8mb4_general_ci COMMENT='contact table';
|
||||
|
||||
--
|
||||
-- TABLE contact-relation
|
||||
--
|
||||
|
|
@ -304,7 +380,8 @@ CREATE TABLE IF NOT EXISTS `conversation` (
|
|||
CREATE TABLE IF NOT EXISTS `diaspora-interaction` (
|
||||
`uri-id` int unsigned NOT NULL COMMENT 'Id of the item-uri table entry that contains the item uri',
|
||||
`interaction` mediumtext COMMENT 'The Diaspora interaction',
|
||||
PRIMARY KEY(`uri-id`)
|
||||
PRIMARY KEY(`uri-id`),
|
||||
FOREIGN KEY (`uri-id`) REFERENCES `item-uri` (`id`) ON UPDATE RESTRICT ON DELETE CASCADE
|
||||
) DEFAULT COLLATE utf8mb4_general_ci COMMENT='Signed Diaspora Interaction';
|
||||
|
||||
--
|
||||
|
|
@ -422,13 +499,16 @@ CREATE TABLE IF NOT EXISTS `gcontact` (
|
|||
`alias` varchar(255) NOT NULL DEFAULT '' COMMENT '',
|
||||
`generation` tinyint unsigned NOT NULL DEFAULT 0 COMMENT '',
|
||||
`server_url` varchar(255) NOT NULL DEFAULT '' COMMENT 'baseurl of the contacts server',
|
||||
`gsid` int unsigned COMMENT 'Global Server ID',
|
||||
PRIMARY KEY(`id`),
|
||||
UNIQUE INDEX `nurl` (`nurl`(190)),
|
||||
INDEX `name` (`name`(64)),
|
||||
INDEX `nick` (`nick`(32)),
|
||||
INDEX `addr` (`addr`(64)),
|
||||
INDEX `hide_network_updated` (`hide`,`network`,`updated`),
|
||||
INDEX `updated` (`updated`)
|
||||
INDEX `updated` (`updated`),
|
||||
INDEX `gsid` (`gsid`),
|
||||
FOREIGN KEY (`gsid`) REFERENCES `gserver` (`id`) ON UPDATE RESTRICT ON DELETE RESTRICT
|
||||
) DEFAULT COLLATE utf8mb4_general_ci COMMENT='global contacts';
|
||||
|
||||
--
|
||||
|
|
@ -482,33 +562,6 @@ CREATE TABLE IF NOT EXISTS `group_member` (
|
|||
UNIQUE INDEX `gid_contactid` (`gid`,`contact-id`)
|
||||
) DEFAULT COLLATE utf8mb4_general_ci COMMENT='privacy groups, member info';
|
||||
|
||||
--
|
||||
-- TABLE gserver
|
||||
--
|
||||
CREATE TABLE IF NOT EXISTS `gserver` (
|
||||
`id` int unsigned NOT NULL auto_increment COMMENT 'sequential ID',
|
||||
`url` varchar(255) NOT NULL DEFAULT '' COMMENT '',
|
||||
`nurl` varchar(255) NOT NULL DEFAULT '' COMMENT '',
|
||||
`version` varchar(255) NOT NULL DEFAULT '' COMMENT '',
|
||||
`site_name` varchar(255) NOT NULL DEFAULT '' COMMENT '',
|
||||
`info` text COMMENT '',
|
||||
`register_policy` tinyint NOT NULL DEFAULT 0 COMMENT '',
|
||||
`registered-users` int unsigned NOT NULL DEFAULT 0 COMMENT 'Number of registered users',
|
||||
`directory-type` tinyint DEFAULT 0 COMMENT 'Type of directory service (Poco, Mastodon)',
|
||||
`poco` varchar(255) NOT NULL DEFAULT '' COMMENT '',
|
||||
`noscrape` varchar(255) NOT NULL DEFAULT '' COMMENT '',
|
||||
`network` char(4) NOT NULL DEFAULT '' COMMENT '',
|
||||
`platform` varchar(255) NOT NULL DEFAULT '' COMMENT '',
|
||||
`relay-subscribe` boolean NOT NULL DEFAULT '0' COMMENT 'Has the server subscribed to the relay system',
|
||||
`relay-scope` varchar(10) NOT NULL DEFAULT '' COMMENT 'The scope of messages that the server wants to get',
|
||||
`created` datetime NOT NULL DEFAULT '0001-01-01 00:00:00' COMMENT '',
|
||||
`last_poco_query` datetime DEFAULT '0001-01-01 00:00:00' COMMENT '',
|
||||
`last_contact` datetime DEFAULT '0001-01-01 00:00:00' COMMENT '',
|
||||
`last_failure` datetime DEFAULT '0001-01-01 00:00:00' COMMENT '',
|
||||
PRIMARY KEY(`id`),
|
||||
UNIQUE INDEX `nurl` (`nurl`(190))
|
||||
) DEFAULT COLLATE utf8mb4_general_ci COMMENT='Global servers';
|
||||
|
||||
--
|
||||
-- TABLE gserver-tag
|
||||
--
|
||||
|
|
@ -589,6 +642,7 @@ CREATE TABLE IF NOT EXISTS `item` (
|
|||
`author-id` int unsigned NOT NULL DEFAULT 0 COMMENT 'Link to the contact table with uid=0 of the author of this item',
|
||||
`icid` int unsigned COMMENT 'Id of the item-content table entry that contains the whole item content',
|
||||
`iaid` int unsigned COMMENT 'Id of the item-activity table entry that contains the activity data',
|
||||
`vid` smallint unsigned COMMENT 'Id of the verb table entry that contains the activity verbs',
|
||||
`extid` varchar(255) NOT NULL DEFAULT '' COMMENT '',
|
||||
`post-type` tinyint unsigned NOT NULL DEFAULT 0 COMMENT 'Post type (personal note, bookmark, ...)',
|
||||
`global` boolean NOT NULL DEFAULT '0' COMMENT '',
|
||||
|
|
@ -666,7 +720,14 @@ CREATE TABLE IF NOT EXISTS `item` (
|
|||
INDEX `uid_eventid` (`uid`,`event-id`),
|
||||
INDEX `icid` (`icid`),
|
||||
INDEX `iaid` (`iaid`),
|
||||
INDEX `psid_wall` (`psid`,`wall`)
|
||||
INDEX `psid_wall` (`psid`,`wall`),
|
||||
INDEX `uri-id` (`uri-id`),
|
||||
INDEX `parent-uri-id` (`parent-uri-id`),
|
||||
INDEX `thr-parent-id` (`thr-parent-id`),
|
||||
FOREIGN KEY (`uri-id`) REFERENCES `item-uri` (`id`) ON UPDATE RESTRICT ON DELETE CASCADE,
|
||||
FOREIGN KEY (`parent-uri-id`) REFERENCES `item-uri` (`id`) ON UPDATE RESTRICT ON DELETE CASCADE,
|
||||
FOREIGN KEY (`thr-parent-id`) REFERENCES `item-uri` (`id`) ON UPDATE RESTRICT ON DELETE CASCADE,
|
||||
FOREIGN KEY (`psid`) REFERENCES `permissionset` (`id`) ON UPDATE RESTRICT ON DELETE RESTRICT
|
||||
) DEFAULT COLLATE utf8mb4_general_ci COMMENT='Structure for all posts';
|
||||
|
||||
--
|
||||
|
|
@ -681,7 +742,8 @@ CREATE TABLE IF NOT EXISTS `item-activity` (
|
|||
PRIMARY KEY(`id`),
|
||||
UNIQUE INDEX `uri-hash` (`uri-hash`),
|
||||
INDEX `uri` (`uri`(191)),
|
||||
INDEX `uri-id` (`uri-id`)
|
||||
INDEX `uri-id` (`uri-id`),
|
||||
FOREIGN KEY (`uri-id`) REFERENCES `item-uri` (`id`) ON UPDATE RESTRICT ON DELETE CASCADE
|
||||
) DEFAULT COLLATE utf8mb4_general_ci COMMENT='Activities for items';
|
||||
|
||||
--
|
||||
|
|
@ -711,39 +773,10 @@ CREATE TABLE IF NOT EXISTS `item-content` (
|
|||
UNIQUE INDEX `uri-plink-hash` (`uri-plink-hash`),
|
||||
INDEX `uri` (`uri`(191)),
|
||||
INDEX `plink` (`plink`(191)),
|
||||
INDEX `uri-id` (`uri-id`)
|
||||
INDEX `uri-id` (`uri-id`),
|
||||
FOREIGN KEY (`uri-id`) REFERENCES `item-uri` (`id`) ON UPDATE RESTRICT ON DELETE CASCADE
|
||||
) DEFAULT COLLATE utf8mb4_general_ci COMMENT='Content for all posts';
|
||||
|
||||
--
|
||||
-- TABLE item-delivery-data
|
||||
--
|
||||
CREATE TABLE IF NOT EXISTS `item-delivery-data` (
|
||||
`iid` int unsigned NOT NULL COMMENT 'Item id',
|
||||
`postopts` text COMMENT 'External post connectors add their network name to this comma-separated string to identify that they should be delivered to these networks during delivery',
|
||||
`inform` mediumtext COMMENT 'Additional receivers of the linked item',
|
||||
`queue_count` mediumint NOT NULL DEFAULT 0 COMMENT 'Initial number of delivery recipients, used as item.delivery_queue_count',
|
||||
`queue_done` mediumint NOT NULL DEFAULT 0 COMMENT 'Number of successful deliveries, used as item.delivery_queue_done',
|
||||
`queue_failed` mediumint NOT NULL DEFAULT 0 COMMENT 'Number of unsuccessful deliveries, used as item.delivery_queue_failed',
|
||||
`activitypub` mediumint NOT NULL DEFAULT 0 COMMENT 'Number of successful deliveries via ActivityPub',
|
||||
`dfrn` mediumint NOT NULL DEFAULT 0 COMMENT 'Number of successful deliveries via DFRN',
|
||||
`legacy_dfrn` mediumint NOT NULL DEFAULT 0 COMMENT 'Number of successful deliveries via legacy DFRN',
|
||||
`diaspora` mediumint NOT NULL DEFAULT 0 COMMENT 'Number of successful deliveries via Diaspora',
|
||||
`ostatus` mediumint NOT NULL DEFAULT 0 COMMENT 'Number of successful deliveries via OStatus',
|
||||
PRIMARY KEY(`iid`)
|
||||
) DEFAULT COLLATE utf8mb4_general_ci COMMENT='Delivery data for items';
|
||||
|
||||
--
|
||||
-- TABLE item-uri
|
||||
--
|
||||
CREATE TABLE IF NOT EXISTS `item-uri` (
|
||||
`id` int unsigned NOT NULL auto_increment,
|
||||
`uri` varbinary(255) NOT NULL COMMENT 'URI of an item',
|
||||
`guid` varbinary(255) COMMENT 'A unique identifier for an item',
|
||||
PRIMARY KEY(`id`),
|
||||
UNIQUE INDEX `uri` (`uri`),
|
||||
INDEX `guid` (`guid`)
|
||||
) DEFAULT COLLATE utf8mb4_general_ci COMMENT='URI and GUID for items';
|
||||
|
||||
--
|
||||
-- TABLE locks
|
||||
--
|
||||
|
|
@ -832,6 +865,8 @@ CREATE TABLE IF NOT EXISTS `notify` (
|
|||
`link` varchar(255) NOT NULL DEFAULT '' COMMENT '',
|
||||
`iid` int unsigned NOT NULL DEFAULT 0 COMMENT 'item.id',
|
||||
`parent` int unsigned NOT NULL DEFAULT 0 COMMENT '',
|
||||
`uri-id` int unsigned COMMENT 'Item-uri id of the related post',
|
||||
`parent-uri-id` int unsigned COMMENT 'Item-uri id of the parent of the related post',
|
||||
`seen` boolean NOT NULL DEFAULT '0' COMMENT '',
|
||||
`verb` varchar(100) NOT NULL DEFAULT '' COMMENT '',
|
||||
`otype` varchar(10) NOT NULL DEFAULT '' COMMENT '',
|
||||
|
|
@ -850,9 +885,11 @@ CREATE TABLE IF NOT EXISTS `notify-threads` (
|
|||
`id` int unsigned NOT NULL auto_increment COMMENT 'sequential ID',
|
||||
`notify-id` int unsigned NOT NULL DEFAULT 0 COMMENT '',
|
||||
`master-parent-item` int unsigned NOT NULL DEFAULT 0 COMMENT '',
|
||||
`master-parent-uri-id` int unsigned COMMENT 'Item-uri id of the parent of the related post',
|
||||
`parent-item` int unsigned NOT NULL DEFAULT 0 COMMENT '',
|
||||
`receiver-uid` mediumint unsigned NOT NULL DEFAULT 0 COMMENT 'User id',
|
||||
PRIMARY KEY(`id`)
|
||||
PRIMARY KEY(`id`),
|
||||
INDEX `master-parent-uri-id` (`master-parent-uri-id`)
|
||||
) DEFAULT COLLATE utf8mb4_general_ci COMMENT='';
|
||||
|
||||
--
|
||||
|
|
@ -919,20 +956,6 @@ CREATE TABLE IF NOT EXISTS `pconfig` (
|
|||
UNIQUE INDEX `uid_cat_k` (`uid`,`cat`,`k`)
|
||||
) DEFAULT COLLATE utf8mb4_general_ci COMMENT='personal (per user) configuration storage';
|
||||
|
||||
--
|
||||
-- TABLE permissionset
|
||||
--
|
||||
CREATE TABLE IF NOT EXISTS `permissionset` (
|
||||
`id` int unsigned NOT NULL auto_increment COMMENT 'sequential ID',
|
||||
`uid` mediumint unsigned NOT NULL DEFAULT 0 COMMENT 'Owner id of this permission set',
|
||||
`allow_cid` mediumtext COMMENT 'Access Control - list of allowed contact.id \'<19><78>\'',
|
||||
`allow_gid` mediumtext COMMENT 'Access Control - list of allowed groups',
|
||||
`deny_cid` mediumtext COMMENT 'Access Control - list of denied contact.id',
|
||||
`deny_gid` mediumtext COMMENT 'Access Control - list of denied groups',
|
||||
PRIMARY KEY(`id`),
|
||||
INDEX `uid_allow_cid_allow_gid_deny_cid_deny_gid` (`allow_cid`(50),`allow_gid`(30),`deny_cid`(50),`deny_gid`(30))
|
||||
) DEFAULT COLLATE utf8mb4_general_ci COMMENT='';
|
||||
|
||||
--
|
||||
-- TABLE photo
|
||||
--
|
||||
|
|
@ -1003,6 +1026,55 @@ CREATE TABLE IF NOT EXISTS `poll_result` (
|
|||
INDEX `poll_id` (`poll_id`)
|
||||
) DEFAULT COLLATE utf8mb4_general_ci COMMENT='data for polls - currently unused';
|
||||
|
||||
--
|
||||
-- TABLE post-category
|
||||
--
|
||||
CREATE TABLE IF NOT EXISTS `post-category` (
|
||||
`uri-id` int unsigned NOT NULL COMMENT 'Id of the item-uri table entry that contains the item uri',
|
||||
`uid` mediumint unsigned NOT NULL DEFAULT 0 COMMENT 'User id',
|
||||
`type` tinyint unsigned NOT NULL DEFAULT 0 COMMENT '',
|
||||
`tid` int unsigned NOT NULL DEFAULT 0 COMMENT '',
|
||||
PRIMARY KEY(`uri-id`,`uid`,`type`,`tid`),
|
||||
INDEX `uri-id` (`tid`),
|
||||
FOREIGN KEY (`uri-id`) REFERENCES `item-uri` (`id`) ON UPDATE RESTRICT ON DELETE CASCADE,
|
||||
FOREIGN KEY (`tid`) REFERENCES `tag` (`id`) ON UPDATE RESTRICT ON DELETE RESTRICT
|
||||
) DEFAULT COLLATE utf8mb4_general_ci COMMENT='post relation to categories';
|
||||
|
||||
--
|
||||
-- TABLE post-delivery-data
|
||||
--
|
||||
CREATE TABLE IF NOT EXISTS `post-delivery-data` (
|
||||
`uri-id` int unsigned NOT NULL COMMENT 'Id of the item-uri table entry that contains the item uri',
|
||||
`postopts` text COMMENT 'External post connectors add their network name to this comma-separated string to identify that they should be delivered to these networks during delivery',
|
||||
`inform` mediumtext COMMENT 'Additional receivers of the linked item',
|
||||
`queue_count` mediumint NOT NULL DEFAULT 0 COMMENT 'Initial number of delivery recipients, used as item.delivery_queue_count',
|
||||
`queue_done` mediumint NOT NULL DEFAULT 0 COMMENT 'Number of successful deliveries, used as item.delivery_queue_done',
|
||||
`queue_failed` mediumint NOT NULL DEFAULT 0 COMMENT 'Number of unsuccessful deliveries, used as item.delivery_queue_failed',
|
||||
`activitypub` mediumint NOT NULL DEFAULT 0 COMMENT 'Number of successful deliveries via ActivityPub',
|
||||
`dfrn` mediumint NOT NULL DEFAULT 0 COMMENT 'Number of successful deliveries via DFRN',
|
||||
`legacy_dfrn` mediumint NOT NULL DEFAULT 0 COMMENT 'Number of successful deliveries via legacy DFRN',
|
||||
`diaspora` mediumint NOT NULL DEFAULT 0 COMMENT 'Number of successful deliveries via Diaspora',
|
||||
`ostatus` mediumint NOT NULL DEFAULT 0 COMMENT 'Number of successful deliveries via OStatus',
|
||||
PRIMARY KEY(`uri-id`),
|
||||
FOREIGN KEY (`uri-id`) REFERENCES `item-uri` (`id`) ON UPDATE RESTRICT ON DELETE CASCADE
|
||||
) DEFAULT COLLATE utf8mb4_general_ci COMMENT='Delivery data for items';
|
||||
|
||||
--
|
||||
-- TABLE post-tag
|
||||
--
|
||||
CREATE TABLE IF NOT EXISTS `post-tag` (
|
||||
`uri-id` int unsigned NOT NULL COMMENT 'Id of the item-uri table entry that contains the item uri',
|
||||
`type` tinyint unsigned NOT NULL DEFAULT 0 COMMENT '',
|
||||
`tid` int unsigned NOT NULL DEFAULT 0 COMMENT '',
|
||||
`cid` int unsigned NOT NULL DEFAULT 0 COMMENT 'Contact id of the mentioned public contact',
|
||||
PRIMARY KEY(`uri-id`,`type`,`tid`,`cid`),
|
||||
INDEX `tid` (`tid`),
|
||||
INDEX `cid` (`cid`),
|
||||
FOREIGN KEY (`uri-id`) REFERENCES `item-uri` (`id`) ON UPDATE RESTRICT ON DELETE CASCADE,
|
||||
FOREIGN KEY (`tid`) REFERENCES `tag` (`id`) ON UPDATE RESTRICT ON DELETE RESTRICT,
|
||||
FOREIGN KEY (`cid`) REFERENCES `contact` (`id`) ON UPDATE RESTRICT ON DELETE RESTRICT
|
||||
) DEFAULT COLLATE utf8mb4_general_ci COMMENT='post relation to tags';
|
||||
|
||||
--
|
||||
-- TABLE process
|
||||
--
|
||||
|
|
@ -1093,7 +1165,8 @@ CREATE TABLE IF NOT EXISTS `profile_field` (
|
|||
PRIMARY KEY(`id`),
|
||||
INDEX `uid` (`uid`),
|
||||
INDEX `order` (`order`),
|
||||
INDEX `psid` (`psid`)
|
||||
INDEX `psid` (`psid`),
|
||||
FOREIGN KEY (`psid`) REFERENCES `permissionset` (`id`) ON UPDATE RESTRICT ON DELETE RESTRICT
|
||||
) DEFAULT COLLATE utf8mb4_general_ci COMMENT='Custom profile fields';
|
||||
|
||||
--
|
||||
|
|
@ -1153,46 +1226,20 @@ CREATE TABLE IF NOT EXISTS `session` (
|
|||
) DEFAULT COLLATE utf8mb4_general_ci COMMENT='web session storage';
|
||||
|
||||
--
|
||||
-- TABLE sign
|
||||
-- TABLE storage
|
||||
--
|
||||
CREATE TABLE IF NOT EXISTS `sign` (
|
||||
`id` int unsigned NOT NULL auto_increment COMMENT 'sequential ID',
|
||||
`iid` int unsigned NOT NULL DEFAULT 0 COMMENT 'item.id',
|
||||
`signed_text` mediumtext COMMENT '',
|
||||
`signature` text COMMENT '',
|
||||
`signer` varchar(255) NOT NULL DEFAULT '' COMMENT '',
|
||||
PRIMARY KEY(`id`),
|
||||
UNIQUE INDEX `iid` (`iid`)
|
||||
) DEFAULT COLLATE utf8mb4_general_ci COMMENT='Diaspora signatures';
|
||||
|
||||
--
|
||||
-- TABLE term
|
||||
--
|
||||
CREATE TABLE IF NOT EXISTS `term` (
|
||||
`tid` int unsigned NOT NULL auto_increment COMMENT '',
|
||||
`oid` int unsigned NOT NULL DEFAULT 0 COMMENT '',
|
||||
`otype` tinyint unsigned NOT NULL DEFAULT 0 COMMENT '',
|
||||
`type` tinyint unsigned NOT NULL DEFAULT 0 COMMENT '',
|
||||
`term` varchar(255) NOT NULL DEFAULT '' COMMENT '',
|
||||
`url` varchar(255) NOT NULL DEFAULT '' COMMENT '',
|
||||
`guid` varchar(255) NOT NULL DEFAULT '' COMMENT '',
|
||||
`created` datetime NOT NULL DEFAULT '0001-01-01 00:00:00' COMMENT '',
|
||||
`received` datetime NOT NULL DEFAULT '0001-01-01 00:00:00' COMMENT '',
|
||||
`global` boolean NOT NULL DEFAULT '0' COMMENT '',
|
||||
`uid` mediumint unsigned NOT NULL DEFAULT 0 COMMENT 'User id',
|
||||
PRIMARY KEY(`tid`),
|
||||
INDEX `term_type` (`term`(64),`type`),
|
||||
INDEX `oid_otype_type_term` (`oid`,`otype`,`type`,`term`(32)),
|
||||
INDEX `uid_otype_type_term_global_created` (`uid`,`otype`,`type`,`term`(32),`global`,`created`),
|
||||
INDEX `uid_otype_type_url` (`uid`,`otype`,`type`,`url`(64)),
|
||||
INDEX `guid` (`guid`(64))
|
||||
) DEFAULT COLLATE utf8mb4_general_ci COMMENT='item taxonomy (categories, tags, etc.) table';
|
||||
CREATE TABLE IF NOT EXISTS `storage` (
|
||||
`id` int unsigned NOT NULL auto_increment COMMENT 'Auto incremented image data id',
|
||||
`data` longblob NOT NULL COMMENT 'file data',
|
||||
PRIMARY KEY(`id`)
|
||||
) DEFAULT COLLATE utf8mb4_general_ci COMMENT='Data stored by Database storage backend';
|
||||
|
||||
--
|
||||
-- TABLE thread
|
||||
--
|
||||
CREATE TABLE IF NOT EXISTS `thread` (
|
||||
`iid` int unsigned NOT NULL DEFAULT 0 COMMENT 'sequential ID',
|
||||
`uri-id` int unsigned COMMENT 'Id of the item-uri table entry that contains the item uri',
|
||||
`uid` mediumint unsigned NOT NULL DEFAULT 0 COMMENT 'User id',
|
||||
`contact-id` int unsigned NOT NULL DEFAULT 0 COMMENT '',
|
||||
`owner-id` int unsigned NOT NULL DEFAULT 0 COMMENT 'Item owner',
|
||||
|
|
@ -1228,7 +1275,9 @@ CREATE TABLE IF NOT EXISTS `thread` (
|
|||
INDEX `uid_received` (`uid`,`received`),
|
||||
INDEX `uid_commented` (`uid`,`commented`),
|
||||
INDEX `uid_wall_received` (`uid`,`wall`,`received`),
|
||||
INDEX `private_wall_origin_commented` (`private`,`wall`,`origin`,`commented`)
|
||||
INDEX `private_wall_origin_commented` (`private`,`wall`,`origin`,`commented`),
|
||||
INDEX `uri-id` (`uri-id`),
|
||||
FOREIGN KEY (`uri-id`) REFERENCES `item-uri` (`id`) ON UPDATE RESTRICT ON DELETE CASCADE
|
||||
) DEFAULT COLLATE utf8mb4_general_ci COMMENT='Thread related data';
|
||||
|
||||
--
|
||||
|
|
@ -1241,7 +1290,9 @@ CREATE TABLE IF NOT EXISTS `tokens` (
|
|||
`expires` int NOT NULL DEFAULT 0 COMMENT '',
|
||||
`scope` varchar(200) NOT NULL DEFAULT '' COMMENT '',
|
||||
`uid` mediumint unsigned NOT NULL DEFAULT 0 COMMENT 'User id',
|
||||
PRIMARY KEY(`id`)
|
||||
PRIMARY KEY(`id`),
|
||||
INDEX `client_id` (`client_id`),
|
||||
FOREIGN KEY (`client_id`) REFERENCES `clients` (`client_id`) ON UPDATE RESTRICT ON DELETE CASCADE
|
||||
) DEFAULT COLLATE utf8mb4_general_ci COMMENT='OAuth usage';
|
||||
|
||||
--
|
||||
|
|
@ -1334,6 +1385,15 @@ CREATE TABLE IF NOT EXISTS `user-item` (
|
|||
INDEX `iid_uid` (`iid`,`uid`)
|
||||
) DEFAULT COLLATE utf8mb4_general_ci COMMENT='User specific item data';
|
||||
|
||||
--
|
||||
-- TABLE verb
|
||||
--
|
||||
CREATE TABLE IF NOT EXISTS `verb` (
|
||||
`id` smallint unsigned NOT NULL auto_increment,
|
||||
`name` varchar(100) NOT NULL DEFAULT '' COMMENT '',
|
||||
PRIMARY KEY(`id`)
|
||||
) DEFAULT COLLATE utf8mb4_general_ci COMMENT='Activity Verbs';
|
||||
|
||||
--
|
||||
-- TABLE worker-ipc
|
||||
--
|
||||
|
|
@ -1366,12 +1426,227 @@ CREATE TABLE IF NOT EXISTS `workerqueue` (
|
|||
) DEFAULT COLLATE utf8mb4_general_ci COMMENT='Background tasks queue entries';
|
||||
|
||||
--
|
||||
-- TABLE storage
|
||||
-- VIEW category-view
|
||||
--
|
||||
CREATE TABLE IF NOT EXISTS `storage` (
|
||||
`id` int unsigned NOT NULL auto_increment COMMENT 'Auto incremented image data id',
|
||||
`data` longblob NOT NULL COMMENT 'file data',
|
||||
PRIMARY KEY(`id`)
|
||||
) DEFAULT COLLATE utf8mb4_general_ci COMMENT='Data stored by Database storage backend';
|
||||
DROP VIEW IF EXISTS `category-view`;
|
||||
CREATE VIEW `category-view` AS SELECT
|
||||
`post-category`.`uri-id` AS `uri-id`,
|
||||
`post-category`.`uid` AS `uid`,
|
||||
`item-uri`.`uri` AS `uri`,
|
||||
`item-uri`.`guid` AS `guid`,
|
||||
`post-category`.`type` AS `type`,
|
||||
`post-category`.`tid` AS `tid`,
|
||||
`tag`.`name` AS `name`,
|
||||
`tag`.`url` AS `url`
|
||||
FROM `post-category`
|
||||
INNER JOIN `item-uri` ON `item-uri`.id = `post-category`.`uri-id`
|
||||
LEFT JOIN `tag` ON `post-category`.`tid` = `tag`.`id`;
|
||||
|
||||
--
|
||||
-- VIEW tag-view
|
||||
--
|
||||
DROP VIEW IF EXISTS `tag-view`;
|
||||
CREATE VIEW `tag-view` AS SELECT
|
||||
`post-tag`.`uri-id` AS `uri-id`,
|
||||
`item-uri`.`uri` AS `uri`,
|
||||
`item-uri`.`guid` AS `guid`,
|
||||
`post-tag`.`type` AS `type`,
|
||||
`post-tag`.`tid` AS `tid`,
|
||||
`post-tag`.`cid` AS `cid`,
|
||||
CASE `cid` WHEN 0 THEN `tag`.`name` ELSE `contact`.`name` END AS `name`,
|
||||
CASE `cid` WHEN 0 THEN `tag`.`url` ELSE `contact`.`url` END AS `url`
|
||||
FROM `post-tag`
|
||||
INNER JOIN `item-uri` ON `item-uri`.id = `post-tag`.`uri-id`
|
||||
LEFT JOIN `tag` ON `post-tag`.`tid` = `tag`.`id`
|
||||
LEFT JOIN `contact` ON `post-tag`.`cid` = `contact`.`id`;
|
||||
|
||||
--
|
||||
-- VIEW owner-view
|
||||
--
|
||||
DROP VIEW IF EXISTS `owner-view`;
|
||||
CREATE VIEW `owner-view` AS SELECT
|
||||
`contact`.`id` AS `id`,
|
||||
`contact`.`uid` AS `uid`,
|
||||
`contact`.`created` AS `created`,
|
||||
`contact`.`updated` AS `updated`,
|
||||
`contact`.`self` AS `self`,
|
||||
`contact`.`remote_self` AS `remote_self`,
|
||||
`contact`.`rel` AS `rel`,
|
||||
`contact`.`duplex` AS `duplex`,
|
||||
`contact`.`network` AS `network`,
|
||||
`contact`.`protocol` AS `protocol`,
|
||||
`contact`.`name` AS `name`,
|
||||
`contact`.`nick` AS `nick`,
|
||||
`contact`.`location` AS `location`,
|
||||
`contact`.`about` AS `about`,
|
||||
`contact`.`keywords` AS `keywords`,
|
||||
`contact`.`gender` AS `gender`,
|
||||
`contact`.`xmpp` AS `xmpp`,
|
||||
`contact`.`attag` AS `attag`,
|
||||
`contact`.`avatar` AS `avatar`,
|
||||
`contact`.`photo` AS `photo`,
|
||||
`contact`.`thumb` AS `thumb`,
|
||||
`contact`.`micro` AS `micro`,
|
||||
`contact`.`site-pubkey` AS `site-pubkey`,
|
||||
`contact`.`issued-id` AS `issued-id`,
|
||||
`contact`.`dfrn-id` AS `dfrn-id`,
|
||||
`contact`.`url` AS `url`,
|
||||
`contact`.`nurl` AS `nurl`,
|
||||
`contact`.`addr` AS `addr`,
|
||||
`contact`.`alias` AS `alias`,
|
||||
`contact`.`pubkey` AS `pubkey`,
|
||||
`contact`.`prvkey` AS `prvkey`,
|
||||
`contact`.`batch` AS `batch`,
|
||||
`contact`.`request` AS `request`,
|
||||
`contact`.`notify` AS `notify`,
|
||||
`contact`.`poll` AS `poll`,
|
||||
`contact`.`confirm` AS `confirm`,
|
||||
`contact`.`poco` AS `poco`,
|
||||
`contact`.`aes_allow` AS `aes_allow`,
|
||||
`contact`.`ret-aes` AS `ret-aes`,
|
||||
`contact`.`usehub` AS `usehub`,
|
||||
`contact`.`subhub` AS `subhub`,
|
||||
`contact`.`hub-verify` AS `hub-verify`,
|
||||
`contact`.`last-update` AS `last-update`,
|
||||
`contact`.`success_update` AS `success_update`,
|
||||
`contact`.`failure_update` AS `failure_update`,
|
||||
`contact`.`name-date` AS `name-date`,
|
||||
`contact`.`uri-date` AS `uri-date`,
|
||||
`contact`.`avatar-date` AS `avatar-date`,
|
||||
`contact`.`avatar-date` AS `picdate`,
|
||||
`contact`.`term-date` AS `term-date`,
|
||||
`contact`.`last-item` AS `last-item`,
|
||||
`contact`.`priority` AS `priority`,
|
||||
`contact`.`blocked` AS `blocked`,
|
||||
`contact`.`block_reason` AS `block_reason`,
|
||||
`contact`.`readonly` AS `readonly`,
|
||||
`contact`.`writable` AS `writable`,
|
||||
`contact`.`forum` AS `forum`,
|
||||
`contact`.`prv` AS `prv`,
|
||||
`contact`.`contact-type` AS `contact-type`,
|
||||
`contact`.`hidden` AS `hidden`,
|
||||
`contact`.`archive` AS `archive`,
|
||||
`contact`.`pending` AS `pending`,
|
||||
`contact`.`deleted` AS `deleted`,
|
||||
`contact`.`rating` AS `rating`,
|
||||
`contact`.`unsearchable` AS `unsearchable`,
|
||||
`contact`.`sensitive` AS `sensitive`,
|
||||
`contact`.`baseurl` AS `baseurl`,
|
||||
`contact`.`reason` AS `reason`,
|
||||
`contact`.`closeness` AS `closeness`,
|
||||
`contact`.`info` AS `info`,
|
||||
`contact`.`profile-id` AS `profile-id`,
|
||||
`contact`.`bdyear` AS `bdyear`,
|
||||
`contact`.`bd` AS `bd`,
|
||||
`contact`.`notify_new_posts` AS `notify_new_posts`,
|
||||
`contact`.`fetch_further_information` AS `fetch_further_information`,
|
||||
`contact`.`ffi_keyword_denylist` AS `ffi_keyword_denylist`,
|
||||
`user`.`parent-uid` AS `parent-uid`,
|
||||
`user`.`guid` AS `guid`,
|
||||
`user`.`nickname` AS `nickname`,
|
||||
`user`.`email` AS `email`,
|
||||
`user`.`openid` AS `openid`,
|
||||
`user`.`timezone` AS `timezone`,
|
||||
`user`.`language` AS `language`,
|
||||
`user`.`register_date` AS `register_date`,
|
||||
`user`.`login_date` AS `login_date`,
|
||||
`user`.`default-location` AS `default-location`,
|
||||
`user`.`allow_location` AS `allow_location`,
|
||||
`user`.`theme` AS `theme`,
|
||||
`user`.`pubkey` AS `upubkey`,
|
||||
`user`.`prvkey` AS `uprvkey`,
|
||||
`user`.`sprvkey` AS `sprvkey`,
|
||||
`user`.`spubkey` AS `spubkey`,
|
||||
`user`.`verified` AS `verified`,
|
||||
`user`.`blockwall` AS `blockwall`,
|
||||
`user`.`hidewall` AS `hidewall`,
|
||||
`user`.`blocktags` AS `blocktags`,
|
||||
`user`.`unkmail` AS `unkmail`,
|
||||
`user`.`cntunkmail` AS `cntunkmail`,
|
||||
`user`.`notify-flags` AS `notify-flags`,
|
||||
`user`.`page-flags` AS `page-flags`,
|
||||
`user`.`account-type` AS `account-type`,
|
||||
`user`.`prvnets` AS `prvnets`,
|
||||
`user`.`maxreq` AS `maxreq`,
|
||||
`user`.`expire` AS `expire`,
|
||||
`user`.`account_removed` AS `account_removed`,
|
||||
`user`.`account_expired` AS `account_expired`,
|
||||
`user`.`account_expires_on` AS `account_expires_on`,
|
||||
`user`.`expire_notification_sent` AS `expire_notification_sent`,
|
||||
`user`.`def_gid` AS `def_gid`,
|
||||
`user`.`allow_cid` AS `allow_cid`,
|
||||
`user`.`allow_gid` AS `allow_gid`,
|
||||
`user`.`deny_cid` AS `deny_cid`,
|
||||
`user`.`deny_gid` AS `deny_gid`,
|
||||
`user`.`openidserver` AS `openidserver`,
|
||||
`profile`.`publish` AS `publish`,
|
||||
`profile`.`net-publish` AS `net-publish`,
|
||||
`profile`.`hide-friends` AS `hide-friends`,
|
||||
`profile`.`prv_keywords` AS `prv_keywords`,
|
||||
`profile`.`pub_keywords` AS `pub_keywords`,
|
||||
`profile`.`address` AS `address`,
|
||||
`profile`.`locality` AS `locality`,
|
||||
`profile`.`region` AS `region`,
|
||||
`profile`.`postal-code` AS `postal-code`,
|
||||
`profile`.`country-name` AS `country-name`,
|
||||
`profile`.`homepage` AS `homepage`,
|
||||
`profile`.`dob` AS `dob`
|
||||
FROM `user`
|
||||
INNER JOIN `contact` ON `contact`.`uid` = `user`.`uid` AND `contact`.`self`
|
||||
INNER JOIN `profile` ON `profile`.`uid` = `user`.`uid`;
|
||||
|
||||
--
|
||||
-- VIEW pending-view
|
||||
--
|
||||
DROP VIEW IF EXISTS `pending-view`;
|
||||
CREATE VIEW `pending-view` AS SELECT
|
||||
`register`.`id` AS `id`,
|
||||
`register`.`hash` AS `hash`,
|
||||
`register`.`created` AS `created`,
|
||||
`register`.`uid` AS `uid`,
|
||||
`register`.`password` AS `password`,
|
||||
`register`.`language` AS `language`,
|
||||
`register`.`note` AS `note`,
|
||||
`contact`.`self` AS `self`,
|
||||
`contact`.`name` AS `name`,
|
||||
`contact`.`url` AS `url`,
|
||||
`contact`.`micro` AS `micro`,
|
||||
`user`.`email` AS `email`,
|
||||
`contact`.`nick` AS `nick`
|
||||
FROM `register`
|
||||
INNER JOIN `contact` ON `register`.`uid` = `contact`.`uid`
|
||||
INNER JOIN `user` ON `register`.`uid` = `user`.`uid`;
|
||||
|
||||
--
|
||||
-- VIEW tag-search-view
|
||||
--
|
||||
DROP VIEW IF EXISTS `tag-search-view`;
|
||||
CREATE VIEW `tag-search-view` AS SELECT
|
||||
`post-tag`.`uri-id` AS `uri-id`,
|
||||
`item`.`id` AS `iid`,
|
||||
`item`.`uri` AS `uri`,
|
||||
`item`.`guid` AS `guid`,
|
||||
`item`.`uid` AS `uid`,
|
||||
`item`.`private` AS `private`,
|
||||
`item`.`wall` AS `wall`,
|
||||
`item`.`origin` AS `origin`,
|
||||
`item`.`gravity` AS `gravity`,
|
||||
`item`.`received` AS `received`,
|
||||
`tag`.`name` AS `name`
|
||||
FROM `post-tag`
|
||||
INNER JOIN `tag` ON `tag`.`id` = `post-tag`.`tid`
|
||||
INNER JOIN `item` ON `item`.`uri-id` = `post-tag`.`uri-id`
|
||||
WHERE `post-tag`.`type` = 1;
|
||||
|
||||
--
|
||||
-- VIEW workerqueue-view
|
||||
--
|
||||
DROP VIEW IF EXISTS `workerqueue-view`;
|
||||
CREATE VIEW `workerqueue-view` AS SELECT
|
||||
`process`.`pid` AS `pid`,
|
||||
`workerqueue`.`priority` AS `priority`
|
||||
FROM `process`
|
||||
INNER JOIN `workerqueue` ON `workerqueue`.`pid` = `process`.`pid`
|
||||
WHERE NOT `workerqueue`.`done`;
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -152,19 +152,29 @@ These endpoints use the [Friendica API entities](help/API-Entities).
|
|||
- [GET api/friendships/incoming](https://developer.twitter.com/en/docs/accounts-and-users/follow-search-get-users/api-reference/get-friendships-incoming)
|
||||
- Unsupported parameters
|
||||
- `stringify_ids`
|
||||
- [GET api/followers/ids](https://developer.twitter.com/en/docs/accounts-and-users/follow-search-get-users/api-reference/get-followers-ids)
|
||||
- Unsupported parameters:
|
||||
- `user_id`: Relationships aren't returned for other users than self
|
||||
- `screen_name`: Relationships aren't returned for other users than self
|
||||
- [GET api/friends/ids](https://developer.twitter.com/en/docs/accounts-and-users/follow-search-get-users/api-reference/get-friends-ids)
|
||||
- Unsupported parameters:
|
||||
- `user_id`: Relationships aren't returned for other users than self
|
||||
- `screen_name`: Relationships aren't returned for other users than self
|
||||
|
||||
- - [GET api/followers/ids](https://developer.twitter.com/en/docs/accounts-and-users/follow-search-get-users/api-reference/get-followers-ids)
|
||||
- [GET api/followers/list](https://developer.twitter.com/en/docs/accounts-and-users/follow-search-get-users/api-reference/get-followers-list)
|
||||
- [GET api/friends/ids](https://developer.twitter.com/en/docs/accounts-and-users/follow-search-get-users/api-reference/get-friends-ids)
|
||||
- [GET api/friends/list](https://developer.twitter.com/en/docs/accounts-and-users/follow-search-get-users/api-reference/get-friends-list)
|
||||
- Additional parameters:
|
||||
- `since_id`: You can use the `next_cursor` value to load the next page.
|
||||
- `max_id`: You can use the inverse of the `previous_cursor` value to load the previous page.
|
||||
- Unsupported parameter:
|
||||
- `skip_status`: No status is returned even if it isn't set to true.
|
||||
- Caveats:
|
||||
- `cursor` trumps `since_id` trumps `max_id` if any combination is provided.
|
||||
- `user_id` must be the ID of a contact associated with a local user account.
|
||||
- `screen_name` must be associated with a local user account.
|
||||
- `screen_name` trumps `user_id` if both are provided (undocumented Twitter behavior).
|
||||
- Will succeed but return an empty array for users hiding their contact lists.
|
||||
|
||||
|
||||
- [POST api/friendships/destroy](https://developer.twitter.com/en/docs/accounts-and-users/follow-search-get-users/api-reference/post-friendships-destroy)
|
||||
|
||||
|
||||
|
||||
|
||||
## Non-implemented endpoints
|
||||
|
||||
- [GET oauth/authenticate](https://developer.twitter.com/en/docs/basics/authentication/api-reference/authenticate)
|
||||
|
|
@ -188,8 +198,6 @@ These endpoints use the [Friendica API entities](help/API-Entities).
|
|||
- [POST lists/subscribers/destroy](https://developer.twitter.com/en/docs/accounts-and-users/create-manage-lists/api-reference/post-lists-subscribers-destroy)
|
||||
|
||||
|
||||
- [GET followers/list](https://developer.twitter.com/en/docs/accounts-and-users/follow-search-get-users/api-reference/get-followers-list)
|
||||
- [GET friends/list](https://developer.twitter.com/en/docs/accounts-and-users/follow-search-get-users/api-reference/get-friends-list)
|
||||
- [GET friendships/lookup](https://developer.twitter.com/en/docs/accounts-and-users/follow-search-get-users/api-reference/get-friendships-lookup)
|
||||
- [GET friendships/no_retweets/ids](https://developer.twitter.com/en/docs/accounts-and-users/follow-search-get-users/api-reference/get-friendships-no_retweets-ids)
|
||||
- [GET friendships/outgoing](https://developer.twitter.com/en/docs/accounts-and-users/follow-search-get-users/api-reference/get-friendships-outgoing)
|
||||
|
|
|
|||
|
|
@ -466,6 +466,19 @@ Hook data is a `\FastRoute\RouterCollector` object that should be used to add ad
|
|||
|
||||
**Notice**: The class whose name is provided in the route handler must be reachable via auto-loader.
|
||||
|
||||
### probe_detect
|
||||
|
||||
Called before trying to detect the target network of a URL.
|
||||
If any registered hook function sets the `result` key of the hook data array, it will be returned immediately.
|
||||
Hook functions should also return immediately if the hook data contains an existing result.
|
||||
|
||||
Hook data:
|
||||
|
||||
- **uri** (input): the profile URI.
|
||||
- **network** (input): the target network (can be empty for auto-detection).
|
||||
- **uid** (input): the user to return the contact data for (can be empty for public contacts).
|
||||
- **result** (output): Set by the hook function to indicate a successful detection.
|
||||
|
||||
## Complete list of hook callbacks
|
||||
|
||||
Here is a complete list of all hook callbacks with file locations (as of 24-Sep-2018). Please see the source for details of any hooks not documented above.
|
||||
|
|
|
|||
|
|
@ -65,17 +65,17 @@ table.bbcodes > * > tr > th {
|
|||
<td><a href="http://friendi.ca" target="external-link">Friendica</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>[img]https://raw.githubusercontent.com/friendica/friendica/master/images/friendica-32.jpg[/img]</td>
|
||||
<td><img src="https://raw.githubusercontent.com/friendica/friendica/master/images/friendica-32.jpg" alt="Immagine/foto"></td>
|
||||
<td>[img]https://raw.githubusercontent.com/friendica/friendica/stable/images/friendica-32.jpg[/img]</td>
|
||||
<td><img src="https://raw.githubusercontent.com/friendica/friendica/stable/images/friendica-32.jpg" alt="Immagine/foto"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>[img=https://raw.githubusercontent.com/friendica/friendica/master/images/friendica-32.jpg]The Friendica Logo[/img]</td>
|
||||
<td><img src="https://raw.githubusercontent.com/friendica/friendica/master/images/friendica-32.jpg" alt="The Friendica Logo"></td>
|
||||
<td>[img=https://raw.githubusercontent.com/friendica/friendica/stable/images/friendica-32.jpg]The Friendica Logo[/img]</td>
|
||||
<td><img src="https://raw.githubusercontent.com/friendica/friendica/stable/images/friendica-32.jpg" alt="The Friendica Logo"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>[img=64x32]https://raw.githubusercontent.com/friendica/friendica/master/images/friendica-32.jpg[/img]<br>
|
||||
<td>[img=64x32]https://raw.githubusercontent.com/friendica/friendica/stable/images/friendica-32.jpg[/img]<br>
|
||||
<br>Note: provided height is simply discarded.</td>
|
||||
<td><img src="https://raw.githubusercontent.com/friendica/friendica/master/images/friendica-32.jpg" style="width: 64px;"></td>
|
||||
<td><img src="https://raw.githubusercontent.com/friendica/friendica/stable/images/friendica-32.jpg" style="width: 64px;"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>[size=xx-small]small text[/size]</td>
|
||||
|
|
@ -613,15 +613,34 @@ On Mastodon this field is used for the content warning.
|
|||
<th>Result</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>If you need to put literal bbcode in a message, [noparse], [nobb] or [pre] are used to escape bbcode:
|
||||
<td>If you need to put literal BBCode in a message, [noparse], [nobb] or [pre] blocks prevent BBCode conversion:
|
||||
<ul>
|
||||
<li>[noparse][b]bold[/b][/noparse]</li>
|
||||
<li>[nobb][b]bold[/b][/nobb]</li>
|
||||
<li>[pre][b]bold[/b][/pre]</li>
|
||||
</ul>
|
||||
Note: [code] has priority over [noparse], [nobb] and [pre] which makes them display as BBCode tags in code blocks instead of being removed.
|
||||
[code] blocks inside [noparse] will still be converted to a code block.
|
||||
</td>
|
||||
<td>[b]bold[/b]</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Additionally, [noparse] and [pre] blocks prevent mention and hashtag conversion to links:
|
||||
<ul>
|
||||
<li>[noparse]@user@domain.tld #hashtag[/noparse]</li>
|
||||
<li>[pre]@user@domain.tld #hashtag[/pre]</li>
|
||||
</ul>
|
||||
</td>
|
||||
<td>@user@domain.tld #hashtag</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Additionally, [pre] blocks preserve spaces:
|
||||
<ul>
|
||||
<li>[pre] Spaces[/pre]</li>
|
||||
</ul>
|
||||
</td>
|
||||
<td> Spaces</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>[nosmile] is used to disable smilies on a post by post basis<br>
|
||||
<br>
|
||||
|
|
|
|||
|
|
@ -43,7 +43,7 @@ At first you have to get the current version. You can either pull it from [Githu
|
|||
|
||||
$> cd /var/www/virtual/YOURSPACE/html/addon; git pull
|
||||
|
||||
Or you can download a tar archive here: [jappixmini.tgz](https://github.com/friendica/friendica-addons/blob/master/jappixmini.tgz) (click at „view raw“).
|
||||
Or you can download a tar archive here: [jappixmini.tgz](https://github.com/friendica/friendica-addons/blob/stable/jappixmini.tgz) (click at „view raw“).
|
||||
|
||||
Just unpack the file and rename the directory to „jappixmini“.
|
||||
Next, upload this directory and the .tgz-file into your addon directory of your friendica installation.
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@ Our Git Branches
|
|||
|
||||
There are two relevant branches in the main repo on GitHub:
|
||||
|
||||
1. master: This branch contains stable releases only.
|
||||
1. stable: This branch contains stable releases only.
|
||||
2. develop: This branch contains the latest code.
|
||||
This is what you want to work with.
|
||||
|
||||
|
|
@ -43,7 +43,7 @@ Release branches
|
|||
A release branch is created when the develop branch contains all features it should have.
|
||||
A release branch is used for a few things.
|
||||
|
||||
1. It allows last-minute bug fixing before the release goes to master branch.
|
||||
1. It allows last-minute bug fixing before the release goes to stable branch.
|
||||
2. It allows meta-data changes (README, CHANGELOG, etc.) for version bumps and documentation changes.
|
||||
3. It makes sure the develop branch can receive new features that are **not** part of this release.
|
||||
|
||||
|
|
|
|||
|
|
@ -72,7 +72,7 @@ This makes the software much easier to update.
|
|||
|
||||
The Linux commands to clone the repository into a directory "mywebsite" would be
|
||||
|
||||
git clone https://github.com/friendica/friendica.git -b master mywebsite
|
||||
git clone https://github.com/friendica/friendica.git -b stable mywebsite
|
||||
cd mywebsite
|
||||
bin/composer.phar install --no-dev
|
||||
|
||||
|
|
@ -88,7 +88,7 @@ Get the addons by going into your website folder.
|
|||
|
||||
Clone the addon repository (separately):
|
||||
|
||||
git clone https://github.com/friendica/friendica-addons.git -b master addon
|
||||
git clone https://github.com/friendica/friendica-addons.git -b stable addon
|
||||
|
||||
If you want to use the development version of Friendica you can switch to the develop branch in the repository by running
|
||||
|
||||
|
|
@ -435,7 +435,7 @@ provided by one of our members.
|
|||
>
|
||||
> This is obvious as soon as you notice that the friendica-cron uses `proc_open`
|
||||
> to execute PHP scripts that also use `proc_open`, but it took me quite some time to find that out.
|
||||
> I hope this saves some time for other people using suhosin with function blacklists.
|
||||
> I hope this saves some time for other people using suhosin with function blocklists.
|
||||
|
||||
### Unable to create all mysql tables on MySQL 5.7.17 or newer
|
||||
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ Friendica Message Flow
|
|||
This page documents some of the details of how messages get from one person to another in the Friendica network.
|
||||
There are multiple paths, using multiple protocols and message formats.
|
||||
|
||||
Those attempting to understand these message flows should become familiar with (at the minimum) the [DFRN protocol document](https://github.com/friendica/friendica/blob/master/spec/dfrn2.pdf) and the message passing elements of the OStatus stack (salmon and Pubsubhubbub).
|
||||
Those attempting to understand these message flows should become familiar with (at the minimum) the [DFRN protocol document](https://github.com/friendica/friendica/blob/stable/spec/dfrn2.pdf) and the message passing elements of the OStatus stack (salmon and Pubsubhubbub).
|
||||
|
||||
Most message passing involves the file include/items.php, which has functions for several feed-related import/export activities.
|
||||
|
||||
|
|
|
|||
|
|
@ -74,7 +74,7 @@ You can chose between the following modes:
|
|||
##### Invitation based registry
|
||||
|
||||
Additionally to the setting in the admin panel, you can decide if registrations are only possible using an invitation code or not.
|
||||
To enable invitation based registration, you have to set the `invitation_only` setting in the [config/local.config.php](/help/Config) file.
|
||||
To enable invitation based registration, you have to set the `invitation_only` setting to `true` in the `system` section of the [config/local.config.php](/help/Config) file.
|
||||
If you want to use this method, the registration policy has to be set to either *open* or *requires approval*.
|
||||
|
||||
#### Check Full Names
|
||||
|
|
|
|||
|
|
@ -8,7 +8,13 @@ Updating Friendica
|
|||
If you installed Friendica in the ``path/to/friendica`` folder:
|
||||
|
||||
1. Unpack the new Friendica archive in ``path/to/friendica_new``.
|
||||
2. Copy ``config/local.config.php``, ``photo/`` and ``proxy/`` from ``path/to/friendica`` to ``path/to/friendica_new``.
|
||||
2. Copy the following items from ``path/to/friendica`` to ``path/to/friendica_new``:
|
||||
* ``config/local.config.php``
|
||||
* ``proxy/``
|
||||
The following items only need to be copied if they are located inside your friendica path:
|
||||
* your storage folder as set in **Admin -> Site -> File Upload -> Storage base path**
|
||||
* your item cache as set in **Admin -> Site -> Performance -> Path to item cache**
|
||||
* your temp folder as set in **Admin -> Site -> Advanced -> Temp path**
|
||||
3. Rename the ``path/to/friendica`` folder to ``path/to/friendica_old``.
|
||||
4. Rename the ``path/to/friendica_new`` folder to ``path/to/friendica``.
|
||||
5. Check your site. Note: it may go into maintenance mode to update the database schema.
|
||||
|
|
@ -30,11 +36,11 @@ The addon tree has to be updated separately like so:
|
|||
git pull
|
||||
|
||||
For both repositories:
|
||||
The default branch to use is the ``master`` branch, which is the stable version of Friendica.
|
||||
The default branch to use is the ``stable`` branch, which is the stable version of Friendica.
|
||||
It is updated about four times a year on a fixed schedule.
|
||||
|
||||
If you want to use and test bleeding edge code please checkout the ``develop`` branch.
|
||||
The new features and fixes will be merged from ``develop`` into ``master`` after a release candidate period before each release.
|
||||
The new features and fixes will be merged from ``develop`` into ``stable`` after a release candidate period before each release.
|
||||
|
||||
Warning: The ``develop`` branch is unstable, and breaks on average once a month for at most 24 hours until a patch is submitted and merged.
|
||||
Be sure to pull frequently if you choose the ``develop`` branch.
|
||||
|
|
|
|||
|
|
@ -67,6 +67,6 @@ Table contact
|
|||
| bd | | date | NO | | 0001-01-01 | |
|
||||
| notify_new_posts | | tinyint(1) | NO | | 0 | |
|
||||
| fetch_further_information | | tinyint(1) | NO | | 0 | |
|
||||
| ffi_keyword_blacklist | | mediumtext | NO | | NULL | |
|
||||
| ffi_keyword_denylist | | mediumtext | NO | | NULL | |
|
||||
|
||||
Return to [database documentation](help/database)
|
||||
|
|
|
|||
|
|
@ -65,17 +65,17 @@ table.bbcodes > * > tr > th {
|
|||
<td><a href="http://friendi.ca" target="external-link">Friendica</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>[img]https://raw.githubusercontent.com/friendica/friendica/master/images/friendica-32.jpg[/img]</td>
|
||||
<td><img src="https://raw.githubusercontent.com/friendica/friendica/master/images/friendica-32.jpg" alt="Immagine/foto"></td>
|
||||
<td>[img]https://raw.githubusercontent.com/friendica/friendica/stable/images/friendica-32.jpg[/img]</td>
|
||||
<td><img src="https://raw.githubusercontent.com/friendica/friendica/stable/images/friendica-32.jpg" alt="Immagine/foto"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>[img=https://raw.githubusercontent.com/friendica/friendica/master/images/friendica-32.jpg]Das Friendica Logo[/img]</td>
|
||||
<td><img src="https://raw.githubusercontent.com/friendica/friendica/master/images/friendica-32.jpg" alt="Das Friendica Logo"></td>
|
||||
<td>[img=https://raw.githubusercontent.com/friendica/friendica/stable/images/friendica-32.jpg]Das Friendica Logo[/img]</td>
|
||||
<td><img src="https://raw.githubusercontent.com/friendica/friendica/stable/images/friendica-32.jpg" alt="Das Friendica Logo"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>[img=64x32]https://raw.githubusercontent.com/friendica/friendica/master/images/friendica-32.jpg[/img]<br>
|
||||
<td>[img=64x32]https://raw.githubusercontent.com/friendica/friendica/stable/images/friendica-32.jpg[/img]<br>
|
||||
<br>Note: provided height is simply discarded.</td>
|
||||
<td><img src="https://raw.githubusercontent.com/friendica/friendica/master/images/friendica-32.jpg" style="width: 64px;"></td>
|
||||
<td><img src="https://raw.githubusercontent.com/friendica/friendica/stable/images/friendica-32.jpg" style="width: 64px;"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>[size=xx-small]kleiner Text[/size]</td>
|
||||
|
|
|
|||
|
|
@ -49,7 +49,7 @@ Per Git:
|
|||
cd /var/www/<Pfad zu Deiner friendica-Installation>/addon; git pull
|
||||
</p>
|
||||
|
||||
oder als normaler Download von hier: https://github.com/friendica/friendica-addons/blob/master/jappixmini.tgz (auf „view raw“ klicken)
|
||||
oder als normaler Download von hier: https://github.com/friendica/friendica-addons/blob/stable/jappixmini.tgz (auf „view raw“ klicken)
|
||||
|
||||
Entpacke diese Datei (ggf. den entpackten Ordner in „jappixmini“ umbenennen) und lade sowohl den entpackten Ordner komplett als auch die .tgz Datei in den Addon Ordner Deiner Friendica Installation hoch.
|
||||
|
||||
|
|
|
|||
|
|
@ -55,7 +55,7 @@ Wenn du die Möglichkeit hierzu hast, empfehlen wir dir "git" zu nutzen, um die
|
|||
Das macht die Aktualisierung wesentlich einfacher.
|
||||
Der Linux-Code, mit dem man die Dateien direkt in ein Verzeichnis wie "meinewebseite" kopiert, ist
|
||||
|
||||
git clone https://github.com/friendica/friendica.git -b master mywebsite
|
||||
git clone https://github.com/friendica/friendica.git -b stable mywebsite
|
||||
cd mywebsite
|
||||
bin/composer.phar install
|
||||
|
||||
|
|
@ -70,7 +70,7 @@ Falls Addons installiert werden sollen: Gehe in den Friendica-Ordner
|
|||
|
||||
Und die Addon Repository klonst:
|
||||
|
||||
git clone https://github.com/friendica/friendica-addons.git -b master addon
|
||||
git clone https://github.com/friendica/friendica-addons.git -b stable addon
|
||||
|
||||
Um das Addon-Verzeichnis aktuell zu halten, solltest du in diesem Pfad ein "git pull"-Befehl eintragen
|
||||
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ Friendica Nachrichtenfluss
|
|||
Diese Seite soll einige Infos darüber dokumentieren, wie Nachrichten innerhalb von Friendica von einer Person zur anderen übertragen werden.
|
||||
Es gibt verschiedene Pfade, die verschiedene Protokolle und Nachrichtenformate nutzen.
|
||||
|
||||
Diejenigen, die den Nachrichtenfluss genauer verstehen wollen, sollten sich mindestens mit dem DFRN-Protokoll ([Dokument mit den DFRN Spezifikationen](https://github.com/friendica/friendica/blob/master/spec/dfrn2.pdf)) und den Elementen zur Nachrichtenverarbeitung des OStatus Stack informieren (salmon und Pubsubhubbub).
|
||||
Diejenigen, die den Nachrichtenfluss genauer verstehen wollen, sollten sich mindestens mit dem DFRN-Protokoll ([Dokument mit den DFRN Spezifikationen](https://github.com/friendica/friendica/blob/stable/spec/dfrn2.pdf)) und den Elementen zur Nachrichtenverarbeitung des OStatus Stack informieren (salmon und Pubsubhubbub).
|
||||
|
||||
Der Großteil der Nachrichtenverarbeitung nutzt die Datei include/items.php, welche Funktionen für verschiedene Feed-bezogene Import-/Exportaktivitäten liefert.
|
||||
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
* [Home](help)
|
||||
|
||||
To change the look of friendica you have to touch the themes.
|
||||
The current default theme is [Vier](https://github.com/friendica/friendica/tree/master/view/theme/vier) but there are numerous others.
|
||||
The current default theme is [Vier](https://github.com/friendica/friendica/tree/stable/view/theme/vier) but there are numerous others.
|
||||
Have a look at [friendica-themes.com](http://friendica-themes.com) for an overview of the existing themes.
|
||||
In case none of them suits your needs, there are several ways to change a theme.
|
||||
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ Friendica translations
|
|||
The Friendica translation process is based on `gettext` PO files.
|
||||
|
||||
Basic worflow:
|
||||
1. `xgettext` is used to collect translation strings across the project in the master PO file located in `view/lang/C/messages.po`.
|
||||
1. `xgettext` is used to collect translation strings across the project in the authoritative PO file located in `view/lang/C/messages.po`.
|
||||
2. This file makes translations strings available at [the Transifex Friendica page](https://www.transifex.com/Friendica/friendica/dashboard/).
|
||||
3. The translation itself is done at Transifex by volunteers.
|
||||
4. The resulting PO files by languages are manually updated in `view/lang/<language>/messages.po`.
|
||||
|
|
|
|||
File diff suppressed because one or more lines are too long
234
include/api.php
234
include/api.php
|
|
@ -43,6 +43,7 @@ use Friendica\Model\Notify;
|
|||
use Friendica\Model\Photo;
|
||||
use Friendica\Model\User;
|
||||
use Friendica\Model\UserItem;
|
||||
use Friendica\Model\Verb;
|
||||
use Friendica\Network\FKOAuth1;
|
||||
use Friendica\Network\HTTPException;
|
||||
use Friendica\Network\HTTPException\BadRequestException;
|
||||
|
|
@ -263,7 +264,10 @@ function api_login(App $a)
|
|||
throw new UnauthorizedException("This API requires login");
|
||||
}
|
||||
|
||||
DI::auth()->setForUser($a, $record);
|
||||
// Don't refresh the login date more often than twice a day to spare database writes
|
||||
$login_refresh = strcmp(DateTimeFormat::utc('now - 12 hours'), $record['login_date']) > 0;
|
||||
|
||||
DI::auth()->setForUser($a, $record, false, false, $login_refresh);
|
||||
|
||||
$_SESSION["allow_api"] = true;
|
||||
|
||||
|
|
@ -331,16 +335,16 @@ function api_call(App $a, App\Arguments $args = null)
|
|||
|
||||
if (!empty($info['auth']) && api_user() === false) {
|
||||
api_login($a);
|
||||
Logger::info(API_LOG_PREFIX . 'username {username}', ['module' => 'api', 'action' => 'call', 'username' => $a->user['username']]);
|
||||
}
|
||||
|
||||
Logger::info(API_LOG_PREFIX . 'username {username}', ['module' => 'api', 'action' => 'call', 'username' => $a->user['username']]);
|
||||
Logger::debug(API_LOG_PREFIX . 'parameters', ['module' => 'api', 'action' => 'call', 'parameters' => $_REQUEST]);
|
||||
|
||||
$stamp = microtime(true);
|
||||
$return = call_user_func($info['func'], $type);
|
||||
$duration = floatval(microtime(true) - $stamp);
|
||||
|
||||
Logger::info(API_LOG_PREFIX . 'username {username}', ['module' => 'api', 'action' => 'call', 'username' => $a->user['username'], 'duration' => round($duration, 2)]);
|
||||
Logger::info(API_LOG_PREFIX . 'duration {duration}', ['module' => 'api', 'action' => 'call', 'duration' => round($duration, 2)]);
|
||||
|
||||
DI::profiler()->saveLog(DI::logger(), API_LOG_PREFIX . 'performance');
|
||||
|
||||
|
|
@ -623,7 +627,7 @@ function api_get_user(App $a, $contact_id = null)
|
|||
'name' => $contact["name"],
|
||||
'screen_name' => (($contact['nick']) ? $contact['nick'] : $contact['name']),
|
||||
'location' => ($contact["location"] != "") ? $contact["location"] : ContactSelector::networkToName($contact['network'], $contact['url'], $contact['protocol']),
|
||||
'description' => BBCode::toPlaintext($contact["about"]),
|
||||
'description' => BBCode::toPlaintext($contact["about"] ?? ''),
|
||||
'profile_image_url' => $contact["micro"],
|
||||
'profile_image_url_https' => $contact["micro"],
|
||||
'profile_image_url_profile_size' => $contact["thumb"],
|
||||
|
|
@ -697,7 +701,7 @@ function api_get_user(App $a, $contact_id = null)
|
|||
'name' => (($uinfo[0]['name']) ? $uinfo[0]['name'] : $uinfo[0]['nick']),
|
||||
'screen_name' => (($uinfo[0]['nick']) ? $uinfo[0]['nick'] : $uinfo[0]['name']),
|
||||
'location' => $location,
|
||||
'description' => BBCode::toPlaintext($description),
|
||||
'description' => BBCode::toPlaintext($description ?? ''),
|
||||
'profile_image_url' => $uinfo[0]['micro'],
|
||||
'profile_image_url_https' => $uinfo[0]['micro'],
|
||||
'profile_image_url_profile_size' => $uinfo[0]["thumb"],
|
||||
|
|
@ -1240,7 +1244,7 @@ function api_media_upload()
|
|||
"image_type" => $media["type"],
|
||||
"friendica_preview_url" => $media["preview"]];
|
||||
|
||||
Logger::log("Media uploaded: " . print_r($returndata, true), Logger::DEBUG);
|
||||
Logger::info('Media uploaded', ['return' => $returndata]);
|
||||
|
||||
return ["media" => $returndata];
|
||||
}
|
||||
|
|
@ -1310,7 +1314,7 @@ api_register_func('api/media/metadata/create', 'api_media_metadata_create', true
|
|||
/**
|
||||
* @param string $type Return format (atom, rss, xml, json)
|
||||
* @param int $item_id
|
||||
* @return string
|
||||
* @return array|string
|
||||
* @throws Exception
|
||||
*/
|
||||
function api_status_show($type, $item_id)
|
||||
|
|
@ -1538,34 +1542,27 @@ function api_search($type)
|
|||
$params = ['order' => ['id' => true], 'limit' => [$start, $count]];
|
||||
if (preg_match('/^#(\w+)$/', $searchTerm, $matches) === 1 && isset($matches[1])) {
|
||||
$searchTerm = $matches[1];
|
||||
$condition = ["`oid` > ?
|
||||
AND (`uid` = 0 OR (`uid` = ? AND NOT `global`))
|
||||
AND `otype` = ? AND `type` = ? AND `term` = ?",
|
||||
$since_id, local_user(), TERM_OBJ_POST, TERM_HASHTAG, $searchTerm];
|
||||
if ($max_id > 0) {
|
||||
$condition[0] .= ' AND `oid` <= ?';
|
||||
$condition[] = $max_id;
|
||||
$condition = ["`iid` > ? AND `name` = ? AND (NOT `private` OR (`private` AND `uid` = ?))", $since_id, $searchTerm, local_user()];
|
||||
$tags = DBA::select('tag-search-view', ['uri-id'], $condition);
|
||||
$uriids = [];
|
||||
while ($tag = DBA::fetch($tags)) {
|
||||
$uriids[] = $tag['uri-id'];
|
||||
}
|
||||
$terms = DBA::select('term', ['oid'], $condition, []);
|
||||
$itemIds = [];
|
||||
while ($term = DBA::fetch($terms)) {
|
||||
$itemIds[] = $term['oid'];
|
||||
}
|
||||
DBA::close($terms);
|
||||
DBA::close($tags);
|
||||
|
||||
if (empty($itemIds)) {
|
||||
if (empty($uriids)) {
|
||||
return api_format_data('statuses', $type, $data);
|
||||
}
|
||||
|
||||
$preCondition = ['`id` IN (' . implode(', ', $itemIds) . ')'];
|
||||
$condition = ['uri-id' => $uriids];
|
||||
if ($exclude_replies) {
|
||||
$preCondition[] = '`id` = `parent`';
|
||||
$condition['gravity'] = GRAVITY_PARENT;
|
||||
}
|
||||
|
||||
$condition = [implode(' AND ', $preCondition)];
|
||||
$params['group_by'] = ['uri-id'];
|
||||
} else {
|
||||
$condition = ["`id` > ?
|
||||
" . ($exclude_replies ? " AND `id` = `parent` " : ' ') . "
|
||||
" . ($exclude_replies ? " AND `gravity` = " . GRAVITY_PARENT : ' ') . "
|
||||
AND (`uid` = 0 OR (`uid` = ? AND NOT `global`))
|
||||
AND `body` LIKE CONCAT('%',?,'%')",
|
||||
$since_id, api_user(), $_REQUEST['q']];
|
||||
|
|
@ -1653,7 +1650,8 @@ function api_statuses_home_timeline($type)
|
|||
$condition[] = $max_id;
|
||||
}
|
||||
if ($exclude_replies) {
|
||||
$condition[0] .= ' AND `item`.`parent` = `item`.`id`';
|
||||
$condition[0] .= ' AND `item`.`gravity` = ?';
|
||||
$condition[] = GRAVITY_PARENT;
|
||||
}
|
||||
if ($conversation_id > 0) {
|
||||
$condition[0] .= " AND `item`.`parent` = ?";
|
||||
|
|
@ -2040,7 +2038,7 @@ function api_statuses_repeat($type)
|
|||
|
||||
Logger::log('API: api_statuses_repeat: '.$id);
|
||||
|
||||
$fields = ['body', 'title', 'attach', 'tag', 'author-name', 'author-link', 'author-avatar', 'guid', 'created', 'plink'];
|
||||
$fields = ['uri-id', 'body', 'title', 'attach', 'author-name', 'author-link', 'author-avatar', 'guid', 'created', 'plink'];
|
||||
$item = Item::selectFirst($fields, ['id' => $id, 'private' => [Item::PUBLIC, Item::UNLISTED]]);
|
||||
|
||||
if (DBA::isResult($item) && $item['body'] != "") {
|
||||
|
|
@ -2048,7 +2046,7 @@ function api_statuses_repeat($type)
|
|||
$pos = strpos($item['body'], "[share");
|
||||
$post = substr($item['body'], $pos);
|
||||
} else {
|
||||
$post = share_header($item['author-name'], $item['author-link'], $item['author-avatar'], $item['guid'], $item['created'], $item['plink']);
|
||||
$post = BBCode::getShareOpeningTag($item['author-name'], $item['author-link'], $item['author-avatar'], $item['plink'], $item['created'], $item['guid']);
|
||||
|
||||
if (!empty($item['title'])) {
|
||||
$post .= '[h3]' . $item['title'] . "[/h3]\n";
|
||||
|
|
@ -2058,7 +2056,6 @@ function api_statuses_repeat($type)
|
|||
$post .= "[/share]";
|
||||
}
|
||||
$_REQUEST['body'] = $post;
|
||||
$_REQUEST['tag'] = $item['tag'];
|
||||
$_REQUEST['attach'] = $item['attach'];
|
||||
$_REQUEST['profile_uid'] = api_user();
|
||||
$_REQUEST['api_source'] = true;
|
||||
|
|
@ -2068,6 +2065,8 @@ function api_statuses_repeat($type)
|
|||
}
|
||||
|
||||
$item_id = item_post($a);
|
||||
|
||||
/// @todo Copy tags from the original post to the new one
|
||||
} else {
|
||||
throw new ForbiddenException();
|
||||
}
|
||||
|
|
@ -2234,12 +2233,7 @@ function api_statuses_user_timeline($type)
|
|||
throw new ForbiddenException();
|
||||
}
|
||||
|
||||
Logger::log(
|
||||
"api_statuses_user_timeline: api_user: ". api_user() .
|
||||
"\nuser_info: ".print_r($user_info, true) .
|
||||
"\n_REQUEST: ".print_r($_REQUEST, true),
|
||||
Logger::DEBUG
|
||||
);
|
||||
Logger::info('api_statuses_user_timeline', ['api_user' => api_user(), 'user_info' => $user_info, '_REQUEST' => $_REQUEST]);
|
||||
|
||||
$since_id = $_REQUEST['since_id'] ?? 0;
|
||||
$max_id = $_REQUEST['max_id'] ?? 0;
|
||||
|
|
@ -2260,7 +2254,8 @@ function api_statuses_user_timeline($type)
|
|||
}
|
||||
|
||||
if ($exclude_replies) {
|
||||
$condition[0] .= ' AND `item`.`parent` = `item`.`id`';
|
||||
$condition[0] .= ' AND `item`.`gravity` = ?';
|
||||
$condition[] = GRAVITY_PARENT;
|
||||
}
|
||||
|
||||
if ($conversation_id > 0) {
|
||||
|
|
@ -2497,10 +2492,10 @@ function api_format_messages($item, $recipient, $sender)
|
|||
if ($_GET['getText'] == 'html') {
|
||||
$ret['text'] = BBCode::convert($item['body'], false);
|
||||
} elseif ($_GET['getText'] == 'plain') {
|
||||
$ret['text'] = trim(HTML::toPlaintext(BBCode::convert(api_clean_plain_items($item['body']), false, 2, true), 0));
|
||||
$ret['text'] = trim(HTML::toPlaintext(BBCode::convert(api_clean_plain_items($item['body']), false, BBCode::API, true), 0));
|
||||
}
|
||||
} else {
|
||||
$ret['text'] = $item['title'] . "\n" . HTML::toPlaintext(BBCode::convert(api_clean_plain_items($item['body']), false, 2, true), 0);
|
||||
$ret['text'] = $item['title'] . "\n" . HTML::toPlaintext(BBCode::convert(api_clean_plain_items($item['body']), false, BBCode::API, true), 0);
|
||||
}
|
||||
if (!empty($_GET['getUserObjects']) && $_GET['getUserObjects'] == 'false') {
|
||||
unset($ret['sender']);
|
||||
|
|
@ -2526,7 +2521,7 @@ function api_convert_item($item)
|
|||
$attachments = api_get_attachments($body);
|
||||
|
||||
// Workaround for ostatus messages where the title is identically to the body
|
||||
$html = BBCode::convert(api_clean_plain_items($body), false, 2, true);
|
||||
$html = BBCode::convert(api_clean_plain_items($body), false, BBCode::API, true);
|
||||
$statusbody = trim(HTML::toPlaintext($html, 0));
|
||||
|
||||
// handle data: images
|
||||
|
|
@ -3033,7 +3028,7 @@ function api_format_item($item, $type = "json", $status_user = null, $author_use
|
|||
$retweeted_item = [];
|
||||
$quoted_item = [];
|
||||
|
||||
if ($item["id"] == $item["parent"]) {
|
||||
if ($item['gravity'] == GRAVITY_PARENT) {
|
||||
$body = $item['body'];
|
||||
$retweeted_item = api_share_as_retweet($item);
|
||||
if ($body != $item['body']) {
|
||||
|
|
@ -3310,7 +3305,8 @@ function api_lists_statuses($type)
|
|||
$condition[] = $max_id;
|
||||
}
|
||||
if ($exclude_replies > 0) {
|
||||
$condition[0] .= ' AND `item`.`parent` = `item`.`id`';
|
||||
$condition[0] .= ' AND `item`.`gravity` = ?';
|
||||
$condition[] = GRAVITY_PARENT;
|
||||
}
|
||||
if ($conversation_id > 0) {
|
||||
$condition[0] .= " AND `item`.`parent` = ?";
|
||||
|
|
@ -3582,96 +3578,6 @@ function api_statusnet_version($type)
|
|||
api_register_func('api/gnusocial/version', 'api_statusnet_version', false);
|
||||
api_register_func('api/statusnet/version', 'api_statusnet_version', false);
|
||||
|
||||
/**
|
||||
*
|
||||
* @param string $type Return type (atom, rss, xml, json)
|
||||
*
|
||||
* @param int $rel A contact relationship constant
|
||||
* @return array|string|void
|
||||
* @throws BadRequestException
|
||||
* @throws ForbiddenException
|
||||
* @throws ImagickException
|
||||
* @throws InternalServerErrorException
|
||||
* @throws UnauthorizedException
|
||||
* @todo use api_format_data() to return data
|
||||
*/
|
||||
function api_ff_ids($type, int $rel)
|
||||
{
|
||||
if (!api_user()) {
|
||||
throw new ForbiddenException();
|
||||
}
|
||||
|
||||
$a = DI::app();
|
||||
|
||||
api_get_user($a);
|
||||
|
||||
$stringify_ids = $_REQUEST['stringify_ids'] ?? false;
|
||||
|
||||
$contacts = DBA::p("SELECT `pcontact`.`id`
|
||||
FROM `contact`
|
||||
INNER JOIN `contact` AS `pcontact`
|
||||
ON `contact`.`nurl` = `pcontact`.`nurl`
|
||||
AND `pcontact`.`uid` = 0
|
||||
WHERE `contact`.`uid` = ?
|
||||
AND NOT `contact`.`self`
|
||||
AND `contact`.`rel` IN (?, ?)",
|
||||
api_user(),
|
||||
$rel,
|
||||
Contact::FRIEND
|
||||
);
|
||||
|
||||
$ids = [];
|
||||
foreach (DBA::toArray($contacts) as $contact) {
|
||||
if ($stringify_ids) {
|
||||
$ids[] = $contact['id'];
|
||||
} else {
|
||||
$ids[] = intval($contact['id']);
|
||||
}
|
||||
}
|
||||
|
||||
return api_format_data('ids', $type, ['id' => $ids]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the ID of every user the user is following.
|
||||
*
|
||||
* @param string $type Return type (atom, rss, xml, json)
|
||||
*
|
||||
* @return array|string
|
||||
* @throws BadRequestException
|
||||
* @throws ForbiddenException
|
||||
* @throws ImagickException
|
||||
* @throws InternalServerErrorException
|
||||
* @throws UnauthorizedException
|
||||
* @see https://developer.twitter.com/en/docs/accounts-and-users/follow-search-get-users/api-reference/get-friends-ids
|
||||
*/
|
||||
function api_friends_ids($type)
|
||||
{
|
||||
return api_ff_ids($type, Contact::SHARING);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the ID of every user following the user.
|
||||
*
|
||||
* @param string $type Return type (atom, rss, xml, json)
|
||||
*
|
||||
* @return array|string
|
||||
* @throws BadRequestException
|
||||
* @throws ForbiddenException
|
||||
* @throws ImagickException
|
||||
* @throws InternalServerErrorException
|
||||
* @throws UnauthorizedException
|
||||
* @see https://developer.twitter.com/en/docs/accounts-and-users/follow-search-get-users/api-reference/get-followers-ids
|
||||
*/
|
||||
function api_followers_ids($type)
|
||||
{
|
||||
return api_ff_ids($type, Contact::FOLLOWER);
|
||||
}
|
||||
|
||||
/// @TODO move to top of file or somewhere better
|
||||
api_register_func('api/friends/ids', 'api_friends_ids', true);
|
||||
api_register_func('api/followers/ids', 'api_followers_ids', true);
|
||||
|
||||
/**
|
||||
* Sends a new direct message.
|
||||
*
|
||||
|
|
@ -4167,26 +4073,18 @@ function api_fr_photoalbum_delete($type)
|
|||
throw new BadRequestException("no albumname specified");
|
||||
}
|
||||
// check if album is existing
|
||||
$r = q(
|
||||
"SELECT DISTINCT `resource-id` FROM `photo` WHERE `uid` = %d AND `album` = '%s'",
|
||||
intval(api_user()),
|
||||
DBA::escape($album)
|
||||
);
|
||||
if (!DBA::isResult($r)) {
|
||||
|
||||
$photos = DBA::selectToArray('photo', ['resource-id'], ['uid' => api_user(), 'album' => $album], ['group_by' => ['resource-id']]);
|
||||
if (!DBA::isResult($photos)) {
|
||||
throw new BadRequestException("album not available");
|
||||
}
|
||||
|
||||
$resourceIds = array_column($photos, 'resource-id');
|
||||
|
||||
// function for setting the items to "deleted = 1" which ensures that comments, likes etc. are not shown anymore
|
||||
// to the user and the contacts of the users (drop_items() performs the federation of the deletion to other networks
|
||||
foreach ($r as $rr) {
|
||||
$condition = ['uid' => local_user(), 'resource-id' => $rr['resource-id'], 'type' => 'photo'];
|
||||
$photo_item = Item::selectFirstForUser(local_user(), ['id'], $condition);
|
||||
|
||||
if (!DBA::isResult($photo_item)) {
|
||||
throw new InternalServerErrorException("problem with deleting items occured");
|
||||
}
|
||||
Item::deleteForUser(['id' => $photo_item['id']], api_user());
|
||||
}
|
||||
$condition = ['uid' => api_user(), 'resource-id' => $resourceIds, 'type' => 'photo'];
|
||||
Item::deleteForUser($condition, api_user());
|
||||
|
||||
// now let's delete all photos from the album
|
||||
$result = Photo::delete(['uid' => api_user(), 'album' => $album]);
|
||||
|
|
@ -4463,19 +4361,13 @@ function api_fr_photo_delete($type)
|
|||
|
||||
// return success of deletion or error message
|
||||
if ($result) {
|
||||
// retrieve the id of the parent element (the photo element)
|
||||
$condition = ['uid' => local_user(), 'resource-id' => $photo_id, 'type' => 'photo'];
|
||||
$photo_item = Item::selectFirstForUser(local_user(), ['id'], $condition);
|
||||
|
||||
if (!DBA::isResult($photo_item)) {
|
||||
throw new InternalServerErrorException("problem with deleting items occured");
|
||||
}
|
||||
// function for setting the items to "deleted = 1" which ensures that comments, likes etc. are not shown anymore
|
||||
// to the user and the contacts of the users (drop_items() do all the necessary magic to avoid orphans in database and federate deletion)
|
||||
Item::deleteForUser(['id' => $photo_item['id']], api_user());
|
||||
$condition = ['uid' => api_user(), 'resource-id' => $photo_id, 'type' => 'photo'];
|
||||
Item::deleteForUser($condition, api_user());
|
||||
|
||||
$answer = ['result' => 'deleted', 'message' => 'photo with id `' . $photo_id . '` has been deleted from server.'];
|
||||
return api_format_data("photo_delete", $type, ['$result' => $answer]);
|
||||
$result = ['result' => 'deleted', 'message' => 'photo with id `' . $photo_id . '` has been deleted from server.'];
|
||||
return api_format_data("photo_delete", $type, ['$result' => $result]);
|
||||
} else {
|
||||
throw new InternalServerErrorException("unknown error on deleting photo from database table");
|
||||
}
|
||||
|
|
@ -4734,13 +4626,8 @@ function save_media_to_database($mediatype, $media, $type, $album, $allow_cid, $
|
|||
}
|
||||
}
|
||||
|
||||
if ($filetype == "") {
|
||||
$filetype = Images::guessType($filename);
|
||||
}
|
||||
$imagedata = @getimagesize($src);
|
||||
if ($imagedata) {
|
||||
$filetype = $imagedata['mime'];
|
||||
}
|
||||
$filetype = Images::getMimeTypeBySource($src, $filename, $filetype);
|
||||
|
||||
Logger::log(
|
||||
"File upload src: " . $src . " - filename: " . $filename .
|
||||
" - size: " . $filesize . " - type: " . $filetype,
|
||||
|
|
@ -4839,7 +4726,7 @@ function save_media_to_database($mediatype, $media, $type, $album, $allow_cid, $
|
|||
Logger::log("photo upload: new profile image upload ended", Logger::DEBUG);
|
||||
}
|
||||
|
||||
if (isset($r) && $r) {
|
||||
if (!empty($r)) {
|
||||
// create entry in 'item'-table on new uploads to enable users to comment/like/dislike the photo
|
||||
if ($photo_id == null && $mediatype == "photo") {
|
||||
post_photo_item($resource_id, $allow_cid, $deny_cid, $allow_gid, $deny_gid, $filetype, $visibility);
|
||||
|
|
@ -4986,8 +4873,8 @@ function prepare_photo_data($type, $scale, $photo_id)
|
|||
}
|
||||
|
||||
// retrieve item element for getting activities (like, dislike etc.) related to photo
|
||||
$condition = ['uid' => local_user(), 'resource-id' => $photo_id, 'type' => 'photo'];
|
||||
$item = Item::selectFirstForUser(local_user(), ['id'], $condition);
|
||||
$condition = ['uid' => api_user(), 'resource-id' => $photo_id, 'type' => 'photo'];
|
||||
$item = Item::selectFirst(['id', 'uid', 'uri', 'parent', 'allow_cid', 'deny_cid', 'allow_gid', 'deny_gid'], $condition);
|
||||
if (!DBA::isResult($item)) {
|
||||
throw new NotFoundException('Photo-related item not found.');
|
||||
}
|
||||
|
|
@ -4996,7 +4883,7 @@ function prepare_photo_data($type, $scale, $photo_id)
|
|||
|
||||
// retrieve comments on photo
|
||||
$condition = ["`parent` = ? AND `uid` = ? AND (`gravity` IN (?, ?) OR `type`='photo')",
|
||||
$item[0]['parent'], api_user(), GRAVITY_PARENT, GRAVITY_COMMENT];
|
||||
$item['parent'], api_user(), GRAVITY_PARENT, GRAVITY_COMMENT];
|
||||
|
||||
$statuses = Item::selectForUser(api_user(), [], $condition);
|
||||
|
||||
|
|
@ -5016,10 +4903,10 @@ function prepare_photo_data($type, $scale, $photo_id)
|
|||
$data['photo']['friendica_comments'] = $comments;
|
||||
|
||||
// include info if rights on photo and rights on item are mismatching
|
||||
$rights_mismatch = $data['photo']['allow_cid'] != $item[0]['allow_cid'] ||
|
||||
$data['photo']['deny_cid'] != $item[0]['deny_cid'] ||
|
||||
$data['photo']['allow_gid'] != $item[0]['allow_gid'] ||
|
||||
$data['photo']['deny_cid'] != $item[0]['deny_cid'];
|
||||
$rights_mismatch = $data['photo']['allow_cid'] != $item['allow_cid'] ||
|
||||
$data['photo']['deny_cid'] != $item['deny_cid'] ||
|
||||
$data['photo']['allow_gid'] != $item['allow_gid'] ||
|
||||
$data['photo']['deny_gid'] != $item['deny_gid'];
|
||||
$data['photo']['rights_mismatch'] = $rights_mismatch;
|
||||
|
||||
return $data;
|
||||
|
|
@ -5113,8 +5000,7 @@ function api_get_announce($item)
|
|||
}
|
||||
|
||||
$fields = ['author-id', 'author-name', 'author-link', 'author-avatar'];
|
||||
$activity = Item::activityToIndex(Activity::ANNOUNCE);
|
||||
$condition = ['parent-uri' => $item['uri'], 'gravity' => GRAVITY_ACTIVITY, 'uid' => [0, $item['uid']], 'activity' => $activity];
|
||||
$condition = ['parent-uri' => $item['uri'], 'gravity' => GRAVITY_ACTIVITY, 'uid' => [0, $item['uid']], 'vid' => Verb::getID(Activity::ANNOUNCE)];
|
||||
$announce = Item::selectFirstForUser($item['uid'], $fields, $condition, ['order' => ['received' => true]]);
|
||||
if (!DBA::isResult($announce)) {
|
||||
return [];
|
||||
|
|
@ -5210,7 +5096,7 @@ function api_in_reply_to($item)
|
|||
$in_reply_to['user_id_str'] = null;
|
||||
$in_reply_to['screen_name'] = null;
|
||||
|
||||
if (($item['thr-parent'] != $item['uri']) && (intval($item['parent']) != intval($item['id']))) {
|
||||
if (($item['thr-parent'] != $item['uri']) && ($item['gravity'] != GRAVITY_PARENT)) {
|
||||
$parent = Item::selectFirst(['id'], ['uid' => $item['uid'], 'uri' => $item['thr-parent']]);
|
||||
if (DBA::isResult($parent)) {
|
||||
$in_reply_to['status_id'] = intval($parent['id']);
|
||||
|
|
|
|||
|
|
@ -22,7 +22,6 @@
|
|||
use Friendica\App;
|
||||
use Friendica\Content\ContactSelector;
|
||||
use Friendica\Content\Feature;
|
||||
use Friendica\Content\Pager;
|
||||
use Friendica\Content\Text\BBCode;
|
||||
use Friendica\Core\Hook;
|
||||
use Friendica\Core\Logger;
|
||||
|
|
@ -34,7 +33,8 @@ use Friendica\DI;
|
|||
use Friendica\Model\Contact;
|
||||
use Friendica\Model\Item;
|
||||
use Friendica\Model\Profile;
|
||||
use Friendica\Model\Term;
|
||||
use Friendica\Model\Tag;
|
||||
use Friendica\Model\Verb;
|
||||
use Friendica\Object\Post;
|
||||
use Friendica\Object\Thread;
|
||||
use Friendica\Protocol\Activity;
|
||||
|
|
@ -144,222 +144,106 @@ function localize_item(&$item)
|
|||
$item['body'] = item_redir_and_replace_images($extracted['body'], $extracted['images'], $item['contact-id']);
|
||||
}
|
||||
|
||||
/*
|
||||
heluecht 2018-06-19: from my point of view this whole code part is useless.
|
||||
It just renders the body message of technical posts (Like, dislike, ...).
|
||||
But: The body isn't visible at all. So we do this stuff just because we can.
|
||||
Even if these messages were visible, this would only mean that something went wrong.
|
||||
During the further steps of the database restructuring I would like to address this issue.
|
||||
*/
|
||||
|
||||
$activity = DI::activity();
|
||||
|
||||
$xmlhead = "<" . "?xml version='1.0' encoding='UTF-8' ?" . ">";
|
||||
if ($activity->match($item['verb'], Activity::LIKE)
|
||||
|| $activity->match($item['verb'], Activity::DISLIKE)
|
||||
|| $activity->match($item['verb'], Activity::ATTEND)
|
||||
|| $activity->match($item['verb'], Activity::ATTENDNO)
|
||||
|| $activity->match($item['verb'], Activity::ATTENDMAYBE)) {
|
||||
|
||||
$fields = ['author-link', 'author-name', 'verb', 'object-type', 'resource-id', 'body', 'plink'];
|
||||
$obj = Item::selectFirst($fields, ['uri' => $item['parent-uri']]);
|
||||
if (!DBA::isResult($obj)) {
|
||||
return;
|
||||
}
|
||||
|
||||
$author = '[url=' . $item['author-link'] . ']' . $item['author-name'] . '[/url]';
|
||||
$objauthor = '[url=' . $obj['author-link'] . ']' . $obj['author-name'] . '[/url]';
|
||||
|
||||
switch ($obj['verb']) {
|
||||
case Activity::POST:
|
||||
switch ($obj['object-type']) {
|
||||
case Activity\ObjectType::EVENT:
|
||||
$post_type = DI::l10n()->t('event');
|
||||
break;
|
||||
default:
|
||||
$post_type = DI::l10n()->t('status');
|
||||
}
|
||||
break;
|
||||
default:
|
||||
if ($obj['resource-id']) {
|
||||
$post_type = DI::l10n()->t('photo');
|
||||
$m = [];
|
||||
preg_match("/\[url=([^]]*)\]/", $obj['body'], $m);
|
||||
$rr['plink'] = $m[1];
|
||||
} else {
|
||||
$post_type = DI::l10n()->t('status');
|
||||
}
|
||||
}
|
||||
|
||||
$plink = '[url=' . $obj['plink'] . ']' . $post_type . '[/url]';
|
||||
|
||||
$bodyverb = '';
|
||||
if ($activity->match($item['verb'], Activity::LIKE)) {
|
||||
$bodyverb = DI::l10n()->t('%1$s likes %2$s\'s %3$s');
|
||||
} elseif ($activity->match($item['verb'], Activity::DISLIKE)) {
|
||||
$bodyverb = DI::l10n()->t('%1$s doesn\'t like %2$s\'s %3$s');
|
||||
} elseif ($activity->match($item['verb'], Activity::ATTEND)) {
|
||||
$bodyverb = DI::l10n()->t('%1$s attends %2$s\'s %3$s');
|
||||
} elseif ($activity->match($item['verb'], Activity::ATTENDNO)) {
|
||||
$bodyverb = DI::l10n()->t('%1$s doesn\'t attend %2$s\'s %3$s');
|
||||
} elseif ($activity->match($item['verb'], Activity::ATTENDMAYBE)) {
|
||||
$bodyverb = DI::l10n()->t('%1$s attends maybe %2$s\'s %3$s');
|
||||
}
|
||||
|
||||
$item['body'] = sprintf($bodyverb, $author, $objauthor, $plink);
|
||||
}
|
||||
|
||||
if ($activity->match($item['verb'], Activity::FRIEND)) {
|
||||
|
||||
if ($item['object-type']=="" || $item['object-type']!== Activity\ObjectType::PERSON) return;
|
||||
|
||||
$Aname = $item['author-name'];
|
||||
$Alink = $item['author-link'];
|
||||
|
||||
$xmlhead="<"."?xml version='1.0' encoding='UTF-8' ?".">";
|
||||
|
||||
$obj = XML::parseString($xmlhead.$item['object']);
|
||||
$links = XML::parseString($xmlhead."<links>".XML::unescape($obj->link)."</links>");
|
||||
|
||||
$Bname = $obj->title;
|
||||
$Blink = "";
|
||||
$Bphoto = "";
|
||||
foreach ($links->link as $l) {
|
||||
$atts = $l->attributes();
|
||||
switch ($atts['rel']) {
|
||||
case "alternate": $Blink = $atts['href']; break;
|
||||
case "photo": $Bphoto = $atts['href']; break;
|
||||
}
|
||||
}
|
||||
|
||||
$A = '[url=' . Contact::magicLink($Alink) . ']' . $Aname . '[/url]';
|
||||
$B = '[url=' . Contact::magicLink($Blink) . ']' . $Bname . '[/url]';
|
||||
if ($Bphoto != "") {
|
||||
$Bphoto = '[url=' . Contact::magicLink($Blink) . '][img]' . $Bphoto . '[/img][/url]';
|
||||
}
|
||||
|
||||
$item['body'] = DI::l10n()->t('%1$s is now friends with %2$s', $A, $B)."\n\n\n".$Bphoto;
|
||||
|
||||
}
|
||||
if (stristr($item['verb'], Activity::POKE)) {
|
||||
$verb = urldecode(substr($item['verb'],strpos($item['verb'],'#')+1));
|
||||
if (!$verb) {
|
||||
return;
|
||||
}
|
||||
if ($item['object-type']=="" || $item['object-type']!== Activity\ObjectType::PERSON) {
|
||||
return;
|
||||
}
|
||||
|
||||
$Aname = $item['author-name'];
|
||||
$Alink = $item['author-link'];
|
||||
/// @todo The following functionality needs to be cleaned up.
|
||||
if (!empty($item['verb'])) {
|
||||
$activity = DI::activity();
|
||||
|
||||
$xmlhead = "<" . "?xml version='1.0' encoding='UTF-8' ?" . ">";
|
||||
|
||||
$obj = XML::parseString($xmlhead.$item['object']);
|
||||
|
||||
$Bname = $obj->title;
|
||||
$Blink = $obj->id;
|
||||
$Bphoto = "";
|
||||
|
||||
foreach ($obj->link as $l) {
|
||||
$atts = $l->attributes();
|
||||
switch ($atts['rel']) {
|
||||
case "alternate": $Blink = $atts['href'];
|
||||
case "photo": $Bphoto = $atts['href'];
|
||||
if (stristr($item['verb'], Activity::POKE)) {
|
||||
$verb = urldecode(substr($item['verb'], strpos($item['verb'],'#') + 1));
|
||||
if (!$verb) {
|
||||
return;
|
||||
}
|
||||
if ($item['object-type'] == "" || $item['object-type'] !== Activity\ObjectType::PERSON) {
|
||||
return;
|
||||
}
|
||||
|
||||
$Aname = $item['author-name'];
|
||||
$Alink = $item['author-link'];
|
||||
|
||||
$obj = XML::parseString($xmlhead . $item['object']);
|
||||
|
||||
$Bname = $obj->title;
|
||||
$Blink = $obj->id;
|
||||
$Bphoto = "";
|
||||
|
||||
foreach ($obj->link as $l) {
|
||||
$atts = $l->attributes();
|
||||
switch ($atts['rel']) {
|
||||
case "alternate": $Blink = $atts['href'];
|
||||
case "photo": $Bphoto = $atts['href'];
|
||||
}
|
||||
}
|
||||
|
||||
$A = '[url=' . Contact::magicLink($Alink) . ']' . $Aname . '[/url]';
|
||||
$B = '[url=' . Contact::magicLink($Blink) . ']' . $Bname . '[/url]';
|
||||
if ($Bphoto != "") {
|
||||
$Bphoto = '[url=' . Contact::magicLink($Blink) . '][img=80x80]' . $Bphoto . '[/img][/url]';
|
||||
}
|
||||
|
||||
/*
|
||||
* we can't have a translation string with three positions but no distinguishable text
|
||||
* So here is the translate string.
|
||||
*/
|
||||
$txt = DI::l10n()->t('%1$s poked %2$s');
|
||||
|
||||
// now translate the verb
|
||||
$poked_t = trim(sprintf($txt, '', ''));
|
||||
$txt = str_replace($poked_t, DI::l10n()->t($verb), $txt);
|
||||
|
||||
// then do the sprintf on the translation string
|
||||
|
||||
$item['body'] = sprintf($txt, $A, $B) . "\n\n\n" . $Bphoto;
|
||||
|
||||
}
|
||||
|
||||
$A = '[url=' . Contact::magicLink($Alink) . ']' . $Aname . '[/url]';
|
||||
$B = '[url=' . Contact::magicLink($Blink) . ']' . $Bname . '[/url]';
|
||||
if ($Bphoto != "") {
|
||||
$Bphoto = '[url=' . Contact::magicLink($Blink) . '][img=80x80]' . $Bphoto . '[/img][/url]';
|
||||
}
|
||||
if ($activity->match($item['verb'], Activity::TAG)) {
|
||||
$fields = ['author-id', 'author-link', 'author-name', 'author-network',
|
||||
'verb', 'object-type', 'resource-id', 'body', 'plink'];
|
||||
$obj = Item::selectFirst($fields, ['uri' => $item['parent-uri']]);
|
||||
if (!DBA::isResult($obj)) {
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* we can't have a translation string with three positions but no distinguishable text
|
||||
* So here is the translate string.
|
||||
*/
|
||||
$txt = DI::l10n()->t('%1$s poked %2$s');
|
||||
$author_arr = ['uid' => 0, 'id' => $item['author-id'],
|
||||
'network' => $item['author-network'], 'url' => $item['author-link']];
|
||||
$author = '[url=' . Contact::magicLinkByContact($author_arr) . ']' . $item['author-name'] . '[/url]';
|
||||
|
||||
// now translate the verb
|
||||
$poked_t = trim(sprintf($txt, "", ""));
|
||||
$txt = str_replace($poked_t, DI::l10n()->t($verb), $txt);
|
||||
$author_arr = ['uid' => 0, 'id' => $obj['author-id'],
|
||||
'network' => $obj['author-network'], 'url' => $obj['author-link']];
|
||||
$objauthor = '[url=' . Contact::magicLinkByContact($author_arr) . ']' . $obj['author-name'] . '[/url]';
|
||||
|
||||
// then do the sprintf on the translation string
|
||||
|
||||
$item['body'] = sprintf($txt, $A, $B). "\n\n\n" . $Bphoto;
|
||||
|
||||
}
|
||||
|
||||
if ($activity->match($item['verb'], Activity::TAG)) {
|
||||
$fields = ['author-id', 'author-link', 'author-name', 'author-network',
|
||||
'verb', 'object-type', 'resource-id', 'body', 'plink'];
|
||||
$obj = Item::selectFirst($fields, ['uri' => $item['parent-uri']]);
|
||||
if (!DBA::isResult($obj)) {
|
||||
return;
|
||||
}
|
||||
|
||||
$author_arr = ['uid' => 0, 'id' => $item['author-id'],
|
||||
'network' => $item['author-network'], 'url' => $item['author-link']];
|
||||
$author = '[url=' . Contact::magicLinkByContact($author_arr) . ']' . $item['author-name'] . '[/url]';
|
||||
|
||||
$author_arr = ['uid' => 0, 'id' => $obj['author-id'],
|
||||
'network' => $obj['author-network'], 'url' => $obj['author-link']];
|
||||
$objauthor = '[url=' . Contact::magicLinkByContact($author_arr) . ']' . $obj['author-name'] . '[/url]';
|
||||
|
||||
switch ($obj['verb']) {
|
||||
case Activity::POST:
|
||||
switch ($obj['object-type']) {
|
||||
case Activity\ObjectType::EVENT:
|
||||
$post_type = DI::l10n()->t('event');
|
||||
break;
|
||||
default:
|
||||
switch ($obj['verb']) {
|
||||
case Activity::POST:
|
||||
switch ($obj['object-type']) {
|
||||
case Activity\ObjectType::EVENT:
|
||||
$post_type = DI::l10n()->t('event');
|
||||
break;
|
||||
default:
|
||||
$post_type = DI::l10n()->t('status');
|
||||
}
|
||||
break;
|
||||
default:
|
||||
if ($obj['resource-id']) {
|
||||
$post_type = DI::l10n()->t('photo');
|
||||
$m=[]; preg_match("/\[url=([^]]*)\]/", $obj['body'], $m);
|
||||
$rr['plink'] = $m[1];
|
||||
} else {
|
||||
$post_type = DI::l10n()->t('status');
|
||||
}
|
||||
break;
|
||||
default:
|
||||
if ($obj['resource-id']) {
|
||||
$post_type = DI::l10n()->t('photo');
|
||||
$m=[]; preg_match("/\[url=([^]]*)\]/", $obj['body'], $m);
|
||||
$rr['plink'] = $m[1];
|
||||
} else {
|
||||
$post_type = DI::l10n()->t('status');
|
||||
}
|
||||
// Let's break everthing ... ;-)
|
||||
break;
|
||||
}
|
||||
$plink = '[url=' . $obj['plink'] . ']' . $post_type . '[/url]';
|
||||
|
||||
$parsedobj = XML::parseString($xmlhead.$item['object']);
|
||||
|
||||
$tag = sprintf('#[url=%s]%s[/url]', $parsedobj->id, $parsedobj->content);
|
||||
$item['body'] = DI::l10n()->t('%1$s tagged %2$s\'s %3$s with %4$s', $author, $objauthor, $plink, $tag);
|
||||
}
|
||||
|
||||
if ($activity->match($item['verb'], Activity::FAVORITE)) {
|
||||
if ($item['object-type'] == "") {
|
||||
return;
|
||||
}
|
||||
|
||||
$Aname = $item['author-name'];
|
||||
$Alink = $item['author-link'];
|
||||
|
||||
$xmlhead = "<" . "?xml version='1.0' encoding='UTF-8' ?" . ">";
|
||||
|
||||
$obj = XML::parseString($xmlhead.$item['object']);
|
||||
if (strlen($obj->id)) {
|
||||
$fields = ['author-link', 'author-name', 'plink'];
|
||||
$target = Item::selectFirst($fields, ['uri' => $obj->id, 'uid' => $item['uid']]);
|
||||
if (DBA::isResult($target) && $target['plink']) {
|
||||
$Bname = $target['author-name'];
|
||||
$Blink = $target['author-link'];
|
||||
$A = '[url=' . Contact::magicLink($Alink) . ']' . $Aname . '[/url]';
|
||||
$B = '[url=' . Contact::magicLink($Blink) . ']' . $Bname . '[/url]';
|
||||
$P = '[url=' . $target['plink'] . ']' . DI::l10n()->t('post/item') . '[/url]';
|
||||
$item['body'] = DI::l10n()->t('%1$s marked %2$s\'s %3$s as favorite', $A, $B, $P)."\n";
|
||||
}
|
||||
// Let's break everthing ... ;-)
|
||||
break;
|
||||
}
|
||||
$plink = '[url=' . $obj['plink'] . ']' . $post_type . '[/url]';
|
||||
|
||||
$parsedobj = XML::parseString($xmlhead . $item['object']);
|
||||
|
||||
$tag = sprintf('#[url=%s]%s[/url]', $parsedobj->id, $parsedobj->content);
|
||||
$item['body'] = DI::l10n()->t('%1$s tagged %2$s\'s %3$s with %4$s', $author, $objauthor, $plink, $tag);
|
||||
}
|
||||
}
|
||||
|
||||
$matches = null;
|
||||
if (preg_match_all('/@\[url=(.*?)\]/is', $item['body'], $matches, PREG_SET_ORDER)) {
|
||||
foreach ($matches as $mtch) {
|
||||
|
|
@ -493,17 +377,17 @@ function conversation(App $a, array $items, $mode, $update, $preview = false, $o
|
|||
. "<script> var profile_uid = " . $_SESSION['uid']
|
||||
. "; var netargs = '" . substr(DI::args()->getCommand(), 8)
|
||||
. '?f='
|
||||
. (!empty($_GET['cid']) ? '&cid=' . rawurlencode($_GET['cid']) : '')
|
||||
. (!empty($_GET['search']) ? '&search=' . rawurlencode($_GET['search']) : '')
|
||||
. (!empty($_GET['star']) ? '&star=' . rawurlencode($_GET['star']) : '')
|
||||
. (!empty($_GET['order']) ? '&order=' . rawurlencode($_GET['order']) : '')
|
||||
. (!empty($_GET['bmark']) ? '&bmark=' . rawurlencode($_GET['bmark']) : '')
|
||||
. (!empty($_GET['liked']) ? '&liked=' . rawurlencode($_GET['liked']) : '')
|
||||
. (!empty($_GET['conv']) ? '&conv=' . rawurlencode($_GET['conv']) : '')
|
||||
. (!empty($_GET['nets']) ? '&nets=' . rawurlencode($_GET['nets']) : '')
|
||||
. (!empty($_GET['cmin']) ? '&cmin=' . rawurlencode($_GET['cmin']) : '')
|
||||
. (!empty($_GET['cmax']) ? '&cmax=' . rawurlencode($_GET['cmax']) : '')
|
||||
. (!empty($_GET['file']) ? '&file=' . rawurlencode($_GET['file']) : '')
|
||||
. (!empty($_GET['contactid']) ? '&contactid=' . rawurlencode($_GET['contactid']) : '')
|
||||
. (!empty($_GET['search']) ? '&search=' . rawurlencode($_GET['search']) : '')
|
||||
. (!empty($_GET['star']) ? '&star=' . rawurlencode($_GET['star']) : '')
|
||||
. (!empty($_GET['order']) ? '&order=' . rawurlencode($_GET['order']) : '')
|
||||
. (!empty($_GET['bmark']) ? '&bmark=' . rawurlencode($_GET['bmark']) : '')
|
||||
. (!empty($_GET['liked']) ? '&liked=' . rawurlencode($_GET['liked']) : '')
|
||||
. (!empty($_GET['conv']) ? '&conv=' . rawurlencode($_GET['conv']) : '')
|
||||
. (!empty($_GET['nets']) ? '&nets=' . rawurlencode($_GET['nets']) : '')
|
||||
. (!empty($_GET['cmin']) ? '&cmin=' . rawurlencode($_GET['cmin']) : '')
|
||||
. (!empty($_GET['cmax']) ? '&cmax=' . rawurlencode($_GET['cmax']) : '')
|
||||
. (!empty($_GET['file']) ? '&file=' . rawurlencode($_GET['file']) : '')
|
||||
|
||||
. "'; </script>\r\n";
|
||||
}
|
||||
|
|
@ -643,7 +527,7 @@ function conversation(App $a, array $items, $mode, $update, $preview = false, $o
|
|||
$profile_name = $item['author-link'];
|
||||
}
|
||||
|
||||
$tags = Term::populateTagsFromItem($item);
|
||||
$tags = Tag::populateFromItem($item);
|
||||
|
||||
$author = ['uid' => 0, 'id' => $item['author-id'],
|
||||
'network' => $item['author-network'], 'url' => $item['author-link']];
|
||||
|
|
@ -787,7 +671,7 @@ function conversation(App $a, array $items, $mode, $update, $preview = false, $o
|
|||
|
||||
$item['pagedrop'] = $page_dropping;
|
||||
|
||||
if ($item['id'] == $item['parent']) {
|
||||
if ($item['gravity'] == GRAVITY_PARENT) {
|
||||
$item_object = new Post($item);
|
||||
$conv->addParent($item_object);
|
||||
}
|
||||
|
|
@ -876,7 +760,11 @@ function conversation_fetch_comments($thread_items, $pinned) {
|
|||
* @throws \Friendica\Network\HTTPException\InternalServerErrorException
|
||||
*/
|
||||
function conversation_add_children(array $parents, $block_authors, $order, $uid) {
|
||||
$max_comments = DI::config()->get('system', 'max_comments', 100);
|
||||
if (count($parents) > 1) {
|
||||
$max_comments = DI::config()->get('system', 'max_comments', 100);
|
||||
} else {
|
||||
$max_comments = DI::config()->get('system', 'max_display_comments', 1000);
|
||||
}
|
||||
|
||||
$params = ['order' => ['uid', 'commented' => true]];
|
||||
|
||||
|
|
@ -887,19 +775,9 @@ function conversation_add_children(array $parents, $block_authors, $order, $uid)
|
|||
$items = [];
|
||||
|
||||
foreach ($parents AS $parent) {
|
||||
$condition = ["`item`.`parent-uri` = ? AND `item`.`uid` IN (0, ?) ",
|
||||
$parent['uri'], $uid];
|
||||
if ($block_authors) {
|
||||
$condition[0] .= "AND NOT `author`.`hidden`";
|
||||
}
|
||||
|
||||
$thread_items = Item::selectForUser(local_user(), array_merge(Item::DISPLAY_FIELDLIST, ['contact-uid', 'gravity']), $condition, $params);
|
||||
|
||||
$comments = conversation_fetch_comments($thread_items, $parent['pinned'] ?? false);
|
||||
|
||||
if (count($comments) != 0) {
|
||||
$items = array_merge($items, $comments);
|
||||
}
|
||||
$condition = ["`item`.`parent-uri` = ? AND `item`.`uid` IN (0, ?) AND (`vid` != ? OR `vid` IS NULL)",
|
||||
$parent['uri'], $uid, Verb::getID(Activity::FOLLOW)];
|
||||
$items = conversation_fetch_items($parent, $items, $condition, $block_authors, $params);
|
||||
}
|
||||
|
||||
foreach ($items as $index => $item) {
|
||||
|
|
@ -913,6 +791,31 @@ function conversation_add_children(array $parents, $block_authors, $order, $uid)
|
|||
return $items;
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetch conversation items
|
||||
*
|
||||
* @param array $parent
|
||||
* @param array $items
|
||||
* @param array $condition
|
||||
* @param boolean $block_authors
|
||||
* @param array $params
|
||||
* @return array
|
||||
*/
|
||||
function conversation_fetch_items(array $parent, array $items, array $condition, bool $block_authors, array $params) {
|
||||
if ($block_authors) {
|
||||
$condition[0] .= " AND NOT `author`.`hidden`";
|
||||
}
|
||||
|
||||
$thread_items = Item::selectForUser(local_user(), array_merge(Item::DISPLAY_FIELDLIST, ['contact-uid', 'gravity']), $condition, $params);
|
||||
|
||||
$comments = conversation_fetch_comments($thread_items, $parent['pinned'] ?? false);
|
||||
|
||||
if (count($comments) != 0) {
|
||||
$items = array_merge($items, $comments);
|
||||
}
|
||||
return $items;
|
||||
}
|
||||
|
||||
function item_photo_menu($item) {
|
||||
$sub_link = '';
|
||||
$poke_link = '';
|
||||
|
|
@ -924,7 +827,7 @@ function item_photo_menu($item) {
|
|||
$block_link = '';
|
||||
$ignore_link = '';
|
||||
|
||||
if (local_user() && local_user() == $item['uid'] && $item['parent'] == $item['id'] && !$item['self']) {
|
||||
if (local_user() && local_user() == $item['uid'] && $item['gravity'] == GRAVITY_PARENT && !$item['self']) {
|
||||
$sub_link = 'javascript:dosubthread(' . $item['id'] . '); return false;';
|
||||
}
|
||||
|
||||
|
|
@ -953,15 +856,15 @@ function item_photo_menu($item) {
|
|||
|
||||
if (!empty($pcid)) {
|
||||
$contact_url = 'contact/' . $pcid;
|
||||
$posts_link = 'contact/' . $pcid . '/posts';
|
||||
$block_link = 'contact/' . $pcid . '/block';
|
||||
$ignore_link = 'contact/' . $pcid . '/ignore';
|
||||
$posts_link = $contact_url . '/posts';
|
||||
$block_link = $contact_url . '/block';
|
||||
$ignore_link = $contact_url . '/ignore';
|
||||
}
|
||||
|
||||
if ($cid && !$item['self']) {
|
||||
$poke_link = 'poke?c=' . $cid;
|
||||
$contact_url = 'contact/' . $cid;
|
||||
$posts_link = 'contact/' . $cid . '/posts';
|
||||
$poke_link = $contact_url . '/poke';
|
||||
$posts_link = $contact_url . '/posts';
|
||||
|
||||
if (in_array($network, [Protocol::ACTIVITYPUB, Protocol::DFRN, Protocol::DIASPORA])) {
|
||||
$pm_url = 'message/new/' . $cid;
|
||||
|
|
@ -1049,7 +952,7 @@ function builtin_activity_puller($item, &$conv_responses) {
|
|||
return;
|
||||
}
|
||||
|
||||
if (!empty($item['verb']) && DI::activity()->match($item['verb'], $verb) && ($item['id'] != $item['parent'])) {
|
||||
if (!empty($item['verb']) && DI::activity()->match($item['verb'], $verb) && ($item['gravity'] != GRAVITY_PARENT)) {
|
||||
$author = ['uid' => 0, 'id' => $item['author-id'],
|
||||
'network' => $item['author-network'], 'url' => $item['author-link']];
|
||||
$url = Contact::magicLinkByContact($author);
|
||||
|
|
@ -1295,6 +1198,8 @@ function status_editor(App $a, $x, $notes_cid = 0, $popup = false)
|
|||
//jot nav tab (used in some themes)
|
||||
'$message' => DI::l10n()->t('Message'),
|
||||
'$browser' => DI::l10n()->t('Browser'),
|
||||
|
||||
'$compose_link_title' => DI::l10n()->t('Open Compose page'),
|
||||
]);
|
||||
|
||||
|
||||
|
|
@ -1317,7 +1222,7 @@ function get_item_children(array &$item_list, array $parent, $recursive = true)
|
|||
{
|
||||
$children = [];
|
||||
foreach ($item_list as $i => $item) {
|
||||
if ($item['id'] != $item['parent']) {
|
||||
if ($item['gravity'] != GRAVITY_PARENT) {
|
||||
if ($recursive) {
|
||||
// Fallback to parent-uri if thr-parent is not set
|
||||
$thr_parent = $item['thr-parent'];
|
||||
|
|
@ -1465,7 +1370,7 @@ function conv_sort(array $item_list, $order)
|
|||
|
||||
// Extract the top level items
|
||||
foreach ($item_array as $item) {
|
||||
if ($item['id'] == $item['parent']) {
|
||||
if ($item['gravity'] == GRAVITY_PARENT) {
|
||||
$parents[] = $item;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -107,12 +107,24 @@ function notification($params)
|
|||
$item_id = 0;
|
||||
}
|
||||
|
||||
if (isset($params['item']['uri-id'])) {
|
||||
$uri_id = $params['item']['uri-id'];
|
||||
} else {
|
||||
$uri_id = 0;
|
||||
}
|
||||
|
||||
if (isset($params['parent'])) {
|
||||
$parent_id = $params['parent'];
|
||||
} else {
|
||||
$parent_id = 0;
|
||||
}
|
||||
|
||||
if (isset($params['item']['parent-uri-id'])) {
|
||||
$parent_uri_id = $params['item']['parent-uri-id'];
|
||||
} else {
|
||||
$parent_uri_id = 0;
|
||||
}
|
||||
|
||||
$epreamble = '';
|
||||
$preamble = '';
|
||||
$subject = '';
|
||||
|
|
@ -452,19 +464,26 @@ function notification($params)
|
|||
|
||||
if ($show_in_notification_page) {
|
||||
$notification = DI::notify()->insert([
|
||||
'name' => $params['source_name'] ?? '',
|
||||
'name_cache' => substr(strip_tags(BBCode::convert($params['source_name'] ?? '')), 0, 255),
|
||||
'url' => $params['source_link'] ?? '',
|
||||
'photo' => $params['source_photo'] ?? '',
|
||||
'link' => $itemlink ?? '',
|
||||
'uid' => $params['uid'] ?? 0,
|
||||
'iid' => $item_id ?? 0,
|
||||
'parent' => $parent_id ?? 0,
|
||||
'type' => $params['type'] ?? '',
|
||||
'verb' => $params['verb'] ?? '',
|
||||
'otype' => $params['otype'] ?? '',
|
||||
'name' => $params['source_name'] ?? '',
|
||||
'name_cache' => substr(strip_tags(BBCode::convert($params['source_name'])), 0, 255),
|
||||
'url' => $params['source_link'] ?? '',
|
||||
'photo' => $params['source_photo'] ?? '',
|
||||
'link' => $itemlink ?? '',
|
||||
'uid' => $params['uid'] ?? 0,
|
||||
'iid' => $item_id,
|
||||
'uri-id' => $uri_id,
|
||||
'parent' => $parent_id,
|
||||
'parent-uri-id' => $parent_uri_id,
|
||||
'type' => $params['type'] ?? '',
|
||||
'verb' => $params['verb'] ?? '',
|
||||
'otype' => $params['otype'] ?? '',
|
||||
]);
|
||||
|
||||
// Notification insertion can be intercepted by an addon registering the 'enotify_store' hook
|
||||
if (!$notification) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$notification->msg = Renderer::replaceMacros($epreamble, ['$itemlink' => $notification->link]);
|
||||
|
||||
DI::notify()->update($notification);
|
||||
|
|
@ -486,8 +505,9 @@ function notification($params)
|
|||
if (!DBA::exists('notify-threads', ['master-parent-item' => $params['parent'], 'receiver-uid' => $params['uid']])) {
|
||||
Logger::log("notify_id:" . intval($notify_id) . ", parent: " . intval($params['parent']) . "uid: " . intval($params['uid']), Logger::DEBUG);
|
||||
|
||||
$fields = ['notify-id' => $notify_id, 'master-parent-item' => $params['parent'],
|
||||
'receiver-uid' => $params['uid'], 'parent-item' => 0];
|
||||
$fields = ['notify-id' => $notify_id, 'master-parent-item' => $params['parent'],
|
||||
'master-parent-uri-id' => $parent_uri_id,
|
||||
'receiver-uid' => $params['uid'], 'parent-item' => 0];
|
||||
DBA::insert('notify-threads', $fields);
|
||||
|
||||
$additional_mail_header .= "Message-ID: <${id_for_parent}>\n";
|
||||
|
|
@ -574,7 +594,7 @@ function check_user_notification($itemid) {
|
|||
* @throws \Friendica\Network\HTTPException\InternalServerErrorException
|
||||
*/
|
||||
function check_item_notification($itemid, $uid, $notification_type) {
|
||||
$fields = ['id', 'mention', 'tag', 'parent', 'title', 'body',
|
||||
$fields = ['id', 'uri-id', 'mention', 'parent', 'parent-uri-id', 'title', 'body',
|
||||
'author-link', 'author-name', 'author-avatar', 'author-id',
|
||||
'guid', 'parent-uri', 'uri', 'contact-id', 'network'];
|
||||
$condition = ['id' => $itemid, 'gravity' => [GRAVITY_PARENT, GRAVITY_COMMENT], 'deleted' => false];
|
||||
|
|
|
|||
|
|
@ -19,433 +19,56 @@
|
|||
*
|
||||
*/
|
||||
|
||||
use Friendica\Core\Hook;
|
||||
use Friendica\Core\Logger;
|
||||
use Friendica\Core\Protocol;
|
||||
use Friendica\Core\Renderer;
|
||||
use Friendica\Core\Session;
|
||||
use Friendica\Database\DBA;
|
||||
use Friendica\DI;
|
||||
use Friendica\Model\Item;
|
||||
use Friendica\Protocol\DFRN;
|
||||
use Friendica\Protocol\Feed;
|
||||
use Friendica\Protocol\OStatus;
|
||||
use Friendica\Util\Network;
|
||||
use Friendica\Util\ParseUrl;
|
||||
use Friendica\Util\Strings;
|
||||
|
||||
require_once __DIR__ . '/../mod/share.php';
|
||||
|
||||
/**
|
||||
* @deprecated since 2020.06
|
||||
* @see \Friendica\Content\PageInfo::getFooterFromData
|
||||
*/
|
||||
function add_page_info_data(array $data, $no_photos = false)
|
||||
{
|
||||
Hook::callAll('page_info_data', $data);
|
||||
|
||||
if (empty($data['type'])) {
|
||||
return '';
|
||||
}
|
||||
|
||||
// It maybe is a rich content, but if it does have everything that a link has,
|
||||
// then treat it that way
|
||||
if (($data["type"] == "rich") && is_string($data["title"]) &&
|
||||
is_string($data["text"]) && !empty($data["images"])) {
|
||||
$data["type"] = "link";
|
||||
}
|
||||
|
||||
$data["title"] = $data["title"] ?? '';
|
||||
|
||||
if ((($data["type"] != "link") && ($data["type"] != "video") && ($data["type"] != "photo")) || ($data["title"] == $data["url"])) {
|
||||
return "";
|
||||
}
|
||||
|
||||
if ($no_photos && ($data["type"] == "photo")) {
|
||||
return "";
|
||||
}
|
||||
|
||||
// Escape some bad characters
|
||||
$data["url"] = str_replace(["[", "]"], ["[", "]"], htmlentities($data["url"], ENT_QUOTES, 'UTF-8', false));
|
||||
$data["title"] = str_replace(["[", "]"], ["[", "]"], htmlentities($data["title"], ENT_QUOTES, 'UTF-8', false));
|
||||
|
||||
$text = "[attachment type='".$data["type"]."'";
|
||||
|
||||
if (empty($data["text"])) {
|
||||
$data["text"] = $data["title"];
|
||||
}
|
||||
|
||||
if (empty($data["text"])) {
|
||||
$data["text"] = $data["url"];
|
||||
}
|
||||
|
||||
if (!empty($data["url"])) {
|
||||
$text .= " url='".$data["url"]."'";
|
||||
}
|
||||
|
||||
if (!empty($data["title"])) {
|
||||
$text .= " title='".$data["title"]."'";
|
||||
}
|
||||
|
||||
// Only embedd a picture link when it seems to be a valid picture ("width" is set)
|
||||
if (!empty($data["images"]) && !empty($data["images"][0]["width"])) {
|
||||
$preview = str_replace(["[", "]"], ["[", "]"], htmlentities($data["images"][0]["src"], ENT_QUOTES, 'UTF-8', false));
|
||||
// if the preview picture is larger than 500 pixels then show it in a larger mode
|
||||
// But only, if the picture isn't higher than large (To prevent huge posts)
|
||||
if (!DI::config()->get('system', 'always_show_preview') && ($data["images"][0]["width"] >= 500)
|
||||
&& ($data["images"][0]["width"] >= $data["images"][0]["height"])) {
|
||||
$text .= " image='".$preview."'";
|
||||
} else {
|
||||
$text .= " preview='".$preview."'";
|
||||
}
|
||||
}
|
||||
|
||||
$text .= "]".$data["text"]."[/attachment]";
|
||||
|
||||
$hashtags = "";
|
||||
if (isset($data["keywords"]) && count($data["keywords"])) {
|
||||
$hashtags = "\n";
|
||||
foreach ($data["keywords"] as $keyword) {
|
||||
/// @TODO make a positive list of allowed characters
|
||||
$hashtag = str_replace([' ', '+', '/', '.', '#', '@', "'", '"', '’', '`', '(', ')', '„', '“'], '', $keyword);
|
||||
$hashtags .= "#[url=" . DI::baseUrl() . "/search?tag=" . $hashtag . "]" . $hashtag . "[/url] ";
|
||||
}
|
||||
}
|
||||
|
||||
return "\n".$text.$hashtags;
|
||||
}
|
||||
|
||||
function query_page_info($url, $photo = "", $keywords = false, $keyword_blacklist = "")
|
||||
{
|
||||
$data = ParseUrl::getSiteinfoCached($url, true);
|
||||
|
||||
if ($photo != "") {
|
||||
$data["images"][0]["src"] = $photo;
|
||||
}
|
||||
|
||||
Logger::log('fetch page info for ' . $url . ' ' . print_r($data, true), Logger::DEBUG);
|
||||
|
||||
if (!$keywords && isset($data["keywords"])) {
|
||||
unset($data["keywords"]);
|
||||
}
|
||||
|
||||
if (($keyword_blacklist != "") && isset($data["keywords"])) {
|
||||
$list = explode(", ", $keyword_blacklist);
|
||||
|
||||
foreach ($list as $keyword) {
|
||||
$keyword = trim($keyword);
|
||||
|
||||
$index = array_search($keyword, $data["keywords"]);
|
||||
if ($index !== false) {
|
||||
unset($data["keywords"][$index]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
function add_page_keywords($url, $photo = "", $keywords = false, $keyword_blacklist = "")
|
||||
{
|
||||
$data = query_page_info($url, $photo, $keywords, $keyword_blacklist);
|
||||
|
||||
$tags = "";
|
||||
if (isset($data["keywords"]) && count($data["keywords"])) {
|
||||
foreach ($data["keywords"] as $keyword) {
|
||||
$hashtag = str_replace([" ", "+", "/", ".", "#", "'"],
|
||||
["", "", "", "", "", ""], $keyword);
|
||||
|
||||
if ($tags != "") {
|
||||
$tags .= ", ";
|
||||
}
|
||||
|
||||
$tags .= "#[url=" . DI::baseUrl() . "/search?tag=" . $hashtag . "]" . $hashtag . "[/url]";
|
||||
}
|
||||
}
|
||||
|
||||
return $tags;
|
||||
}
|
||||
|
||||
function add_page_info($url, $no_photos = false, $photo = "", $keywords = false, $keyword_blacklist = "")
|
||||
{
|
||||
$data = query_page_info($url, $photo, $keywords, $keyword_blacklist);
|
||||
|
||||
$text = '';
|
||||
|
||||
if (is_array($data)) {
|
||||
$text = add_page_info_data($data, $no_photos);
|
||||
}
|
||||
|
||||
return $text;
|
||||
}
|
||||
|
||||
function add_page_info_to_body($body, $texturl = false, $no_photos = false)
|
||||
{
|
||||
Logger::log('add_page_info_to_body: fetch page info for body ' . $body, Logger::DEBUG);
|
||||
|
||||
$URLSearchString = "^\[\]";
|
||||
|
||||
// Fix for Mastodon where the mentions are in a different format
|
||||
$body = preg_replace("/\[url\=([$URLSearchString]*)\]([#!@])(.*?)\[\/url\]/ism",
|
||||
'$2[url=$1]$3[/url]', $body);
|
||||
|
||||
// Adding these spaces is a quick hack due to my problems with regular expressions :)
|
||||
preg_match("/[^!#@]\[url\]([$URLSearchString]*)\[\/url\]/ism", " " . $body, $matches);
|
||||
|
||||
if (!$matches) {
|
||||
preg_match("/[^!#@]\[url\=([$URLSearchString]*)\](.*?)\[\/url\]/ism", " " . $body, $matches);
|
||||
}
|
||||
|
||||
// Convert urls without bbcode elements
|
||||
if (!$matches && $texturl) {
|
||||
preg_match("/([^\]\='".'"'."]|^)(https?\:\/\/[a-zA-Z0-9\:\/\-\?\&\;\.\=\_\~\#\%\$\!\+\,]+)/ism", " ".$body, $matches);
|
||||
|
||||
// Yeah, a hack. I really hate regular expressions :)
|
||||
if ($matches) {
|
||||
$matches[1] = $matches[2];
|
||||
}
|
||||
}
|
||||
|
||||
if ($matches) {
|
||||
$footer = add_page_info($matches[1], $no_photos);
|
||||
}
|
||||
|
||||
// Remove the link from the body if the link is attached at the end of the post
|
||||
if (isset($footer) && (trim($footer) != "") && (strpos($footer, $matches[1]))) {
|
||||
$removedlink = trim(str_replace($matches[1], "", $body));
|
||||
if (($removedlink == "") || strstr($body, $removedlink)) {
|
||||
$body = $removedlink;
|
||||
}
|
||||
|
||||
$removedlink = preg_replace("/\[url\=" . preg_quote($matches[1], '/') . "\](.*?)\[\/url\]/ism", '', $body);
|
||||
if (($removedlink == "") || strstr($body, $removedlink)) {
|
||||
$body = $removedlink;
|
||||
}
|
||||
}
|
||||
|
||||
// Add the page information to the bottom
|
||||
if (isset($footer) && (trim($footer) != "")) {
|
||||
$body .= $footer;
|
||||
}
|
||||
|
||||
return $body;
|
||||
return "\n" . \Friendica\Content\PageInfo::getFooterFromData($data, $no_photos);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* consume_feed - process atom feed and update anything/everything we might need to update
|
||||
*
|
||||
* $xml = the (atom) feed to consume - RSS isn't as fully supported but may work for simple feeds.
|
||||
*
|
||||
* $importer = the contact_record (joined to user_record) of the local user who owns this relationship.
|
||||
* It is this person's stuff that is going to be updated.
|
||||
* $contact = the person who is sending us stuff. If not set, we MAY be processing a "follow" activity
|
||||
* from an external network and MAY create an appropriate contact record. Otherwise, we MUST
|
||||
* have a contact record.
|
||||
* $hub = should we find a hub declation in the feed, pass it back to our calling process, who might (or
|
||||
* might not) try and subscribe to it.
|
||||
* $datedir sorts in reverse order
|
||||
* $pass - by default ($pass = 0) we cannot guarantee that a parent item has been
|
||||
* imported prior to its children being seen in the stream unless we are certain
|
||||
* of how the feed is arranged/ordered.
|
||||
* With $pass = 1, we only pull parent items out of the stream.
|
||||
* With $pass = 2, we only pull children (comments/likes).
|
||||
*
|
||||
* So running this twice, first with pass 1 and then with pass 2 will do the right
|
||||
* thing regardless of feed ordering. This won't be adequate in a fully-threaded
|
||||
* model where comments can have sub-threads. That would require some massive sorting
|
||||
* to get all the feed items into a mostly linear ordering, and might still require
|
||||
* recursion.
|
||||
*
|
||||
* @param $xml
|
||||
* @param array $importer
|
||||
* @param array $contact
|
||||
* @param $hub
|
||||
* @throws ImagickException
|
||||
* @throws \Friendica\Network\HTTPException\InternalServerErrorException
|
||||
* @deprecated since 2020.06
|
||||
* @see \Friendica\Content\PageInfo::queryUrl
|
||||
*/
|
||||
function query_page_info($url, $photo = "", $keywords = false, $keyword_denylist = "")
|
||||
{
|
||||
return \Friendica\Content\PageInfo::queryUrl($url, $photo, $keywords, $keyword_denylist);
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated since 2020.06
|
||||
* @see \Friendica\Content\PageInfo::getTagsFromUrl()
|
||||
*/
|
||||
function get_page_keywords($url, $photo = "", $keywords = false, $keyword_denylist = "")
|
||||
{
|
||||
return $keywords ? \Friendica\Content\PageInfo::getTagsFromUrl($url, $photo, $keyword_denylist) : [];
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated since 2020.06
|
||||
* @see \Friendica\Content\PageInfo::getFooterFromUrl
|
||||
*/
|
||||
function add_page_info($url, $no_photos = false, $photo = "", $keywords = false, $keyword_denylist = "")
|
||||
{
|
||||
return "\n" . \Friendica\Content\PageInfo::getFooterFromUrl($url, $no_photos, $photo, $keywords, $keyword_denylist);
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated since 2020.06
|
||||
* @see \Friendica\Content\PageInfo::appendToBody
|
||||
*/
|
||||
function add_page_info_to_body($body, $texturl = false, $no_photos = false)
|
||||
{
|
||||
return \Friendica\Content\PageInfo::appendToBody($body, $texturl, $no_photos);
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated since 2020.06
|
||||
* @see \Friendica\Protocol\Feed::consume
|
||||
*/
|
||||
function consume_feed($xml, array $importer, array $contact, &$hub)
|
||||
{
|
||||
if ($contact['network'] === Protocol::OSTATUS) {
|
||||
Logger::log("Consume OStatus messages ", Logger::DEBUG);
|
||||
OStatus::import($xml, $importer, $contact, $hub);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if ($contact['network'] === Protocol::FEED) {
|
||||
Logger::log("Consume feeds", Logger::DEBUG);
|
||||
Feed::import($xml, $importer, $contact);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if ($contact['network'] === Protocol::DFRN) {
|
||||
Logger::log("Consume DFRN messages", Logger::DEBUG);
|
||||
$dfrn_importer = DFRN::getImporter($contact["id"], $importer["uid"]);
|
||||
if (!empty($dfrn_importer)) {
|
||||
Logger::log("Now import the DFRN feed");
|
||||
DFRN::import($xml, $dfrn_importer, true);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function subscribe_to_hub($url, array $importer, array $contact, $hubmode = 'subscribe')
|
||||
{
|
||||
/*
|
||||
* Diaspora has different message-ids in feeds than they do
|
||||
* through the direct Diaspora protocol. If we try and use
|
||||
* the feed, we'll get duplicates. So don't.
|
||||
*/
|
||||
if ($contact['network'] === Protocol::DIASPORA) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Without an importer we don't have a user id - so we quit
|
||||
if (empty($importer)) {
|
||||
return;
|
||||
}
|
||||
|
||||
$user = DBA::selectFirst('user', ['nickname'], ['uid' => $importer['uid']]);
|
||||
|
||||
// No user, no nickname, we quit
|
||||
if (!DBA::isResult($user)) {
|
||||
return;
|
||||
}
|
||||
|
||||
$push_url = DI::baseUrl() . '/pubsub/' . $user['nickname'] . '/' . $contact['id'];
|
||||
|
||||
// Use a single verify token, even if multiple hubs
|
||||
$verify_token = ((strlen($contact['hub-verify'])) ? $contact['hub-verify'] : Strings::getRandomHex());
|
||||
|
||||
$params= 'hub.mode=' . $hubmode . '&hub.callback=' . urlencode($push_url) . '&hub.topic=' . urlencode($contact['poll']) . '&hub.verify=async&hub.verify_token=' . $verify_token;
|
||||
|
||||
Logger::log('subscribe_to_hub: ' . $hubmode . ' ' . $contact['name'] . ' to hub ' . $url . ' endpoint: ' . $push_url . ' with verifier ' . $verify_token);
|
||||
|
||||
if (!strlen($contact['hub-verify']) || ($contact['hub-verify'] != $verify_token)) {
|
||||
DBA::update('contact', ['hub-verify' => $verify_token], ['id' => $contact['id']]);
|
||||
}
|
||||
|
||||
$postResult = Network::post($url, $params);
|
||||
|
||||
Logger::log('subscribe_to_hub: returns: ' . $postResult->getReturnCode(), Logger::DEBUG);
|
||||
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
function drop_items(array $items)
|
||||
{
|
||||
$uid = 0;
|
||||
|
||||
if (!Session::isAuthenticated()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!empty($items)) {
|
||||
foreach ($items as $item) {
|
||||
$owner = Item::deleteForUser(['id' => $item], local_user());
|
||||
|
||||
if ($owner && !$uid) {
|
||||
$uid = $owner;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function drop_item($id, $return = '')
|
||||
{
|
||||
$a = DI::app();
|
||||
|
||||
// locate item to be deleted
|
||||
|
||||
$fields = ['id', 'uid', 'guid', 'contact-id', 'deleted', 'gravity', 'parent'];
|
||||
$item = Item::selectFirstForUser(local_user(), $fields, ['id' => $id]);
|
||||
|
||||
if (!DBA::isResult($item)) {
|
||||
notice(DI::l10n()->t('Item not found.') . EOL);
|
||||
DI::baseUrl()->redirect('network');
|
||||
}
|
||||
|
||||
if ($item['deleted']) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
$contact_id = 0;
|
||||
|
||||
// check if logged in user is either the author or owner of this item
|
||||
if (Session::getRemoteContactID($item['uid']) == $item['contact-id']) {
|
||||
$contact_id = $item['contact-id'];
|
||||
}
|
||||
|
||||
if ((local_user() == $item['uid']) || $contact_id) {
|
||||
// Check if we should do HTML-based delete confirmation
|
||||
if (!empty($_REQUEST['confirm'])) {
|
||||
// <form> can't take arguments in its "action" parameter
|
||||
// so add any arguments as hidden inputs
|
||||
$query = explode_querystring(DI::args()->getQueryString());
|
||||
$inputs = [];
|
||||
|
||||
foreach ($query['args'] as $arg) {
|
||||
if (strpos($arg, 'confirm=') === false) {
|
||||
$arg_parts = explode('=', $arg);
|
||||
$inputs[] = ['name' => $arg_parts[0], 'value' => $arg_parts[1]];
|
||||
}
|
||||
}
|
||||
|
||||
return Renderer::replaceMacros(Renderer::getMarkupTemplate('confirm.tpl'), [
|
||||
'$method' => 'get',
|
||||
'$message' => DI::l10n()->t('Do you really want to delete this item?'),
|
||||
'$extra_inputs' => $inputs,
|
||||
'$confirm' => DI::l10n()->t('Yes'),
|
||||
'$confirm_url' => $query['base'],
|
||||
'$confirm_name' => 'confirmed',
|
||||
'$cancel' => DI::l10n()->t('Cancel'),
|
||||
]);
|
||||
}
|
||||
// Now check how the user responded to the confirmation query
|
||||
if (!empty($_REQUEST['canceled'])) {
|
||||
DI::baseUrl()->redirect('display/' . $item['guid']);
|
||||
}
|
||||
|
||||
$is_comment = ($item['gravity'] == GRAVITY_COMMENT) ? true : false;
|
||||
$parentitem = null;
|
||||
if (!empty($item['parent'])){
|
||||
$fields = ['guid'];
|
||||
$parentitem = Item::selectFirstForUser(local_user(), $fields, ['id' => $item['parent']]);
|
||||
}
|
||||
|
||||
// delete the item
|
||||
Item::deleteForUser(['id' => $item['id']], local_user());
|
||||
|
||||
$return_url = hex2bin($return);
|
||||
|
||||
// removes update_* from return_url to ignore Ajax refresh
|
||||
$return_url = str_replace("update_", "", $return_url);
|
||||
|
||||
// Check if delete a comment
|
||||
if ($is_comment) {
|
||||
// Return to parent guid
|
||||
if (!empty($parentitem)) {
|
||||
DI::baseUrl()->redirect('display/' . $parentitem['guid']);
|
||||
//NOTREACHED
|
||||
}
|
||||
// In case something goes wrong
|
||||
else {
|
||||
DI::baseUrl()->redirect('network');
|
||||
//NOTREACHED
|
||||
}
|
||||
}
|
||||
else {
|
||||
// if unknown location or deleting top level post called from display
|
||||
if (empty($return_url) || strpos($return_url, 'display') !== false) {
|
||||
DI::baseUrl()->redirect('network');
|
||||
//NOTREACHED
|
||||
} else {
|
||||
DI::baseUrl()->redirect($return_url);
|
||||
//NOTREACHED
|
||||
}
|
||||
}
|
||||
} else {
|
||||
notice(DI::l10n()->t('Permission denied.') . EOL);
|
||||
DI::baseUrl()->redirect('display/' . $item['guid']);
|
||||
//NOTREACHED
|
||||
}
|
||||
\Friendica\Protocol\Feed::consume($xml, $importer, $contact, $hub);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -96,7 +96,7 @@ abstract class OAuthSignatureMethod
|
|||
* @param OAuthToken $token
|
||||
* @return string
|
||||
*/
|
||||
abstract public function build_signature(OAuthRequest $request, OAuthConsumer $consumer, OAuthToken $token);
|
||||
abstract public function build_signature(OAuthRequest $request, OAuthConsumer $consumer, OAuthToken $token = null);
|
||||
|
||||
/**
|
||||
* Verifies that a given signature is correct
|
||||
|
|
@ -107,7 +107,7 @@ abstract class OAuthSignatureMethod
|
|||
* @param string $signature
|
||||
* @return bool
|
||||
*/
|
||||
public function check_signature($request, $consumer, $token, $signature)
|
||||
public function check_signature(OAuthRequest $request, OAuthConsumer $consumer, $signature, OAuthToken $token = null)
|
||||
{
|
||||
$built = $this->build_signature($request, $consumer, $token);
|
||||
return ($built == $signature);
|
||||
|
|
@ -134,7 +134,7 @@ class OAuthSignatureMethod_HMAC_SHA1 extends OAuthSignatureMethod
|
|||
* @param OAuthToken $token
|
||||
* @return string
|
||||
*/
|
||||
public function build_signature(OAuthRequest $request, OAuthConsumer $consumer, OAuthToken $token)
|
||||
public function build_signature(OAuthRequest $request, OAuthConsumer $consumer, OAuthToken $token = null)
|
||||
{
|
||||
$base_string = $request->get_signature_base_string();
|
||||
$request->base_string = $base_string;
|
||||
|
|
@ -179,7 +179,7 @@ class OAuthSignatureMethod_PLAINTEXT extends OAuthSignatureMethod
|
|||
* @param $token
|
||||
* @return string
|
||||
*/
|
||||
public function build_signature(OAuthRequest $request, OAuthConsumer $consumer, OAuthToken $token)
|
||||
public function build_signature(OAuthRequest $request, OAuthConsumer $consumer, OAuthToken $token = null)
|
||||
{
|
||||
$key_parts = array(
|
||||
$consumer->secret,
|
||||
|
|
@ -223,7 +223,7 @@ abstract class OAuthSignatureMethod_RSA_SHA1 extends OAuthSignatureMethod
|
|||
// Either way should return a string representation of the certificate
|
||||
protected abstract function fetch_private_cert(&$request);
|
||||
|
||||
public function build_signature(OAuthRequest $request, OAuthConsumer $consumer, OAuthToken $token)
|
||||
public function build_signature(OAuthRequest $request, OAuthConsumer $consumer, OAuthToken $token = null)
|
||||
{
|
||||
$base_string = $request->get_signature_base_string();
|
||||
$request->base_string = $base_string;
|
||||
|
|
@ -243,7 +243,7 @@ abstract class OAuthSignatureMethod_RSA_SHA1 extends OAuthSignatureMethod
|
|||
return base64_encode($signature);
|
||||
}
|
||||
|
||||
public function check_signature($request, $consumer, $token, $signature)
|
||||
public function check_signature(OAuthRequest $request, OAuthConsumer $consumer, $signature, OAuthToken $token = null)
|
||||
{
|
||||
$decoded_sig = base64_decode($signature);
|
||||
|
||||
|
|
@ -358,7 +358,7 @@ class OAuthRequest
|
|||
* @param array|null $parameters
|
||||
* @return OAuthRequest
|
||||
*/
|
||||
public static function from_consumer_and_token(OAuthConsumer $consumer, OAuthToken $token, $http_method, $http_url, array $parameters = NULL)
|
||||
public static function from_consumer_and_token(OAuthConsumer $consumer, $http_method, $http_url, array $parameters = null, OAuthToken $token = null)
|
||||
{
|
||||
@$parameters or $parameters = array();
|
||||
$defaults = array(
|
||||
|
|
@ -788,11 +788,10 @@ class OAuthServer
|
|||
$valid_sig = $signature_method->check_signature(
|
||||
$request,
|
||||
$consumer,
|
||||
$token,
|
||||
$signature
|
||||
$signature,
|
||||
$token
|
||||
);
|
||||
|
||||
|
||||
if (!$valid_sig) {
|
||||
throw new OAuthException("Invalid signature");
|
||||
}
|
||||
|
|
|
|||
23
mod/cal.php
23
mod/cal.php
|
|
@ -37,17 +37,18 @@ use Friendica\Model\Event;
|
|||
use Friendica\Model\Item;
|
||||
use Friendica\Model\Profile;
|
||||
use Friendica\Module\BaseProfile;
|
||||
use Friendica\Network\HTTPException;
|
||||
use Friendica\Util\DateTimeFormat;
|
||||
use Friendica\Util\Temporal;
|
||||
|
||||
function cal_init(App $a)
|
||||
{
|
||||
if (DI::config()->get('system', 'block_public') && !Session::isAuthenticated()) {
|
||||
throw new \Friendica\Network\HTTPException\ForbiddenException(DI::l10n()->t('Access denied.'));
|
||||
throw new HTTPException\ForbiddenException(DI::l10n()->t('Access denied.'));
|
||||
}
|
||||
|
||||
if ($a->argc < 2) {
|
||||
throw new \Friendica\Network\HTTPException\ForbiddenException(DI::l10n()->t('Access denied.'));
|
||||
throw new HTTPException\ForbiddenException(DI::l10n()->t('Access denied.'));
|
||||
}
|
||||
|
||||
Nav::setSelected('events');
|
||||
|
|
@ -55,7 +56,7 @@ function cal_init(App $a)
|
|||
$nick = $a->argv[1];
|
||||
$user = DBA::selectFirst('user', [], ['nickname' => $nick, 'blocked' => false]);
|
||||
if (!DBA::isResult($user)) {
|
||||
throw new \Friendica\Network\HTTPException\NotFoundException();
|
||||
throw new HTTPException\NotFoundException();
|
||||
}
|
||||
|
||||
$a->data['user'] = $user;
|
||||
|
|
@ -67,18 +68,22 @@ function cal_init(App $a)
|
|||
return;
|
||||
}
|
||||
|
||||
$profile = Profile::getByNickname($nick, $a->profile_uid);
|
||||
$a->profile = Profile::getByNickname($nick, $a->profile_uid);
|
||||
|
||||
$account_type = Contact::getAccountType($profile);
|
||||
if (empty($a->profile)) {
|
||||
throw new HTTPException\NotFoundException(DI::l10n()->t('User not found.'));
|
||||
}
|
||||
|
||||
$account_type = Contact::getAccountType($a->profile);
|
||||
|
||||
$tpl = Renderer::getMarkupTemplate('widget/vcard.tpl');
|
||||
|
||||
$vcard_widget = Renderer::replaceMacros($tpl, [
|
||||
'$name' => $profile['name'],
|
||||
'$photo' => $profile['photo'],
|
||||
'$addr' => $profile['addr'] ?: '',
|
||||
'$name' => $a->profile['name'],
|
||||
'$photo' => $a->profile['photo'],
|
||||
'$addr' => $a->profile['addr'] ?: '',
|
||||
'$account_type' => $account_type,
|
||||
'$about' => BBCode::convert($profile['about'] ?: ''),
|
||||
'$about' => BBCode::convert($a->profile['about']),
|
||||
]);
|
||||
|
||||
$cal_widget = Widget\CalendarExport::getHTML();
|
||||
|
|
|
|||
|
|
@ -27,9 +27,9 @@
|
|||
* 2. We may be the target or other side of the conversation to scenario 1, and will
|
||||
* interact with that process on our own user's behalf.
|
||||
*
|
||||
* @see PDF with dfrn specs: https://github.com/friendica/friendica/blob/master/spec/dfrn2.pdf
|
||||
* @see PDF with dfrn specs: https://github.com/friendica/friendica/blob/stable/spec/dfrn2.pdf
|
||||
* You also find a graphic which describes the confirmation process at
|
||||
* https://github.com/friendica/friendica/blob/master/spec/dfrn2_contact_confirmation.png
|
||||
* https://github.com/friendica/friendica/blob/stable/spec/dfrn2_contact_confirmation.png
|
||||
*/
|
||||
|
||||
use Friendica\App;
|
||||
|
|
@ -214,7 +214,7 @@ function dfrn_confirm_post(App $a, $handsfree = null)
|
|||
$params['page'] = 2;
|
||||
}
|
||||
|
||||
Logger::log('Confirm: posting data to ' . $dfrn_confirm . ': ' . print_r($params, true), Logger::DATA);
|
||||
Logger::debug('Confirm: posting data', ['confirm' => $dfrn_confirm, 'parameter' => $params]);
|
||||
|
||||
/*
|
||||
*
|
||||
|
|
@ -372,9 +372,9 @@ function dfrn_confirm_post(App $a, $handsfree = null)
|
|||
$forum = (($page == 1) ? 1 : 0);
|
||||
$prv = (($page == 2) ? 1 : 0);
|
||||
|
||||
Logger::log('dfrn_confirm: requestee contacted: ' . $node);
|
||||
Logger::notice('requestee contacted', ['node' => $node]);
|
||||
|
||||
Logger::log('dfrn_confirm: request: POST=' . print_r($_POST, true), Logger::DATA);
|
||||
Logger::debug('request', ['POST' => $_POST]);
|
||||
|
||||
// If $aes_key is set, both of these items require unpacking from the hex transport encoding.
|
||||
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@
|
|||
*
|
||||
* The dfrn notify endpoint
|
||||
*
|
||||
* @see PDF with dfrn specs: https://github.com/friendica/friendica/blob/master/spec/dfrn2.pdf
|
||||
* @see PDF with dfrn specs: https://github.com/friendica/friendica/blob/stable/spec/dfrn2.pdf
|
||||
*/
|
||||
|
||||
use Friendica\App;
|
||||
|
|
|
|||
|
|
@ -379,7 +379,7 @@ function dfrn_poll_post(App $a)
|
|||
// NOTREACHED
|
||||
} else {
|
||||
// Update the writable flag if it changed
|
||||
Logger::log('dfrn_poll: post request feed: ' . print_r($_POST, true), Logger::DATA);
|
||||
Logger::debug('post request feed', ['post' => $_POST]);
|
||||
if ($dfrn_version >= 2.21) {
|
||||
if ($perm === 'rw') {
|
||||
$writable = 1;
|
||||
|
|
@ -521,7 +521,7 @@ function dfrn_poll_content(App $a)
|
|||
if (strlen($s) && strstr($s, '<?xml')) {
|
||||
$xml = XML::parseString($s);
|
||||
|
||||
Logger::log('dfrn_poll: profile: parsed xml: ' . print_r($xml, true), Logger::DATA);
|
||||
Logger::debug(' profile: parsed', ['xml' => $xml]);
|
||||
|
||||
Logger::log('dfrn_poll: secure profile: challenge: ' . $xml->challenge . ' expecting ' . $hash);
|
||||
Logger::log('dfrn_poll: secure profile: sec: ' . $xml->sec . ' expecting ' . $sec);
|
||||
|
|
|
|||
|
|
@ -19,9 +19,9 @@
|
|||
*
|
||||
*Handles communication associated with the issuance of friend requests.
|
||||
*
|
||||
* @see PDF with dfrn specs: https://github.com/friendica/friendica/blob/master/spec/dfrn2.pdf
|
||||
* @see PDF with dfrn specs: https://github.com/friendica/friendica/blob/stable/spec/dfrn2.pdf
|
||||
* You also find a graphic which describes the confirmation process at
|
||||
* https://github.com/friendica/friendica/blob/master/spec/dfrn2_contact_request.png
|
||||
* https://github.com/friendica/friendica/blob/stable/spec/dfrn2_contact_request.png
|
||||
*/
|
||||
|
||||
use Friendica\App;
|
||||
|
|
@ -297,8 +297,8 @@ function dfrn_request_post(App $a)
|
|||
$data = Probe::uri($url);
|
||||
$network = $data["network"];
|
||||
|
||||
// Canonicalise email-style profile locator
|
||||
$url = Probe::webfingerDfrn($url, $hcard);
|
||||
// Canonicalize email-style profile locator
|
||||
$url = Probe::webfingerDfrn($data['url'], $hcard);
|
||||
|
||||
if (substr($url, 0, 5) === 'stat:') {
|
||||
// Every time we detect the remote subscription we define this as OStatus.
|
||||
|
|
|
|||
|
|
@ -42,7 +42,7 @@ use Friendica\Util\Strings;
|
|||
function display_init(App $a)
|
||||
{
|
||||
if (ActivityPub::isRequest()) {
|
||||
Objects::rawContent();
|
||||
Objects::rawContent(['guid' => $a->argv[1] ?? null]);
|
||||
}
|
||||
|
||||
if (DI::config()->get('system', 'block_public') && !Session::isAuthenticated()) {
|
||||
|
|
@ -54,7 +54,7 @@ function display_init(App $a)
|
|||
$item = null;
|
||||
$item_user = local_user();
|
||||
|
||||
$fields = ['id', 'parent', 'author-id', 'body', 'uid', 'guid'];
|
||||
$fields = ['id', 'parent', 'author-id', 'body', 'uid', 'guid', 'gravity'];
|
||||
|
||||
// If there is only one parameter, then check if this parameter could be a guid
|
||||
if ($a->argc == 2) {
|
||||
|
|
@ -101,12 +101,12 @@ function display_init(App $a)
|
|||
}
|
||||
|
||||
if (!empty($_SERVER['HTTP_ACCEPT']) && strstr($_SERVER['HTTP_ACCEPT'], 'application/atom+xml')) {
|
||||
Logger::log('Directly serving XML for id '.$item["id"], Logger::DEBUG);
|
||||
displayShowFeed($item["id"], false);
|
||||
Logger::log('Directly serving XML for id '.$item['id'], Logger::DEBUG);
|
||||
displayShowFeed($item['id'], false);
|
||||
}
|
||||
|
||||
if ($item["id"] != $item["parent"]) {
|
||||
$parent = Item::selectFirstForUser($item_user, $fields, ['id' => $item["parent"]]);
|
||||
if ($item['gravity'] != GRAVITY_PARENT) {
|
||||
$parent = Item::selectFirstForUser($item_user, $fields, ['id' => $item['parent']]);
|
||||
$item = $parent ?: $item;
|
||||
}
|
||||
|
||||
|
|
@ -116,11 +116,7 @@ function display_init(App $a)
|
|||
$nickname = str_replace(Strings::normaliseLink(DI::baseUrl()) . '/profile/', '', Strings::normaliseLink($profiledata['url']));
|
||||
|
||||
if (!empty($a->user['nickname']) && $nickname != $a->user['nickname']) {
|
||||
$profile = DBA::fetchFirst("SELECT `profile`.* , `contact`.`avatar-date` AS picdate, `user`.* FROM `profile`
|
||||
INNER JOIN `contact` on `contact`.`uid` = `profile`.`uid` INNER JOIN `user` ON `profile`.`uid` = `user`.`uid`
|
||||
WHERE `user`.`nickname` = ? AND `contact`.`self` LIMIT 1",
|
||||
$nickname
|
||||
);
|
||||
$profile = DBA::selectFirst('owner-view', [], ['nickname' => $nickname]);
|
||||
if (DBA::isResult($profile)) {
|
||||
$profiledata = $profile;
|
||||
}
|
||||
|
|
@ -187,6 +183,8 @@ function display_content(App $a, $update = false, $update_uid = 0)
|
|||
|
||||
$item = null;
|
||||
|
||||
$force = (bool)($_REQUEST['force'] ?? false);
|
||||
|
||||
if ($update) {
|
||||
$item_id = $_REQUEST['item_id'];
|
||||
$item = Item::selectFirst(['uid', 'parent', 'parent-uri'], ['id' => $item_id]);
|
||||
|
|
@ -209,8 +207,8 @@ function display_content(App $a, $update = false, $update_uid = 0)
|
|||
$condition = ['guid' => $a->argv[1], 'uid' => local_user()];
|
||||
$item = Item::selectFirstForUser(local_user(), $fields, $condition);
|
||||
if (DBA::isResult($item)) {
|
||||
$item_id = $item["id"];
|
||||
$item_parent = $item["parent"];
|
||||
$item_id = $item['id'];
|
||||
$item_parent = $item['parent'];
|
||||
$item_parent_uri = $item['parent-uri'];
|
||||
}
|
||||
}
|
||||
|
|
@ -218,8 +216,8 @@ function display_content(App $a, $update = false, $update_uid = 0)
|
|||
if (($item_parent == 0) && remote_user()) {
|
||||
$item = Item::selectFirst($fields, ['guid' => $a->argv[1], 'private' => Item::PRIVATE, 'origin' => true]);
|
||||
if (DBA::isResult($item) && Contact::isFollower(remote_user(), $item['uid'])) {
|
||||
$item_id = $item["id"];
|
||||
$item_parent = $item["parent"];
|
||||
$item_id = $item['id'];
|
||||
$item_parent = $item['parent'];
|
||||
$item_parent_uri = $item['parent-uri'];
|
||||
}
|
||||
}
|
||||
|
|
@ -228,8 +226,8 @@ function display_content(App $a, $update = false, $update_uid = 0)
|
|||
$condition = ['private' => [Item::PUBLIC, Item::UNLISTED], 'guid' => $a->argv[1], 'uid' => 0];
|
||||
$item = Item::selectFirstForUser(local_user(), $fields, $condition);
|
||||
if (DBA::isResult($item)) {
|
||||
$item_id = $item["id"];
|
||||
$item_parent = $item["parent"];
|
||||
$item_id = $item['id'];
|
||||
$item_parent = $item['parent'];
|
||||
$item_parent_uri = $item['parent-uri'];
|
||||
}
|
||||
}
|
||||
|
|
@ -285,7 +283,7 @@ function display_content(App $a, $update = false, $update_uid = 0)
|
|||
}
|
||||
|
||||
// We need the editor here to be able to reshare an item.
|
||||
if ($is_owner) {
|
||||
if ($is_owner && !$update) {
|
||||
$x = [
|
||||
'is_owner' => true,
|
||||
'allow_location' => $a->user['allow_location'],
|
||||
|
|
@ -308,7 +306,7 @@ function display_content(App $a, $update = false, $update_uid = 0)
|
|||
$unseen = false;
|
||||
}
|
||||
|
||||
if ($update && !$unseen) {
|
||||
if ($update && !$unseen && !$force) {
|
||||
return '';
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -132,6 +132,8 @@ function editpost_content(App $a)
|
|||
'$message' => DI::l10n()->t('Message'),
|
||||
'$browser' => DI::l10n()->t('Browser'),
|
||||
'$shortpermset' => DI::l10n()->t('permissions'),
|
||||
|
||||
'$compose_link_title' => DI::l10n()->t('Open Compose page'),
|
||||
]);
|
||||
|
||||
return $o;
|
||||
|
|
|
|||
|
|
@ -66,7 +66,7 @@ function events_init(App $a)
|
|||
function events_post(App $a)
|
||||
{
|
||||
|
||||
Logger::log('post: ' . print_r($_REQUEST, true), Logger::DATA);
|
||||
Logger::debug('post', ['request' => $_REQUEST]);
|
||||
|
||||
if (!local_user()) {
|
||||
return;
|
||||
|
|
|
|||
|
|
@ -39,31 +39,26 @@ function fbrowser_content(App $a)
|
|||
|
||||
switch ($a->argv[1]) {
|
||||
case "image":
|
||||
$path = [["", DI::l10n()->t("Photos")]];
|
||||
$path = ['' => DI::l10n()->t('Photos')];
|
||||
$albums = false;
|
||||
$sql_extra = "";
|
||||
$sql_extra2 = " ORDER BY created DESC LIMIT 0, 10";
|
||||
|
||||
if ($a->argc==2) {
|
||||
$albums = q("SELECT distinct(`album`) AS `album` FROM `photo` WHERE `uid` = %d AND `album` != '%s' AND `album` != '%s' ",
|
||||
$photos = q("SELECT distinct(`album`) AS `album` FROM `photo` WHERE `uid` = %d AND `album` != '%s' AND `album` != '%s' ",
|
||||
intval(local_user()),
|
||||
DBA::escape('Contact Photos'),
|
||||
DBA::escape(DI::l10n()->t('Contact Photos'))
|
||||
);
|
||||
|
||||
function _map_folder1($el)
|
||||
{
|
||||
return [bin2hex($el['album']),$el['album']];
|
||||
};
|
||||
|
||||
$albums = array_map("_map_folder1", $albums);
|
||||
$albums = array_column($photos, 'album');
|
||||
}
|
||||
|
||||
if ($a->argc == 3) {
|
||||
$album = hex2bin($a->argv[2]);
|
||||
$album = $a->argv[2];
|
||||
$sql_extra = sprintf("AND `album` = '%s' ", DBA::escape($album));
|
||||
$sql_extra2 = "";
|
||||
$path[] = [$a->argv[2], $album];
|
||||
$path[$album] = $album;
|
||||
}
|
||||
|
||||
$r = q("SELECT `resource-id`, ANY_VALUE(`id`) AS `id`, ANY_VALUE(`filename`) AS `filename`, ANY_VALUE(`type`) AS `type`,
|
||||
|
|
|
|||
104
mod/follow.php
104
mod/follow.php
|
|
@ -28,6 +28,7 @@ use Friendica\Model\Profile;
|
|||
use Friendica\Model\Item;
|
||||
use Friendica\Network\Probe;
|
||||
use Friendica\Database\DBA;
|
||||
use Friendica\Model\User;
|
||||
use Friendica\Util\Strings;
|
||||
|
||||
function follow_post(App $a)
|
||||
|
|
@ -40,7 +41,6 @@ function follow_post(App $a)
|
|||
DI::baseUrl()->redirect('contact');
|
||||
}
|
||||
|
||||
$uid = local_user();
|
||||
$url = Probe::cleanURI($_REQUEST['url']);
|
||||
$return_path = 'follow?url=' . urlencode($url);
|
||||
|
||||
|
|
@ -48,7 +48,7 @@ function follow_post(App $a)
|
|||
// This is just a precaution if maybe this page is called somewhere directly via POST
|
||||
$_SESSION['fastlane'] = $url;
|
||||
|
||||
$result = Contact::createFromProbe($uid, $url, true);
|
||||
$result = Contact::createFromProbe($a->user, $url, true);
|
||||
|
||||
if ($result['success'] == false) {
|
||||
// Possibly it is a remote item and not an account
|
||||
|
|
@ -95,88 +95,63 @@ function follow_content(App $a)
|
|||
$submit = DI::l10n()->t('Submit Request');
|
||||
|
||||
// Don't try to add a pending contact
|
||||
$r = q("SELECT `pending` FROM `contact` WHERE `uid` = %d AND ((`rel` != %d) OR (`network` = '%s')) AND
|
||||
(`nurl` = '%s' OR `alias` = '%s' OR `alias` = '%s') AND
|
||||
`network` != '%s' LIMIT 1",
|
||||
intval(local_user()), DBA::escape(Contact::FOLLOWER), DBA::escape(Protocol::DFRN), DBA::escape(Strings::normaliseLink($url)),
|
||||
DBA::escape(Strings::normaliseLink($url)), DBA::escape($url), DBA::escape(Protocol::STATUSNET));
|
||||
$user_contact = DBA::selectFirst('contact', ['pending'], ["`uid` = ? AND ((`rel` != ?) OR (`network` = ?)) AND
|
||||
(`nurl` = ? OR `alias` = ? OR `alias` = ?) AND `network` != ?",
|
||||
$uid, Contact::FOLLOWER, Protocol::DFRN, Strings::normaliseLink($url),
|
||||
Strings::normaliseLink($url), $url, Protocol::STATUSNET]);
|
||||
|
||||
if ($r) {
|
||||
if ($r[0]['pending']) {
|
||||
if (DBA::isResult($user_contact)) {
|
||||
if ($user_contact['pending']) {
|
||||
notice(DI::l10n()->t('You already added this contact.'));
|
||||
$submit = '';
|
||||
//$a->internalRedirect($_SESSION['return_path']);
|
||||
// NOTREACHED
|
||||
}
|
||||
}
|
||||
|
||||
$ret = Probe::uri($url);
|
||||
|
||||
$protocol = Contact::getProtocol($ret['url'], $ret['network']);
|
||||
|
||||
if (($protocol == Protocol::DIASPORA) && !DI::config()->get('system', 'diaspora_enabled')) {
|
||||
notice(DI::l10n()->t("Diaspora support isn't enabled. Contact can't be added."));
|
||||
$submit = '';
|
||||
//$a->internalRedirect($_SESSION['return_path']);
|
||||
// NOTREACHED
|
||||
}
|
||||
|
||||
if (($protocol == Protocol::OSTATUS) && DI::config()->get('system', 'ostatus_disabled')) {
|
||||
notice(DI::l10n()->t("OStatus support is disabled. Contact can't be added."));
|
||||
$submit = '';
|
||||
//$a->internalRedirect($_SESSION['return_path']);
|
||||
// NOTREACHED
|
||||
}
|
||||
|
||||
if ($protocol == Protocol::PHANTOM) {
|
||||
$contact = Contact::getByURL($url, 0, [], true);
|
||||
if (empty($contact)) {
|
||||
// Possibly it is a remote item and not an account
|
||||
follow_remote_item($url);
|
||||
|
||||
notice(DI::l10n()->t("The network type couldn't be detected. Contact can't be added."));
|
||||
$submit = '';
|
||||
//$a->internalRedirect($_SESSION['return_path']);
|
||||
// NOTREACHED
|
||||
$contact = ['url' => $url, 'network' => Protocol::PHANTOM, 'name' => $url, 'keywords' => ''];
|
||||
}
|
||||
|
||||
$protocol = Contact::getProtocol($contact['url'], $contact['network']);
|
||||
|
||||
if (($protocol == Protocol::DIASPORA) && !DI::config()->get('system', 'diaspora_enabled')) {
|
||||
notice(DI::l10n()->t("Diaspora support isn't enabled. Contact can't be added."));
|
||||
$submit = '';
|
||||
}
|
||||
|
||||
if (($protocol == Protocol::OSTATUS) && DI::config()->get('system', 'ostatus_disabled')) {
|
||||
notice(DI::l10n()->t("OStatus support is disabled. Contact can't be added."));
|
||||
$submit = '';
|
||||
}
|
||||
|
||||
if ($protocol == Protocol::MAIL) {
|
||||
$ret['url'] = $ret['addr'];
|
||||
$contact['url'] = $contact['addr'];
|
||||
}
|
||||
|
||||
if (($protocol === Protocol::DFRN) && !DBA::isResult($r)) {
|
||||
$request = $ret['request'];
|
||||
if (($protocol === Protocol::DFRN) && !DBA::isResult($contact)) {
|
||||
$request = $contact['request'];
|
||||
$tpl = Renderer::getMarkupTemplate('dfrn_request.tpl');
|
||||
} else {
|
||||
$request = DI::baseUrl() . '/follow';
|
||||
$tpl = Renderer::getMarkupTemplate('auto_request.tpl');
|
||||
}
|
||||
|
||||
$r = q("SELECT `url` FROM `contact` WHERE `uid` = %d AND `self` LIMIT 1", intval($uid));
|
||||
|
||||
if (!$r) {
|
||||
$owner = User::getOwnerDataById($uid);
|
||||
if (empty($owner)) {
|
||||
notice(DI::l10n()->t('Permission denied.'));
|
||||
DI::baseUrl()->redirect($return_path);
|
||||
// NOTREACHED
|
||||
}
|
||||
|
||||
$myaddr = $r[0]['url'];
|
||||
$gcontact_id = 0;
|
||||
$myaddr = $owner['url'];
|
||||
|
||||
// Makes the connection request for friendica contacts easier
|
||||
$_SESSION['fastlane'] = $ret['url'];
|
||||
|
||||
$r = q("SELECT `id`, `location`, `about`, `keywords` FROM `gcontact` WHERE `nurl` = '%s'",
|
||||
Strings::normaliseLink($ret['url']));
|
||||
|
||||
if (!$r) {
|
||||
$r = [['location' => '', 'about' => '', 'keywords' => '']];
|
||||
} else {
|
||||
$gcontact_id = $r[0]['id'];
|
||||
}
|
||||
|
||||
if ($protocol === Protocol::DIASPORA) {
|
||||
$r[0]['location'] = '';
|
||||
$r[0]['about'] = '';
|
||||
}
|
||||
$_SESSION['fastlane'] = $contact['url'];
|
||||
|
||||
$o = Renderer::replaceMacros($tpl, [
|
||||
'$header' => DI::l10n()->t('Connect/Follow'),
|
||||
|
|
@ -188,30 +163,27 @@ function follow_content(App $a)
|
|||
'$cancel' => DI::l10n()->t('Cancel'),
|
||||
|
||||
'$request' => $request,
|
||||
'$name' => $ret['name'],
|
||||
'$url' => $ret['url'],
|
||||
'$zrl' => Profile::zrl($ret['url']),
|
||||
'$name' => $contact['name'],
|
||||
'$url' => $contact['url'],
|
||||
'$zrl' => Profile::zrl($contact['url']),
|
||||
'$myaddr' => $myaddr,
|
||||
'$keywords' => $r[0]['keywords'],
|
||||
'$keywords' => $contact['keywords'],
|
||||
|
||||
'$does_know_you' => ['knowyou', DI::l10n()->t('%s knows you', $ret['name'])],
|
||||
'$does_know_you' => ['knowyou', DI::l10n()->t('%s knows you', $contact['name'])],
|
||||
'$addnote_field' => ['dfrn-request-message', DI::l10n()->t('Add a personal note:')],
|
||||
]);
|
||||
|
||||
DI::page()['aside'] = '';
|
||||
|
||||
$profiledata = Contact::getDetailsByURL($ret['url']);
|
||||
if ($profiledata) {
|
||||
Profile::load($a, '', $profiledata, false);
|
||||
}
|
||||
if ($protocol != Protocol::PHANTOM) {
|
||||
Profile::load($a, '', $contact, false);
|
||||
|
||||
if ($gcontact_id <> 0) {
|
||||
$o .= Renderer::replaceMacros(Renderer::getMarkupTemplate('section_title.tpl'),
|
||||
['$title' => DI::l10n()->t('Status Messages and Posts')]
|
||||
);
|
||||
|
||||
// Show last public posts
|
||||
$o .= Contact::getPostsFromUrl($ret['url']);
|
||||
$o .= Contact::getPostsFromUrl($contact['url']);
|
||||
}
|
||||
|
||||
return $o;
|
||||
|
|
|
|||
368
mod/item.php
368
mod/item.php
|
|
@ -29,11 +29,12 @@
|
|||
*/
|
||||
|
||||
use Friendica\App;
|
||||
use Friendica\Content\Pager;
|
||||
use Friendica\Content\Item as ItemHelper;
|
||||
use Friendica\Content\Text\BBCode;
|
||||
use Friendica\Core\Hook;
|
||||
use Friendica\Core\Logger;
|
||||
use Friendica\Core\Protocol;
|
||||
use Friendica\Core\Renderer;
|
||||
use Friendica\Core\Session;
|
||||
use Friendica\Core\System;
|
||||
use Friendica\Core\Worker;
|
||||
|
|
@ -46,7 +47,7 @@ use Friendica\Model\FileTag;
|
|||
use Friendica\Model\Item;
|
||||
use Friendica\Model\Notify\Type;
|
||||
use Friendica\Model\Photo;
|
||||
use Friendica\Model\Term;
|
||||
use Friendica\Model\Tag;
|
||||
use Friendica\Network\HTTPException;
|
||||
use Friendica\Object\EMail\ItemCCEMail;
|
||||
use Friendica\Protocol\Activity;
|
||||
|
|
@ -67,7 +68,10 @@ function item_post(App $a) {
|
|||
|
||||
if (!empty($_REQUEST['dropitems'])) {
|
||||
$arr_drop = explode(',', $_REQUEST['dropitems']);
|
||||
drop_items($arr_drop);
|
||||
foreach ($arr_drop as $item) {
|
||||
Item::deleteForUser(['id' => $item], $uid);
|
||||
}
|
||||
|
||||
$json = ['success' => 1];
|
||||
System::jsonExit($json);
|
||||
}
|
||||
|
|
@ -101,14 +105,9 @@ function item_post(App $a) {
|
|||
$toplevel_item_id = intval($_REQUEST['parent'] ?? 0);
|
||||
$thr_parent_uri = trim($_REQUEST['parent_uri'] ?? '');
|
||||
|
||||
$thread_parent_id = 0;
|
||||
$thread_parent_contact = null;
|
||||
|
||||
$toplevel_item = null;
|
||||
$parent_user = null;
|
||||
|
||||
$parent_contact = null;
|
||||
|
||||
$objecttype = null;
|
||||
$profile_uid = ($_REQUEST['profile_uid'] ?? 0) ?: local_user();
|
||||
$posttype = ($_REQUEST['post_type'] ?? '') ?: Item::PT_ARTICLE;
|
||||
|
|
@ -123,11 +122,9 @@ function item_post(App $a) {
|
|||
// if this isn't the top-level parent of the conversation, find it
|
||||
if (DBA::isResult($toplevel_item)) {
|
||||
// The URI and the contact is taken from the direct parent which needn't to be the top parent
|
||||
$thread_parent_id = $toplevel_item['id'];
|
||||
$thr_parent_uri = $toplevel_item['uri'];
|
||||
$thread_parent_contact = Contact::getDetailsByURL($toplevel_item["author-link"]);
|
||||
|
||||
if ($toplevel_item['id'] != $toplevel_item['parent']) {
|
||||
if ($toplevel_item['gravity'] != GRAVITY_PARENT) {
|
||||
$toplevel_item = Item::selectFirst([], ['id' => $toplevel_item['parent']]);
|
||||
}
|
||||
}
|
||||
|
|
@ -253,7 +250,7 @@ function item_post(App $a) {
|
|||
$verb = $orig_post['verb'];
|
||||
$objecttype = $orig_post['object-type'];
|
||||
$app = $orig_post['app'];
|
||||
$categories = $orig_post['file'];
|
||||
$categories = $orig_post['file'] ?? '';
|
||||
$title = Strings::escapeTags(trim($_REQUEST['title']));
|
||||
$body = trim($body);
|
||||
$private = $orig_post['private'];
|
||||
|
|
@ -370,74 +367,63 @@ function item_post(App $a) {
|
|||
|
||||
// get contact info for owner
|
||||
if ($profile_uid == local_user() || $allow_comment) {
|
||||
$contact_record = $author;
|
||||
$contact_record = $author ?: [];
|
||||
} else {
|
||||
$contact_record = DBA::selectFirst('contact', [], ['uid' => $profile_uid, 'self' => true]);
|
||||
$contact_record = DBA::selectFirst('contact', [], ['uid' => $profile_uid, 'self' => true]) ?: [];
|
||||
}
|
||||
|
||||
// Look for any tags and linkify them
|
||||
$str_tags = '';
|
||||
$inform = '';
|
||||
|
||||
$tags = BBCode::getTags($body);
|
||||
|
||||
if ($thread_parent_id && !\Friendica\Content\Feature::isEnabled($uid, 'explicit_mentions')) {
|
||||
$tags = item_add_implicit_mentions($tags, $thread_parent_contact, $thread_parent_id);
|
||||
}
|
||||
|
||||
$tagged = [];
|
||||
|
||||
$private_forum = false;
|
||||
$private_id = null;
|
||||
$only_to_forum = false;
|
||||
$forum_contact = [];
|
||||
|
||||
if (count($tags)) {
|
||||
$body = BBCode::performWithEscapedTags($body, ['noparse', 'pre', 'code', 'img'], function ($body) use ($profile_uid, $network, $str_contact_allow, &$inform, &$private_forum, &$private_id, &$only_to_forum, &$forum_contact) {
|
||||
$tags = BBCode::getTags($body);
|
||||
|
||||
$tagged = [];
|
||||
|
||||
foreach ($tags as $tag) {
|
||||
$tag_type = substr($tag, 0, 1);
|
||||
|
||||
if ($tag_type == Term::TAG_CHARACTER[Term::HASHTAG]) {
|
||||
if ($tag_type == Tag::TAG_CHARACTER[Tag::HASHTAG]) {
|
||||
continue;
|
||||
}
|
||||
|
||||
/*
|
||||
* If we already tagged 'Robert Johnson', don't try and tag 'Robert'.
|
||||
/* If we already tagged 'Robert Johnson', don't try and tag 'Robert'.
|
||||
* Robert Johnson should be first in the $tags array
|
||||
*/
|
||||
$fullnametagged = false;
|
||||
/// @TODO $tagged is initialized above if () block and is not filled, maybe old-lost code?
|
||||
foreach ($tagged as $nextTag) {
|
||||
if (stristr($nextTag, $tag . ' ')) {
|
||||
$fullnametagged = true;
|
||||
break;
|
||||
continue 2;
|
||||
}
|
||||
}
|
||||
if ($fullnametagged) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$success = handle_tag($body, $inform, $str_tags, local_user() ? local_user() : $profile_uid, $tag, $network);
|
||||
$success = ItemHelper::replaceTag($body, $inform, local_user() ? local_user() : $profile_uid, $tag, $network);
|
||||
if ($success['replaced']) {
|
||||
$tagged[] = $tag;
|
||||
}
|
||||
// When the forum is private or the forum is addressed with a "!" make the post private
|
||||
if (is_array($success['contact']) && (!empty($success['contact']['prv']) || ($tag_type == Term::TAG_CHARACTER[Term::EXCLUSIVE_MENTION]))) {
|
||||
if (!empty($success['contact']['prv']) || ($tag_type == Tag::TAG_CHARACTER[Tag::EXCLUSIVE_MENTION])) {
|
||||
$private_forum = $success['contact']['prv'];
|
||||
$only_to_forum = ($tag_type == Term::TAG_CHARACTER[Term::EXCLUSIVE_MENTION]);
|
||||
$only_to_forum = ($tag_type == Tag::TAG_CHARACTER[Tag::EXCLUSIVE_MENTION]);
|
||||
$private_id = $success['contact']['id'];
|
||||
$forum_contact = $success['contact'];
|
||||
} elseif (is_array($success['contact']) && !empty($success['contact']['forum']) &&
|
||||
($str_contact_allow == '<' . $success['contact']['id'] . '>')) {
|
||||
} elseif (!empty($success['contact']['forum']) && ($str_contact_allow == '<' . $success['contact']['id'] . '>')) {
|
||||
$private_forum = false;
|
||||
$only_to_forum = true;
|
||||
$private_id = $success['contact']['id'];
|
||||
$forum_contact = $success['contact'];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $body;
|
||||
});
|
||||
|
||||
$original_contact_id = $contact_id;
|
||||
|
||||
if (!$toplevel_item_id && count($forum_contact) && ($private_forum || $only_to_forum)) {
|
||||
if (!$toplevel_item_id && !empty($forum_contact) && ($private_forum || $only_to_forum)) {
|
||||
// we tagged a forum in a top level post. Now we change the post
|
||||
$private = $private_forum;
|
||||
|
||||
|
|
@ -578,9 +564,9 @@ function item_post(App $a) {
|
|||
$datarray['gravity'] = $gravity;
|
||||
$datarray['network'] = $network;
|
||||
$datarray['contact-id'] = $contact_id;
|
||||
$datarray['owner-name'] = $contact_record['name'];
|
||||
$datarray['owner-link'] = $contact_record['url'];
|
||||
$datarray['owner-avatar'] = $contact_record['thumb'];
|
||||
$datarray['owner-name'] = $contact_record['name'] ?? '';
|
||||
$datarray['owner-link'] = $contact_record['url'] ?? '';
|
||||
$datarray['owner-avatar'] = $contact_record['thumb'] ?? '';
|
||||
$datarray['owner-id'] = Contact::getIdForURL($datarray['owner-link']);
|
||||
$datarray['author-name'] = $author['name'];
|
||||
$datarray['author-link'] = $author['url'];
|
||||
|
|
@ -599,7 +585,6 @@ function item_post(App $a) {
|
|||
$datarray['app'] = $app;
|
||||
$datarray['location'] = $location;
|
||||
$datarray['coord'] = $coord;
|
||||
$datarray['tag'] = $str_tags;
|
||||
$datarray['file'] = $categories;
|
||||
$datarray['inform'] = $inform;
|
||||
$datarray['verb'] = $verb;
|
||||
|
|
@ -656,7 +641,7 @@ function item_post(App $a) {
|
|||
|
||||
// Check for hashtags in the body and repair or add hashtag links
|
||||
if ($preview || $orig_post) {
|
||||
Item::setHashtags($datarray);
|
||||
$datarray['body'] = Item::setHashtags($datarray['body']);
|
||||
}
|
||||
|
||||
// preview mode - prepare the body for display and send it via json
|
||||
|
|
@ -664,6 +649,7 @@ function item_post(App $a) {
|
|||
// We set the datarray ID to -1 because in preview mode the dataray
|
||||
// doesn't have an ID.
|
||||
$datarray["id"] = -1;
|
||||
$datarray["uri-id"] = -1;
|
||||
$datarray["item_id"] = -1;
|
||||
$datarray["author-network"] = Protocol::DFRN;
|
||||
|
||||
|
|
@ -696,7 +682,6 @@ function item_post(App $a) {
|
|||
$fields = [
|
||||
'title' => $datarray['title'],
|
||||
'body' => $datarray['body'],
|
||||
'tag' => $datarray['tag'],
|
||||
'attach' => $datarray['attach'],
|
||||
'file' => $datarray['file'],
|
||||
'rendered-html' => $datarray['rendered-html'],
|
||||
|
|
@ -750,12 +735,18 @@ function item_post(App $a) {
|
|||
throw new HTTPException\InternalServerErrorException(DI::l10n()->t('Item couldn\'t be fetched.'));
|
||||
}
|
||||
|
||||
Tag::storeFromBody($datarray['uri-id'], $datarray['body']);
|
||||
|
||||
if (!\Friendica\Content\Feature::isEnabled($uid, 'explicit_mentions') && ($datarray['gravity'] == GRAVITY_COMMENT)) {
|
||||
Tag::createImplicitMentions($datarray['uri-id'], $datarray['thr-parent-id']);
|
||||
}
|
||||
|
||||
// update filetags in pconfig
|
||||
FileTag::updatePconfig($uid, $categories_old, $categories_new, 'category');
|
||||
|
||||
// These notifications are sent if someone else is commenting other your wall
|
||||
if ($toplevel_item_id) {
|
||||
if ($contact_record != $author) {
|
||||
if ($contact_record != $author) {
|
||||
if ($toplevel_item_id) {
|
||||
notification([
|
||||
'type' => Type::COMMENT,
|
||||
'notify_flags' => $user['notify-flags'],
|
||||
|
|
@ -773,9 +764,7 @@ function item_post(App $a) {
|
|||
'parent' => $toplevel_item_id,
|
||||
'parent_uri' => $toplevel_item['uri']
|
||||
]);
|
||||
}
|
||||
} else {
|
||||
if (($contact_record != $author) && !count($forum_contact)) {
|
||||
} elseif (empty($forum_contact)) {
|
||||
notification([
|
||||
'type' => Type::WALL,
|
||||
'notify_flags' => $user['notify-flags'],
|
||||
|
|
@ -863,7 +852,9 @@ function item_content(App $a)
|
|||
|
||||
if (($a->argc >= 3) && ($a->argv[1] === 'drop') && intval($a->argv[2])) {
|
||||
if (DI::mode()->isAjax()) {
|
||||
$o = Item::deleteForUser(['id' => $a->argv[2]], local_user());
|
||||
Item::deleteForUser(['id' => $a->argv[2]], local_user());
|
||||
// ajax return: [<item id>, 0 (no perm) | <owner id>]
|
||||
System::jsonExit([intval($a->argv[2]), local_user()]);
|
||||
} else {
|
||||
if (!empty($a->argv[3])) {
|
||||
$o = drop_item($a->argv[2], $a->argv[3]);
|
||||
|
|
@ -872,203 +863,110 @@ function item_content(App $a)
|
|||
$o = drop_item($a->argv[2]);
|
||||
}
|
||||
}
|
||||
|
||||
if (DI::mode()->isAjax()) {
|
||||
// ajax return: [<item id>, 0 (no perm) | <owner id>]
|
||||
System::jsonExit([intval($a->argv[2]), intval($o)]);
|
||||
}
|
||||
}
|
||||
|
||||
return $o;
|
||||
}
|
||||
|
||||
/**
|
||||
* This function removes the tag $tag from the text $body and replaces it with
|
||||
* the appropriate link.
|
||||
*
|
||||
* @param App $a
|
||||
* @param string $body the text to replace the tag in
|
||||
* @param string $inform a comma-seperated string containing everybody to inform
|
||||
* @param string $str_tags string to add the tag to
|
||||
* @param integer $profile_uid
|
||||
* @param string $tag the tag to replace
|
||||
* @param string $network The network of the post
|
||||
*
|
||||
* @return array|bool ['replaced' => $replaced, 'contact' => $contact];
|
||||
* @throws ImagickException
|
||||
* @param int $id
|
||||
* @param string $return
|
||||
* @return string
|
||||
* @throws HTTPException\InternalServerErrorException
|
||||
*/
|
||||
function handle_tag(&$body, &$inform, &$str_tags, $profile_uid, $tag, $network = "")
|
||||
function drop_item(int $id, string $return = '')
|
||||
{
|
||||
$replaced = false;
|
||||
$r = null;
|
||||
// locate item to be deleted
|
||||
$fields = ['id', 'uid', 'guid', 'contact-id', 'deleted', 'gravity', 'parent'];
|
||||
$item = Item::selectFirstForUser(local_user(), $fields, ['id' => $id]);
|
||||
|
||||
//is it a person tag?
|
||||
if (Term::isType($tag, Term::MENTION, Term::IMPLICIT_MENTION, Term::EXCLUSIVE_MENTION)) {
|
||||
$tag_type = substr($tag, 0, 1);
|
||||
//is it already replaced?
|
||||
if (strpos($tag, '[url=')) {
|
||||
//append tag to str_tags
|
||||
if (!stristr($str_tags, $tag)) {
|
||||
if (strlen($str_tags)) {
|
||||
$str_tags .= ',';
|
||||
}
|
||||
$str_tags .= $tag;
|
||||
}
|
||||
|
||||
// Checking for the alias that is used for OStatus
|
||||
$pattern = "/[@!]\[url\=(.*?)\](.*?)\[\/url\]/ism";
|
||||
if (preg_match($pattern, $tag, $matches)) {
|
||||
$data = Contact::getDetailsByURL($matches[1]);
|
||||
|
||||
if ($data["alias"] != "") {
|
||||
$newtag = '@[url=' . $data["alias"] . ']' . $data["nick"] . '[/url]';
|
||||
|
||||
if (!stripos($str_tags, '[url=' . $data["alias"] . ']')) {
|
||||
if (strlen($str_tags)) {
|
||||
$str_tags .= ',';
|
||||
}
|
||||
|
||||
$str_tags .= $newtag;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $replaced;
|
||||
}
|
||||
|
||||
//get the person's name
|
||||
$name = substr($tag, 1);
|
||||
|
||||
// Sometimes the tag detection doesn't seem to work right
|
||||
// This is some workaround
|
||||
$nameparts = explode(" ", $name);
|
||||
$name = $nameparts[0];
|
||||
|
||||
// Try to detect the contact in various ways
|
||||
if (strpos($name, 'http://')) {
|
||||
// At first we have to ensure that the contact exists
|
||||
Contact::getIdForURL($name);
|
||||
|
||||
// Now we should have something
|
||||
$contact = Contact::getDetailsByURL($name);
|
||||
} elseif (strpos($name, '@')) {
|
||||
// This function automatically probes when no entry was found
|
||||
$contact = Contact::getDetailsByAddr($name);
|
||||
} else {
|
||||
$contact = false;
|
||||
$fields = ['id', 'url', 'nick', 'name', 'alias', 'network', 'forum', 'prv'];
|
||||
|
||||
if (strrpos($name, '+')) {
|
||||
// Is it in format @nick+number?
|
||||
$tagcid = intval(substr($name, strrpos($name, '+') + 1));
|
||||
$contact = DBA::selectFirst('contact', $fields, ['id' => $tagcid, 'uid' => $profile_uid]);
|
||||
}
|
||||
|
||||
// select someone by nick or attag in the current network
|
||||
if (!DBA::isResult($contact) && ($network != "")) {
|
||||
$condition = ["(`nick` = ? OR `attag` = ?) AND `network` = ? AND `uid` = ?",
|
||||
$name, $name, $network, $profile_uid];
|
||||
$contact = DBA::selectFirst('contact', $fields, $condition);
|
||||
}
|
||||
|
||||
//select someone by name in the current network
|
||||
if (!DBA::isResult($contact) && ($network != "")) {
|
||||
$condition = ['name' => $name, 'network' => $network, 'uid' => $profile_uid];
|
||||
$contact = DBA::selectFirst('contact', $fields, $condition);
|
||||
}
|
||||
|
||||
// select someone by nick or attag in any network
|
||||
if (!DBA::isResult($contact)) {
|
||||
$condition = ["(`nick` = ? OR `attag` = ?) AND `uid` = ?", $name, $name, $profile_uid];
|
||||
$contact = DBA::selectFirst('contact', $fields, $condition);
|
||||
}
|
||||
|
||||
// select someone by name in any network
|
||||
if (!DBA::isResult($contact)) {
|
||||
$condition = ['name' => $name, 'uid' => $profile_uid];
|
||||
$contact = DBA::selectFirst('contact', $fields, $condition);
|
||||
}
|
||||
}
|
||||
|
||||
// Check if $contact has been successfully loaded
|
||||
if (DBA::isResult($contact)) {
|
||||
if (strlen($inform) && (isset($contact["notify"]) || isset($contact["id"]))) {
|
||||
$inform .= ',';
|
||||
}
|
||||
|
||||
if (isset($contact["id"])) {
|
||||
$inform .= 'cid:' . $contact["id"];
|
||||
} elseif (isset($contact["notify"])) {
|
||||
$inform .= $contact["notify"];
|
||||
}
|
||||
|
||||
$profile = $contact["url"];
|
||||
$alias = $contact["alias"];
|
||||
$newname = ($contact["name"] ?? '') ?: $contact["nick"];
|
||||
}
|
||||
|
||||
//if there is an url for this persons profile
|
||||
if (isset($profile) && ($newname != "")) {
|
||||
$replaced = true;
|
||||
// create profile link
|
||||
$profile = str_replace(',', '%2c', $profile);
|
||||
$newtag = $tag_type.'[url=' . $profile . ']' . $newname . '[/url]';
|
||||
$body = str_replace($tag_type . $name, $newtag, $body);
|
||||
// append tag to str_tags
|
||||
if (!stristr($str_tags, $newtag)) {
|
||||
if (strlen($str_tags)) {
|
||||
$str_tags .= ',';
|
||||
}
|
||||
$str_tags .= $newtag;
|
||||
}
|
||||
|
||||
/*
|
||||
* Status.Net seems to require the numeric ID URL in a mention if the person isn't
|
||||
* subscribed to you. But the nickname URL is OK if they are. Grrr. We'll tag both.
|
||||
*/
|
||||
if (!empty($alias)) {
|
||||
$newtag = '@[url=' . $alias . ']' . $newname . '[/url]';
|
||||
if (!stripos($str_tags, '[url=' . $alias . ']')) {
|
||||
if (strlen($str_tags)) {
|
||||
$str_tags .= ',';
|
||||
}
|
||||
$str_tags .= $newtag;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!DBA::isResult($item)) {
|
||||
notice(DI::l10n()->t('Item not found.') . EOL);
|
||||
DI::baseUrl()->redirect('network');
|
||||
}
|
||||
|
||||
return ['replaced' => $replaced, 'contact' => $contact];
|
||||
}
|
||||
if ($item['deleted']) {
|
||||
return '';
|
||||
}
|
||||
|
||||
function item_add_implicit_mentions(array $tags, array $thread_parent_contact, $thread_parent_id)
|
||||
{
|
||||
if (DI::config()->get('system', 'disable_implicit_mentions')) {
|
||||
// Add a tag if the parent contact is from ActivityPub or OStatus (This will notify them)
|
||||
if (in_array($thread_parent_contact['network'], [Protocol::OSTATUS, Protocol::ACTIVITYPUB])) {
|
||||
$contact = Term::TAG_CHARACTER[Term::MENTION] . '[url=' . $thread_parent_contact['url'] . ']' . $thread_parent_contact['nick'] . '[/url]';
|
||||
if (!stripos(implode($tags), '[url=' . $thread_parent_contact['url'] . ']')) {
|
||||
$tags[] = $contact;
|
||||
$contact_id = 0;
|
||||
|
||||
// check if logged in user is either the author or owner of this item
|
||||
if (Session::getRemoteContactID($item['uid']) == $item['contact-id']) {
|
||||
$contact_id = $item['contact-id'];
|
||||
}
|
||||
|
||||
if ((local_user() == $item['uid']) || $contact_id) {
|
||||
// Check if we should do HTML-based delete confirmation
|
||||
if (!empty($_REQUEST['confirm'])) {
|
||||
// <form> can't take arguments in its "action" parameter
|
||||
// so add any arguments as hidden inputs
|
||||
$query = explode_querystring(DI::args()->getQueryString());
|
||||
$inputs = [];
|
||||
|
||||
foreach ($query['args'] as $arg) {
|
||||
if (strpos($arg, 'confirm=') === false) {
|
||||
$arg_parts = explode('=', $arg);
|
||||
$inputs[] = ['name' => $arg_parts[0], 'value' => $arg_parts[1]];
|
||||
}
|
||||
}
|
||||
|
||||
return Renderer::replaceMacros(Renderer::getMarkupTemplate('confirm.tpl'), [
|
||||
'$method' => 'get',
|
||||
'$message' => DI::l10n()->t('Do you really want to delete this item?'),
|
||||
'$extra_inputs' => $inputs,
|
||||
'$confirm' => DI::l10n()->t('Yes'),
|
||||
'$confirm_url' => $query['base'],
|
||||
'$confirm_name' => 'confirmed',
|
||||
'$cancel' => DI::l10n()->t('Cancel'),
|
||||
]);
|
||||
}
|
||||
// Now check how the user responded to the confirmation query
|
||||
if (!empty($_REQUEST['canceled'])) {
|
||||
DI::baseUrl()->redirect('display/' . $item['guid']);
|
||||
}
|
||||
|
||||
$is_comment = $item['gravity'] == GRAVITY_COMMENT;
|
||||
$parentitem = null;
|
||||
if (!empty($item['parent'])) {
|
||||
$fields = ['guid'];
|
||||
$parentitem = Item::selectFirstForUser(local_user(), $fields, ['id' => $item['parent']]);
|
||||
}
|
||||
|
||||
// delete the item
|
||||
Item::deleteForUser(['id' => $item['id']], local_user());
|
||||
|
||||
$return_url = hex2bin($return);
|
||||
|
||||
// removes update_* from return_url to ignore Ajax refresh
|
||||
$return_url = str_replace("update_", "", $return_url);
|
||||
|
||||
// Check if delete a comment
|
||||
if ($is_comment) {
|
||||
// Return to parent guid
|
||||
if (!empty($parentitem)) {
|
||||
DI::baseUrl()->redirect('display/' . $parentitem['guid']);
|
||||
//NOTREACHED
|
||||
} // In case something goes wrong
|
||||
else {
|
||||
DI::baseUrl()->redirect('network');
|
||||
//NOTREACHED
|
||||
}
|
||||
} else {
|
||||
// if unknown location or deleting top level post called from display
|
||||
if (empty($return_url) || strpos($return_url, 'display') !== false) {
|
||||
DI::baseUrl()->redirect('network');
|
||||
//NOTREACHED
|
||||
} else {
|
||||
DI::baseUrl()->redirect($return_url);
|
||||
//NOTREACHED
|
||||
}
|
||||
}
|
||||
} else {
|
||||
$implicit_mentions = [
|
||||
$thread_parent_contact['url'] => $thread_parent_contact['nick']
|
||||
];
|
||||
|
||||
$parent_terms = Term::tagArrayFromItemId($thread_parent_id, [Term::MENTION, Term::IMPLICIT_MENTION]);
|
||||
|
||||
foreach ($parent_terms as $parent_term) {
|
||||
$implicit_mentions[$parent_term['url']] = $parent_term['term'];
|
||||
}
|
||||
|
||||
foreach ($implicit_mentions as $url => $label) {
|
||||
if ($url != \Friendica\Model\Profile::getMyURL() && !stripos(implode($tags), '[url=' . $url . ']')) {
|
||||
$tags[] = Term::TAG_CHARACTER[Term::IMPLICIT_MENTION] . '[url=' . $url . ']' . $label . '[/url]';
|
||||
}
|
||||
}
|
||||
notice(DI::l10n()->t('Permission denied.'));
|
||||
DI::baseUrl()->redirect('display/' . $item['guid']);
|
||||
//NOTREACHED
|
||||
}
|
||||
|
||||
return $tags;
|
||||
return '';
|
||||
}
|
||||
|
|
|
|||
|
|
@ -41,10 +41,10 @@ function lostpass_post(App $a)
|
|||
DI::baseUrl()->redirect();
|
||||
}
|
||||
|
||||
$pwdreset_token = Strings::getRandomName(12) . random_int(1000, 9999);
|
||||
$pwdreset_token = Strings::getRandomHex(32);
|
||||
|
||||
$fields = [
|
||||
'pwdreset' => $pwdreset_token,
|
||||
'pwdreset' => hash('sha256', $pwdreset_token),
|
||||
'pwdreset_time' => DateTimeFormat::utcNow()
|
||||
];
|
||||
$result = DBA::update('user', $fields, ['uid' => $user['uid']]);
|
||||
|
|
@ -95,7 +95,7 @@ function lostpass_content(App $a)
|
|||
if ($a->argc > 1) {
|
||||
$pwdreset_token = $a->argv[1];
|
||||
|
||||
$user = DBA::selectFirst('user', ['uid', 'username', 'nickname', 'email', 'pwdreset_time', 'language'], ['pwdreset' => $pwdreset_token]);
|
||||
$user = DBA::selectFirst('user', ['uid', 'username', 'nickname', 'email', 'pwdreset_time', 'language'], ['pwdreset' => hash('sha256', $pwdreset_token)]);
|
||||
if (!DBA::isResult($user)) {
|
||||
notice(DI::l10n()->t("Request could not be verified. \x28You may have previously submitted it.\x29 Password reset failed."));
|
||||
|
||||
|
|
|
|||
|
|
@ -352,13 +352,7 @@ function message_content(App $a)
|
|||
$messages = DBA::toArray($messages_stmt);
|
||||
|
||||
DBA::update('mail', ['seen' => 1], ['parent-uri' => $message['parent-uri'], 'uid' => local_user()]);
|
||||
|
||||
if ($message['convid']) {
|
||||
// Clear Diaspora private message notifications
|
||||
DBA::update('notify', ['seen' => 1], ['type' => Type::MAIL, 'parent' => $message['convid'], 'uid' => local_user()]);
|
||||
}
|
||||
// Clear DFRN private message notifications
|
||||
DBA::update('notify', ['seen' => 1], ['type' => Type::MAIL, 'parent' => $message['parent-uri'], 'uid' => local_user()]);
|
||||
DBA::update('notify', ['seen' => 1], ['type' => Type::MAIL, 'parent' => $message['id'], 'uid' => local_user()]);
|
||||
} else {
|
||||
$messages = false;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -68,7 +68,7 @@ function msearch_post(App $a)
|
|||
$perpage
|
||||
);
|
||||
|
||||
while($search_result = DBA::fetch($search_stmt)) {
|
||||
while ($search_result = DBA::fetch($search_stmt)) {
|
||||
$results[] = [
|
||||
'name' => $search_result['name'],
|
||||
'url' => DI::baseUrl() . '/profile/' . $search_result['nickname'],
|
||||
|
|
@ -77,6 +77,8 @@ function msearch_post(App $a)
|
|||
];
|
||||
}
|
||||
|
||||
DBA::close($search_stmt);
|
||||
|
||||
$output = ['total' => $total, 'items_page' => $perpage, 'page' => $page, 'results' => $results];
|
||||
|
||||
echo json_encode($output);
|
||||
|
|
|
|||
|
|
@ -37,8 +37,8 @@ use Friendica\DI;
|
|||
use Friendica\Model\Contact;
|
||||
use Friendica\Model\Group;
|
||||
use Friendica\Model\Item;
|
||||
use Friendica\Model\Post\Category;
|
||||
use Friendica\Model\Profile;
|
||||
use Friendica\Model\Term;
|
||||
use Friendica\Module\Security\Login;
|
||||
use Friendica\Util\DateTimeFormat;
|
||||
use Friendica\Util\Proxy as ProxyUtils;
|
||||
|
|
@ -58,8 +58,8 @@ function network_init(App $a)
|
|||
$group_id = (($a->argc > 1 && is_numeric($a->argv[1])) ? intval($a->argv[1]) : 0);
|
||||
|
||||
$cid = 0;
|
||||
if (!empty($_GET['cid'])) {
|
||||
$cid = $_GET['cid'];
|
||||
if (!empty($_GET['contactid'])) {
|
||||
$cid = $_GET['contactid'];
|
||||
$_GET['nets'] = '';
|
||||
$group_id = 0;
|
||||
}
|
||||
|
|
@ -379,25 +379,25 @@ function networkFlatView(App $a, $update = 0)
|
|||
|
||||
networkPager($a, $pager, $update);
|
||||
|
||||
$item_params = ['order' => ['id' => true]];
|
||||
|
||||
if (strlen($file)) {
|
||||
$term_condition = ["`term` = ? AND `otype` = ? AND `type` = ? AND `uid` = ?",
|
||||
$file, Term::OBJECT_TYPE_POST, Term::FILE, local_user()];
|
||||
$term_params = ['order' => ['tid' => true], 'limit' => [$pager->getStart(), $pager->getItemsPerPage()]];
|
||||
$result = DBA::select('term', ['oid'], $term_condition, $term_params);
|
||||
$item_params = ['order' => ['uri-id' => true]];
|
||||
$term_condition = ['name' => $file, 'type' => Category::FILE, 'uid' => local_user()];
|
||||
$term_params = ['order' => ['uri-id' => true], 'limit' => [$pager->getStart(), $pager->getItemsPerPage()]];
|
||||
$result = DBA::select('category-view', ['uri-id'], $term_condition, $term_params);
|
||||
|
||||
$posts = [];
|
||||
while ($term = DBA::fetch($result)) {
|
||||
$posts[] = $term['oid'];
|
||||
$posts[] = $term['uri-id'];
|
||||
}
|
||||
DBA::close($result);
|
||||
|
||||
if (count($posts) == 0) {
|
||||
return '';
|
||||
}
|
||||
$item_condition = ['uid' => local_user(), 'id' => $posts];
|
||||
$item_condition = ['uid' => local_user(), 'uri-id' => $posts];
|
||||
} else {
|
||||
$item_params = ['order' => ['id' => true]];
|
||||
$item_condition = ['uid' => local_user()];
|
||||
$item_params['limit'] = [$pager->getStart(), $pager->getItemsPerPage()];
|
||||
|
||||
|
|
@ -466,12 +466,12 @@ function networkThreadedView(App $a, $update, $parent)
|
|||
|
||||
$o = '';
|
||||
|
||||
$cid = intval($_GET['cid'] ?? 0);
|
||||
$star = intval($_GET['star'] ?? 0);
|
||||
$bmark = intval($_GET['bmark'] ?? 0);
|
||||
$conv = intval($_GET['conv'] ?? 0);
|
||||
$cid = intval($_GET['contactid'] ?? 0);
|
||||
$star = intval($_GET['star'] ?? 0);
|
||||
$bmark = intval($_GET['bmark'] ?? 0);
|
||||
$conv = intval($_GET['conv'] ?? 0);
|
||||
$order = Strings::escapeTags(($_GET['order'] ?? '') ?: 'activity');
|
||||
$nets = $_GET['nets'] ?? '';
|
||||
$nets = $_GET['nets'] ?? '';
|
||||
|
||||
$allowedCids = [];
|
||||
if ($cid) {
|
||||
|
|
@ -709,7 +709,7 @@ function networkThreadedView(App $a, $update, $parent)
|
|||
}
|
||||
if ($order === 'post') {
|
||||
// Only show toplevel posts when updating posts in this order mode
|
||||
$sql_extra4 .= " AND `item`.`id` = `item`.`parent`";
|
||||
$sql_extra4 .= " AND `item`.`gravity` = " . GRAVITY_PARENT;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -786,15 +786,21 @@ function networkThreadedView(App $a, $update, $parent)
|
|||
$top_limit = DateTimeFormat::utcNow();
|
||||
}
|
||||
|
||||
// Handle bad performance situations when the distance between top and bottom is too high
|
||||
// See issue https://github.com/friendica/friendica/issues/8619
|
||||
if (strtotime($top_limit) - strtotime($bottom_limit) > 86400) {
|
||||
// Set the bottom limit to one day in the past at maximum
|
||||
$bottom_limit = DateTimeFormat::utc(date('c', strtotime($top_limit) - 86400));
|
||||
}
|
||||
|
||||
$items = DBA::p("SELECT `item`.`parent-uri` AS `uri`, 0 AS `item_id`, `item`.$ordering AS `order_date`, `author`.`url` AS `author-link` FROM `item`
|
||||
STRAIGHT_JOIN (SELECT `oid` FROM `term` WHERE `term` IN
|
||||
(SELECT SUBSTR(`term`, 2) FROM `search` WHERE `uid` = ? AND `term` LIKE '#%') AND `otype` = ? AND `type` = ? AND `uid` = 0) AS `term`
|
||||
ON `item`.`id` = `term`.`oid`
|
||||
STRAIGHT_JOIN (SELECT `uri-id` FROM `tag-search-view` WHERE `name` IN
|
||||
(SELECT SUBSTR(`term`, 2) FROM `search` WHERE `uid` = ? AND `term` LIKE '#%') AND `uid` = 0) AS `tag-search`
|
||||
ON `item`.`uri-id` = `tag-search`.`uri-id`
|
||||
STRAIGHT_JOIN `contact` AS `author` ON `author`.`id` = `item`.`author-id`
|
||||
WHERE `item`.`uid` = 0 AND `item`.$ordering < ? AND `item`.$ordering > ? AND `item`.`gravity` = ?
|
||||
AND NOT `author`.`hidden` AND NOT `author`.`blocked`" . $sql_tag_nets,
|
||||
local_user(), TERM_OBJ_POST, TERM_HASHTAG,
|
||||
$top_limit, $bottom_limit, GRAVITY_PARENT);
|
||||
local_user(), $top_limit, $bottom_limit, GRAVITY_PARENT);
|
||||
|
||||
$data = DBA::toArray($items);
|
||||
|
||||
|
|
@ -892,8 +898,8 @@ function network_tabs(App $a)
|
|||
$cmd = DI::args()->getCommand();
|
||||
|
||||
$def_param = [];
|
||||
if (!empty($_GET['cid'])) {
|
||||
$def_param['cid'] = $_GET['cid'];
|
||||
if (!empty($_GET['contactid'])) {
|
||||
$def_param['contactid'] = $_GET['contactid'];
|
||||
}
|
||||
|
||||
// tabs
|
||||
|
|
|
|||
|
|
@ -48,7 +48,6 @@ function ostatus_subscribe_content(App $a)
|
|||
}
|
||||
|
||||
$contact = Probe::uri($_REQUEST['url']);
|
||||
|
||||
if (!$contact) {
|
||||
DI::pConfig()->delete($uid, 'ostatus', 'legacy_contact');
|
||||
return $o . DI::l10n()->t('Couldn\'t fetch information for contact.');
|
||||
|
|
@ -91,7 +90,7 @@ function ostatus_subscribe_content(App $a)
|
|||
|
||||
$probed = Probe::uri($url);
|
||||
if ($probed['network'] == Protocol::OSTATUS) {
|
||||
$result = Contact::createFromProbe($uid, $url, true, Protocol::OSTATUS);
|
||||
$result = Contact::createFromProbe($a->user, $probed['url'], true, Protocol::OSTATUS);
|
||||
if ($result['success']) {
|
||||
$o .= ' - ' . DI::l10n()->t('success');
|
||||
} else {
|
||||
|
|
|
|||
|
|
@ -36,6 +36,7 @@ use Friendica\Model\Contact;
|
|||
use Friendica\Model\Item;
|
||||
use Friendica\Model\Photo;
|
||||
use Friendica\Model\Profile;
|
||||
use Friendica\Model\Tag;
|
||||
use Friendica\Model\User;
|
||||
use Friendica\Module\BaseProfile;
|
||||
use Friendica\Network\Probe;
|
||||
|
|
@ -81,7 +82,7 @@ function photos_init(App $a) {
|
|||
'$photo' => $profile['photo'],
|
||||
'$addr' => $profile['addr'] ?? '',
|
||||
'$account_type' => $account_type,
|
||||
'$about' => BBCode::convert($profile['about'] ?? ''),
|
||||
'$about' => BBCode::convert($profile['about']),
|
||||
]);
|
||||
|
||||
$albums = Photo::getAlbums($a->data['user']['uid']);
|
||||
|
|
@ -309,7 +310,7 @@ function photos_post(App $a)
|
|||
$desc = !empty($_POST['desc']) ? Strings::escapeTags(trim($_POST['desc'])) : '';
|
||||
$rawtags = !empty($_POST['newtag']) ? Strings::escapeTags(trim($_POST['newtag'])) : '';
|
||||
$item_id = !empty($_POST['item_id']) ? intval($_POST['item_id']) : 0;
|
||||
$albname = !empty($_POST['albname']) ? Strings::escapeTags(trim($_POST['albname'])) : '';
|
||||
$albname = !empty($_POST['albname']) ? trim($_POST['albname']) : '';
|
||||
$origaname = !empty($_POST['origaname']) ? Strings::escapeTags(trim($_POST['origaname'])) : '';
|
||||
|
||||
$aclFormatter = DI::aclFormatter();
|
||||
|
|
@ -421,16 +422,14 @@ function photos_post(App $a)
|
|||
}
|
||||
|
||||
if ($item_id) {
|
||||
$item = Item::selectFirst(['tag', 'inform'], ['id' => $item_id, 'uid' => $page_owner_uid]);
|
||||
$item = Item::selectFirst(['tag', 'inform', 'uri-id'], ['id' => $item_id, 'uid' => $page_owner_uid]);
|
||||
|
||||
if (DBA::isResult($item)) {
|
||||
$old_tag = $item['tag'];
|
||||
$old_inform = $item['inform'];
|
||||
}
|
||||
}
|
||||
|
||||
if (strlen($rawtags)) {
|
||||
$str_tags = '';
|
||||
$inform = '';
|
||||
|
||||
// if the new tag doesn't have a namespace specifier (@foo or #foo) give it a hashtag
|
||||
|
|
@ -510,38 +509,33 @@ function photos_post(App $a)
|
|||
|
||||
if ($profile) {
|
||||
if (!empty($contact)) {
|
||||
$taginfo[] = [$newname, $profile, $notify, $contact, '@[url=' . str_replace(',', '%2c', $profile) . ']' . $newname . '[/url]'];
|
||||
$taginfo[] = [$newname, $profile, $notify, $contact];
|
||||
} else {
|
||||
$taginfo[] = [$newname, $profile, $notify, null, $str_tags .= '@[url=' . $profile . ']' . $newname . '[/url]'];
|
||||
}
|
||||
|
||||
if (strlen($str_tags)) {
|
||||
$str_tags .= ',';
|
||||
$taginfo[] = [$newname, $profile, $notify, null];
|
||||
}
|
||||
|
||||
$profile = str_replace(',', '%2c', $profile);
|
||||
$str_tags .= '@[url=' . $profile . ']' . $newname . '[/url]';
|
||||
|
||||
if (!empty($item['uri-id'])) {
|
||||
Tag::store($item['uri-id'], Tag::MENTION, $newname, $profile);
|
||||
}
|
||||
}
|
||||
} elseif (strpos($tag, '#') === 0) {
|
||||
$tagname = substr($tag, 1);
|
||||
$str_tags .= '#[url=' . DI::baseUrl() . "/search?tag=" . $tagname . ']' . $tagname . '[/url],';
|
||||
if (!empty($item['uri-id'])) {
|
||||
Tag::store($item['uri-id'], Tag::HASHTAG, $tagname);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$newtag = $old_tag ?? '';
|
||||
if (strlen($newtag) && strlen($str_tags)) {
|
||||
$newtag .= ',';
|
||||
}
|
||||
$newtag .= $str_tags;
|
||||
|
||||
$newinform = $old_inform ?? '';
|
||||
if (strlen($newinform) && strlen($inform)) {
|
||||
$newinform .= ',';
|
||||
}
|
||||
$newinform .= $inform;
|
||||
|
||||
$fields = ['tag' => $newtag, 'inform' => $newinform, 'edited' => DateTimeFormat::utcNow(), 'changed' => DateTimeFormat::utcNow()];
|
||||
$fields = ['inform' => $newinform, 'edited' => DateTimeFormat::utcNow(), 'changed' => DateTimeFormat::utcNow()];
|
||||
$condition = ['id' => $item_id];
|
||||
Item::update($fields, $condition);
|
||||
|
||||
|
|
@ -585,7 +579,6 @@ function photos_post(App $a)
|
|||
$arr['gravity'] = GRAVITY_PARENT;
|
||||
$arr['object-type'] = Activity\ObjectType::PERSON;
|
||||
$arr['target-type'] = Activity\ObjectType::IMAGE;
|
||||
$arr['tag'] = $tagged[4];
|
||||
$arr['inform'] = $tagged[2];
|
||||
$arr['origin'] = 1;
|
||||
$arr['body'] = DI::l10n()->t('%1$s was tagged in %2$s by %3$s', '[url=' . $tagged[1] . ']' . $tagged[0] . '[/url]', '[url=' . DI::baseUrl() . '/photos/' . $owner_record['nickname'] . '/image/' . $photo['resource-id'] . ']' . DI::l10n()->t('a photo') . '[/url]', '[url=' . $owner_record['url'] . ']' . $owner_record['name'] . '[/url]') ;
|
||||
|
|
@ -615,10 +608,10 @@ function photos_post(App $a)
|
|||
Hook::callAll('photo_post_init', $_POST);
|
||||
|
||||
// Determine the album to use
|
||||
$album = !empty($_REQUEST['album']) ? Strings::escapeTags(trim($_REQUEST['album'])) : '';
|
||||
$newalbum = !empty($_REQUEST['newalbum']) ? Strings::escapeTags(trim($_REQUEST['newalbum'])) : '';
|
||||
$album = trim($_REQUEST['album'] ?? '');
|
||||
$newalbum = trim($_REQUEST['newalbum'] ?? '');
|
||||
|
||||
Logger::log('mod/photos.php: photos_post(): album= ' . $album . ' newalbum= ' . $newalbum , Logger::DEBUG);
|
||||
Logger::info('album= ' . $album . ' newalbum= ' . $newalbum);
|
||||
|
||||
if (!strlen($album)) {
|
||||
if (strlen($newalbum)) {
|
||||
|
|
@ -706,9 +699,7 @@ function photos_post(App $a)
|
|||
return;
|
||||
}
|
||||
|
||||
if ($type == "") {
|
||||
$type = Images::guessType($filename);
|
||||
}
|
||||
$type = Images::getMimeTypeBySource($src, $filename, $type);
|
||||
|
||||
Logger::log('photos: upload: received file: ' . $filename . ' as ' . $src . ' ('. $type . ') ' . $filesize . ' bytes', Logger::DEBUG);
|
||||
|
||||
|
|
@ -787,7 +778,7 @@ function photos_post(App $a)
|
|||
|
||||
// Create item container
|
||||
$lat = $lon = null;
|
||||
if ($exif && $exif['GPS'] && Feature::isEnabled($page_owner_uid, 'photo_location')) {
|
||||
if (!empty($exif['GPS']) && Feature::isEnabled($page_owner_uid, 'photo_location')) {
|
||||
$lat = Photo::getGps($exif['GPS']['GPSLatitude'], $exif['GPS']['GPSLatitudeRef']);
|
||||
$lon = Photo::getGps($exif['GPS']['GPSLongitude'], $exif['GPS']['GPSLongitudeRef']);
|
||||
}
|
||||
|
|
@ -1296,7 +1287,7 @@ function photos_content(App $a)
|
|||
}
|
||||
|
||||
if (!empty($link_item['parent']) && !empty($link_item['uid'])) {
|
||||
$condition = ["`parent` = ? AND `parent` != `id`", $link_item['parent']];
|
||||
$condition = ["`parent` = ? AND `gravity` != ?", $link_item['parent'], GRAVITY_PARENT];
|
||||
$total = DBA::count('item', $condition);
|
||||
|
||||
$pager = new Pager(DI::l10n(), DI::args()->getQueryString());
|
||||
|
|
@ -1316,8 +1307,9 @@ function photos_content(App $a)
|
|||
|
||||
$tags = null;
|
||||
|
||||
if (!empty($link_item['id']) && !empty($link_item['tag'])) {
|
||||
$arr = explode(',', $link_item['tag']);
|
||||
if (!empty($link_item['id'])) {
|
||||
$tag_text = Tag::getCSVByURIId($link_item['uri-id']);
|
||||
$arr = explode(',', $tag_text);
|
||||
// parse tags and add links
|
||||
$tag_arr = [];
|
||||
foreach ($arr as $tag) {
|
||||
|
|
@ -1464,7 +1456,7 @@ function photos_content(App $a)
|
|||
|
||||
if (($activity->match($item['verb'], Activity::LIKE) ||
|
||||
$activity->match($item['verb'], Activity::DISLIKE)) &&
|
||||
($item['id'] != $item['parent'])) {
|
||||
($item['gravity'] != GRAVITY_PARENT)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
|
|
|||
11
mod/ping.php
11
mod/ping.php
|
|
@ -30,6 +30,8 @@ use Friendica\Model\Contact;
|
|||
use Friendica\Model\Group;
|
||||
use Friendica\Model\Item;
|
||||
use Friendica\Model\Notify\Type;
|
||||
use Friendica\Model\Verb;
|
||||
use Friendica\Protocol\Activity;
|
||||
use Friendica\Util\DateTimeFormat;
|
||||
use Friendica\Util\Temporal;
|
||||
use Friendica\Util\Proxy as ProxyUtils;
|
||||
|
|
@ -134,9 +136,10 @@ function ping_init(App $a)
|
|||
|
||||
$notifs = ping_get_notifications(local_user());
|
||||
|
||||
$condition = ["`unseen` AND `uid` = ? AND `contact-id` != ?", local_user(), local_user()];
|
||||
$condition = ["`unseen` AND `uid` = ? AND `contact-id` != ? AND (`vid` != ? OR `vid` IS NULL)",
|
||||
local_user(), local_user(), Verb::getID(Activity::FOLLOW)];
|
||||
$fields = ['id', 'parent', 'verb', 'author-name', 'unseen', 'author-link', 'author-avatar', 'contact-avatar',
|
||||
'network', 'created', 'object', 'parent-author-name', 'parent-author-link', 'parent-guid', 'wall'];
|
||||
'network', 'created', 'object', 'parent-author-name', 'parent-author-link', 'parent-guid', 'wall', 'activity'];
|
||||
$params = ['order' => ['received' => true]];
|
||||
$items = Item::selectForUser(local_user(), $fields, $condition, $params);
|
||||
|
||||
|
|
@ -464,13 +467,13 @@ function ping_get_notifications($uid)
|
|||
|
||||
if ($notification["visible"]
|
||||
&& !$notification["deleted"]
|
||||
&& empty($result[$notification["parent"]])
|
||||
&& empty($result[$notification['parent']])
|
||||
) {
|
||||
// Should we condense the notifications or show them all?
|
||||
if (DI::pConfig()->get(local_user(), 'system', 'detailed_notif')) {
|
||||
$result[$notification["id"]] = $notification;
|
||||
} else {
|
||||
$result[$notification["parent"]] = $notification;
|
||||
$result[$notification['parent']] = $notification;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
302
mod/poco.php
302
mod/poco.php
|
|
@ -81,10 +81,7 @@ function poco_init(App $a) {
|
|||
}
|
||||
|
||||
if (!$system_mode && !$global) {
|
||||
$user = DBA::fetchFirst("SELECT `user`.`uid`, `user`.`nickname` FROM `user`
|
||||
INNER JOIN `profile` ON `user`.`uid` = `profile`.`uid`
|
||||
WHERE `user`.`nickname` = ? AND NOT `profile`.`hide-friends`",
|
||||
$nickname);
|
||||
$user = DBA::selectFirst('owner-view', ['uid', 'nickname'], ['nickname' => $nickname, 'hide-friends' => false]);
|
||||
if (!DBA::isResult($user)) {
|
||||
throw new \Friendica\Network\HTTPException\NotFoundException();
|
||||
}
|
||||
|
|
@ -147,16 +144,7 @@ function poco_init(App $a) {
|
|||
);
|
||||
} elseif ($system_mode) {
|
||||
Logger::log("Start system mode query", Logger::DEBUG);
|
||||
$contacts = q("SELECT `contact`.*, `profile`.`about` AS `pabout`, `profile`.`locality` AS `plocation`, `profile`.`pub_keywords`,
|
||||
`profile`.`address` AS `paddress`, `profile`.`region` AS `pregion`,
|
||||
`profile`.`postal-code` AS `ppostalcode`, `profile`.`country-name` AS `pcountry`, `user`.`account-type`
|
||||
FROM `contact` INNER JOIN `profile` ON `profile`.`uid` = `contact`.`uid`
|
||||
INNER JOIN `user` ON `user`.`uid` = `contact`.`uid`
|
||||
WHERE `self` = 1 AND `profile`.`net-publish`
|
||||
LIMIT %d, %d",
|
||||
intval($startIndex),
|
||||
intval($itemsPerPage)
|
||||
);
|
||||
$contacts = DBA::selectToArray('owner-view', [], ['net-publish' => true], ['limit' => [$startIndex, $itemsPerPage]]);
|
||||
} else {
|
||||
Logger::log("Start query for user " . $user['nickname'], Logger::DEBUG);
|
||||
$contacts = q("SELECT * FROM `contact` WHERE `uid` = %d AND `blocked` = 0 AND `pending` = 0 AND `hidden` = 0 AND `archive` = 0
|
||||
|
|
@ -216,164 +204,142 @@ function poco_init(App $a) {
|
|||
}
|
||||
}
|
||||
|
||||
if (is_array($contacts)) {
|
||||
if (DBA::isResult($contacts)) {
|
||||
foreach ($contacts as $contact) {
|
||||
if (!isset($contact['updated'])) {
|
||||
$contact['updated'] = '';
|
||||
}
|
||||
if (!is_array($contacts)) {
|
||||
throw new \Friendica\Network\HTTPException\InternalServerErrorException();
|
||||
}
|
||||
|
||||
if (! isset($contact['generation'])) {
|
||||
if ($global) {
|
||||
$contact['generation'] = 3;
|
||||
} elseif ($system_mode) {
|
||||
$contact['generation'] = 1;
|
||||
} else {
|
||||
$contact['generation'] = 2;
|
||||
}
|
||||
}
|
||||
|
||||
if (($contact['about'] == "") && isset($contact['pabout'])) {
|
||||
$contact['about'] = $contact['pabout'];
|
||||
}
|
||||
if ($contact['location'] == "") {
|
||||
if (isset($contact['plocation'])) {
|
||||
$contact['location'] = $contact['plocation'];
|
||||
}
|
||||
if (isset($contact['pregion']) && ( $contact['pregion'] != "")) {
|
||||
if ($contact['location'] != "") {
|
||||
$contact['location'] .= ", ";
|
||||
}
|
||||
$contact['location'] .= $contact['pregion'];
|
||||
}
|
||||
|
||||
if (isset($contact['pcountry']) && ( $contact['pcountry'] != "")) {
|
||||
if ($contact['location'] != "") {
|
||||
$contact['location'] .= ", ";
|
||||
}
|
||||
$contact['location'] .= $contact['pcountry'];
|
||||
}
|
||||
}
|
||||
|
||||
if (($contact['keywords'] == "") && isset($contact['pub_keywords'])) {
|
||||
$contact['keywords'] = $contact['pub_keywords'];
|
||||
}
|
||||
if (isset($contact['account-type'])) {
|
||||
$contact['contact-type'] = $contact['account-type'];
|
||||
}
|
||||
$about = DI::cache()->get("about:" . $contact['updated'] . ":" . $contact['nurl']);
|
||||
if (is_null($about)) {
|
||||
$about = BBCode::convert($contact['about'], false);
|
||||
DI::cache()->set("about:" . $contact['updated'] . ":" . $contact['nurl'], $about);
|
||||
}
|
||||
|
||||
// Non connected persons can only see the keywords of a Diaspora account
|
||||
if ($contact['network'] == Protocol::DIASPORA) {
|
||||
$contact['location'] = "";
|
||||
$about = "";
|
||||
}
|
||||
|
||||
$entry = [];
|
||||
if ($fields_ret['id']) {
|
||||
$entry['id'] = (int)$contact['id'];
|
||||
}
|
||||
if ($fields_ret['displayName']) {
|
||||
$entry['displayName'] = $contact['name'];
|
||||
}
|
||||
if ($fields_ret['aboutMe']) {
|
||||
$entry['aboutMe'] = $about;
|
||||
}
|
||||
if ($fields_ret['currentLocation']) {
|
||||
$entry['currentLocation'] = $contact['location'];
|
||||
}
|
||||
if ($fields_ret['generation']) {
|
||||
$entry['generation'] = (int)$contact['generation'];
|
||||
}
|
||||
if ($fields_ret['urls']) {
|
||||
$entry['urls'] = [['value' => $contact['url'], 'type' => 'profile']];
|
||||
if ($contact['addr'] && ($contact['network'] !== Protocol::MAIL)) {
|
||||
$entry['urls'][] = ['value' => 'acct:' . $contact['addr'], 'type' => 'webfinger'];
|
||||
}
|
||||
}
|
||||
if ($fields_ret['preferredUsername']) {
|
||||
$entry['preferredUsername'] = $contact['nick'];
|
||||
}
|
||||
if ($fields_ret['updated']) {
|
||||
if (! $global) {
|
||||
$entry['updated'] = $contact['success_update'];
|
||||
|
||||
if ($contact['name-date'] > $entry['updated']) {
|
||||
$entry['updated'] = $contact['name-date'];
|
||||
}
|
||||
if ($contact['uri-date'] > $entry['updated']) {
|
||||
$entry['updated'] = $contact['uri-date'];
|
||||
}
|
||||
if ($contact['avatar-date'] > $entry['updated']) {
|
||||
$entry['updated'] = $contact['avatar-date'];
|
||||
}
|
||||
} else {
|
||||
$entry['updated'] = $contact['updated'];
|
||||
}
|
||||
$entry['updated'] = date("c", strtotime($entry['updated']));
|
||||
}
|
||||
if ($fields_ret['photos']) {
|
||||
$entry['photos'] = [['value' => $contact['photo'], 'type' => 'profile']];
|
||||
}
|
||||
if ($fields_ret['network']) {
|
||||
$entry['network'] = $contact['network'];
|
||||
if ($entry['network'] == Protocol::STATUSNET) {
|
||||
$entry['network'] = Protocol::OSTATUS;
|
||||
}
|
||||
if (($entry['network'] == "") && ($contact['self'])) {
|
||||
$entry['network'] = Protocol::DFRN;
|
||||
}
|
||||
}
|
||||
if ($fields_ret['tags']) {
|
||||
$tags = str_replace(",", " ", $contact['keywords']);
|
||||
$tags = explode(" ", $tags);
|
||||
|
||||
$cleaned = [];
|
||||
foreach ($tags as $tag) {
|
||||
$tag = trim(strtolower($tag));
|
||||
if ($tag != "") {
|
||||
$cleaned[] = $tag;
|
||||
}
|
||||
}
|
||||
|
||||
$entry['tags'] = [$cleaned];
|
||||
}
|
||||
if ($fields_ret['address']) {
|
||||
$entry['address'] = [];
|
||||
|
||||
// Deactivated. It just reveals too much data. (Although its from the default profile)
|
||||
//if (isset($rr['paddress']))
|
||||
// $entry['address']['streetAddress'] = $rr['paddress'];
|
||||
|
||||
if (isset($contact['plocation'])) {
|
||||
$entry['address']['locality'] = $contact['plocation'];
|
||||
}
|
||||
if (isset($contact['pregion'])) {
|
||||
$entry['address']['region'] = $contact['pregion'];
|
||||
}
|
||||
// See above
|
||||
//if (isset($rr['ppostalcode']))
|
||||
// $entry['address']['postalCode'] = $rr['ppostalcode'];
|
||||
|
||||
if (isset($contact['pcountry'])) {
|
||||
$entry['address']['country'] = $contact['pcountry'];
|
||||
}
|
||||
}
|
||||
|
||||
if ($fields_ret['contactType']) {
|
||||
$entry['contactType'] = intval($contact['contact-type']);
|
||||
}
|
||||
$ret['entry'][] = $entry;
|
||||
if (DBA::isResult($contacts)) {
|
||||
foreach ($contacts as $contact) {
|
||||
if (!isset($contact['updated'])) {
|
||||
$contact['updated'] = '';
|
||||
}
|
||||
} else {
|
||||
$ret['entry'][] = [];
|
||||
|
||||
if (! isset($contact['generation'])) {
|
||||
if ($global) {
|
||||
$contact['generation'] = 3;
|
||||
} elseif ($system_mode) {
|
||||
$contact['generation'] = 1;
|
||||
} else {
|
||||
$contact['generation'] = 2;
|
||||
}
|
||||
}
|
||||
|
||||
if (($contact['keywords'] == "") && isset($contact['pub_keywords'])) {
|
||||
$contact['keywords'] = $contact['pub_keywords'];
|
||||
}
|
||||
if (isset($contact['account-type'])) {
|
||||
$contact['contact-type'] = $contact['account-type'];
|
||||
}
|
||||
$about = DI::cache()->get("about:" . $contact['updated'] . ":" . $contact['nurl']);
|
||||
if (is_null($about)) {
|
||||
$about = BBCode::convert($contact['about'], false);
|
||||
DI::cache()->set("about:" . $contact['updated'] . ":" . $contact['nurl'], $about);
|
||||
}
|
||||
|
||||
// Non connected persons can only see the keywords of a Diaspora account
|
||||
if ($contact['network'] == Protocol::DIASPORA) {
|
||||
$contact['location'] = "";
|
||||
$about = "";
|
||||
}
|
||||
|
||||
$entry = [];
|
||||
if ($fields_ret['id']) {
|
||||
$entry['id'] = (int)$contact['id'];
|
||||
}
|
||||
if ($fields_ret['displayName']) {
|
||||
$entry['displayName'] = $contact['name'];
|
||||
}
|
||||
if ($fields_ret['aboutMe']) {
|
||||
$entry['aboutMe'] = $about;
|
||||
}
|
||||
if ($fields_ret['currentLocation']) {
|
||||
$entry['currentLocation'] = $contact['location'];
|
||||
}
|
||||
if ($fields_ret['generation']) {
|
||||
$entry['generation'] = (int)$contact['generation'];
|
||||
}
|
||||
if ($fields_ret['urls']) {
|
||||
$entry['urls'] = [['value' => $contact['url'], 'type' => 'profile']];
|
||||
if ($contact['addr'] && ($contact['network'] !== Protocol::MAIL)) {
|
||||
$entry['urls'][] = ['value' => 'acct:' . $contact['addr'], 'type' => 'webfinger'];
|
||||
}
|
||||
}
|
||||
if ($fields_ret['preferredUsername']) {
|
||||
$entry['preferredUsername'] = $contact['nick'];
|
||||
}
|
||||
if ($fields_ret['updated']) {
|
||||
if (! $global) {
|
||||
$entry['updated'] = $contact['success_update'];
|
||||
|
||||
if ($contact['name-date'] > $entry['updated']) {
|
||||
$entry['updated'] = $contact['name-date'];
|
||||
}
|
||||
if ($contact['uri-date'] > $entry['updated']) {
|
||||
$entry['updated'] = $contact['uri-date'];
|
||||
}
|
||||
if ($contact['avatar-date'] > $entry['updated']) {
|
||||
$entry['updated'] = $contact['avatar-date'];
|
||||
}
|
||||
} else {
|
||||
$entry['updated'] = $contact['updated'];
|
||||
}
|
||||
$entry['updated'] = date("c", strtotime($entry['updated']));
|
||||
}
|
||||
if ($fields_ret['photos']) {
|
||||
$entry['photos'] = [['value' => $contact['photo'], 'type' => 'profile']];
|
||||
}
|
||||
if ($fields_ret['network']) {
|
||||
$entry['network'] = $contact['network'];
|
||||
if ($entry['network'] == Protocol::STATUSNET) {
|
||||
$entry['network'] = Protocol::OSTATUS;
|
||||
}
|
||||
if (($entry['network'] == "") && ($contact['self'])) {
|
||||
$entry['network'] = Protocol::DFRN;
|
||||
}
|
||||
}
|
||||
if ($fields_ret['tags']) {
|
||||
$tags = str_replace(",", " ", $contact['keywords']);
|
||||
$tags = explode(" ", $tags);
|
||||
|
||||
$cleaned = [];
|
||||
foreach ($tags as $tag) {
|
||||
$tag = trim(strtolower($tag));
|
||||
if ($tag != "") {
|
||||
$cleaned[] = $tag;
|
||||
}
|
||||
}
|
||||
|
||||
$entry['tags'] = [$cleaned];
|
||||
}
|
||||
if ($fields_ret['address']) {
|
||||
$entry['address'] = [];
|
||||
|
||||
// Deactivated. It just reveals too much data. (Although its from the default profile)
|
||||
//if (isset($rr['address']))
|
||||
// $entry['address']['streetAddress'] = $rr['address'];
|
||||
|
||||
if (isset($contact['locality'])) {
|
||||
$entry['address']['locality'] = $contact['locality'];
|
||||
}
|
||||
if (isset($contact['region'])) {
|
||||
$entry['address']['region'] = $contact['region'];
|
||||
}
|
||||
// See above
|
||||
//if (isset($rr['postal-code']))
|
||||
// $entry['address']['postalCode'] = $rr['postal-code'];
|
||||
|
||||
if (isset($contact['country'])) {
|
||||
$entry['address']['country'] = $contact['country'];
|
||||
}
|
||||
}
|
||||
|
||||
if ($fields_ret['contactType']) {
|
||||
$entry['contactType'] = intval($contact['contact-type']);
|
||||
}
|
||||
$ret['entry'][] = $entry;
|
||||
}
|
||||
} else {
|
||||
throw new \Friendica\Network\HTTPException\InternalServerErrorException();
|
||||
$ret['entry'][] = [];
|
||||
}
|
||||
|
||||
Logger::log("End of poco", Logger::DEBUG);
|
||||
|
|
|
|||
191
mod/poke.php
191
mod/poke.php
|
|
@ -1,191 +0,0 @@
|
|||
<?php
|
||||
/**
|
||||
* Poke, prod, finger, or otherwise do unspeakable things to somebody - who must be a connection in your address book
|
||||
* This function can be invoked with the required arguments (verb and cid and private and possibly parent) silently via ajax or
|
||||
* other web request. You must be logged in and connected to a profile.
|
||||
* If the required arguments aren't present, we'll display a simple form to choose a recipient and a verb.
|
||||
* parent is a special argument which let's you attach this activity as a comment to an existing conversation, which
|
||||
* may have started with somebody else poking (etc.) somebody, but this isn't necessary. This can be used in the more pokes
|
||||
* addon version to have entire conversations where Alice poked Bob, Bob fingered Alice, Alice hugged Bob, etc.
|
||||
*
|
||||
* private creates a private conversation with the recipient. Otherwise your profile's default post privacy is used.
|
||||
*
|
||||
* @file mod/poke.php
|
||||
*/
|
||||
|
||||
use Friendica\App;
|
||||
use Friendica\Core\Hook;
|
||||
use Friendica\Core\Logger;
|
||||
use Friendica\Core\Renderer;
|
||||
use Friendica\Core\System;
|
||||
use Friendica\Database\DBA;
|
||||
use Friendica\DI;
|
||||
use Friendica\Model\Item;
|
||||
use Friendica\Protocol\Activity;
|
||||
use Friendica\Util\Strings;
|
||||
use Friendica\Util\XML;
|
||||
|
||||
function poke_init(App $a)
|
||||
{
|
||||
if (!local_user()) {
|
||||
return;
|
||||
}
|
||||
|
||||
$uid = local_user();
|
||||
|
||||
if (empty($_GET['verb'])) {
|
||||
return;
|
||||
}
|
||||
|
||||
$verb = Strings::escapeTags(trim($_GET['verb']));
|
||||
|
||||
$verbs = DI::l10n()->getPokeVerbs();
|
||||
|
||||
if (!array_key_exists($verb, $verbs)) {
|
||||
return;
|
||||
}
|
||||
|
||||
$activity = Activity::POKE . '#' . urlencode($verbs[$verb][0]);
|
||||
|
||||
$contact_id = intval($_GET['cid']);
|
||||
if (!$contact_id) {
|
||||
return;
|
||||
}
|
||||
|
||||
$parent = (!empty($_GET['parent']) ? intval($_GET['parent']) : 0);
|
||||
|
||||
|
||||
Logger::log('poke: verb ' . $verb . ' contact ' . $contact_id, Logger::DEBUG);
|
||||
|
||||
|
||||
$r = q("SELECT * FROM `contact` WHERE `id` = %d AND `uid` = %d LIMIT 1",
|
||||
intval($contact_id),
|
||||
intval($uid)
|
||||
);
|
||||
|
||||
if (!DBA::isResult($r)) {
|
||||
Logger::log('poke: no contact ' . $contact_id);
|
||||
return;
|
||||
}
|
||||
|
||||
$target = $r[0];
|
||||
|
||||
if ($parent) {
|
||||
$fields = ['uri', 'private', 'allow_cid', 'allow_gid', 'deny_cid', 'deny_gid'];
|
||||
$condition = ['id' => $parent, 'parent' => $parent, 'uid' => $uid];
|
||||
$item = Item::selectFirst($fields, $condition);
|
||||
|
||||
if (DBA::isResult($item)) {
|
||||
$parent_uri = $item['uri'];
|
||||
$private = $item['private'];
|
||||
$allow_cid = $item['allow_cid'];
|
||||
$allow_gid = $item['allow_gid'];
|
||||
$deny_cid = $item['deny_cid'];
|
||||
$deny_gid = $item['deny_gid'];
|
||||
}
|
||||
} else {
|
||||
$private = (!empty($_GET['private']) ? intval($_GET['private']) : Item::PUBLIC);
|
||||
|
||||
$allow_cid = ($private ? '<' . $target['id']. '>' : $a->user['allow_cid']);
|
||||
$allow_gid = ($private ? '' : $a->user['allow_gid']);
|
||||
$deny_cid = ($private ? '' : $a->user['deny_cid']);
|
||||
$deny_gid = ($private ? '' : $a->user['deny_gid']);
|
||||
}
|
||||
|
||||
$poster = $a->contact;
|
||||
|
||||
$uri = Item::newURI($uid);
|
||||
|
||||
$arr = [];
|
||||
|
||||
$arr['guid'] = System::createUUID();
|
||||
$arr['uid'] = $uid;
|
||||
$arr['uri'] = $uri;
|
||||
$arr['parent-uri'] = (!empty($parent_uri) ? $parent_uri : $uri);
|
||||
$arr['wall'] = 1;
|
||||
$arr['contact-id'] = $poster['id'];
|
||||
$arr['owner-name'] = $poster['name'];
|
||||
$arr['owner-link'] = $poster['url'];
|
||||
$arr['owner-avatar'] = $poster['thumb'];
|
||||
$arr['author-name'] = $poster['name'];
|
||||
$arr['author-link'] = $poster['url'];
|
||||
$arr['author-avatar'] = $poster['thumb'];
|
||||
$arr['title'] = '';
|
||||
$arr['allow_cid'] = $allow_cid;
|
||||
$arr['allow_gid'] = $allow_gid;
|
||||
$arr['deny_cid'] = $deny_cid;
|
||||
$arr['deny_gid'] = $deny_gid;
|
||||
$arr['visible'] = 1;
|
||||
$arr['verb'] = $activity;
|
||||
$arr['private'] = $private;
|
||||
$arr['object-type'] = Activity\ObjectType::PERSON;
|
||||
|
||||
$arr['origin'] = 1;
|
||||
$arr['body'] = '[url=' . $poster['url'] . ']' . $poster['name'] . '[/url]' . ' ' . DI::l10n()->t($verbs[$verb][0]) . ' ' . '[url=' . $target['url'] . ']' . $target['name'] . '[/url]';
|
||||
|
||||
$arr['object'] = '<object><type>' . Activity\ObjectType::PERSON . '</type><title>' . $target['name'] . '</title><id>' . $target['url'] . '</id>';
|
||||
$arr['object'] .= '<link>' . XML::escape('<link rel="alternate" type="text/html" href="' . $target['url'] . '" />' . "\n");
|
||||
|
||||
$arr['object'] .= XML::escape('<link rel="photo" type="image/jpeg" href="' . $target['photo'] . '" />' . "\n");
|
||||
$arr['object'] .= '</link></object>' . "\n";
|
||||
|
||||
Item::insert($arr);
|
||||
|
||||
Hook::callAll('post_local_end', $arr);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
function poke_content(App $a)
|
||||
{
|
||||
if (!local_user()) {
|
||||
notice(DI::l10n()->t('Permission denied.') . EOL);
|
||||
return;
|
||||
}
|
||||
|
||||
if (empty($_GET['c'])) {
|
||||
return;
|
||||
}
|
||||
|
||||
$contact = DBA::selectFirst('contact', ['id', 'name'], ['id' => $_GET['c'], 'uid' => local_user()]);
|
||||
if (!DBA::isResult($contact)) {
|
||||
return;
|
||||
}
|
||||
|
||||
$name = $contact['name'];
|
||||
$id = $contact['id'];
|
||||
|
||||
$head_tpl = Renderer::getMarkupTemplate('poke_head.tpl');
|
||||
DI::page()['htmlhead'] .= Renderer::replaceMacros($head_tpl,[
|
||||
'$baseurl' => DI::baseUrl()->get(true),
|
||||
]);
|
||||
|
||||
$parent = (!empty($_GET['parent']) ? intval($_GET['parent']) : '0');
|
||||
|
||||
|
||||
$verbs = DI::l10n()->getPokeVerbs();
|
||||
|
||||
$shortlist = [];
|
||||
foreach ($verbs as $k => $v) {
|
||||
if ($v[1] !== 'NOTRANSLATION') {
|
||||
$shortlist[] = [$k, $v[1]];
|
||||
}
|
||||
}
|
||||
|
||||
$tpl = Renderer::getMarkupTemplate('poke_content.tpl');
|
||||
|
||||
$o = Renderer::replaceMacros($tpl,[
|
||||
'$title' => DI::l10n()->t('Poke/Prod'),
|
||||
'$desc' => DI::l10n()->t('poke, prod or do other things to somebody'),
|
||||
'$clabel' => DI::l10n()->t('Recipient'),
|
||||
'$choice' => DI::l10n()->t('Choose what you wish to do to recipient'),
|
||||
'$verbs' => $shortlist,
|
||||
'$parent' => $parent,
|
||||
'$prv_desc' => DI::l10n()->t('Make this post private'),
|
||||
'$submit' => DI::l10n()->t('Submit'),
|
||||
'$name' => $name,
|
||||
'$id' => $id
|
||||
]);
|
||||
|
||||
return $o;
|
||||
}
|
||||
189
mod/redir.php
189
mod/redir.php
|
|
@ -31,6 +31,9 @@ use Friendica\Util\Network;
|
|||
use Friendica\Util\Strings;
|
||||
|
||||
function redir_init(App $a) {
|
||||
if (!Session::isAuthenticated()) {
|
||||
throw new \Friendica\Network\HTTPException\ForbiddenException(DI::l10n()->t('Access denied.'));
|
||||
}
|
||||
|
||||
$url = $_GET['url'] ?? '';
|
||||
$quiet = !empty($_GET['quiet']) ? '&quiet=1' : '';
|
||||
|
|
@ -44,102 +47,102 @@ function redir_init(App $a) {
|
|||
// Try magic auth before the legacy stuff
|
||||
redir_magic($a, $cid, $url);
|
||||
|
||||
if (!empty($cid)) {
|
||||
$fields = ['id', 'uid', 'nurl', 'url', 'addr', 'name', 'network', 'poll', 'issued-id', 'dfrn-id', 'duplex', 'pending'];
|
||||
$contact = DBA::selectFirst('contact', $fields, ['id' => $cid, 'uid' => [0, local_user()]]);
|
||||
if (!DBA::isResult($contact)) {
|
||||
notice(DI::l10n()->t('Contact not found.'));
|
||||
DI::baseUrl()->redirect();
|
||||
if (empty($cid)) {
|
||||
throw new \Friendica\Network\HTTPException\BadRequestException(DI::l10n()->t('Bad Request.'));
|
||||
}
|
||||
|
||||
$fields = ['id', 'uid', 'nurl', 'url', 'addr', 'name', 'network', 'poll', 'issued-id', 'dfrn-id', 'duplex', 'pending'];
|
||||
$contact = DBA::selectFirst('contact', $fields, ['id' => $cid, 'uid' => [0, local_user()]]);
|
||||
if (!DBA::isResult($contact)) {
|
||||
throw new \Friendica\Network\HTTPException\NotFoundException(DI::l10n()->t('Contact not found.'));
|
||||
}
|
||||
|
||||
$contact_url = $contact['url'];
|
||||
|
||||
if (!empty($a->contact['id']) && $a->contact['id'] == $cid) {
|
||||
// Local user is already authenticated.
|
||||
redir_check_url($contact_url, $url);
|
||||
$a->redirect($url ?: $contact_url);
|
||||
}
|
||||
|
||||
if ($contact['uid'] == 0 && local_user()) {
|
||||
// Let's have a look if there is an established connection
|
||||
// between the public contact we have found and the local user.
|
||||
$contact = DBA::selectFirst('contact', $fields, ['nurl' => $contact['nurl'], 'uid' => local_user()]);
|
||||
|
||||
if (DBA::isResult($contact)) {
|
||||
$cid = $contact['id'];
|
||||
}
|
||||
|
||||
$contact_url = $contact['url'];
|
||||
if (!empty($a->contact['id']) && $a->contact['id'] == $cid) {
|
||||
// Local user is already authenticated.
|
||||
redir_check_url($contact_url, $url);
|
||||
$target_url = $url ?: $contact_url;
|
||||
Logger::log($contact['name'] . " is already authenticated. Redirecting to " . $target_url, Logger::DEBUG);
|
||||
$a->redirect($target_url);
|
||||
}
|
||||
}
|
||||
|
||||
if (!Session::isAuthenticated() // Visitors (not logged in or not remotes) can't authenticate.
|
||||
|| (!empty($a->contact['id']) && $a->contact['id'] == $cid)) // Local user is already authenticated.
|
||||
{
|
||||
$a->redirect($url ?: $contact_url);
|
||||
if (remote_user()) {
|
||||
$host = substr(DI::baseUrl()->getUrlPath() . (DI::baseUrl()->getUrlPath() ? '/' . DI::baseUrl()->getUrlPath() : ''), strpos(DI::baseUrl()->getUrlPath(), '://') + 3);
|
||||
$remotehost = substr($contact['addr'], strpos($contact['addr'], '@') + 1);
|
||||
|
||||
// On a local instance we have to check if the local user has already authenticated
|
||||
// with the local contact. Otherwise the local user would ask the local contact
|
||||
// for authentification everytime he/she is visiting a profile page of the local
|
||||
// contact.
|
||||
if (($host == $remotehost) && (Session::getRemoteContactID(Session::get('visitor_visiting')) == Session::get('visitor_id'))) {
|
||||
// Remote user is already authenticated.
|
||||