Merge branch 'stable' into develop
This commit is contained in:
commit
2b95a7e7cd
323 changed files with 21146 additions and 16271 deletions
|
|
@ -8,7 +8,7 @@ coverage:
|
|||
round: down
|
||||
range: "70...100"
|
||||
status:
|
||||
project: off
|
||||
patch: off
|
||||
project: false
|
||||
patch: false
|
||||
|
||||
comment: off
|
||||
comment: false
|
||||
|
|
|
|||
141
.drone.yml
141
.drone.yml
|
|
@ -52,21 +52,81 @@ trigger:
|
|||
- pull_request
|
||||
|
||||
steps:
|
||||
- name: Restore cache
|
||||
image: meltwater/drone-cache:dev
|
||||
settings:
|
||||
backend: "filesystem"
|
||||
restore: true
|
||||
cache_key: '{{ .Repo.Name }}_phpcs_{{ arch }}_{{ os }}'
|
||||
archive_format: "gzip"
|
||||
mount:
|
||||
- '.composer'
|
||||
volumes:
|
||||
- name: cache
|
||||
path: /tmp/cache
|
||||
- name: Install dependencies
|
||||
image: composer
|
||||
commands:
|
||||
- export COMPOSER_HOME=.composer
|
||||
- ./bin/composer.phar run cs:install
|
||||
- name: Rebuild cache
|
||||
image: meltwater/drone-cache:dev
|
||||
settings:
|
||||
backend: "filesystem"
|
||||
rebuild: true
|
||||
cache_key: '{{ .Repo.Name }}_phpcs_{{ arch }}_{{ os }}'
|
||||
archive_format: "gzip"
|
||||
mount:
|
||||
- '.composer'
|
||||
volumes:
|
||||
- name: cache
|
||||
path: /tmp/cache
|
||||
- name: Run coding standards check
|
||||
image: friendicaci/php-cs
|
||||
commands:
|
||||
- export CHANGED_FILES="$(git diff --name-status ${DRONE_COMMIT_BEFORE}..${DRONE_COMMIT_AFTER} | grep ^A | cut -f2)"
|
||||
- /check-php-cs.sh
|
||||
|
||||
volumes:
|
||||
- name: cache
|
||||
host:
|
||||
path: /tmp/drone-cache
|
||||
---
|
||||
kind: pipeline
|
||||
type: docker
|
||||
name: php7.3-mariadb
|
||||
|
||||
steps:
|
||||
- name: Restore cache
|
||||
image: meltwater/drone-cache:dev
|
||||
settings:
|
||||
backend: "filesystem"
|
||||
restore: true
|
||||
cache_key: '{{ .Repo.Name }}_php73_{{ arch }}_{{ os }}'
|
||||
archive_format: "gzip"
|
||||
mount:
|
||||
- '.composer'
|
||||
volumes:
|
||||
- name: cache
|
||||
path: /tmp/cache
|
||||
- name: Composer install
|
||||
image: friendicaci/php7.3:php7.3.28
|
||||
commands:
|
||||
- export COMPOSER_HOME=.composer
|
||||
- ./bin/composer.phar validate
|
||||
- ./bin/composer.phar install --prefer-dist
|
||||
- name: Rebuild cache
|
||||
image: meltwater/drone-cache:dev
|
||||
settings:
|
||||
backend: "filesystem"
|
||||
rebuild: true
|
||||
cache_key: '{{ .Repo.Name }}_php73_{{ arch }}_{{ os }}'
|
||||
archive_format: "gzip"
|
||||
mount:
|
||||
- '.composer'
|
||||
volumes:
|
||||
- name: cache
|
||||
path: /tmp/cache
|
||||
- name: Test Friendica
|
||||
image: friendicaci/php7.3:php7.3.28
|
||||
environment:
|
||||
|
|
@ -79,8 +139,6 @@ steps:
|
|||
MEMCACHED_HOST: "memcached"
|
||||
MEMCACHE_HOST: "memcached"
|
||||
commands:
|
||||
- composer validate
|
||||
- composer install --prefer-dist
|
||||
- cp config/local-sample.config.php config/local.config.php
|
||||
- if ! bin/wait-for-connection $MYSQL_HOST $MYSQL_PORT 300; then echo "[ERROR] Waited 300 seconds, no response" >&2; exit 1; fi
|
||||
- mysql -h$MYSQL_HOST -P$MYSQL_PORT -p$MYSQL_PASSWORD -u$MYSQL_USER $MYSQL_DATABASE < database.sql
|
||||
|
|
@ -102,12 +160,47 @@ services:
|
|||
|
||||
- name: redis
|
||||
image: redis
|
||||
|
||||
volumes:
|
||||
- name: cache
|
||||
host:
|
||||
path: /tmp/drone-cache
|
||||
---
|
||||
kind: pipeline
|
||||
type: docker
|
||||
name: php7.4-mariadb
|
||||
|
||||
steps:
|
||||
- name: Restore cache
|
||||
image: meltwater/drone-cache:dev
|
||||
settings:
|
||||
backend: "filesystem"
|
||||
restore: true
|
||||
cache_key: '{{ .Repo.Name }}_php74_{{ arch }}_{{ os }}'
|
||||
archive_format: "gzip"
|
||||
mount:
|
||||
- '.composer'
|
||||
volumes:
|
||||
- name: cache
|
||||
path: /tmp/cache
|
||||
- name: Composer install
|
||||
image: friendicaci/php7.4:php7.4.18
|
||||
commands:
|
||||
- export COMPOSER_HOME=.composer
|
||||
- ./bin/composer.phar validate
|
||||
- ./bin/composer.phar install --prefer-dist
|
||||
- name: Rebuild cache
|
||||
image: meltwater/drone-cache:dev
|
||||
settings:
|
||||
backend: "filesystem"
|
||||
rebuild: true
|
||||
cache_key: '{{ .Repo.Name }}_php74_{{ arch }}_{{ os }}'
|
||||
archive_format: "gzip"
|
||||
mount:
|
||||
- '.composer'
|
||||
volumes:
|
||||
- name: cache
|
||||
path: /tmp/cache
|
||||
- name: Test Friendica
|
||||
image: friendicaci/php7.4:php7.4.18
|
||||
environment:
|
||||
|
|
@ -122,8 +215,6 @@ steps:
|
|||
XDEBUG_MODE: "coverage"
|
||||
commands:
|
||||
- phpenmod xdebug
|
||||
- composer validate
|
||||
- composer install --prefer-dist
|
||||
- cp config/local-sample.config.php config/local.config.php
|
||||
- if ! bin/wait-for-connection $MYSQL_HOST $MYSQL_PORT 300; then echo "[ERROR] Waited 300 seconds, no response" >&2; exit 1; fi
|
||||
- mysql -h$MYSQL_HOST -P$MYSQL_PORT -p$MYSQL_PASSWORD -u$MYSQL_USER $MYSQL_DATABASE < database.sql
|
||||
|
|
@ -155,12 +246,47 @@ services:
|
|||
|
||||
- name: redis
|
||||
image: redis
|
||||
|
||||
volumes:
|
||||
- name: cache
|
||||
host:
|
||||
path: /tmp/drone-cache
|
||||
---
|
||||
kind: pipeline
|
||||
type: docker
|
||||
name: php8.0-mariadb
|
||||
|
||||
steps:
|
||||
- name: Restore cache
|
||||
image: meltwater/drone-cache:dev
|
||||
settings:
|
||||
backend: "filesystem"
|
||||
restore: true
|
||||
cache_key: '{{ .Repo.Name }}_php80_{{ arch }}_{{ os }}'
|
||||
archive_format: "gzip"
|
||||
mount:
|
||||
- '.composer'
|
||||
volumes:
|
||||
- name: cache
|
||||
path: /tmp/cache
|
||||
- name: Composer install
|
||||
image: friendicaci/php8.0:php8.0.5
|
||||
commands:
|
||||
- export COMPOSER_HOME=.composer
|
||||
- ./bin/composer.phar validate
|
||||
- ./bin/composer.phar install --prefer-dist
|
||||
- name: Rebuild cache
|
||||
image: meltwater/drone-cache:dev
|
||||
settings:
|
||||
backend: "filesystem"
|
||||
rebuild: true
|
||||
cache_key: '{{ .Repo.Name }}_php80_{{ arch }}_{{ os }}'
|
||||
archive_format: "gzip"
|
||||
mount:
|
||||
- '.composer'
|
||||
volumes:
|
||||
- name: cache
|
||||
path: /tmp/cache
|
||||
- name: Test Friendica
|
||||
image: friendicaci/php8.0:php8.0.5
|
||||
environment:
|
||||
|
|
@ -173,8 +299,6 @@ steps:
|
|||
MEMCACHED_HOST: "memcached"
|
||||
MEMCACHE_HOST: "memcached"
|
||||
commands:
|
||||
- composer validate
|
||||
- composer install --prefer-dist
|
||||
- cp config/local-sample.config.php config/local.config.php
|
||||
- if ! bin/wait-for-connection $MYSQL_HOST $MYSQL_PORT 300; then echo "[ERROR] Waited 300 seconds, no response" >&2; exit 1; fi
|
||||
- mysql -h$MYSQL_HOST -P$MYSQL_PORT -p$MYSQL_PASSWORD -u$MYSQL_USER $MYSQL_DATABASE < database.sql
|
||||
|
|
@ -196,3 +320,8 @@ services:
|
|||
|
||||
- name: redis
|
||||
image: redis
|
||||
|
||||
volumes:
|
||||
- name: cache
|
||||
host:
|
||||
path: /tmp/drone-cache
|
||||
|
|
|
|||
3
.gitignore
vendored
3
.gitignore
vendored
|
|
@ -16,7 +16,8 @@ robots.txt
|
|||
/config/addon.ini.php
|
||||
|
||||
#ignore documentation, it should be newly built
|
||||
/doc/html
|
||||
/doc/api
|
||||
/doc/cache
|
||||
|
||||
#ignore reports, should be generated with every build
|
||||
report/
|
||||
|
|
|
|||
68
CHANGELOG
68
CHANGELOG
|
|
@ -1,3 +1,71 @@
|
|||
Version 2021.07 (2021-07-04)
|
||||
Friendica Core
|
||||
Updates to the translation DE, EN-GB, HU, IT, JA [translation teams]
|
||||
Updates to the themes (frio, vier) [annando, MrPetovan]
|
||||
Updates to the documentation [annando, nupplaphil]
|
||||
Updated composer and dependencies [nupplaphil, MrPetovan]
|
||||
General code cleanup [annando, nupplaphil, mexon, MrPetovan, very-apen]
|
||||
Enhanced the Mastodon compatible API [annando]
|
||||
Enhanced the possibilities to download the calendar [annando]
|
||||
Enhanced the Vagrant development box setup [fabrixxm]
|
||||
Enhanced the console commands [fabrixxm, mexon]
|
||||
Enhances the support of PHP8 [nupplaphil, MrPetovan]
|
||||
Enhanced the link detection [annando]
|
||||
Enhanced the worker task display in the admin panel [tobiasd]
|
||||
Enhanced the installation wizard [tobiasd]
|
||||
Enhanced the federation statistics page [annando]
|
||||
Enhanced the profile picture handling [annando]
|
||||
Fixed information contained in the nodeinfo [MrPetovan]
|
||||
Fixed an avatar setting problem during the account creation [nupplaphil]
|
||||
Fixed a display problem with picture only postings from Diaspora* [annando]
|
||||
Fixed a problem receiving BCC postings from accounts that are not followed [annando]
|
||||
Fixed a problem with local delivery of postings [annando]
|
||||
Fixed a problem with block/ignore via API [nupplaphil]
|
||||
Fixed a problem with directory search results [MrPetovan]
|
||||
Fixed problems with the console autoinstall command [annando, tobiasd]
|
||||
Fixed problems with forum delivery [annando]
|
||||
Fixed a problem fetching photos in private postings [annando]
|
||||
Fixed a problem with author names containing hash tags [annando]
|
||||
Fixed a problem when following local contacts [annando]
|
||||
Fixed problems with the addon settings [MrPetovan]
|
||||
Removed the Diaspora* relay support [annando]
|
||||
Removed the system user from the user counting [annando]
|
||||
Make birthday time comparison 32-bit safe in Protocol/DFRN [MrPetovan]
|
||||
CI process was switched to drone [nupplaphil]
|
||||
The "authenticate" hook was moved deeper into the process [very-ape]
|
||||
Added support for RTL languages [MrPetovan]
|
||||
Added download link for the calendar entries [annando]
|
||||
|
||||
Friendica Addons
|
||||
Updates to the translations DE, HU, IT, JA [translation teams]
|
||||
nitter
|
||||
added addon to replace links to twitter in postings [tobiasd]
|
||||
keycloakpassword
|
||||
added addon for password-based authentication against Keycloak [very-ape]
|
||||
SAML
|
||||
added addon to support SAML services [very-ape]
|
||||
twitter
|
||||
improved the image upload [annando]
|
||||
improved the exception handling [nupplaphil]
|
||||
incoming posts are unlisted [annando]
|
||||
openstreetmap
|
||||
Ensure location key is available in hook data [MrPetovan]
|
||||
catavatar
|
||||
make the addon work again [nupplaphil]
|
||||
securemail
|
||||
fixed a problem in connection with the phpmailer addon [nupplaphil]
|
||||
Blockbot
|
||||
Move Zabbix to the "good" agents [annando]
|
||||
mailstream
|
||||
adaptation of new addon functionalities and code improvements [mexon]
|
||||
phpmailer
|
||||
updated dependencies [nupplaphil]
|
||||
|
||||
Closed Issues
|
||||
7967, 8262, 9715, 9064, 9993, 10055, 10147, 10184, 10198, 10205, 10210,
|
||||
10219, 10232, 10254, 10287, 10293, 10306, 10312, 10314, 10342, 10364,
|
||||
10375, 10378, 10392, 10424, 10433, 10439, 10443
|
||||
|
||||
Version 2021.04 (2021-04-26)
|
||||
Friendica Core
|
||||
Updates to the translations BG, DE, EN-US, ES, HU, IT, RU [translation teams]
|
||||
|
|
|
|||
11
CREDITS.txt
11
CREDITS.txt
|
|
@ -46,6 +46,8 @@ ben-utzer
|
|||
Beringer Zsolt
|
||||
BinkaDroid
|
||||
Bjoessi
|
||||
bob lebonche
|
||||
Boris Daniel Martinez Millàn
|
||||
bufalo1973
|
||||
ButterflyOfFire
|
||||
Calango Jr
|
||||
|
|
@ -71,6 +73,7 @@ Daria Początek
|
|||
David
|
||||
David Martín Miranda
|
||||
David Rabel
|
||||
Davide Pesenti
|
||||
Dean Townsley
|
||||
Denis Chenu
|
||||
dependabot[bot]
|
||||
|
|
@ -109,7 +112,6 @@ Gregory Smith
|
|||
guzzisti
|
||||
Haakon Meland Eriksen
|
||||
Hans Meine
|
||||
hauke
|
||||
Hauke
|
||||
Hauke Altmann
|
||||
Herbert Thielen
|
||||
|
|
@ -259,12 +261,14 @@ Thecross
|
|||
Thomas
|
||||
Thomas Willingham
|
||||
thorsten23
|
||||
Till Mohr
|
||||
Tim Stahel
|
||||
TiMESPLiNTER
|
||||
Tino
|
||||
Tobias Diekershoff
|
||||
Tobias Hößl
|
||||
Tom
|
||||
Tom Aurlund
|
||||
tomamplius
|
||||
tomtom84
|
||||
Tony Baldwin
|
||||
|
|
@ -282,14 +286,19 @@ utzer
|
|||
Valvin
|
||||
Vasudev Kamath
|
||||
Vasya Novikov
|
||||
very-ape
|
||||
Vinzenz Vietzke
|
||||
vislav
|
||||
vladimir N
|
||||
Vladimir Núñez
|
||||
VVelox
|
||||
Vít Šesták 'v6ak'
|
||||
Waldemar Stoczkowski
|
||||
Wil Tur
|
||||
Wouter Broers
|
||||
XMPPはいいぞ
|
||||
Yasen Pramatarov
|
||||
Yasmine A
|
||||
ylms
|
||||
Zach Prezkuta
|
||||
Zane C. Bowers-Hadley
|
||||
|
|
|
|||
2
VERSION
2
VERSION
|
|
@ -1 +1 @@
|
|||
2021.06-dev
|
||||
2021.07
|
||||
|
|
|
|||
6
Vagrantfile
vendored
6
Vagrantfile
vendored
|
|
@ -34,10 +34,14 @@ Vagrant.configure(2) do |config|
|
|||
#
|
||||
# # Customize the amount of memory on the VM:
|
||||
vb.memory = server_memory
|
||||
|
||||
unless Vagrant.has_plugin?("vagrant-vbguest")
|
||||
raise 'vagrant-vbguest plugin is not installed! Install with "vagrant plugin install vagrant-vbguest"'
|
||||
end
|
||||
end
|
||||
|
||||
# Enable provisioning with a shell script.
|
||||
config.vm.provision "shell", path: "./bin/dev/vagrant_provision.sh"
|
||||
config.vm.provision "shell", path: "./bin/dev/vagrant_provision.sh", privileged: true
|
||||
# run: "always"
|
||||
# run: "once"
|
||||
end
|
||||
|
|
|
|||
Binary file not shown.
|
|
@ -1,13 +1,23 @@
|
|||
#!/bin/bash
|
||||
#Script to setup the vagrant instance for running friendica
|
||||
# Script to setup the vagrant instance for running friendica
|
||||
#
|
||||
#DO NOT RUN on your physical machine as this won't be of any use
|
||||
#and f.e. deletes your /var/www/ folder!
|
||||
echo "Friendica configuration settings"
|
||||
sudo apt-get update
|
||||
# DO NOT RUN on your physical machine as this won't be of any use
|
||||
# and f.e. deletes your /var/www/ folder!
|
||||
#
|
||||
# Run as root by vagrant
|
||||
#
|
||||
##
|
||||
|
||||
# Install virtualbox guest additions
|
||||
sudo apt-get install virtualbox-guest-x11
|
||||
ADMIN_NICK="admin"
|
||||
ADMIN_PASSW="admin"
|
||||
|
||||
USER_NICK="user"
|
||||
USER_PASSW="user"
|
||||
|
||||
##
|
||||
|
||||
echo "Friendica configuration settings"
|
||||
apt-get update
|
||||
|
||||
#Selfsigned cert
|
||||
echo ">>> Installing *.xip.io self-signed SSL"
|
||||
|
|
@ -23,32 +33,32 @@ localityName=New Haven/
|
|||
commonName=$DOMAIN/
|
||||
subjectAltName=DNS:$EXTRADOMAIN
|
||||
"
|
||||
sudo mkdir -p "$SSL_DIR"
|
||||
sudo openssl genrsa -out "$SSL_DIR/xip.io.key" 4096
|
||||
sudo openssl req -new -subj "$(echo -n "$SUBJ" | tr "\n" "/")" -key "$SSL_DIR/xip.io.key" -out "$SSL_DIR/xip.io.csr" -passin pass:$PASSPHRASE
|
||||
sudo openssl x509 -req -days 365 -in "$SSL_DIR/xip.io.csr" -signkey "$SSL_DIR/xip.io.key" -out "$SSL_DIR/xip.io.crt"
|
||||
mkdir -p "$SSL_DIR"
|
||||
openssl genrsa -out "$SSL_DIR/xip.io.key" 4096
|
||||
openssl req -new -subj "$(echo -n "$SUBJ" | tr "\n" "/")" -key "$SSL_DIR/xip.io.key" -out "$SSL_DIR/xip.io.csr" -passin pass:$PASSPHRASE
|
||||
openssl x509 -req -days 365 -in "$SSL_DIR/xip.io.csr" -signkey "$SSL_DIR/xip.io.key" -out "$SSL_DIR/xip.io.crt"
|
||||
|
||||
|
||||
#Install apache2
|
||||
echo ">>> Installing Apache2 webserver"
|
||||
sudo apt-get install -y apache2
|
||||
sudo a2enmod rewrite actions ssl
|
||||
sudo cp /vagrant/bin/dev/vagrant_vhost.sh /usr/local/bin/vhost
|
||||
sudo chmod guo+x /usr/local/bin/vhost
|
||||
sudo vhost -s 192.168.22.10.xip.io -d /var/www -p /etc/ssl/xip.io -c xip.io -a friendica.local
|
||||
sudo a2dissite 000-default
|
||||
sudo service apache2 restart
|
||||
apt-get install -qq apache2
|
||||
a2enmod rewrite actions ssl
|
||||
cp /vagrant/bin/dev/vagrant_vhost.sh /usr/local/bin/vhost
|
||||
chmod guo+x /usr/local/bin/vhost
|
||||
vhost -s 192.168.22.10.xip.io -d /var/www -p /etc/ssl/xip.io -c xip.io -a friendica.local
|
||||
a2dissite 000-default
|
||||
service apache2 restart
|
||||
|
||||
#Install php
|
||||
echo ">>> Installing PHP7"
|
||||
sudo apt-get install -y php libapache2-mod-php php-cli php-mysql php-curl php-gd php-mbstring php-xml imagemagick php-imagick php-zip
|
||||
sudo systemctl restart apache2
|
||||
apt-get install -qq php libapache2-mod-php php-cli php-mysql php-curl php-gd php-mbstring php-xml imagemagick php-imagick php-zip
|
||||
systemctl restart apache2
|
||||
|
||||
#Install mysql
|
||||
echo ">>> Installing Mysql"
|
||||
sudo debconf-set-selections <<< "mariadb-server mariadb-server/root_password password root"
|
||||
sudo debconf-set-selections <<< "mariadb-server mariadb-server/root_password_again password root"
|
||||
sudo apt-get install -qq mariadb-server
|
||||
debconf-set-selections <<< "mariadb-server mariadb-server/root_password password root"
|
||||
debconf-set-selections <<< "mariadb-server mariadb-server/root_password_again password root"
|
||||
apt-get install -qq mariadb-server
|
||||
# enable remote access
|
||||
# setting the mysql bind-address to allow connections from everywhere
|
||||
sed -i "s/bind-address.*/bind-address = 0.0.0.0/" /etc/mysql/my.cnf
|
||||
|
|
@ -66,41 +76,60 @@ $MYSQL -uroot -proot -e "FLUSH PRIVILEGES"
|
|||
systemctl restart mysql
|
||||
|
||||
|
||||
|
||||
#configure rudimentary mail server (local delivery only)
|
||||
#add Friendica accounts for local user accounts, use email address like vagrant@friendica.local, read the email with 'mail'.
|
||||
echo ">>> Installing 'Local Only' postfix"
|
||||
debconf-set-selections <<< "postfix postfix/mailname string friendica.local"
|
||||
debconf-set-selections <<< "postfix postfix/main_mailer_type string 'Local Only'"
|
||||
sudo apt-get install -y postfix mailutils libmailutils-dev
|
||||
sudo echo -e "friendica1: vagrant\nfriendica2: vagrant\nfriendica3: vagrant\nfriendica4: vagrant\nfriendica5: vagrant" >> /etc/aliases && sudo newaliases
|
||||
apt-get install -qq postfix mailutils libmailutils-dev
|
||||
echo -e "friendica1: vagrant\nfriendica2: vagrant\nfriendica3: vagrant\nfriendica4: vagrant\nfriendica5: vagrant" >> /etc/aliases && newaliases
|
||||
|
||||
# Friendica needs git for fetching some dependencies
|
||||
sudo apt-get install -y git
|
||||
echo ">>> Installing git"
|
||||
apt-get install -qq git
|
||||
|
||||
#make the vagrant directory the docroot
|
||||
sudo rm -rf /var/www/
|
||||
sudo ln -fs /vagrant /var/www
|
||||
echo ">>> Symlink /var/www to /vagrant"
|
||||
rm -rf /var/www/
|
||||
ln -fs /vagrant /var/www
|
||||
|
||||
# install deps with composer
|
||||
sudo apt install unzip
|
||||
echo ">>> Installing php requirements"
|
||||
apt install unzip
|
||||
cd /var/www
|
||||
sudo -u www-data php bin/composer.phar install
|
||||
php bin/composer.phar install
|
||||
|
||||
# initial config file for friendica in vagrant
|
||||
cp /vagrant/mods/local.config.vagrant.php /vagrant/config/local.config.php
|
||||
|
||||
echo ">>> Setup Friendica"
|
||||
|
||||
# copy the .htaccess-dist file to .htaccess so that rewrite rules work
|
||||
cp /vagrant/.htaccess-dist /vagrant/.htaccess
|
||||
|
||||
# create the friendica database
|
||||
echo "create database friendica DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci" | $MYSQL -u root -proot
|
||||
# import test database
|
||||
$MYSQL -uroot -proot friendica < /vagrant/friendica_test_data.sql
|
||||
# import test database (disabled because too old)
|
||||
#$MYSQL -uroot -proot friendica < /vagrant/friendica_test_data.sql
|
||||
|
||||
# install friendica
|
||||
bin/console autoinstall -f /vagrant/mods/local.config.vagrant.php
|
||||
|
||||
# add users
|
||||
# (disable a bunch of validation because this is a dev install, deh, it needs invalid emails and stupid passwords)
|
||||
bin/console config system disable_email_validation 1
|
||||
bin/console config system disable_password_exposed 1
|
||||
bin/console user add "$ADMIN_NICK" "$ADMIN_NICK" "$ADMIN_NICK@friendica.local" en
|
||||
bin/console user password "$ADMIN_NICK" "$ADMIN_PASSW"
|
||||
bin/console user add "$USER_NICK" "$USER_NICK" "$USER_NICK@friendica.local" en
|
||||
bin/console user password "$USER_NICK" "$USER_PASSW"
|
||||
|
||||
# set the admin
|
||||
bin/console config config admin_email ""$ADMIN_NICK@friendica.local""
|
||||
|
||||
|
||||
# create cronjob - activate if you have enough memory in you dev VM
|
||||
echo "*/10 * * * * cd /vagrant; /usr/bin/php bin/worker.php" >> friendicacron
|
||||
sudo crontab friendicacron
|
||||
sudo rm friendicacron
|
||||
# cronjob runs as www-data user
|
||||
echo ">>> Installing cronjob"
|
||||
echo "*/10 * * * * www-data cd /vagrant; /usr/bin/php bin/worker.php" >> /etc/cron.d/friendica
|
||||
|
||||
# friendica needs write access to /tmp
|
||||
sudo chmod 777 /tmp
|
||||
chmod 777 /tmp
|
||||
|
|
|
|||
2
boot.php
2
boot.php
|
|
@ -38,7 +38,7 @@ use Friendica\Util\DateTimeFormat;
|
|||
|
||||
define('FRIENDICA_PLATFORM', 'Friendica');
|
||||
define('FRIENDICA_CODENAME', 'Siberian Iris');
|
||||
define('FRIENDICA_VERSION', '2021.06-dev');
|
||||
define('FRIENDICA_VERSION', '2021.07');
|
||||
define('DFRN_PROTOCOL_VERSION', '2.23');
|
||||
define('NEW_TABLE_STRUCTURE_VERSION', 1288);
|
||||
|
||||
|
|
|
|||
76
build.xml
76
build.xml
|
|
@ -1,76 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<project name="friendica" default="test">
|
||||
<!-- ====================================================== -->
|
||||
<!-- Target: clean-test -->
|
||||
<!-- deletes directories with old test reports -->
|
||||
<!-- ====================================================== -->
|
||||
<target name="clean-test">
|
||||
<delete dir="report" />
|
||||
</target>
|
||||
|
||||
<!-- ====================================================== -->
|
||||
<!-- Target: prepare-test -->
|
||||
<!-- creates directories for test reports -->
|
||||
<!-- ====================================================== -->
|
||||
<target name="prepare-test" depends="clean-test">
|
||||
<mkdir dir="report" />
|
||||
</target>
|
||||
|
||||
<!-- =================================== -->
|
||||
<!-- Target: test -->
|
||||
<!-- this target runs all test files -->
|
||||
<!-- =================================== -->
|
||||
<target name="test" depends="prepare-test">
|
||||
<!-- coverage-setup database="./report/coverage-database">
|
||||
<fileset dir=".">
|
||||
<include name="**/*.php" />
|
||||
<exclude name="*test.php"/>
|
||||
<exclude name="index.php"/>
|
||||
<exclude name="library/**"/>
|
||||
<exclude name="doc/**"/>
|
||||
<exclude name=".."/>
|
||||
</fileset>
|
||||
</coverage-setup -->
|
||||
<phpunit printsummary="true">
|
||||
<batchtest>
|
||||
<fileset dir="tests">
|
||||
<include name="*test.php" />
|
||||
</fileset>
|
||||
</batchtest>
|
||||
<formatter type="xml" todir="report" outfile="testlog.xml" />
|
||||
</phpunit>
|
||||
<phpunitreport infile="report/testlog.xml" todir="report" />
|
||||
<!-- coverage-report outfile="report/coverage-database">
|
||||
<report todir="report" styledir="/home/phing/etc" />
|
||||
</coverage-report -->
|
||||
</target>
|
||||
|
||||
<!-- ===================================================== -->
|
||||
<!-- Target: clean-doc -->
|
||||
<!-- this target removes documentation from a previous run -->
|
||||
<!-- ===================================================== -->
|
||||
<target name="doc-clean">
|
||||
<echo msg="Removing old documentation..." />
|
||||
<delete dir="./doc/api/" />
|
||||
<echo msg="Generate documentation directory..." />
|
||||
<mkdir dir="./doc/api/" />
|
||||
</target>
|
||||
|
||||
<!-- ====================================== -->
|
||||
<!-- Target: doc -->
|
||||
<!-- this target builds all documentation -->
|
||||
<!-- ====================================== -->
|
||||
<target name="doc" depends="doc-clean">
|
||||
<echo msg="Building documentation..." />
|
||||
<docblox title="Friendica API" destdir="./doc/api">
|
||||
<fileset dir=".">
|
||||
<include name="**/*.php" />
|
||||
<include name="README"/>
|
||||
<include name="INSTALL.txt"/>
|
||||
<include name="LICENSE"/>
|
||||
</fileset>
|
||||
</docblox>
|
||||
</target>
|
||||
|
||||
</project>
|
||||
91
composer.lock
generated
91
composer.lock
generated
|
|
@ -736,16 +736,16 @@
|
|||
},
|
||||
{
|
||||
"name": "guzzlehttp/psr7",
|
||||
"version": "1.8.1",
|
||||
"version": "1.8.2",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/guzzle/psr7.git",
|
||||
"reference": "35ea11d335fd638b5882ff1725228b3d35496ab1"
|
||||
"reference": "dc960a912984efb74d0a90222870c72c87f10c91"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/guzzle/psr7/zipball/35ea11d335fd638b5882ff1725228b3d35496ab1",
|
||||
"reference": "35ea11d335fd638b5882ff1725228b3d35496ab1",
|
||||
"url": "https://api.github.com/repos/guzzle/psr7/zipball/dc960a912984efb74d0a90222870c72c87f10c91",
|
||||
"reference": "dc960a912984efb74d0a90222870c72c87f10c91",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
|
|
@ -803,7 +803,7 @@
|
|||
"uri",
|
||||
"url"
|
||||
],
|
||||
"time": "2021-03-21T16:25:00+00:00"
|
||||
"time": "2021-04-26T09:17:50+00:00"
|
||||
},
|
||||
{
|
||||
"name": "league/html-to-markdown",
|
||||
|
|
@ -1119,16 +1119,16 @@
|
|||
},
|
||||
{
|
||||
"name": "monolog/monolog",
|
||||
"version": "1.26.0",
|
||||
"version": "1.26.1",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/Seldaek/monolog.git",
|
||||
"reference": "2209ddd84e7ef1256b7af205d0717fb62cfc9c33"
|
||||
"reference": "c6b00f05152ae2c9b04a448f99c7590beb6042f5"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/Seldaek/monolog/zipball/2209ddd84e7ef1256b7af205d0717fb62cfc9c33",
|
||||
"reference": "2209ddd84e7ef1256b7af205d0717fb62cfc9c33",
|
||||
"url": "https://api.github.com/repos/Seldaek/monolog/zipball/c6b00f05152ae2c9b04a448f99c7590beb6042f5",
|
||||
"reference": "c6b00f05152ae2c9b04a448f99c7590beb6042f5",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
|
|
@ -1197,7 +1197,7 @@
|
|||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2020-12-14T12:56:38+00:00"
|
||||
"time": "2021-05-28T08:32:12+00:00"
|
||||
},
|
||||
{
|
||||
"name": "nikic/fast-route",
|
||||
|
|
@ -1591,19 +1591,11 @@
|
|||
},
|
||||
{
|
||||
"name": "npm-asset/jgrowl",
|
||||
"version": "1.4.6",
|
||||
"version": "1.4.8",
|
||||
"dist": {
|
||||
"type": "tar",
|
||||
"url": "https://registry.npmjs.org/jgrowl/-/jgrowl-1.4.6.tgz",
|
||||
"shasum": "2736e332aaee73ccf0a14a5f0066391a0a13f4a3"
|
||||
},
|
||||
"require-dev": {
|
||||
"npm-asset/grunt": "~0.4.2",
|
||||
"npm-asset/grunt-contrib-cssmin": "~0.9.0",
|
||||
"npm-asset/grunt-contrib-jshint": "~0.6.3",
|
||||
"npm-asset/grunt-contrib-less": "~0.11.0",
|
||||
"npm-asset/grunt-contrib-uglify": "~0.4.0",
|
||||
"npm-asset/grunt-contrib-watch": "~0.6.1"
|
||||
"url": "https://registry.npmjs.org/jgrowl/-/jgrowl-1.4.8.tgz",
|
||||
"shasum": "4ba40ffb93757a7e1d9b262d916be299d03df3a4"
|
||||
},
|
||||
"type": "npm-asset-library",
|
||||
"extra": {
|
||||
|
|
@ -1616,8 +1608,13 @@
|
|||
"type": "git",
|
||||
"url": "git+ssh://git@github.com/stanlemon/jGrowl.git"
|
||||
},
|
||||
"npm-asset-scripts": []
|
||||
"npm-asset-scripts": {
|
||||
"build": "grunt"
|
||||
}
|
||||
},
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Stan Lemon",
|
||||
|
|
@ -1627,7 +1624,7 @@
|
|||
],
|
||||
"description": "jGrowl is a jQuery plugin that raises unobtrusive messages within the browser, similar to the way that OS X's Growl Framework works. The idea is simple, deliver notifications to the end user in a noticeable way that doesn't obstruct the work flow and yet ",
|
||||
"homepage": "https://github.com/stanlemon/jGrowl#readme",
|
||||
"time": "2017-07-21T02:36:34+00:00"
|
||||
"time": "2021-05-20T17:11:40+00:00"
|
||||
},
|
||||
{
|
||||
"name": "npm-asset/jquery",
|
||||
|
|
@ -2224,16 +2221,16 @@
|
|||
},
|
||||
{
|
||||
"name": "paragonie/certainty",
|
||||
"version": "v2.8.0",
|
||||
"version": "v2.8.1",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/paragonie/certainty.git",
|
||||
"reference": "94fc99f8c1f5bdce960713d6b63a108a64d90dfa"
|
||||
"reference": "e2a1da558f95074545ad811d60359c74500a5e24"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/paragonie/certainty/zipball/94fc99f8c1f5bdce960713d6b63a108a64d90dfa",
|
||||
"reference": "94fc99f8c1f5bdce960713d6b63a108a64d90dfa",
|
||||
"url": "https://api.github.com/repos/paragonie/certainty/zipball/e2a1da558f95074545ad811d60359c74500a5e24",
|
||||
"reference": "e2a1da558f95074545ad811d60359c74500a5e24",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
|
|
@ -2241,12 +2238,12 @@
|
|||
"ext-json": "*",
|
||||
"guzzlehttp/guzzle": "^6|^7",
|
||||
"paragonie/constant_time_encoding": "^1|^2",
|
||||
"paragonie/sodium_compat": "^1.11",
|
||||
"paragonie/sodium_compat": "^1.13",
|
||||
"php": "^5.5|^7|^8"
|
||||
},
|
||||
"require-dev": {
|
||||
"composer/composer": "^1",
|
||||
"phpunit/phpunit": "^4|^5|^6|^7"
|
||||
"composer/composer": "^1|>=2.0.14",
|
||||
"phpunit/phpunit": "^4|^5|^6|^7|^8|^9"
|
||||
},
|
||||
"bin": [
|
||||
"bin/certainty-cert-symlink"
|
||||
|
|
@ -2282,7 +2279,7 @@
|
|||
"ssl",
|
||||
"tls"
|
||||
],
|
||||
"time": "2020-10-15T08:10:12+00:00"
|
||||
"time": "2021-05-25T18:27:41+00:00"
|
||||
},
|
||||
{
|
||||
"name": "paragonie/constant_time_encoding",
|
||||
|
|
@ -2442,16 +2439,16 @@
|
|||
},
|
||||
{
|
||||
"name": "paragonie/sodium_compat",
|
||||
"version": "v1.14.0",
|
||||
"version": "v1.16.1",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/paragonie/sodium_compat.git",
|
||||
"reference": "a1cfe0b21faf9c0b61ac0c6188c4af7fd6fd0db3"
|
||||
"reference": "2e856afe80bfc968b47da1f4a7e1ea8f03d06b38"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/paragonie/sodium_compat/zipball/a1cfe0b21faf9c0b61ac0c6188c4af7fd6fd0db3",
|
||||
"reference": "a1cfe0b21faf9c0b61ac0c6188c4af7fd6fd0db3",
|
||||
"url": "https://api.github.com/repos/paragonie/sodium_compat/zipball/2e856afe80bfc968b47da1f4a7e1ea8f03d06b38",
|
||||
"reference": "2e856afe80bfc968b47da1f4a7e1ea8f03d06b38",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
|
|
@ -2520,7 +2517,7 @@
|
|||
"secret-key cryptography",
|
||||
"side-channel resistant"
|
||||
],
|
||||
"time": "2020-12-03T16:26:19+00:00"
|
||||
"time": "2021-05-25T12:58:14+00:00"
|
||||
},
|
||||
{
|
||||
"name": "patrickschur/language-detection",
|
||||
|
|
@ -2625,16 +2622,16 @@
|
|||
},
|
||||
{
|
||||
"name": "phpseclib/phpseclib",
|
||||
"version": "2.0.30",
|
||||
"version": "2.0.31",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/phpseclib/phpseclib.git",
|
||||
"reference": "136b9ca7eebef78be14abf90d65c5e57b6bc5d36"
|
||||
"reference": "233a920cb38636a43b18d428f9a8db1f0a1a08f4"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/phpseclib/phpseclib/zipball/136b9ca7eebef78be14abf90d65c5e57b6bc5d36",
|
||||
"reference": "136b9ca7eebef78be14abf90d65c5e57b6bc5d36",
|
||||
"url": "https://api.github.com/repos/phpseclib/phpseclib/zipball/233a920cb38636a43b18d428f9a8db1f0a1a08f4",
|
||||
"reference": "233a920cb38636a43b18d428f9a8db1f0a1a08f4",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
|
|
@ -2726,7 +2723,7 @@
|
|||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2020-12-17T05:42:04+00:00"
|
||||
"time": "2021-04-06T13:56:45+00:00"
|
||||
},
|
||||
{
|
||||
"name": "pragmarx/google2fa",
|
||||
|
|
@ -3058,16 +3055,16 @@
|
|||
},
|
||||
{
|
||||
"name": "psr/log",
|
||||
"version": "1.1.3",
|
||||
"version": "1.1.4",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/php-fig/log.git",
|
||||
"reference": "0f73288fd15629204f9d42b7055f72dacbe811fc"
|
||||
"reference": "d49695b909c3b7628b6289db5479a1c204601f11"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/php-fig/log/zipball/0f73288fd15629204f9d42b7055f72dacbe811fc",
|
||||
"reference": "0f73288fd15629204f9d42b7055f72dacbe811fc",
|
||||
"url": "https://api.github.com/repos/php-fig/log/zipball/d49695b909c3b7628b6289db5479a1c204601f11",
|
||||
"reference": "d49695b909c3b7628b6289db5479a1c204601f11",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
|
|
@ -3091,7 +3088,7 @@
|
|||
"authors": [
|
||||
{
|
||||
"name": "PHP-FIG",
|
||||
"homepage": "http://www.php-fig.org/"
|
||||
"homepage": "https://www.php-fig.org/"
|
||||
}
|
||||
],
|
||||
"description": "Common interface for logging libraries",
|
||||
|
|
@ -3101,7 +3098,7 @@
|
|||
"psr",
|
||||
"psr-3"
|
||||
],
|
||||
"time": "2020-03-23T09:12:05+00:00"
|
||||
"time": "2021-05-03T11:20:27+00:00"
|
||||
},
|
||||
{
|
||||
"name": "ralouphie/getallheaders",
|
||||
|
|
|
|||
116
database.sql
116
database.sql
|
|
@ -1,6 +1,6 @@
|
|||
-- ------------------------------------------
|
||||
-- Friendica 2021.06-dev (Siberian Iris)
|
||||
-- DB_UPDATE_VERSION 1418
|
||||
-- Friendica 2021.06-rc (Siberian Iris)
|
||||
-- DB_UPDATE_VERSION 1424
|
||||
-- ------------------------------------------
|
||||
|
||||
|
||||
|
|
@ -120,6 +120,7 @@ CREATE TABLE IF NOT EXISTS `contact` (
|
|||
`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)',
|
||||
`header` varchar(255) COMMENT 'Header picture',
|
||||
`site-pubkey` text COMMENT '',
|
||||
`issued-id` varchar(255) NOT NULL DEFAULT '' COMMENT '',
|
||||
`dfrn-id` varchar(255) NOT NULL DEFAULT '' COMMENT '',
|
||||
|
|
@ -339,10 +340,12 @@ CREATE TABLE IF NOT EXISTS `apcontact` (
|
|||
`outbox` varchar(255) COMMENT '',
|
||||
`sharedinbox` varchar(255) COMMENT '',
|
||||
`manually-approve` boolean COMMENT '',
|
||||
`discoverable` boolean COMMENT 'Mastodon extension: true if profile is published in their directory',
|
||||
`nick` varchar(255) NOT NULL DEFAULT '' COMMENT '',
|
||||
`name` varchar(255) COMMENT '',
|
||||
`about` text COMMENT '',
|
||||
`photo` varchar(255) COMMENT '',
|
||||
`header` varchar(255) COMMENT 'Header picture',
|
||||
`addr` varchar(255) COMMENT '',
|
||||
`alias` varchar(255) COMMENT '',
|
||||
`pubkey` text COMMENT '',
|
||||
|
|
@ -751,6 +754,7 @@ CREATE TABLE IF NOT EXISTS `mail` (
|
|||
`from-photo` varchar(255) NOT NULL DEFAULT '' COMMENT 'contact photo link of the sender',
|
||||
`from-url` varchar(255) NOT NULL DEFAULT '' COMMENT 'profile linke of the sender',
|
||||
`contact-id` varchar(255) COMMENT 'contact.id',
|
||||
`author-id` int unsigned COMMENT 'Link to the contact table with uid=0 of the author of the mail',
|
||||
`convid` int unsigned COMMENT 'conv.id',
|
||||
`title` varchar(255) NOT NULL DEFAULT '' COMMENT '',
|
||||
`body` mediumtext COMMENT '',
|
||||
|
|
@ -759,7 +763,11 @@ CREATE TABLE IF NOT EXISTS `mail` (
|
|||
`replied` boolean NOT NULL DEFAULT '0' COMMENT '',
|
||||
`unknown` boolean NOT NULL DEFAULT '0' COMMENT 'if sender not in the contact table this is 1',
|
||||
`uri` varchar(255) NOT NULL DEFAULT '' COMMENT '',
|
||||
`uri-id` int unsigned COMMENT 'Item-uri id of the related mail',
|
||||
`parent-uri` varchar(255) NOT NULL DEFAULT '' COMMENT '',
|
||||
`parent-uri-id` int unsigned COMMENT 'Item-uri id of the parent of the related mail',
|
||||
`thr-parent` varchar(255) COMMENT '',
|
||||
`thr-parent-id` int unsigned COMMENT 'Id of the item-uri table that contains the thread parent uri',
|
||||
`created` datetime NOT NULL DEFAULT '0001-01-01 00:00:00' COMMENT 'creation time of the private message',
|
||||
PRIMARY KEY(`id`),
|
||||
INDEX `uid_seen` (`uid`,`seen`),
|
||||
|
|
@ -767,7 +775,15 @@ CREATE TABLE IF NOT EXISTS `mail` (
|
|||
INDEX `uri` (`uri`(64)),
|
||||
INDEX `parent-uri` (`parent-uri`(64)),
|
||||
INDEX `contactid` (`contact-id`(32)),
|
||||
FOREIGN KEY (`uid`) REFERENCES `user` (`uid`) ON UPDATE RESTRICT ON DELETE CASCADE
|
||||
INDEX `author-id` (`author-id`),
|
||||
INDEX `uri-id` (`uri-id`),
|
||||
INDEX `parent-uri-id` (`parent-uri-id`),
|
||||
INDEX `thr-parent-id` (`thr-parent-id`),
|
||||
FOREIGN KEY (`uid`) REFERENCES `user` (`uid`) ON UPDATE RESTRICT ON DELETE CASCADE,
|
||||
FOREIGN KEY (`author-id`) REFERENCES `contact` (`id`) ON UPDATE RESTRICT ON DELETE RESTRICT,
|
||||
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
|
||||
) DEFAULT COLLATE utf8mb4_general_ci COMMENT='private messages';
|
||||
|
||||
--
|
||||
|
|
@ -806,6 +822,33 @@ CREATE TABLE IF NOT EXISTS `manage` (
|
|||
FOREIGN KEY (`mid`) REFERENCES `user` (`uid`) ON UPDATE RESTRICT ON DELETE CASCADE
|
||||
) DEFAULT COLLATE utf8mb4_general_ci COMMENT='table of accounts that can manage each other';
|
||||
|
||||
--
|
||||
-- TABLE notification
|
||||
--
|
||||
CREATE TABLE IF NOT EXISTS `notification` (
|
||||
`id` int unsigned NOT NULL auto_increment COMMENT 'sequential ID',
|
||||
`uid` mediumint unsigned COMMENT 'Owner User id',
|
||||
`vid` smallint unsigned COMMENT 'Id of the verb table entry that contains the activity verbs',
|
||||
`type` tinyint unsigned COMMENT '',
|
||||
`actor-id` int unsigned COMMENT 'Link to the contact table with uid=0 of the actor that caused the notification',
|
||||
`target-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',
|
||||
`created` datetime COMMENT '',
|
||||
`seen` boolean DEFAULT '0' COMMENT '',
|
||||
PRIMARY KEY(`id`),
|
||||
UNIQUE INDEX `uid_vid_type_actor-id_target-uri-id` (`uid`,`vid`,`type`,`actor-id`,`target-uri-id`),
|
||||
INDEX `vid` (`vid`),
|
||||
INDEX `actor-id` (`actor-id`),
|
||||
INDEX `target-uri-id` (`target-uri-id`),
|
||||
INDEX `parent-uri-id` (`parent-uri-id`),
|
||||
INDEX `seen_uid` (`seen`,`uid`),
|
||||
FOREIGN KEY (`uid`) REFERENCES `user` (`uid`) ON UPDATE RESTRICT ON DELETE CASCADE,
|
||||
FOREIGN KEY (`vid`) REFERENCES `verb` (`id`) ON UPDATE RESTRICT ON DELETE RESTRICT,
|
||||
FOREIGN KEY (`actor-id`) REFERENCES `contact` (`id`) ON UPDATE RESTRICT ON DELETE CASCADE,
|
||||
FOREIGN KEY (`target-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
|
||||
) DEFAULT COLLATE utf8mb4_general_ci COMMENT='notifications';
|
||||
|
||||
--
|
||||
-- TABLE notify
|
||||
--
|
||||
|
|
@ -1672,7 +1715,9 @@ CREATE VIEW `post-user-view` AS SELECT
|
|||
`parent-post`.`author-id` AS `parent-author-id`,
|
||||
`parent-post-author`.`url` AS `parent-author-link`,
|
||||
`parent-post-author`.`name` AS `parent-author-name`,
|
||||
`parent-post-author`.`network` AS `parent-author-network`
|
||||
`parent-post-author`.`network` AS `parent-author-network`,
|
||||
`parent-post-author`.`blocked` AS `parent-author-blocked`,
|
||||
`parent-post-author`.`hidden` AS `parent-author-hidden`
|
||||
FROM `post-user`
|
||||
STRAIGHT_JOIN `post-thread-user` ON `post-thread-user`.`uri-id` = `post-user`.`parent-uri-id` AND `post-thread-user`.`uid` = `post-user`.`uid`
|
||||
STRAIGHT_JOIN `contact` ON `contact`.`id` = `post-user`.`contact-id`
|
||||
|
|
@ -1832,7 +1877,9 @@ CREATE VIEW `post-thread-user-view` AS SELECT
|
|||
`parent-post`.`author-id` AS `parent-author-id`,
|
||||
`parent-post-author`.`url` AS `parent-author-link`,
|
||||
`parent-post-author`.`name` AS `parent-author-name`,
|
||||
`parent-post-author`.`network` AS `parent-author-network`
|
||||
`parent-post-author`.`network` AS `parent-author-network`,
|
||||
`parent-post-author`.`blocked` AS `parent-author-blocked`,
|
||||
`parent-post-author`.`hidden` AS `parent-author-hidden`
|
||||
FROM `post-thread-user`
|
||||
INNER JOIN `post-user` ON `post-user`.`id` = `post-thread-user`.`post-user-id`
|
||||
STRAIGHT_JOIN `contact` ON `contact`.`id` = `post-thread-user`.`contact-id`
|
||||
|
|
@ -1896,6 +1943,31 @@ CREATE VIEW `post-view` AS SELECT
|
|||
`post-content`.`target-type` AS `target-type`,
|
||||
`post-content`.`target` AS `target`,
|
||||
`post-content`.`resource-id` AS `resource-id`,
|
||||
`post`.`author-id` AS `contact-id`,
|
||||
`author`.`url` AS `contact-link`,
|
||||
`author`.`addr` AS `contact-addr`,
|
||||
`author`.`name` AS `contact-name`,
|
||||
`author`.`nick` AS `contact-nick`,
|
||||
`author`.`thumb` AS `contact-avatar`,
|
||||
`author`.`network` AS `contact-network`,
|
||||
`author`.`blocked` AS `contact-blocked`,
|
||||
`author`.`hidden` AS `contact-hidden`,
|
||||
`author`.`readonly` AS `contact-readonly`,
|
||||
`author`.`archive` AS `contact-archive`,
|
||||
`author`.`pending` AS `contact-pending`,
|
||||
`author`.`rel` AS `contact-rel`,
|
||||
`author`.`uid` AS `contact-uid`,
|
||||
`author`.`contact-type` AS `contact-contact-type`,
|
||||
IF (`post`.`network` IN ('apub', 'dfrn', 'dspr', 'stat'), true, `author`.`writable`) AS `writable`,
|
||||
false AS `self`,
|
||||
`author`.`id` AS `cid`,
|
||||
`author`.`alias` AS `alias`,
|
||||
`author`.`photo` AS `photo`,
|
||||
`author`.`name-date` AS `name-date`,
|
||||
`author`.`uri-date` AS `uri-date`,
|
||||
`author`.`avatar-date` AS `avatar-date`,
|
||||
`author`.`thumb` AS `thumb`,
|
||||
`author`.`dfrn-id` AS `dfrn-id`,
|
||||
`post`.`author-id` AS `author-id`,
|
||||
`author`.`url` AS `author-link`,
|
||||
`author`.`addr` AS `author-addr`,
|
||||
|
|
@ -1931,7 +2003,9 @@ CREATE VIEW `post-view` AS SELECT
|
|||
`parent-post`.`author-id` AS `parent-author-id`,
|
||||
`parent-post-author`.`url` AS `parent-author-link`,
|
||||
`parent-post-author`.`name` AS `parent-author-name`,
|
||||
`parent-post-author`.`network` AS `parent-author-network`
|
||||
`parent-post-author`.`network` AS `parent-author-network`,
|
||||
`parent-post-author`.`blocked` AS `parent-author-blocked`,
|
||||
`parent-post-author`.`hidden` AS `parent-author-hidden`
|
||||
FROM `post`
|
||||
STRAIGHT_JOIN `post-thread` ON `post-thread`.`uri-id` = `post`.`parent-uri-id`
|
||||
STRAIGHT_JOIN `contact` AS `author` ON `author`.`id` = `post`.`author-id`
|
||||
|
|
@ -1991,6 +2065,31 @@ CREATE VIEW `post-thread-view` AS SELECT
|
|||
`post-content`.`target-type` AS `target-type`,
|
||||
`post-content`.`target` AS `target`,
|
||||
`post-content`.`resource-id` AS `resource-id`,
|
||||
`post-thread`.`author-id` AS `contact-id`,
|
||||
`author`.`url` AS `contact-link`,
|
||||
`author`.`addr` AS `contact-addr`,
|
||||
`author`.`name` AS `contact-name`,
|
||||
`author`.`nick` AS `contact-nick`,
|
||||
`author`.`thumb` AS `contact-avatar`,
|
||||
`author`.`network` AS `contact-network`,
|
||||
`author`.`blocked` AS `contact-blocked`,
|
||||
`author`.`hidden` AS `contact-hidden`,
|
||||
`author`.`readonly` AS `contact-readonly`,
|
||||
`author`.`archive` AS `contact-archive`,
|
||||
`author`.`pending` AS `contact-pending`,
|
||||
`author`.`rel` AS `contact-rel`,
|
||||
`author`.`uid` AS `contact-uid`,
|
||||
`author`.`contact-type` AS `contact-contact-type`,
|
||||
IF (`post`.`network` IN ('apub', 'dfrn', 'dspr', 'stat'), true, `author`.`writable`) AS `writable`,
|
||||
false AS `self`,
|
||||
`author`.`id` AS `cid`,
|
||||
`author`.`alias` AS `alias`,
|
||||
`author`.`photo` AS `photo`,
|
||||
`author`.`name-date` AS `name-date`,
|
||||
`author`.`uri-date` AS `uri-date`,
|
||||
`author`.`avatar-date` AS `avatar-date`,
|
||||
`author`.`thumb` AS `thumb`,
|
||||
`author`.`dfrn-id` AS `dfrn-id`,
|
||||
`post-thread`.`author-id` AS `author-id`,
|
||||
`author`.`url` AS `author-link`,
|
||||
`author`.`addr` AS `author-addr`,
|
||||
|
|
@ -2026,7 +2125,9 @@ CREATE VIEW `post-thread-view` AS SELECT
|
|||
`parent-post`.`author-id` AS `parent-author-id`,
|
||||
`parent-post-author`.`url` AS `parent-author-link`,
|
||||
`parent-post-author`.`name` AS `parent-author-name`,
|
||||
`parent-post-author`.`network` AS `parent-author-network`
|
||||
`parent-post-author`.`network` AS `parent-author-network`,
|
||||
`parent-post-author`.`blocked` AS `parent-author-blocked`,
|
||||
`parent-post-author`.`hidden` AS `parent-author-hidden`
|
||||
FROM `post-thread`
|
||||
INNER JOIN `post` ON `post`.`uri-id` = `post-thread`.`uri-id`
|
||||
STRAIGHT_JOIN `contact` AS `author` ON `author`.`id` = `post-thread`.`author-id`
|
||||
|
|
@ -2158,6 +2259,7 @@ CREATE VIEW `owner-view` AS SELECT
|
|||
`contact`.`photo` AS `photo`,
|
||||
`contact`.`thumb` AS `thumb`,
|
||||
`contact`.`micro` AS `micro`,
|
||||
`contact`.`header` AS `header`,
|
||||
`contact`.`site-pubkey` AS `site-pubkey`,
|
||||
`contact`.`issued-id` AS `issued-id`,
|
||||
`contact`.`dfrn-id` AS `dfrn-id`,
|
||||
|
|
|
|||
|
|
@ -11,21 +11,22 @@ Authentication is the same as described in [Using the APIs](help/api#Authenticat
|
|||
|
||||
## Clients
|
||||
|
||||
Supported mobile apps:
|
||||
### Supported apps
|
||||
|
||||
- [AndStatus](http://andstatus.org)
|
||||
- [Husky](https://husky.fwgs.ru)
|
||||
- [Subway Tooter](https://github.com/tateisu/SubwayTooter)
|
||||
- [Tusky](https://tusky.app)
|
||||
- [Twidere](https://github.com/TwidereProject/)
|
||||
- [twitlatte](https://github.com/moko256/twitlatte)
|
||||
- [Yuito](https://github.com/accelforce/Yuito)
|
||||
For supported apps please have a look at the [FAQ](help/FAQ#clients)
|
||||
|
||||
Unsupported mobile apps:
|
||||
### Unsupported apps
|
||||
|
||||
#### Android
|
||||
|
||||
- [Fedilab](https://framagit.org/tom79/fedilab) Automatically uses the legacy API, see issue: https://framagit.org/tom79/fedilab/-/issues/520
|
||||
- [Mammut](https://github.com/jamiesanson/Mammut) There are problems with the token request, see issue https://github.com/jamiesanson/Mammut/issues/19
|
||||
|
||||
#### iOS
|
||||
|
||||
- [Mast](https://github.com/Beesitech/Mast) Doesn't accept the entered instance name. Claims that it is invalid (Message is: "Not a valid instance (may be closed or dead)")
|
||||
- [Toot!](https://apps.apple.com/app/toot/id1229021451)
|
||||
|
||||
## Entities
|
||||
|
||||
These endpoints use the [Mastodon API entities](https://docs.joinmastodon.org/entities/).
|
||||
|
|
@ -73,6 +74,7 @@ These endpoints use the [Mastodon API entities](https://docs.joinmastodon.org/en
|
|||
|
||||
|
||||
- [`GET /api/v1/instance`](https://docs.joinmastodon.org/methods/instance#fetch-instance)
|
||||
- GET /api/v1/instance/rules Undocumented, returns Terms of Service
|
||||
- [`GET /api/v1/instance/peers`](https://docs.joinmastodon.org/methods/instance#list-of-connected-domains)
|
||||
- [`GET /api/v1/lists`](https://docs.joinmastodon.org/methods/timelines/lists/)
|
||||
- [`POST /api/v1/lists`](https://docs.joinmastodon.org/methods/timelines/lists/)
|
||||
|
|
@ -119,17 +121,30 @@ These endpoints use the [Mastodon API entities](https://docs.joinmastodon.org/en
|
|||
|
||||
## Currently unimplemented endpoints
|
||||
|
||||
These emdpoints are planned to be implemented
|
||||
These emdpoints are planned to be implemented somewhere in the future.
|
||||
|
||||
- [`PATCH /api/v1/accounts/update_credentials`](https://docs.joinmastodon.org/methods/accounts/)
|
||||
- [`GET /api/v1/instance/activity`](https://docs.joinmastodon.org/methods/instance#weekly-activity)
|
||||
|
||||
## Dummy endpoints
|
||||
|
||||
These endpoints are returning empty data to avoid error messages when using third party clients.
|
||||
They refer to features that don't exist in Friendica yet.
|
||||
|
||||
- [`GET /api/v1/accounts/:id/identity_proofs`](https://docs.joinmastodon.org/methods/accounts/)
|
||||
- [`GET /api/v1/announcements`](https://docs.joinmastodon.org/methods/announcements/)
|
||||
- [`GET /api/v1/endorsements`](https://docs.joinmastodon.org/methods/accounts/endorsements/)
|
||||
- [`GET /api/v1/filters`](https://docs.joinmastodon.org/methods/accounts/filters/)
|
||||
- [`GET /api/v1/markers`](https://docs.joinmastodon.org/methods/timelines/markers/)
|
||||
- [`GET /api/v1/scheduled_statuses`](https://docs.joinmastodon.org/methods/statuses/scheduled_statuses/)
|
||||
|
||||
## Non supportable endpoints
|
||||
|
||||
These endpoints won't be implemented, since they refer to functionality that doesn't exist in Friendica
|
||||
These endpoints won't be implemented at the moment.
|
||||
They refer to features or data that don't exist in Friendica yet.
|
||||
|
||||
- POST /api/meta Misskey API endpoint.
|
||||
- [`POST /api/v1/accounts`](https://docs.joinmastodon.org/methods/accounts/)
|
||||
- [`GET /api/v1/accounts/:id/identity_proofs`](https://docs.joinmastodon.org/methods/accounts/)
|
||||
- [`GET /api/v1/accounts/:id/featured_tags`](https://docs.joinmastodon.org/methods/accounts/)
|
||||
- [`POST /api/v1/accounts/:id/pin`](https://docs.joinmastodon.org/methods/accounts/)
|
||||
- [`POST /api/v1/accounts/:id/unpin`](https://docs.joinmastodon.org/methods/accounts/)
|
||||
- [`GET /api/v1/admin/accounts`](https://docs.joinmastodon.org/methods/admin/)
|
||||
|
|
@ -138,30 +153,31 @@ These endpoints won't be implemented, since they refer to functionality that doe
|
|||
- [`GET /api/v1/admin/reports`](https://docs.joinmastodon.org/methods/admin/)
|
||||
- [`GET /api/v1/admin/reports/:id`](https://docs.joinmastodon.org/methods/admin/)
|
||||
- [`POST /api/v1/admin/reports/:id/{action}`](https://docs.joinmastodon.org/methods/admin/)
|
||||
- [`GET /api/v1/announcements`](https://docs.joinmastodon.org/methods/announcements/)
|
||||
- [`POST /api/v1/announcements/:id/dismiss`](https://docs.joinmastodon.org/methods/announcements/)
|
||||
- [`PUT /api/v1/announcements/:id/reactions/{name}`](https://docs.joinmastodon.org/methods/announcements/)
|
||||
- [`DELETE /api/v1/announcements/:id/reactions/{name}`](https://docs.joinmastodon.org/methods/announcements/)
|
||||
- [`GET /api/v1/domain_blocks`](https://docs.joinmastodon.org/methods/accounts/domain_blocks/)
|
||||
- [`POST /api/v1/domain_blocks`](https://docs.joinmastodon.org/methods/accounts/domain_blocks/)
|
||||
- [`DELETE /api/v1/domain_blocks`](https://docs.joinmastodon.org/methods/accounts/domain_blocks/)
|
||||
- [`GET /api/v1/endorsements`](https://docs.joinmastodon.org/methods/accounts/endorsements/)
|
||||
- [`GET /api/v1/featured_tags`](https://docs.joinmastodon.org/methods/accounts/featured_tags/)
|
||||
- [`POST /api/v1/featured_tags`](https://docs.joinmastodon.org/methods/accounts/featured_tags/)
|
||||
- [`DELETE /api/v1/featured_tags/:id`](https://docs.joinmastodon.org/methods/accounts/featured_tags/)
|
||||
- [`GET /api/v1/featured_tags/suggestions`](https://docs.joinmastodon.org/methods/accounts/featured_tags/)
|
||||
- [`GET /api/v1/filters`](https://docs.joinmastodon.org/methods/accounts/filters/)
|
||||
- [`GET /api/v1/filters/:id`](https://docs.joinmastodon.org/methods/accounts/filters/)
|
||||
- [`POST /api/v1/filters/:id`](https://docs.joinmastodon.org/methods/accounts/filters/)
|
||||
- [`PUT /api/v1/filters/:id`](https://docs.joinmastodon.org/methods/accounts/filters/)
|
||||
- [`DELETE /api/v1/filters/:id`](https://docs.joinmastodon.org/methods/accounts/filters/)
|
||||
- [`GET /api/v1/markers`](https://docs.joinmastodon.org/methods/timelines/markers/)
|
||||
- [`GET /api/v1/instance/activity`](https://docs.joinmastodon.org/methods/instance#weekly-activity)
|
||||
- [`POST /api/v1/markers`](https://docs.joinmastodon.org/methods/timelines/markers/)
|
||||
- [`GET /api/v1/polls/:id`](https://docs.joinmastodon.org/methods/statuses/polls/)
|
||||
- [`POST /api/v1/polls/:id/votes`](https://docs.joinmastodon.org/methods/statuses/polls/)
|
||||
- [`DELETE /api/v1/push/subscription`](https://docs.joinmastodon.org/methods/notifications/push/)
|
||||
- [`GET /api/v1/push/subscription`](https://docs.joinmastodon.org/methods/notifications/push/)
|
||||
- [`PUSH /api/v1/push/subscription`](https://docs.joinmastodon.org/methods/notifications/push/)
|
||||
- [`PUT /api/v1/push/subscription`](https://docs.joinmastodon.org/methods/notifications/push/)
|
||||
- [`POST /api/v1/reports`](https://docs.joinmastodon.org/methods/accounts/reports/)
|
||||
- [`GET /api/v1/scheduled_statuses`](https://docs.joinmastodon.org/methods/statuses/scheduled_statuses/)
|
||||
- [`GET /api/v1/scheduled_statuses/:id`](https://docs.joinmastodon.org/methods/statuses/scheduled_statuses/)
|
||||
- [`PUT /api/v1/scheduled_statuses/:id`](https://docs.joinmastodon.org/methods/statuses/scheduled_statuses/)
|
||||
- [`DELETE /api/v1/scheduled_statuses/:id`](https://docs.joinmastodon.org/methods/statuses/scheduled_statuses/)
|
||||
- [`GET /api/v1/streaming`](https://docs.joinmastodon.org/methods/timelines/streaming/)
|
||||
- [`DELETE /api/v1/suggestions/:id`](https://docs.joinmastodon.org/methods/accounts/suggestions/)
|
||||
|
|
|
|||
72
doc/FAQ.md
72
doc/FAQ.md
|
|
@ -33,9 +33,10 @@ User
|
|||
If this FAQ does not answer your question you can always reach out to the community via the following options:
|
||||
|
||||
* Friendica Support Forum: [@helpers@forum.friendi.ca](https://forum.friendi.ca/~helpers)
|
||||
* XMPP: support(at)forum.friendi.ca
|
||||
* IRC: [#friendica at freenode.net](https://webchat.freenode.net/?settings=#friendica)
|
||||
* Matrix: [#friendica-en:matrix.org](https://matrix.to/#/#friendica-en:matrix.org) or [#friendi.ca:matrix.org](https://matrix.to/#/#friendi.ca:matrix.org)
|
||||
* Community chat rooms (the IRC, Matrix and XMPP rooms are bridged) these public chats are logged [from IRC](https://gnusociarg.nsupdate.info/2021/%23friendica/) and [Matrix](https://view.matrix.org/alias/%23friendi.ca:matrix.org/)
|
||||
* XMPP: support(at)forum.friendi.ca
|
||||
* IRC: #friendica at libera.chat or [#friendica at freenode.net](https://webchat.freenode.net/?settings=#friendica)
|
||||
* Matrix: [#friendica-en:matrix.org](https://matrix.to/#/#friendica-en:matrix.org) or [#friendi.ca:matrix.org](https://matrix.to/#/#friendi.ca:matrix.org)
|
||||
* [Mailing List](http://mailman.friendi.ca/mailman/listinfo/support-friendi.ca)
|
||||
<!--- * [XMPP](xmpp:support@forum.friendi.ca?join)
|
||||
https://github.com/github/markup/issues/202
|
||||
|
|
@ -182,22 +183,65 @@ Example: Friendica Support
|
|||
### What friendica clients can I use?
|
||||
|
||||
Friendica is using a [Twitter/GNU Social compatible API](help/api), which means you can use any Twitter/GNU Social client for your platform as long as you can change the API path in its settings.
|
||||
Since the 2021.06 release, Friendica also supports the [Mastodon API](help/API-Mastodon) which works with many Mastodon clients.
|
||||
Here is a list of known working clients:
|
||||
|
||||
* Android
|
||||
* [Friendiqa](https://git.friendi.ca/lubuwest/Friendiqa) ([F-Droid](https://git.friendi.ca/lubuwest/Friendiqa#install), [Google Play](https://play.google.com/store/apps/details?id=org.qtproject.friendiqa))
|
||||
* [Fedilab](https://fedilab.app) ([F-Droid](https://f-droid.org/app/fr.gouv.etalab.mastodon), [Google Play](https://play.google.com/store/apps/details?id=app.fedilab.android))
|
||||
* [AndStatus](http://andstatus.org) ([F-Droid](https://f-droid.org/repository/browse/?fdid=org.andstatus.app), [Google Play](https://play.google.com/store/apps/details?id=org.andstatus.app))
|
||||
* [Twidere](https://dimension.im/) ([F-Droid](https://f-droid.org/repository/browse/?fdid=org.mariotaku.twidere), [Google Play](https://play.google.com/store/apps/details?id=com.twidere.twiderex), [GitHub](https://github.com/TwidereProject/Twidere-Android))
|
||||
* SailfishOS
|
||||
* [Friendly](https://openrepos.net/content/fabrixxm/friendly#comment-form)
|
||||
* Linux
|
||||
* [Choqok](https://choqok.kde.org)
|
||||
* Windows
|
||||
* [Friendica Mobile](https://www.microsoft.com/de-DE/store/p/friendica-mobile/9nblggh0fhmn?rtc=1) (Windows 10)
|
||||
#### Android
|
||||
|
||||
* [AndStatus](http://andstatus.org) ([F-Droid](https://f-droid.org/repository/browse/?fdid=org.andstatus.app), [Google Play](https://play.google.com/store/apps/details?id=org.andstatus.app))
|
||||
* [B4X for Pleroma & Mastodon](https://github.com/AnywhereSoftware/B4X-Pleroma)
|
||||
* [DiCa](https://dica.mixi.cool/) (Available at Google Play)
|
||||
* [Fedi](https://play.google.com/store/apps/details?id=com.fediverse.app)
|
||||
* [Fedilab](https://fedilab.app) ([F-Droid](https://f-droid.org/app/fr.gouv.etalab.mastodon), [Google Play](https://play.google.com/store/apps/details?id=app.fedilab.android))
|
||||
* [Friendiqa](https://git.friendi.ca/lubuwest/Friendiqa) ([F-Droid](https://git.friendi.ca/lubuwest/Friendiqa#install), [Google Play](https://play.google.com/store/apps/details?id=org.qtproject.friendiqa))
|
||||
* [Husky](https://husky.fwgs.ru)
|
||||
* [Roma](https://play.google.com/store/apps/details?id=tech.bigfig.roma)
|
||||
* [Subway Tooter](https://github.com/tateisu/SubwayTooter)
|
||||
* [Tooot](https://tooot.app/)
|
||||
* [Tusky](https://tusky.app)
|
||||
* [Twidere](https://dimension.im/) ([F-Droid](https://f-droid.org/repository/browse/?fdid=org.mariotaku.twidere), [Google Play](https://play.google.com/store/apps/details?id=com.twidere.twiderex), [GitHub](https://github.com/TwidereProject/Twidere-Android))
|
||||
* [TwidereX](https://github.com/TwidereProject/TwidereX-Android)
|
||||
* [twitlatte](https://github.com/moko256/twitlatte)
|
||||
* [Yuito](https://github.com/accelforce/Yuito)
|
||||
|
||||
#### SailfishOS
|
||||
|
||||
* [Friendly](https://openrepos.net/content/fabrixxm/friendly#comment-form)
|
||||
|
||||
#### iOS
|
||||
|
||||
* [Amaroq](https://github.com/ReticentJohn/Amaroq/tree/master)
|
||||
* [B4X for Pleroma & Mastodon](https://github.com/AnywhereSoftware/B4X-Pleroma)
|
||||
* [Fedi](https://apps.apple.com/de/app/fedi-for-pleroma-and-mastodon/id1478806281)
|
||||
* [Roma](https://apps.apple.com/de/app/roma-for-pleroma-and-mastodon/id1445328699)
|
||||
* [StarPterano](https://apps.apple.com/de/app/starpterano/id1436972796) Uses an OAuth method where you have to manually copy and paste the provided code.
|
||||
* [Stella](https://apps.apple.com/us/app/stella-for-mastodon-twitter/id921372048?l=ms)
|
||||
* [Tooot](https://tooot.app/)
|
||||
* [Tootle](https://apps.apple.com/de/app/tootle-for-mastodon/id1236013466) entered hostname must match in upper/lower case. Currently crashes on "Status" type notifications.
|
||||
|
||||
#### Linux
|
||||
|
||||
* [Choqok](https://choqok.kde.org)
|
||||
* [Whalebird](https://whalebird.social)
|
||||
* [TheDesk](https://ja.mstdn.wiki/TheDesk)
|
||||
* [Toot](https://toot.readthedocs.io/en/latest/)
|
||||
* [Tootle](https://github.com/bleakgrey/tootle)
|
||||
|
||||
#### MacOS
|
||||
|
||||
- [Mastonaut](https://mastonaut.app/)
|
||||
|
||||
#### Windows
|
||||
|
||||
* [Friendica Mobile](https://www.microsoft.com/de-DE/store/p/friendica-mobile/9nblggh0fhmn?rtc=1) (Windows 10)
|
||||
|
||||
Depending on the features of the client you might encounter some glitches in usability, like being limited in the length of your postings to 140 characters and having no access to the [permission settings](help/Groups-and-Privacy).
|
||||
|
||||
#### Web Frontend
|
||||
|
||||
- [Halcyon](https://www.halcyon.social/)
|
||||
- [Pinafore](https://github.com/nolanlawson/pinafore)
|
||||
|
||||
Admin
|
||||
--------
|
||||
|
||||
|
|
|
|||
|
|
@ -68,9 +68,10 @@ Friendica Documentation and Resources
|
|||
* Ways to get Support
|
||||
* Friendica Support Forum: [@helpers@forum.friendi.ca](https://forum.friendi.ca/~helpers)
|
||||
* [Mailing List Archive](http://mailman.friendi.ca/mailman/listinfo/support-friendi.ca) you can subscribe to the list by sending an email to ``support-request(at)friendi.ca?subject=subscribe``
|
||||
* XMPP/Jabber MUC: support(at)forum.friendi.ca
|
||||
* IRC: [#friendica at freenode.net](https://webchat.freenode.net/?settings=#friendica)
|
||||
* Matrix: [#friendi.ca](https://matrix.to/#/#friendi.ca:matrix.org) or [#friendica-en](https://matrix.to/#/#friendica-en:matrix.org) at matrix.org
|
||||
* Community chat rooms (the IRC, Matrix and XMPP rooms are bridget) these public chats are logged [from IRC](https://gnusociarg.nsupdate.info/2021/%23friendica/) and [Matrix](https://view.matrix.org/alias/%23friendi.ca:matrix.org/)
|
||||
* XMPP/Jabber MUC: support(at)forum.friendi.ca
|
||||
* IRC: [#friendica at freenode.net](https://webchat.freenode.net/?settings=#friendica)
|
||||
* Matrix: [#friendi.ca](https://matrix.to/#/#friendi.ca:matrix.org) or [#friendica-en](https://matrix.to/#/#friendica-en:matrix.org) at matrix.org
|
||||
|
||||
**About**
|
||||
|
||||
|
|
|
|||
120
doc/database.md
120
doc/database.md
|
|
@ -3,50 +3,76 @@ Database Tables
|
|||
|
||||
* [Home](help)
|
||||
|
||||
| Table | Description |
|
||||
|------------------------------------------------------|--------------------------------------------------|
|
||||
| [addon](help/database/db_addon) | registered addons |
|
||||
| [attach](help/database/db_attach) | file attachments |
|
||||
| [auth_codes](help/database/db_auth_codes) | OAuth usage |
|
||||
| [cache](help/database/db_cache) | OEmbed cache |
|
||||
| [challenge](help/database/db_challenge) | |
|
||||
| [clients](help/database/db_clients) | OAuth usage |
|
||||
| [config](help/database/db_config) | main configuration storage |
|
||||
| [contact](help/database/db_contact) | contact table |
|
||||
| [conv](help/database/db_conv) | private messages |
|
||||
| [conversation](help/database/db_conversation) | Raw data and structure information for messages |
|
||||
| [event](help/database/db_event) | Events |
|
||||
| [fcontact](help/database/db_fcontact) | friend suggestion stuff |
|
||||
| [fsuggest](help/database/db_fsuggest) | friend suggestion stuff |
|
||||
| [group](help/database/db_group) | privacy groups, group info |
|
||||
| [group_member](help/database/db_group_member) | privacy groups, member info |
|
||||
| [gserver](help/database/db_gserver) | |
|
||||
| [hook](help/database/db_hook) | addon hook registry |
|
||||
| [intro](help/database/db_intro) | |
|
||||
| [item](help/database/db_item) | all posts |
|
||||
| [locks](help/database/db_locks) | |
|
||||
| [mail](help/database/db_mail) | private messages |
|
||||
| [mailacct](help/database/db_mailacct) | |
|
||||
| [manage](help/database/db_manage) | table of accounts that can "su" each other |
|
||||
| [notify](help/database/db_notify) | notifications |
|
||||
| [notify-threads](help/database/db_notify-threads) | |
|
||||
| [oembed](help/database/db_oembed) | cache for OEmbed queries |
|
||||
| [parsed_url](help/database/db_parsed_url) | cache for "parse_url" queries |
|
||||
| [pconfig](help/database/db_pconfig) | personal (per user) configuration storage |
|
||||
| [photo](help/database/db_photo) | photo storage |
|
||||
| [poll](help/database/db_poll) | data for polls |
|
||||
| [poll_result](help/database/db_poll_result) | data for poll elements |
|
||||
| [profile](help/database/db_profile) | user profiles data |
|
||||
| [profile_check](help/database/db_profile_check) | DFRN remote auth use |
|
||||
| [push_subscriber](help/database/db_push_subscriber) | |
|
||||
| [queue](help/database/db_queue) | |
|
||||
| [register](help/database/db_register) | registrations requiring admin approval |
|
||||
| [search](help/database/db_search) | |
|
||||
| [session](help/database/db_session) | web session storage |
|
||||
| [sign](help/database/db_sign) | Diaspora signatures |
|
||||
| [term](help/database/db_term) | item taxonomy (categories, tags, etc.) table |
|
||||
| [thread](help/database/db_thread) | |
|
||||
| [tokens](help/database/db_tokens) | OAuth usage |
|
||||
| [user](help/database/db_user) | local user table |
|
||||
| [userd](help/database/db_userd) | |
|
||||
| [workerqueue](help/database/db_workerqueue) | |
|
||||
| Table | Description |
|
||||
|-------|-------------|
|
||||
| [2fa_app_specific_password](help/database/db_2fa_app_specific_password) | Two-factor app-specific _password |
|
||||
| [2fa_recovery_codes](help/database/db_2fa_recovery_codes) | Two-factor authentication recovery codes |
|
||||
| [2fa_trusted_browser](help/database/db_2fa_trusted_browser) | Two-factor authentication trusted browsers |
|
||||
| [addon](help/database/db_addon) | registered addons |
|
||||
| [apcontact](help/database/db_apcontact) | ActivityPub compatible contacts - used in the ActivityPub implementation |
|
||||
| [application](help/database/db_application) | OAuth application |
|
||||
| [application-token](help/database/db_application-token) | OAuth user token |
|
||||
| [attach](help/database/db_attach) | file attachments |
|
||||
| [auth_codes](help/database/db_auth_codes) | OAuth usage |
|
||||
| [cache](help/database/db_cache) | Stores temporary data |
|
||||
| [challenge](help/database/db_challenge) | |
|
||||
| [clients](help/database/db_clients) | OAuth usage |
|
||||
| [config](help/database/db_config) | main configuration storage |
|
||||
| [contact](help/database/db_contact) | contact table |
|
||||
| [contact-relation](help/database/db_contact-relation) | Contact relations |
|
||||
| [conv](help/database/db_conv) | private messages |
|
||||
| [conversation](help/database/db_conversation) | Raw data and structure information for messages |
|
||||
| [delayed-post](help/database/db_delayed-post) | Posts that are about to be distributed at a later time |
|
||||
| [diaspora-interaction](help/database/db_diaspora-interaction) | Signed Diaspora Interaction |
|
||||
| [event](help/database/db_event) | Events |
|
||||
| [fcontact](help/database/db_fcontact) | Diaspora compatible contacts - used in the Diaspora implementation |
|
||||
| [fsuggest](help/database/db_fsuggest) | friend suggestion stuff |
|
||||
| [group](help/database/db_group) | privacy groups, group info |
|
||||
| [group_member](help/database/db_group_member) | privacy groups, member info |
|
||||
| [gserver](help/database/db_gserver) | Global servers |
|
||||
| [gserver-tag](help/database/db_gserver-tag) | Tags that the server has subscribed |
|
||||
| [hook](help/database/db_hook) | addon hook registry |
|
||||
| [host](help/database/db_host) | Hostname |
|
||||
| [inbox-status](help/database/db_inbox-status) | Status of ActivityPub inboxes |
|
||||
| [intro](help/database/db_intro) | |
|
||||
| [item-uri](help/database/db_item-uri) | URI and GUID for items |
|
||||
| [locks](help/database/db_locks) | |
|
||||
| [mail](help/database/db_mail) | private messages |
|
||||
| [mailacct](help/database/db_mailacct) | Mail account data for fetching mails |
|
||||
| [manage](help/database/db_manage) | table of accounts that can manage each other |
|
||||
| [notification](help/database/db_notification) | notifications |
|
||||
| [notify](help/database/db_notify) | notifications |
|
||||
| [notify-threads](help/database/db_notify-threads) | |
|
||||
| [oembed](help/database/db_oembed) | cache for OEmbed queries |
|
||||
| [openwebauth-token](help/database/db_openwebauth-token) | Store OpenWebAuth token to verify contacts |
|
||||
| [parsed_url](help/database/db_parsed_url) | cache for 'parse_url' queries |
|
||||
| [pconfig](help/database/db_pconfig) | personal (per user) configuration storage |
|
||||
| [permissionset](help/database/db_permissionset) | |
|
||||
| [photo](help/database/db_photo) | photo storage |
|
||||
| [post](help/database/db_post) | Structure for all posts |
|
||||
| [post-category](help/database/db_post-category) | post relation to categories |
|
||||
| [post-content](help/database/db_post-content) | Content for all posts |
|
||||
| [post-delivery-data](help/database/db_post-delivery-data) | Delivery data for items |
|
||||
| [post-media](help/database/db_post-media) | Attached media |
|
||||
| [post-tag](help/database/db_post-tag) | post relation to tags |
|
||||
| [post-thread](help/database/db_post-thread) | Thread related data |
|
||||
| [post-thread-user](help/database/db_post-thread-user) | Thread related data per user |
|
||||
| [post-user](help/database/db_post-user) | User specific post data |
|
||||
| [post-user-notification](help/database/db_post-user-notification) | User post notifications |
|
||||
| [process](help/database/db_process) | Currently running system processes |
|
||||
| [profile](help/database/db_profile) | user profiles data |
|
||||
| [profile_check](help/database/db_profile_check) | DFRN remote auth use |
|
||||
| [profile_field](help/database/db_profile_field) | Custom profile fields |
|
||||
| [push_subscriber](help/database/db_push_subscriber) | Used for OStatus: Contains feed subscribers |
|
||||
| [register](help/database/db_register) | registrations requiring admin approval |
|
||||
| [search](help/database/db_search) | |
|
||||
| [session](help/database/db_session) | web session storage |
|
||||
| [storage](help/database/db_storage) | Data stored by Database storage backend |
|
||||
| [tag](help/database/db_tag) | tags and mentions |
|
||||
| [tokens](help/database/db_tokens) | OAuth usage |
|
||||
| [user](help/database/db_user) | The local users |
|
||||
| [user-contact](help/database/db_user-contact) | User specific public contact data |
|
||||
| [userd](help/database/db_userd) | Deleted usernames |
|
||||
| [verb](help/database/db_verb) | Activity Verbs |
|
||||
| [worker-ipc](help/database/db_worker-ipc) | Inter process communication between the frontend and the worker |
|
||||
| [workerqueue](help/database/db_workerqueue) | Background tasks queue entries |
|
||||
|
|
|
|||
33
doc/database/db_2fa_app_specific_password.md
Normal file
33
doc/database/db_2fa_app_specific_password.md
Normal file
|
|
@ -0,0 +1,33 @@
|
|||
Table 2fa_app_specific_password
|
||||
===========
|
||||
|
||||
Two-factor app-specific _password
|
||||
|
||||
Fields
|
||||
------
|
||||
|
||||
| Field | Description | Type | Null | Key | Default | Extra |
|
||||
| --------------- | ---------------------------------------- | ------------------ | ---- | --- | ------- | -------------- |
|
||||
| id | Password ID for revocation | mediumint unsigned | NO | PRI | NULL | auto_increment |
|
||||
| uid | User ID | mediumint unsigned | NO | | NULL | |
|
||||
| description | Description of the usage of the password | varchar(255) | YES | | NULL | |
|
||||
| hashed_password | Hashed password | varchar(255) | NO | | NULL | |
|
||||
| generated | Datetime the password was generated | datetime | NO | | NULL | |
|
||||
| last_used | Datetime the password was last used | datetime | YES | | NULL | |
|
||||
|
||||
Indexes
|
||||
------------
|
||||
|
||||
| Name | Fields |
|
||||
| --------------- | --------------------- |
|
||||
| PRIMARY | id |
|
||||
| uid_description | uid, description(190) |
|
||||
|
||||
Foreign Keys
|
||||
------------
|
||||
|
||||
| Field | Target Table | Target Field |
|
||||
|-------|--------------|--------------|
|
||||
| uid | [user](help/database/db_user) | uid |
|
||||
|
||||
Return to [database documentation](help/database)
|
||||
30
doc/database/db_2fa_recovery_codes.md
Normal file
30
doc/database/db_2fa_recovery_codes.md
Normal file
|
|
@ -0,0 +1,30 @@
|
|||
Table 2fa_recovery_codes
|
||||
===========
|
||||
|
||||
Two-factor authentication recovery codes
|
||||
|
||||
Fields
|
||||
------
|
||||
|
||||
| Field | Description | Type | Null | Key | Default | Extra |
|
||||
| --------- | ------------------------------- | ------------------ | ---- | --- | ------- | ----- |
|
||||
| uid | User ID | mediumint unsigned | NO | PRI | NULL | |
|
||||
| code | Recovery code string | varchar(50) | NO | PRI | NULL | |
|
||||
| generated | Datetime the code was generated | datetime | NO | | NULL | |
|
||||
| used | Datetime the code was used | datetime | YES | | NULL | |
|
||||
|
||||
Indexes
|
||||
------------
|
||||
|
||||
| Name | Fields |
|
||||
| ------- | --------- |
|
||||
| PRIMARY | uid, code |
|
||||
|
||||
Foreign Keys
|
||||
------------
|
||||
|
||||
| Field | Target Table | Target Field |
|
||||
|-------|--------------|--------------|
|
||||
| uid | [user](help/database/db_user) | uid |
|
||||
|
||||
Return to [database documentation](help/database)
|
||||
32
doc/database/db_2fa_trusted_browser.md
Normal file
32
doc/database/db_2fa_trusted_browser.md
Normal file
|
|
@ -0,0 +1,32 @@
|
|||
Table 2fa_trusted_browser
|
||||
===========
|
||||
|
||||
Two-factor authentication trusted browsers
|
||||
|
||||
Fields
|
||||
------
|
||||
|
||||
| Field | Description | Type | Null | Key | Default | Extra |
|
||||
| ----------- | ------------------------------------------ | ------------------ | ---- | --- | ------- | ----- |
|
||||
| cookie_hash | Trusted cookie hash | varchar(80) | NO | PRI | NULL | |
|
||||
| uid | User ID | mediumint unsigned | NO | | NULL | |
|
||||
| user_agent | User agent string | text | YES | | NULL | |
|
||||
| created | Datetime the trusted browser was recorded | datetime | NO | | NULL | |
|
||||
| last_used | Datetime the trusted browser was last used | datetime | YES | | NULL | |
|
||||
|
||||
Indexes
|
||||
------------
|
||||
|
||||
| Name | Fields |
|
||||
| ------- | ----------- |
|
||||
| PRIMARY | cookie_hash |
|
||||
| uid | uid |
|
||||
|
||||
Foreign Keys
|
||||
------------
|
||||
|
||||
| Field | Target Table | Target Field |
|
||||
|-------|--------------|--------------|
|
||||
| uid | [user](help/database/db_user) | uid |
|
||||
|
||||
Return to [database documentation](help/database)
|
||||
|
|
@ -1,17 +1,29 @@
|
|||
Table addon
|
||||
===========
|
||||
|
||||
| Field | Description | Type | Null | Key | Default | Extra |
|
||||
| ------------- | --------------------------------------------- | ---------- | ---- | --- | ------- | --------------- |
|
||||
| id | | int(11) | NO | PRI | NULL | auto_increment |
|
||||
| name | addon base (file)name | char(255) | NO | | | |
|
||||
| version | currently unused | char(255) | NO | | | |
|
||||
| installed | currently always 1 | tinyint(1) | NO | | 0 | |
|
||||
| hidden | currently unused | tinyint(1) | NO | | 0 | |
|
||||
| timestamp | file timestamp to check for reloads | bigint(20) | NO | | 0 | |
|
||||
| plugin_admin | 1 = has admin config, 0 = has no admin config | tinyint(1) | NO | | 0 | |
|
||||
registered addons
|
||||
|
||||
Fields
|
||||
------
|
||||
|
||||
| Field | Description | Type | Null | Key | Default | Extra |
|
||||
| ------------ | --------------------------------------------- | ------------ | ---- | --- | ------- | -------------- |
|
||||
| id | | int unsigned | NO | PRI | NULL | auto_increment |
|
||||
| name | addon base (file)name | varchar(50) | NO | | | |
|
||||
| version | currently unused | varchar(50) | NO | | | |
|
||||
| installed | currently always 1 | boolean | NO | | 0 | |
|
||||
| hidden | currently unused | boolean | NO | | 0 | |
|
||||
| timestamp | file timestamp to check for reloads | int unsigned | NO | | 0 | |
|
||||
| plugin_admin | 1 = has admin config, 0 = has no admin config | boolean | NO | | 0 | |
|
||||
|
||||
Indexes
|
||||
------------
|
||||
|
||||
| Name | Fields |
|
||||
| -------------- | --------------- |
|
||||
| PRIMARY | id |
|
||||
| installed_name | installed, name |
|
||||
| name | UNIQUE, name |
|
||||
|
||||
Notes:
|
||||
These are addons which have been enabled by the site administrator on the addon page
|
||||
|
||||
Return to [database documentation](help/database)
|
||||
|
|
|
|||
58
doc/database/db_apcontact.md
Normal file
58
doc/database/db_apcontact.md
Normal file
|
|
@ -0,0 +1,58 @@
|
|||
Table apcontact
|
||||
===========
|
||||
|
||||
ActivityPub compatible contacts - used in the ActivityPub implementation
|
||||
|
||||
Fields
|
||||
------
|
||||
|
||||
| Field | Description | Type | Null | Key | Default | Extra |
|
||||
| ---------------- | ------------------------------------------------------------------- | -------------- | ---- | --- | ------------------- | ----- |
|
||||
| url | URL of the contact | varbinary(255) | NO | PRI | NULL | |
|
||||
| uuid | | varchar(255) | YES | | NULL | |
|
||||
| type | | varchar(20) | NO | | NULL | |
|
||||
| following | | varchar(255) | YES | | NULL | |
|
||||
| followers | | varchar(255) | YES | | NULL | |
|
||||
| inbox | | varchar(255) | NO | | NULL | |
|
||||
| outbox | | varchar(255) | YES | | NULL | |
|
||||
| sharedinbox | | varchar(255) | YES | | NULL | |
|
||||
| manually-approve | | boolean | YES | | NULL | |
|
||||
| discoverable | Mastodon extension: true if profile is published in their directory | boolean | YES | | NULL | |
|
||||
| nick | | varchar(255) | NO | | | |
|
||||
| name | | varchar(255) | YES | | NULL | |
|
||||
| about | | text | YES | | NULL | |
|
||||
| photo | | varchar(255) | YES | | NULL | |
|
||||
| header | Header picture | varchar(255) | YES | | NULL | |
|
||||
| addr | | varchar(255) | YES | | NULL | |
|
||||
| alias | | varchar(255) | YES | | NULL | |
|
||||
| pubkey | | text | YES | | NULL | |
|
||||
| subscribe | | varchar(255) | YES | | NULL | |
|
||||
| baseurl | baseurl of the ap contact | varchar(255) | YES | | NULL | |
|
||||
| gsid | Global Server ID | int unsigned | YES | | NULL | |
|
||||
| generator | Name of the contact's system | varchar(255) | YES | | NULL | |
|
||||
| following_count | Number of following contacts | int unsigned | YES | | 0 | |
|
||||
| followers_count | Number of followers | int unsigned | YES | | 0 | |
|
||||
| statuses_count | Number of posts | int unsigned | YES | | 0 | |
|
||||
| updated | | datetime | NO | | 0001-01-01 00:00:00 | |
|
||||
|
||||
Indexes
|
||||
------------
|
||||
|
||||
| Name | Fields |
|
||||
| ----------- | ---------------- |
|
||||
| PRIMARY | url |
|
||||
| addr | addr(32) |
|
||||
| alias | alias(190) |
|
||||
| followers | followers(190) |
|
||||
| baseurl | baseurl(190) |
|
||||
| sharedinbox | sharedinbox(190) |
|
||||
| gsid | gsid |
|
||||
|
||||
Foreign Keys
|
||||
------------
|
||||
|
||||
| Field | Target Table | Target Field |
|
||||
|-------|--------------|--------------|
|
||||
| gsid | [gserver](help/database/db_gserver) | id |
|
||||
|
||||
Return to [database documentation](help/database)
|
||||
38
doc/database/db_application-token.md
Normal file
38
doc/database/db_application-token.md
Normal file
|
|
@ -0,0 +1,38 @@
|
|||
Table application-token
|
||||
===========
|
||||
|
||||
OAuth user token
|
||||
|
||||
Fields
|
||||
------
|
||||
|
||||
| Field | Description | Type | Null | Key | Default | Extra |
|
||||
| -------------- | ------------- | ------------------ | ---- | --- | ------- | ----- |
|
||||
| application-id | | int unsigned | NO | PRI | NULL | |
|
||||
| uid | Owner User id | mediumint unsigned | NO | PRI | NULL | |
|
||||
| code | | varchar(64) | NO | | NULL | |
|
||||
| access_token | | varchar(64) | NO | | NULL | |
|
||||
| created_at | creation time | datetime | NO | | NULL | |
|
||||
| scopes | | varchar(255) | YES | | NULL | |
|
||||
| read | Read scope | boolean | YES | | NULL | |
|
||||
| write | Write scope | boolean | YES | | NULL | |
|
||||
| follow | Follow scope | boolean | YES | | NULL | |
|
||||
| push | Push scope | boolean | YES | | NULL | |
|
||||
|
||||
Indexes
|
||||
------------
|
||||
|
||||
| Name | Fields |
|
||||
| ------- | ------------------- |
|
||||
| PRIMARY | application-id, uid |
|
||||
| uid_id | uid, application-id |
|
||||
|
||||
Foreign Keys
|
||||
------------
|
||||
|
||||
| Field | Target Table | Target Field |
|
||||
|-------|--------------|--------------|
|
||||
| application-id | [application](help/database/db_application) | id |
|
||||
| uid | [user](help/database/db_user) | uid |
|
||||
|
||||
Return to [database documentation](help/database)
|
||||
32
doc/database/db_application.md
Normal file
32
doc/database/db_application.md
Normal file
|
|
@ -0,0 +1,32 @@
|
|||
Table application
|
||||
===========
|
||||
|
||||
OAuth application
|
||||
|
||||
Fields
|
||||
------
|
||||
|
||||
| Field | Description | Type | Null | Key | Default | Extra |
|
||||
| ------------- | --------------- | ------------ | ---- | --- | ------- | -------------- |
|
||||
| id | generated index | int unsigned | NO | PRI | NULL | auto_increment |
|
||||
| client_id | | varchar(64) | NO | | NULL | |
|
||||
| client_secret | | varchar(64) | NO | | NULL | |
|
||||
| name | | varchar(255) | NO | | NULL | |
|
||||
| redirect_uri | | varchar(255) | NO | | NULL | |
|
||||
| website | | varchar(255) | YES | | NULL | |
|
||||
| scopes | | varchar(255) | YES | | NULL | |
|
||||
| read | Read scope | boolean | YES | | NULL | |
|
||||
| write | Write scope | boolean | YES | | NULL | |
|
||||
| follow | Follow scope | boolean | YES | | NULL | |
|
||||
| push | Push scope | boolean | YES | | NULL | |
|
||||
|
||||
Indexes
|
||||
------------
|
||||
|
||||
| Name | Fields |
|
||||
| --------- | ----------------- |
|
||||
| PRIMARY | id |
|
||||
| client_id | UNIQUE, client_id |
|
||||
|
||||
|
||||
Return to [database documentation](help/database)
|
||||
|
|
@ -1,22 +1,42 @@
|
|||
Table attach
|
||||
============
|
||||
===========
|
||||
|
||||
| Field | Description | Type | Null | Key | Default | Extra |
|
||||
| ---------- | ------------------------------------------------------| ------------ | ---- | --- | ------------------- | --------------- |
|
||||
| id | generated index | int(11) | NO | PRI | NULL | auto_increment |
|
||||
| uid | user_id of owner | int(11) | NO | | 0 | |
|
||||
| hash | hash | varchar(64) | NO | | | |
|
||||
| filename | filename of original | varchar(255) | NO | | | |
|
||||
| filetype | mimetype | varchar(64) | NO | | | |
|
||||
| filesize | size in bytes | int(11) | NO | | 0 | |
|
||||
| data | file data | longblob | NO | | NULL | |
|
||||
| created | creation time | datetime | NO | | 0001-01-01 00:00:00 | |
|
||||
| edited | last edit time | datetime | NO | | 0001-01-01 00:00:00 | |
|
||||
| allow_cid | Access Control - list of allowed contact.id '<19><78> | mediumtext | NO | | NULL | |
|
||||
| allow_gid | Access Control - list of allowed groups | mediumtext | NO | | NULL | |
|
||||
| deny_cid | Access Control - list of denied contact.id | mediumtext | NO | | NULL | |
|
||||
| deny_gid | Access Control - list of denied groups | mediumtext | NO | | NULL | |
|
||||
file attachments
|
||||
|
||||
Notes: Permissions are surrounded by angle chars. e.g. <4>
|
||||
Fields
|
||||
------
|
||||
|
||||
| Field | Description | Type | Null | Key | Default | Extra |
|
||||
| ------------- | ----------------------------------------------------- | ------------------ | ---- | --- | ------------------- | -------------- |
|
||||
| id | generated index | int unsigned | NO | PRI | NULL | auto_increment |
|
||||
| uid | Owner User id | mediumint unsigned | NO | | 0 | |
|
||||
| hash | hash | varchar(64) | NO | | | |
|
||||
| filename | filename of original | varchar(255) | NO | | | |
|
||||
| filetype | mimetype | varchar(64) | NO | | | |
|
||||
| filesize | size in bytes | int unsigned | NO | | 0 | |
|
||||
| data | file data | longblob | NO | | NULL | |
|
||||
| created | creation time | datetime | NO | | 0001-01-01 00:00:00 | |
|
||||
| edited | last edit time | datetime | NO | | 0001-01-01 00:00:00 | |
|
||||
| allow_cid | Access Control - list of allowed contact.id '<19><78> | mediumtext | YES | | NULL | |
|
||||
| allow_gid | Access Control - list of allowed groups | mediumtext | YES | | NULL | |
|
||||
| deny_cid | Access Control - list of denied contact.id | mediumtext | YES | | NULL | |
|
||||
| deny_gid | Access Control - list of denied groups | mediumtext | YES | | NULL | |
|
||||
| backend-class | Storage backend class | tinytext | YES | | NULL | |
|
||||
| backend-ref | Storage backend data reference | text | YES | | NULL | |
|
||||
|
||||
Indexes
|
||||
------------
|
||||
|
||||
| Name | Fields |
|
||||
| ------- | ------ |
|
||||
| PRIMARY | id |
|
||||
| uid | uid |
|
||||
|
||||
Foreign Keys
|
||||
------------
|
||||
|
||||
| Field | Target Table | Target Field |
|
||||
|-------|--------------|--------------|
|
||||
| uid | [user](help/database/db_user) | uid |
|
||||
|
||||
Return to [database documentation](help/database)
|
||||
|
|
|
|||
|
|
@ -1,14 +1,32 @@
|
|||
Table auth_codes
|
||||
================
|
||||
===========
|
||||
|
||||
OAuth2 authorisation register - currently implemented but unused
|
||||
OAuth usage
|
||||
|
||||
| Field | Description | Type | Null | Key | Default | Extra |
|
||||
| ------------- | ----------- | ------------ | ---- | --- | ------- | ----- |
|
||||
| id | | varchar(40) | NO | PRI | NULL | |
|
||||
| client_id | | varchar(20) | NO | | | |
|
||||
| redirect_uri | | varchar(200) | NO | | | |
|
||||
| expires | | int(11) | NO | | 0 | |
|
||||
| scope | | varchar(250) | NO | | | |
|
||||
Fields
|
||||
------
|
||||
|
||||
| Field | Description | Type | Null | Key | Default | Extra |
|
||||
| ------------ | ----------- | ------------ | ---- | --- | ------- | ----- |
|
||||
| id | | varchar(40) | NO | PRI | NULL | |
|
||||
| client_id | | varchar(20) | NO | | | |
|
||||
| redirect_uri | | varchar(200) | NO | | | |
|
||||
| expires | | int | NO | | 0 | |
|
||||
| scope | | varchar(250) | NO | | | |
|
||||
|
||||
Indexes
|
||||
------------
|
||||
|
||||
| Name | Fields |
|
||||
| --------- | --------- |
|
||||
| PRIMARY | id |
|
||||
| client_id | client_id |
|
||||
|
||||
Foreign Keys
|
||||
------------
|
||||
|
||||
| Field | Target Table | Target Field |
|
||||
|-------|--------------|--------------|
|
||||
| client_id | [clients](help/database/db_clients) | client_id |
|
||||
|
||||
Return to [database documentation](help/database)
|
||||
|
|
|
|||
|
|
@ -3,11 +3,23 @@ Table cache
|
|||
|
||||
Stores temporary data
|
||||
|
||||
| Field | Description | Type | Null | Key | Default | Extra |
|
||||
| ------------ | ---------------------------------- | ------------ | ---- | --- | ------------------- | ----- |
|
||||
| k | cache key | varchar(255) | NO | PRI | NULL | |
|
||||
| v | cached serialized value | text | NO | | NULL | |
|
||||
| expires | datetime of cache expiration | datetime | NO | MUL | 0001-01-01 00:00:00 | |
|
||||
| updated | datetime of cache insertion | datetime | NO | MUL | 0001-01-01 00:00:00 | |
|
||||
Fields
|
||||
------
|
||||
|
||||
| Field | Description | Type | Null | Key | Default | Extra |
|
||||
| ------- | ---------------------------- | -------------- | ---- | --- | ------------------- | ----- |
|
||||
| k | cache key | varbinary(255) | NO | PRI | NULL | |
|
||||
| v | cached serialized value | mediumtext | YES | | NULL | |
|
||||
| expires | datetime of cache expiration | datetime | NO | | 0001-01-01 00:00:00 | |
|
||||
| updated | datetime of cache insertion | datetime | NO | | 0001-01-01 00:00:00 | |
|
||||
|
||||
Indexes
|
||||
------------
|
||||
|
||||
| Name | Fields |
|
||||
| --------- | ---------- |
|
||||
| PRIMARY | k |
|
||||
| k_expires | k, expires |
|
||||
|
||||
|
||||
Return to [database documentation](help/database)
|
||||
|
|
|
|||
|
|
@ -1,13 +1,27 @@
|
|||
Table challenge
|
||||
===============
|
||||
===========
|
||||
|
||||
|
||||
|
||||
Fields
|
||||
------
|
||||
|
||||
| Field | Description | Type | Null | Key | Default | Extra |
|
||||
| ----------- | ------------- | ------------ | ---- | --- | ------- | -------------- |
|
||||
| id | sequential ID | int unsigned | NO | PRI | NULL | auto_increment |
|
||||
| challenge | | varchar(255) | NO | | | |
|
||||
| dfrn-id | | varchar(255) | NO | | | |
|
||||
| expire | | int unsigned | NO | | 0 | |
|
||||
| type | | varchar(255) | NO | | | |
|
||||
| last_update | | varchar(255) | NO | | | |
|
||||
|
||||
Indexes
|
||||
------------
|
||||
|
||||
| Name | Fields |
|
||||
| ------- | ------ |
|
||||
| PRIMARY | id |
|
||||
| expire | expire |
|
||||
|
||||
| Field | Description | Type | Null | Key | Default | Extra |
|
||||
|-------------|------------------|------------------|------|-----|---------|----------------|
|
||||
| id | sequential ID | int(10) unsigned | NO | PRI | NULL | auto_increment |
|
||||
| challenge | | varchar(255) | NO | | | |
|
||||
| dfrn-id | | varchar(255) | NO | | | |
|
||||
| expire | | int(11) | NO | | 0 | |
|
||||
| type | | varchar(255) | NO | | | |
|
||||
| last_update | | varchar(255) | NO | | | |
|
||||
|
||||
Return to [database documentation](help/database)
|
||||
|
|
|
|||
|
|
@ -1,13 +1,33 @@
|
|||
Table clients
|
||||
=============
|
||||
===========
|
||||
|
||||
| Field | Description | Type | Null | Key | Default | Extra |
|
||||
| ------------- | ----------- | ------------ | ---- | --- | ------- | ----- |
|
||||
| client_id | | varchar(20) | NO | PRI | NULL | |
|
||||
| pw | | varchar(20) | NO | | | |
|
||||
| redirect_uri | | varchar(200) | NO | | | |
|
||||
| name | | text | YES | | NULL | |
|
||||
| icon | | text | YES | | NULL | |
|
||||
| uid | | int(11) | NO | | 0 | |
|
||||
OAuth usage
|
||||
|
||||
Fields
|
||||
------
|
||||
|
||||
| Field | Description | Type | Null | Key | Default | Extra |
|
||||
| ------------ | ----------- | ------------------ | ---- | --- | ------- | ----- |
|
||||
| client_id | | varchar(20) | NO | PRI | NULL | |
|
||||
| pw | | varchar(20) | NO | | | |
|
||||
| redirect_uri | | varchar(200) | NO | | | |
|
||||
| name | | text | YES | | NULL | |
|
||||
| icon | | text | YES | | NULL | |
|
||||
| uid | User id | mediumint unsigned | NO | | 0 | |
|
||||
|
||||
Indexes
|
||||
------------
|
||||
|
||||
| Name | Fields |
|
||||
| ------- | --------- |
|
||||
| PRIMARY | client_id |
|
||||
| uid | uid |
|
||||
|
||||
Foreign Keys
|
||||
------------
|
||||
|
||||
| Field | Target Table | Target Field |
|
||||
|-------|--------------|--------------|
|
||||
| uid | [user](help/database/db_user) | uid |
|
||||
|
||||
Return to [database documentation](help/database)
|
||||
|
|
|
|||
|
|
@ -1,11 +1,25 @@
|
|||
Table config
|
||||
============
|
||||
===========
|
||||
|
||||
main configuration storage
|
||||
|
||||
Fields
|
||||
------
|
||||
|
||||
| Field | Description | Type | Null | Key | Default | Extra |
|
||||
| ----- | ----------- | ------------- | ---- | --- | ------- | -------------- |
|
||||
| id | | int unsigned | NO | PRI | NULL | auto_increment |
|
||||
| cat | | varbinary(50) | NO | | | |
|
||||
| k | | varbinary(50) | NO | | | |
|
||||
| v | | mediumtext | YES | | NULL | |
|
||||
|
||||
Indexes
|
||||
------------
|
||||
|
||||
| Name | Fields |
|
||||
| ------- | -------------- |
|
||||
| PRIMARY | id |
|
||||
| cat_k | UNIQUE, cat, k |
|
||||
|
||||
| Field | Description | Type | Null | Key | Default | Extra |
|
||||
| ----- | ----------- | ---------------- | ---- | --- | ------- | --------------- |
|
||||
| id | | int(10) unsigned | NO | PRI | NULL | auto_increment |
|
||||
| cat | | char(255) | NO | MUL | | |
|
||||
| k | | char(255) | NO | | | |
|
||||
| v | | text | NO | | NULL | |
|
||||
|
||||
Return to [database documentation](help/database)
|
||||
|
|
|
|||
33
doc/database/db_contact-relation.md
Normal file
33
doc/database/db_contact-relation.md
Normal file
|
|
@ -0,0 +1,33 @@
|
|||
Table contact-relation
|
||||
===========
|
||||
|
||||
Contact relations
|
||||
|
||||
Fields
|
||||
------
|
||||
|
||||
| Field | Description | Type | Null | Key | Default | Extra |
|
||||
| ---------------- | --------------------------------------------------- | ------------ | ---- | --- | ------------------- | ----- |
|
||||
| cid | contact the related contact had interacted with | int unsigned | NO | PRI | 0 | |
|
||||
| relation-cid | related contact who had interacted with the contact | int unsigned | NO | PRI | 0 | |
|
||||
| last-interaction | Date of the last interaction | datetime | NO | | 0001-01-01 00:00:00 | |
|
||||
| follow-updated | Date of the last update of the contact relationship | datetime | NO | | 0001-01-01 00:00:00 | |
|
||||
| follows | | boolean | NO | | 0 | |
|
||||
|
||||
Indexes
|
||||
------------
|
||||
|
||||
| Name | Fields |
|
||||
| ------------ | ----------------- |
|
||||
| PRIMARY | cid, relation-cid |
|
||||
| relation-cid | relation-cid |
|
||||
|
||||
Foreign Keys
|
||||
------------
|
||||
|
||||
| Field | Target Table | Target Field |
|
||||
|-------|--------------|--------------|
|
||||
| cid | [contact](help/database/db_contact) | id |
|
||||
| relation-cid | [contact](help/database/db_contact) | id |
|
||||
|
||||
Return to [database documentation](help/database)
|
||||
|
|
@ -1,72 +1,130 @@
|
|||
Table contact
|
||||
=============
|
||||
===========
|
||||
|
||||
| Field | Description | Type | Null | Key | Default | Extra |
|
||||
|---------------------------|-----------------------------------------------------------|--------------|------|-----|---------------------|----------------|
|
||||
| id | sequential ID | int(11) | NO | PRI | NULL | auto_increment |
|
||||
| uid | user.id of the owner of this data | int(11) | NO | MUL | 0 | |
|
||||
| created | | datetime | NO | | 0001-01-01 00:00:00 | |
|
||||
| self | 1 if the contact is the user him/her self | tinyint(1) | NO | | 0 | |
|
||||
| remote_self | | tinyint(1) | NO | | 0 | |
|
||||
| rel | The kind of the relation between the user and the contact | tinyint(1) | NO | | 0 | |
|
||||
| duplex | | tinyint(1) | NO | | 0 | |
|
||||
| network | Network protocol of the contact | varchar(255) | NO | | | |
|
||||
| name | Name that this contact is known by | varchar(255) | NO | | | |
|
||||
| nick | Nick- and user name of the contact | varchar(255) | NO | | | |
|
||||
| location | | varchar(255) | NO | | | |
|
||||
| about | | text | NO | | NULL | |
|
||||
| keywords | public keywords (interests) of the contact | text | NO | | NULL | |
|
||||
| gender | | varchar(32) | NO | | | |
|
||||
| attag | | varchar(255) | NO | | | |
|
||||
| photo | Link to the profile photo of the contact | text | NO | | NULL | |
|
||||
| thumb | Link to the profile photo (thumb size) | text | NO | | NULL | |
|
||||
| micro | Link to the profile photo (micro size) | text | NO | | NULL | |
|
||||
| site-pubkey | | text | NO | | NULL | |
|
||||
| issued-id | | varchar(255) | NO | | | |
|
||||
| dfrn-id | | varchar(255) | NO | | | |
|
||||
| url | | varchar(255) | NO | | | |
|
||||
| nurl | | varchar(255) | NO | | | |
|
||||
| addr | | varchar(255) | NO | | | |
|
||||
| alias | | varchar(255) | NO | | | |
|
||||
| pubkey | RSA public key 4096 bit | text | NO | | NULL | |
|
||||
| prvkey | RSA private key 4096 bit | text | NO | | NULL | |
|
||||
| batch | | varchar(255) | NO | | | |
|
||||
| request | | text | NO | | NULL | |
|
||||
| notify | | text | NO | | NULL | |
|
||||
| poll | | text | NO | | NULL | |
|
||||
| confirm | | text | NO | | NULL | |
|
||||
| poco | | text | NO | | NULL | |
|
||||
| aes_allow | | tinyint(1) | NO | | 0 | |
|
||||
| ret-aes | | tinyint(1) | NO | | 0 | |
|
||||
| usehub | | tinyint(1) | NO | | 0 | |
|
||||
| subhub | | tinyint(1) | NO | | 0 | |
|
||||
| hub-verify | | varchar(255) | NO | | | |
|
||||
| last-update | Date of the last try to update the contact info | datetime | NO | | 0001-01-01 00:00:00 | |
|
||||
| success_update | Date of the last successful contact update | datetime | NO | | 0001-01-01 00:00:00 | |
|
||||
| failure_update | Date of the last failed update | datetime | NO | | 0001-01-01 00:00:00 | |
|
||||
| name-date | | datetime | NO | | 0001-01-01 00:00:00 | |
|
||||
| uri-date | | datetime | NO | | 0001-01-01 00:00:00 | |
|
||||
| avatar-date | | datetime | NO | | 0001-01-01 00:00:00 | |
|
||||
| term-date | | datetime | NO | | 0001-01-01 00:00:00 | |
|
||||
| last-item | date of the last post | datetime | NO | | 0001-01-01 00:00:00 | |
|
||||
| priority | | tinyint(3) | NO | | 0 | |
|
||||
| blocked | | tinyint(1) | NO | | 1 | |
|
||||
| readonly | posts of the contact are readonly | tinyint(1) | NO | | 0 | |
|
||||
| writable | | tinyint(1) | NO | | 0 | |
|
||||
| forum | contact is a forum | tinyint(1) | NO | | 0 | |
|
||||
| prv | contact is a private group | tinyint(1) | NO | | 0 | |
|
||||
| hidden | | tinyint(1) | NO | | 0 | |
|
||||
| archive | | tinyint(1) | NO | | 0 | |
|
||||
| pending | | tinyint(1) | NO | | 1 | |
|
||||
| rating | | tinyint(1) | NO | | 0 | |
|
||||
| reason | | text | NO | | NULL | |
|
||||
| closeness | | tinyint(2) | NO | | 99 | |
|
||||
| info | | mediumtext | NO | | NULL | |
|
||||
| profile-id | | int(11) | NO | | 0 | |
|
||||
| bdyear | | varchar(4) | NO | | | |
|
||||
| bd | | date | NO | | 0001-01-01 | |
|
||||
| notify_new_posts | | tinyint(1) | NO | | 0 | |
|
||||
| fetch_further_information | | tinyint(1) | NO | | 0 | |
|
||||
| ffi_keyword_denylist | | mediumtext | NO | | NULL | |
|
||||
contact table
|
||||
|
||||
Fields
|
||||
------
|
||||
|
||||
| Field | Description | Type | Null | Key | Default | Extra |
|
||||
| ------------------------- | --------------------------------------------------------- | ------------------ | ---- | --- | ------------------- | -------------- |
|
||||
| id | sequential ID | int unsigned | NO | PRI | NULL | auto_increment |
|
||||
| uid | Owner User id | mediumint unsigned | NO | | 0 | |
|
||||
| created | | datetime | NO | | 0001-01-01 00:00:00 | |
|
||||
| updated | Date of last contact update | datetime | YES | | 0001-01-01 00:00:00 | |
|
||||
| self | 1 if the contact is the user him/her self | boolean | NO | | 0 | |
|
||||
| remote_self | | boolean | NO | | 0 | |
|
||||
| rel | The kind of the relation between the user and the contact | tinyint unsigned | NO | | 0 | |
|
||||
| duplex | | boolean | NO | | 0 | |
|
||||
| network | Network of the contact | char(4) | NO | | | |
|
||||
| protocol | Protocol of the contact | char(4) | NO | | | |
|
||||
| name | Name that this contact is known by | varchar(255) | NO | | | |
|
||||
| nick | Nick- and user name of the contact | varchar(255) | NO | | | |
|
||||
| location | | varchar(255) | YES | | | |
|
||||
| about | | text | YES | | NULL | |
|
||||
| keywords | public keywords (interests) of the contact | text | YES | | NULL | |
|
||||
| gender | Deprecated | varchar(32) | NO | | | |
|
||||
| xmpp | | varchar(255) | NO | | | |
|
||||
| attag | | varchar(255) | NO | | | |
|
||||
| avatar | | varchar(255) | NO | | | |
|
||||
| photo | Link to the profile photo of the contact | varchar(255) | YES | | | |
|
||||
| thumb | Link to the profile photo (thumb size) | varchar(255) | YES | | | |
|
||||
| micro | Link to the profile photo (micro size) | varchar(255) | YES | | | |
|
||||
| header | Header picture | varchar(255) | YES | | NULL | |
|
||||
| site-pubkey | | text | YES | | NULL | |
|
||||
| issued-id | | varchar(255) | NO | | | |
|
||||
| dfrn-id | | varchar(255) | NO | | | |
|
||||
| url | | varchar(255) | NO | | | |
|
||||
| nurl | | varchar(255) | NO | | | |
|
||||
| addr | | varchar(255) | NO | | | |
|
||||
| alias | | varchar(255) | NO | | | |
|
||||
| pubkey | RSA public key 4096 bit | text | YES | | NULL | |
|
||||
| prvkey | RSA private key 4096 bit | text | YES | | NULL | |
|
||||
| batch | | varchar(255) | NO | | | |
|
||||
| request | | varchar(255) | YES | | NULL | |
|
||||
| notify | | varchar(255) | YES | | NULL | |
|
||||
| poll | | varchar(255) | YES | | NULL | |
|
||||
| confirm | | varchar(255) | YES | | NULL | |
|
||||
| subscribe | | varchar(255) | YES | | NULL | |
|
||||
| poco | | varchar(255) | YES | | NULL | |
|
||||
| aes_allow | | boolean | NO | | 0 | |
|
||||
| ret-aes | | boolean | NO | | 0 | |
|
||||
| usehub | | boolean | NO | | 0 | |
|
||||
| subhub | | boolean | NO | | 0 | |
|
||||
| hub-verify | | varchar(255) | NO | | | |
|
||||
| last-update | Date of the last try to update the contact info | datetime | NO | | 0001-01-01 00:00:00 | |
|
||||
| success_update | Date of the last successful contact update | datetime | NO | | 0001-01-01 00:00:00 | |
|
||||
| failure_update | Date of the last failed update | datetime | NO | | 0001-01-01 00:00:00 | |
|
||||
| failed | Connection failed | boolean | YES | | NULL | |
|
||||
| name-date | | datetime | NO | | 0001-01-01 00:00:00 | |
|
||||
| uri-date | | datetime | NO | | 0001-01-01 00:00:00 | |
|
||||
| avatar-date | | datetime | NO | | 0001-01-01 00:00:00 | |
|
||||
| term-date | | datetime | NO | | 0001-01-01 00:00:00 | |
|
||||
| last-item | date of the last post | datetime | NO | | 0001-01-01 00:00:00 | |
|
||||
| last-discovery | date of the last follower discovery | datetime | NO | | 0001-01-01 00:00:00 | |
|
||||
| priority | | tinyint unsigned | NO | | 0 | |
|
||||
| blocked | Node-wide block status | boolean | NO | | 1 | |
|
||||
| block_reason | Node-wide block reason | text | YES | | NULL | |
|
||||
| readonly | posts of the contact are readonly | boolean | NO | | 0 | |
|
||||
| writable | | boolean | NO | | 0 | |
|
||||
| forum | contact is a forum | boolean | NO | | 0 | |
|
||||
| prv | contact is a private group | boolean | NO | | 0 | |
|
||||
| contact-type | | tinyint | NO | | 0 | |
|
||||
| manually-approve | | boolean | YES | | NULL | |
|
||||
| hidden | | boolean | NO | | 0 | |
|
||||
| archive | | boolean | NO | | 0 | |
|
||||
| pending | | boolean | NO | | 1 | |
|
||||
| deleted | Contact has been deleted | boolean | NO | | 0 | |
|
||||
| rating | | tinyint | NO | | 0 | |
|
||||
| unsearchable | Contact prefers to not be searchable | boolean | NO | | 0 | |
|
||||
| sensitive | Contact posts sensitive content | boolean | NO | | 0 | |
|
||||
| baseurl | baseurl of the contact | varchar(255) | YES | | | |
|
||||
| gsid | Global Server ID | int unsigned | YES | | NULL | |
|
||||
| reason | | text | YES | | NULL | |
|
||||
| closeness | | tinyint unsigned | NO | | 99 | |
|
||||
| info | | mediumtext | YES | | NULL | |
|
||||
| profile-id | Deprecated | int unsigned | YES | | NULL | |
|
||||
| bdyear | | varchar(4) | NO | | | |
|
||||
| bd | | date | NO | | 0001-01-01 | |
|
||||
| notify_new_posts | | boolean | NO | | 0 | |
|
||||
| fetch_further_information | | tinyint unsigned | NO | | 0 | |
|
||||
| ffi_keyword_denylist | | text | YES | | NULL | |
|
||||
|
||||
Indexes
|
||||
------------
|
||||
|
||||
| Name | Fields |
|
||||
| --------------------------- | ------------------------------------ |
|
||||
| PRIMARY | id |
|
||||
| uid_name | uid, name(190) |
|
||||
| self_uid | self, uid |
|
||||
| alias_uid | alias(128), uid |
|
||||
| pending_uid | pending, uid |
|
||||
| blocked_uid | blocked, uid |
|
||||
| uid_rel_network_poll | uid, rel, network, poll(64), archive |
|
||||
| uid_network_batch | uid, network, batch(64) |
|
||||
| batch_contact-type | batch(64), contact-type |
|
||||
| addr_uid | addr(128), uid |
|
||||
| nurl_uid | nurl(128), uid |
|
||||
| nick_uid | nick(128), uid |
|
||||
| attag_uid | attag(96), uid |
|
||||
| dfrn-id | dfrn-id(64) |
|
||||
| issued-id | issued-id(64) |
|
||||
| network_uid_lastupdate | network, uid, last-update |
|
||||
| uid_network_self_lastupdate | uid, network, self, last-update |
|
||||
| uid_lastitem | uid, last-item |
|
||||
| baseurl | baseurl(64) |
|
||||
| uid_contact-type | uid, contact-type |
|
||||
| uid_self_contact-type | uid, self, contact-type |
|
||||
| self_network_uid | self, network, uid |
|
||||
| gsid | gsid |
|
||||
|
||||
Foreign Keys
|
||||
------------
|
||||
|
||||
| Field | Target Table | Target Field |
|
||||
|-------|--------------|--------------|
|
||||
| uid | [user](help/database/db_user) | uid |
|
||||
| gsid | [gserver](help/database/db_gserver) | id |
|
||||
|
||||
Return to [database documentation](help/database)
|
||||
|
|
|
|||
|
|
@ -1,15 +1,35 @@
|
|||
Table conv
|
||||
==========
|
||||
===========
|
||||
|
||||
| Field | Description | Type | Null | Key | Default | Extra |
|
||||
| ------- | ----------------------------------------- | ---------------- | ---- | --- | ------------------- | --------------- |
|
||||
| id | sequential ID | int(10) unsigned | NO | PRI | NULL | auto_increment |
|
||||
| guid | A unique identifier for this conversation | varchar(64) | NO | | | |
|
||||
| recips | sender_handle;recipient_handle | mediumtext | NO | | NULL | |
|
||||
| uid | user_id of the owner of this data | int(11) | NO | MUL | 0 | |
|
||||
| creator | handle of creator | varchar(255) | NO | | | |
|
||||
| created | creation timestamp | datetime | NO | | 0001-01-01 00:00:00 | |
|
||||
| updated | edited timestamp | datetime | NO | | 0001-01-01 00:00:00 | |
|
||||
| subject | subject of initial message | mediumtext | NO | | NULL | |
|
||||
private messages
|
||||
|
||||
Fields
|
||||
------
|
||||
|
||||
| Field | Description | Type | Null | Key | Default | Extra |
|
||||
| ------- | ----------------------------------------- | ------------------ | ---- | --- | ------------------- | -------------- |
|
||||
| id | sequential ID | int unsigned | NO | PRI | NULL | auto_increment |
|
||||
| guid | A unique identifier for this conversation | varchar(255) | NO | | | |
|
||||
| recips | sender_handle;recipient_handle | text | YES | | NULL | |
|
||||
| uid | Owner User id | mediumint unsigned | NO | | 0 | |
|
||||
| creator | handle of creator | varchar(255) | NO | | | |
|
||||
| created | creation timestamp | datetime | NO | | 0001-01-01 00:00:00 | |
|
||||
| updated | edited timestamp | datetime | NO | | 0001-01-01 00:00:00 | |
|
||||
| subject | subject of initial message | text | YES | | NULL | |
|
||||
|
||||
Indexes
|
||||
------------
|
||||
|
||||
| Name | Fields |
|
||||
| ------- | ------ |
|
||||
| PRIMARY | id |
|
||||
| uid | uid |
|
||||
|
||||
Foreign Keys
|
||||
------------
|
||||
|
||||
| Field | Target Table | Target Field |
|
||||
|-------|--------------|--------------|
|
||||
| uid | [user](help/database/db_user) | uid |
|
||||
|
||||
Return to [database documentation](help/database)
|
||||
|
|
|
|||
|
|
@ -1,14 +1,30 @@
|
|||
Table conversation
|
||||
==================
|
||||
===========
|
||||
|
||||
Raw data and structure information for messages
|
||||
|
||||
Fields
|
||||
------
|
||||
|
||||
| Field | Description | Type | Null | Key | Default | Extra |
|
||||
| ----------------- | -------------------------------------------------------------------- | ---------------- | ---- | --- | ------------------- | ----- |
|
||||
| item-uri | Original URI of the item - unrelated to the table with the same name | varbinary(255) | NO | PRI | NULL | |
|
||||
| reply-to-uri | URI to which this item is a reply | varbinary(255) | NO | | | |
|
||||
| conversation-uri | GNU Social conversation URI | varbinary(255) | NO | | | |
|
||||
| conversation-href | GNU Social conversation link | varbinary(255) | NO | | | |
|
||||
| protocol | The protocol of the item | tinyint unsigned | NO | | 255 | |
|
||||
| direction | How the message arrived here: 1=push, 2=pull | tinyint unsigned | NO | | 0 | |
|
||||
| source | Original source | mediumtext | YES | | NULL | |
|
||||
| received | Receiving date | datetime | NO | | 0001-01-01 00:00:00 | |
|
||||
|
||||
Indexes
|
||||
------------
|
||||
|
||||
| Name | Fields |
|
||||
| ---------------- | ---------------- |
|
||||
| PRIMARY | item-uri |
|
||||
| conversation-uri | conversation-uri |
|
||||
| received | received |
|
||||
|
||||
| Field | Description | Type | Null | Key | Default | Extra |
|
||||
|-------------------| ---------------------------------- |---------------------|------|-----|---------------------|----------------|
|
||||
| item-uri | URI of the item | varbinary(255) | NO | PRI | NULL | |
|
||||
| reply-to-uri | URI to which this item is a reply | varbinary(255) | NO | | | |
|
||||
| conversation-uri | GNU Social conversation URI | varbinary(255) | NO | | | |
|
||||
| conversation-href | GNU Social conversation link | varbinary(255) | NO | | | |
|
||||
| protocol | The protocol of the item | tinyint(1) unsigned | NO | | 0 | |
|
||||
| source | Original source | mediumtext | NO | | | |
|
||||
| received | Receiving date | datetime | NO | | 0001-01-01 | |
|
||||
|
||||
Return to [database documentation](help/database)
|
||||
|
|
|
|||
31
doc/database/db_delayed-post.md
Normal file
31
doc/database/db_delayed-post.md
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
Table delayed-post
|
||||
===========
|
||||
|
||||
Posts that are about to be distributed at a later time
|
||||
|
||||
Fields
|
||||
------
|
||||
|
||||
| Field | Description | Type | Null | Key | Default | Extra |
|
||||
| ------- | ---------------------------------------------- | ------------------ | ---- | --- | ------- | -------------- |
|
||||
| id | | int unsigned | NO | PRI | NULL | auto_increment |
|
||||
| uri | URI of the post that will be distributed later | varchar(255) | YES | | NULL | |
|
||||
| uid | Owner User id | mediumint unsigned | YES | | NULL | |
|
||||
| delayed | delay time | datetime | YES | | NULL | |
|
||||
|
||||
Indexes
|
||||
------------
|
||||
|
||||
| Name | Fields |
|
||||
| ------- | --------------------- |
|
||||
| PRIMARY | id |
|
||||
| uid_uri | UNIQUE, uid, uri(190) |
|
||||
|
||||
Foreign Keys
|
||||
------------
|
||||
|
||||
| Field | Target Table | Target Field |
|
||||
|-------|--------------|--------------|
|
||||
| uid | [user](help/database/db_user) | uid |
|
||||
|
||||
Return to [database documentation](help/database)
|
||||
28
doc/database/db_diaspora-interaction.md
Normal file
28
doc/database/db_diaspora-interaction.md
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
Table diaspora-interaction
|
||||
===========
|
||||
|
||||
Signed Diaspora Interaction
|
||||
|
||||
Fields
|
||||
------
|
||||
|
||||
| Field | Description | Type | Null | Key | Default | Extra |
|
||||
| ----------- | --------------------------------------------------------- | ------------ | ---- | --- | ------- | ----- |
|
||||
| uri-id | Id of the item-uri table entry that contains the item uri | int unsigned | NO | PRI | NULL | |
|
||||
| interaction | The Diaspora interaction | mediumtext | YES | | NULL | |
|
||||
|
||||
Indexes
|
||||
------------
|
||||
|
||||
| Name | Fields |
|
||||
| ------- | ------ |
|
||||
| PRIMARY | uri-id |
|
||||
|
||||
Foreign Keys
|
||||
------------
|
||||
|
||||
| Field | Target Table | Target Field |
|
||||
|-------|--------------|--------------|
|
||||
| uri-id | [item-uri](help/database/db_item-uri) | id |
|
||||
|
||||
Return to [database documentation](help/database)
|
||||
|
|
@ -1,26 +1,49 @@
|
|||
Table event
|
||||
===========
|
||||
|
||||
| Field | Description | Type | Null | Key | Default | Extra |
|
||||
| ---------- | ----------------------------------------------- -------| ------------------- | ---- | --- | ------------------- | --------------- |
|
||||
| id | sequential ID | int(11) | NO | PRI | NULL | auto_increment |
|
||||
| uid | user_id of the owner of this data | int(11) | NO | MUL | 0 | |
|
||||
| cid | contact_id (ID of the contact in contact table) | int(11) | NO | | 0 | |
|
||||
| uri | | varchar(255) | NO | | | |
|
||||
| created | creation time | datetime | NO | | 0001-01-01 00:00:00 | |
|
||||
| edited | last edit time | datetime | NO | | 0001-01-01 00:00:00 | |
|
||||
| start | event start time | datetime | NO | | 0001-01-01 00:00:00 | |
|
||||
| finish | event end time | datetime | NO | | 0001-01-01 00:00:00 | |
|
||||
| summary | short description or title of the event | text | NO | | NULL | |
|
||||
| desc | event description | text | NO | | NULL | |
|
||||
| location | event location | text | NO | | NULL | |
|
||||
| type | event or birthday | varchar(255) | NO | | | |
|
||||
| nofinish | if event does have no end this is 1 | tinyint(1) | NO | | 0 | |
|
||||
| adjust | adjust to timezone of the recipient (0 or 1) | tinyint(1) | NO | | 1 | |
|
||||
| ignore | 0 or 1 | tinyint(1) unsigned | NO | | 0 | |
|
||||
| allow_cid | Access Control - list of allowed contact.id '<19><78>' | mediumtext | NO | | NULL | |
|
||||
| allow_gid | Access Control - list of allowed groups | mediumtext | NO | | NULL | |
|
||||
| deny_cid | Access Control - list of denied contact.id | mediumtext | NO | | NULL | |
|
||||
| deny_gid | Access Control - list of denied groups | mediumtext | NO | | NULL | |
|
||||
Events
|
||||
|
||||
Fields
|
||||
------
|
||||
|
||||
| Field | Description | Type | Null | Key | Default | Extra |
|
||||
| --------- | ------------------------------------------------------ | ------------------ | ---- | --- | ------------------- | -------------- |
|
||||
| id | sequential ID | int unsigned | NO | PRI | NULL | auto_increment |
|
||||
| guid | | varchar(255) | NO | | | |
|
||||
| uid | Owner User id | mediumint unsigned | NO | | 0 | |
|
||||
| cid | contact_id (ID of the contact in contact table) | int unsigned | NO | | 0 | |
|
||||
| uri | | varchar(255) | NO | | | |
|
||||
| created | creation time | datetime | NO | | 0001-01-01 00:00:00 | |
|
||||
| edited | last edit time | datetime | NO | | 0001-01-01 00:00:00 | |
|
||||
| start | event start time | datetime | NO | | 0001-01-01 00:00:00 | |
|
||||
| finish | event end time | datetime | NO | | 0001-01-01 00:00:00 | |
|
||||
| summary | short description or title of the event | text | YES | | NULL | |
|
||||
| desc | event description | text | YES | | NULL | |
|
||||
| location | event location | text | YES | | NULL | |
|
||||
| type | event or birthday | varchar(20) | NO | | | |
|
||||
| nofinish | if event does have no end this is 1 | boolean | NO | | 0 | |
|
||||
| adjust | adjust to timezone of the recipient (0 or 1) | boolean | NO | | 1 | |
|
||||
| ignore | 0 or 1 | boolean | NO | | 0 | |
|
||||
| allow_cid | Access Control - list of allowed contact.id '<19><78>' | mediumtext | YES | | NULL | |
|
||||
| allow_gid | Access Control - list of allowed groups | mediumtext | YES | | NULL | |
|
||||
| deny_cid | Access Control - list of denied contact.id | mediumtext | YES | | NULL | |
|
||||
| deny_gid | Access Control - list of denied groups | mediumtext | YES | | NULL | |
|
||||
|
||||
Indexes
|
||||
------------
|
||||
|
||||
| Name | Fields |
|
||||
| --------- | ---------- |
|
||||
| PRIMARY | id |
|
||||
| uid_start | uid, start |
|
||||
| cid | cid |
|
||||
|
||||
Foreign Keys
|
||||
------------
|
||||
|
||||
| Field | Target Table | Target Field |
|
||||
|-------|--------------|--------------|
|
||||
| uid | [user](help/database/db_user) | uid |
|
||||
| cid | [contact](help/database/db_contact) | id |
|
||||
|
||||
Return to [database documentation](help/database)
|
||||
|
|
|
|||
|
|
@ -1,24 +1,39 @@
|
|||
Table fcontact
|
||||
==============
|
||||
===========
|
||||
|
||||
Diaspora compatible contacts - used in the Diaspora implementation
|
||||
|
||||
Fields
|
||||
------
|
||||
|
||||
| Field | Description | Type | Null | Key | Default | Extra |
|
||||
| -------- | ------------- | ---------------- | ---- | --- | ------------------- | -------------- |
|
||||
| id | sequential ID | int unsigned | NO | PRI | NULL | auto_increment |
|
||||
| guid | unique id | varchar(255) | NO | | | |
|
||||
| url | | varchar(255) | NO | | | |
|
||||
| name | | varchar(255) | NO | | | |
|
||||
| photo | | varchar(255) | NO | | | |
|
||||
| request | | varchar(255) | NO | | | |
|
||||
| nick | | varchar(255) | NO | | | |
|
||||
| addr | | varchar(255) | NO | | | |
|
||||
| batch | | varchar(255) | NO | | | |
|
||||
| notify | | varchar(255) | NO | | | |
|
||||
| poll | | varchar(255) | NO | | | |
|
||||
| confirm | | varchar(255) | NO | | | |
|
||||
| priority | | tinyint unsigned | NO | | 0 | |
|
||||
| network | | char(4) | NO | | | |
|
||||
| alias | | varchar(255) | NO | | | |
|
||||
| pubkey | | text | YES | | NULL | |
|
||||
| updated | | datetime | NO | | 0001-01-01 00:00:00 | |
|
||||
|
||||
Indexes
|
||||
------------
|
||||
|
||||
| Name | Fields |
|
||||
| ------- | ---------------- |
|
||||
| PRIMARY | id |
|
||||
| addr | addr(32) |
|
||||
| url | UNIQUE, url(190) |
|
||||
|
||||
| Field | Description | Type | Null | Key | Default | Extra |
|
||||
| -------- | ------------- | ---------------- | ---- | --- | ------------------- | --------------- |
|
||||
| id | sequential ID | int(10) unsigned | NO | PRI | NULL | auto_increment |
|
||||
| guid | unique id | varchar(64) | NO | | | |
|
||||
| url | | varchar(255) | NO | | | |
|
||||
| name | | varchar(255) | NO | | | |
|
||||
| photo | | varchar(255) | NO | | | |
|
||||
| request | | varchar(255) | NO | | | |
|
||||
| nick | | varchar(255) | NO | | | |
|
||||
| addr | | varchar(255) | NO | MUL | | |
|
||||
| batch | | varchar(255) | NO | | | |
|
||||
| notify | | varchar(255) | NO | | | |
|
||||
| poll | | varchar(255) | NO | | | |
|
||||
| confirm | | varchar(255) | NO | | | |
|
||||
| priority | | tinyint(1) | NO | | 0 | |
|
||||
| network | | varchar(32) | NO | | | |
|
||||
| alias | | varchar(255) | NO | | | |
|
||||
| pubkey | | text | NO | | NULL | |
|
||||
| updated | | datetime | NO | | 0001-01-01 00:00:00 | |
|
||||
|
||||
Return to [database documentation](help/database)
|
||||
|
|
|
|||
|
|
@ -1,16 +1,38 @@
|
|||
Table fsuggest
|
||||
==============
|
||||
===========
|
||||
|
||||
| Field | Description | Type | Null | Key | Default | Extra |
|
||||
| ------- | ----------- | ------------ | ---- | --- | ------------------- | --------------- |
|
||||
| id | | int(11) | NO | PRI | NULL | auto_increment |
|
||||
| uid | | int(11) | NO | | 0 | |
|
||||
| cid | | int(11) | NO | | 0 | |
|
||||
| name | | varchar(255) | NO | | | |
|
||||
| url | | varchar(255) | NO | | | |
|
||||
| request | | varchar(255) | NO | | | |
|
||||
| photo | | varchar(255) | NO | | | |
|
||||
| note | | text | NO | | NULL | |
|
||||
| created | | datetime | NO | | 0001-01-01 00:00:00 | |
|
||||
friend suggestion stuff
|
||||
|
||||
Fields
|
||||
------
|
||||
|
||||
| Field | Description | Type | Null | Key | Default | Extra |
|
||||
| ------- | ----------- | ------------------ | ---- | --- | ------------------- | -------------- |
|
||||
| id | | int unsigned | NO | PRI | NULL | auto_increment |
|
||||
| uid | User id | mediumint unsigned | NO | | 0 | |
|
||||
| cid | | int unsigned | NO | | 0 | |
|
||||
| name | | varchar(255) | NO | | | |
|
||||
| url | | varchar(255) | NO | | | |
|
||||
| request | | varchar(255) | NO | | | |
|
||||
| photo | | varchar(255) | NO | | | |
|
||||
| note | | text | YES | | NULL | |
|
||||
| created | | datetime | NO | | 0001-01-01 00:00:00 | |
|
||||
|
||||
Indexes
|
||||
------------
|
||||
|
||||
| Name | Fields |
|
||||
| ------- | ------ |
|
||||
| PRIMARY | id |
|
||||
| cid | cid |
|
||||
| uid | uid |
|
||||
|
||||
Foreign Keys
|
||||
------------
|
||||
|
||||
| Field | Target Table | Target Field |
|
||||
|-------|--------------|--------------|
|
||||
| uid | [user](help/database/db_user) | uid |
|
||||
| cid | [contact](help/database/db_contact) | id |
|
||||
|
||||
Return to [database documentation](help/database)
|
||||
|
|
|
|||
|
|
@ -1,12 +1,32 @@
|
|||
Table group
|
||||
===========
|
||||
|
||||
| Field | Description | Type | Null | Key | Default | Extra |
|
||||
| ------- | ------------------------------------------ | ---------------- | ---- | --- | ------- | --------------- |
|
||||
| id | sequential ID | int(10) unsigned | NO | PRI | NULL | auto_increment |
|
||||
| uid | user.id owning this data | int(10) unsigned | NO | MUL | 0 | |
|
||||
| visible | 1 indicates the member list is not private | tinyint(1) | NO | | 0 | |
|
||||
| deleted | 1 indicates the group has been deleted | tinyint(1) | NO | | 0 | |
|
||||
| name | human readable name of group | varchar(255) | NO | | | |
|
||||
privacy groups, group info
|
||||
|
||||
Fields
|
||||
------
|
||||
|
||||
| Field | Description | Type | Null | Key | Default | Extra |
|
||||
| ------- | ------------------------------------------ | ------------------ | ---- | --- | ------- | -------------- |
|
||||
| id | sequential ID | int unsigned | NO | PRI | NULL | auto_increment |
|
||||
| uid | Owner User id | mediumint unsigned | NO | | 0 | |
|
||||
| visible | 1 indicates the member list is not private | boolean | NO | | 0 | |
|
||||
| deleted | 1 indicates the group has been deleted | boolean | NO | | 0 | |
|
||||
| name | human readable name of group | varchar(255) | NO | | | |
|
||||
|
||||
Indexes
|
||||
------------
|
||||
|
||||
| Name | Fields |
|
||||
| ------- | ------ |
|
||||
| PRIMARY | id |
|
||||
| uid | uid |
|
||||
|
||||
Foreign Keys
|
||||
------------
|
||||
|
||||
| Field | Target Table | Target Field |
|
||||
|-------|--------------|--------------|
|
||||
| uid | [user](help/database/db_user) | uid |
|
||||
|
||||
Return to [database documentation](help/database)
|
||||
|
|
|
|||
|
|
@ -1,11 +1,32 @@
|
|||
Table group_member
|
||||
==================
|
||||
===========
|
||||
|
||||
| Field | Description | Type | Null | Key | Default | Extra |
|
||||
| ---------- | ----------------------------------------------------------- | ---------------- | ---- | --- | ------- | --------------- |
|
||||
| id | sequential ID | int(10) unsigned | NO | PRI | NULL | auto_increment |
|
||||
| uid | user.id of the owner of this data | int(10) unsigned | NO | MUL | 0 | |
|
||||
| gid | groups.id of the associated group | int(10) unsigned | NO | | 0 | |
|
||||
| contact-id | contact.id of the member assigned to the associated group | int(10) unsigned | NO | | 0 | |
|
||||
privacy groups, member info
|
||||
|
||||
Fields
|
||||
------
|
||||
|
||||
| Field | Description | Type | Null | Key | Default | Extra |
|
||||
| ---------- | --------------------------------------------------------- | ------------ | ---- | --- | ------- | -------------- |
|
||||
| id | sequential ID | int unsigned | NO | PRI | NULL | auto_increment |
|
||||
| gid | groups.id of the associated group | int unsigned | NO | | 0 | |
|
||||
| contact-id | contact.id of the member assigned to the associated group | int unsigned | NO | | 0 | |
|
||||
|
||||
Indexes
|
||||
------------
|
||||
|
||||
| Name | Fields |
|
||||
| ------------- | ----------------------- |
|
||||
| PRIMARY | id |
|
||||
| contactid | contact-id |
|
||||
| gid_contactid | UNIQUE, gid, contact-id |
|
||||
|
||||
Foreign Keys
|
||||
------------
|
||||
|
||||
| Field | Target Table | Target Field |
|
||||
|-------|--------------|--------------|
|
||||
| gid | [group](help/database/db_group) | id |
|
||||
| contact-id | [contact](help/database/db_contact) | id |
|
||||
|
||||
Return to [database documentation](help/database)
|
||||
|
|
|
|||
29
doc/database/db_gserver-tag.md
Normal file
29
doc/database/db_gserver-tag.md
Normal file
|
|
@ -0,0 +1,29 @@
|
|||
Table gserver-tag
|
||||
===========
|
||||
|
||||
Tags that the server has subscribed
|
||||
|
||||
Fields
|
||||
------
|
||||
|
||||
| Field | Description | Type | Null | Key | Default | Extra |
|
||||
| ---------- | ---------------------------------- | ------------ | ---- | --- | ------- | ----- |
|
||||
| gserver-id | The id of the gserver | int unsigned | NO | PRI | 0 | |
|
||||
| tag | Tag that the server has subscribed | varchar(100) | NO | PRI | | |
|
||||
|
||||
Indexes
|
||||
------------
|
||||
|
||||
| Name | Fields |
|
||||
| ------- | --------------- |
|
||||
| PRIMARY | gserver-id, tag |
|
||||
| tag | tag |
|
||||
|
||||
Foreign Keys
|
||||
------------
|
||||
|
||||
| Field | Target Table | Target Field |
|
||||
|-------|--------------|--------------|
|
||||
| gserver-id | [gserver](help/database/db_gserver) | id |
|
||||
|
||||
Return to [database documentation](help/database)
|
||||
|
|
@ -1,24 +1,46 @@
|
|||
Table gserver
|
||||
=============
|
||||
===========
|
||||
|
||||
| Field | Description | Type | Null | Key | Default | Extra |
|
||||
|------------------|---------------------------|------------------|------|-----|---------------------|----------------|
|
||||
| id | sequential ID | int(10) unsigned | NO | PRI | NULL | auto_increment |
|
||||
| url | | varchar(255) | NO | | | |
|
||||
| nurl | | varchar(255) | NO | MUL | | |
|
||||
| version | | varchar(255) | NO | | | |
|
||||
| site_name | | varchar(255) | NO | | | |
|
||||
| info | | text | NO | | NULL | |
|
||||
| register_policy | | tinyint(1) | NO | | 0 | |
|
||||
| registered-users |Number of registered users | int(10) | NO | | 0 | |
|
||||
| poco | | varchar(255) | NO | | | |
|
||||
| noscrape | | varchar(255) | NO | | | |
|
||||
| network | | varchar(32) | NO | | | |
|
||||
| platform | | varchar(255) | NO | | | |
|
||||
| created | | datetime | NO | | 0001-01-01 00:00:00 | |
|
||||
| last_poco_query | | datetime | YES | | 0001-01-01 00:00:00 | |
|
||||
| last_contact | | datetime | YES | | 0001-01-01 00:00:00 | |
|
||||
| last_failure | | datetime | YES | | 0001-01-01 00:00:00 | |
|
||||
Global servers
|
||||
|
||||
Fields
|
||||
------
|
||||
|
||||
| Field | Description | Type | Null | Key | Default | Extra |
|
||||
| ---------------- | -------------------------------------------------- | ---------------- | ---- | --- | ------------------- | -------------- |
|
||||
| id | sequential ID | int unsigned | NO | PRI | NULL | auto_increment |
|
||||
| url | | varchar(255) | NO | | | |
|
||||
| nurl | | varchar(255) | NO | | | |
|
||||
| version | | varchar(255) | NO | | | |
|
||||
| site_name | | varchar(255) | NO | | | |
|
||||
| info | | text | YES | | NULL | |
|
||||
| register_policy | | tinyint | NO | | 0 | |
|
||||
| registered-users | Number of registered users | int unsigned | NO | | 0 | |
|
||||
| directory-type | Type of directory service (Poco, Mastodon) | tinyint | YES | | 0 | |
|
||||
| poco | | varchar(255) | NO | | | |
|
||||
| noscrape | | varchar(255) | NO | | | |
|
||||
| network | | char(4) | NO | | | |
|
||||
| protocol | The protocol of the server | tinyint unsigned | YES | | NULL | |
|
||||
| platform | | varchar(255) | NO | | | |
|
||||
| relay-subscribe | Has the server subscribed to the relay system | boolean | NO | | 0 | |
|
||||
| relay-scope | The scope of messages that the server wants to get | varchar(10) | NO | | | |
|
||||
| detection-method | Method that had been used to detect that server | tinyint unsigned | YES | | NULL | |
|
||||
| created | | datetime | NO | | 0001-01-01 00:00:00 | |
|
||||
| last_poco_query | | datetime | YES | | 0001-01-01 00:00:00 | |
|
||||
| last_contact | Last successful connection request | datetime | YES | | 0001-01-01 00:00:00 | |
|
||||
| last_failure | Last failed connection request | datetime | YES | | 0001-01-01 00:00:00 | |
|
||||
| failed | Connection failed | boolean | YES | | NULL | |
|
||||
| next_contact | Next connection request | datetime | YES | | 0001-01-01 00:00:00 | |
|
||||
|
||||
Indexes
|
||||
------------
|
||||
|
||||
| Name | Fields |
|
||||
| ------------ | ----------------- |
|
||||
| PRIMARY | id |
|
||||
| nurl | UNIQUE, nurl(190) |
|
||||
| next_contact | next_contact |
|
||||
| network | network |
|
||||
|
||||
|
||||
Return to [database documentation](help/database)
|
||||
|
|
|
|||
|
|
@ -1,12 +1,27 @@
|
|||
Table hook
|
||||
==========
|
||||
===========
|
||||
|
||||
addon hook registry
|
||||
|
||||
Fields
|
||||
------
|
||||
|
||||
| Field | Description | Type | Null | Key | Default | Extra |
|
||||
| -------- | ---------------------------------------------------------------------------------------------------------- | ----------------- | ---- | --- | ------- | -------------- |
|
||||
| id | sequential ID | int unsigned | NO | PRI | NULL | auto_increment |
|
||||
| hook | name of hook | varbinary(100) | NO | | | |
|
||||
| file | relative filename of hook handler | varbinary(200) | NO | | | |
|
||||
| function | function name of hook handler | varbinary(200) | NO | | | |
|
||||
| priority | not yet implemented - can be used to sort conflicts in hook handling by calling handlers in priority order | smallint unsigned | NO | | 0 | |
|
||||
|
||||
Indexes
|
||||
------------
|
||||
|
||||
| Name | Fields |
|
||||
| ------------------ | ---------------------------- |
|
||||
| PRIMARY | id |
|
||||
| priority | priority |
|
||||
| hook_file_function | UNIQUE, hook, file, function |
|
||||
|
||||
| Field | Description | Type | Null | Key | Default | Extra |
|
||||
| -------- | ---------------------------------------------------------------------------------------------------------- | ---------------- | ---- | --- | ------- | --------------- |
|
||||
| id | sequential ID | int(11) | NO | PRI | NULL | auto_increment |
|
||||
| hook | name of hook | varchar(255) | NO | MUL | | |
|
||||
| file | relative filename of hook handler | varchar(255) | NO | | | |
|
||||
| function | function name of hook handler | varchar(255) | NO | | | |
|
||||
| priority | not yet implemented - can be used to sort conflicts in hook handling by calling handlers in priority order | int(11) unsigned | NO | | 0 | |
|
||||
|
||||
Return to [database documentation](help/database)
|
||||
|
|
|
|||
23
doc/database/db_host.md
Normal file
23
doc/database/db_host.md
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
Table host
|
||||
===========
|
||||
|
||||
Hostname
|
||||
|
||||
Fields
|
||||
------
|
||||
|
||||
| Field | Description | Type | Null | Key | Default | Extra |
|
||||
| ----- | ------------- | ---------------- | ---- | --- | ------- | -------------- |
|
||||
| id | sequential ID | tinyint unsigned | NO | PRI | NULL | auto_increment |
|
||||
| name | The hostname | varchar(128) | NO | | | |
|
||||
|
||||
Indexes
|
||||
------------
|
||||
|
||||
| Name | Fields |
|
||||
| ------- | ------------ |
|
||||
| PRIMARY | id |
|
||||
| name | UNIQUE, name |
|
||||
|
||||
|
||||
Return to [database documentation](help/database)
|
||||
27
doc/database/db_inbox-status.md
Normal file
27
doc/database/db_inbox-status.md
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
Table inbox-status
|
||||
===========
|
||||
|
||||
Status of ActivityPub inboxes
|
||||
|
||||
Fields
|
||||
------
|
||||
|
||||
| Field | Description | Type | Null | Key | Default | Extra |
|
||||
| -------- | ------------------------------------ | -------------- | ---- | --- | ------------------- | ----- |
|
||||
| url | URL of the inbox | varbinary(255) | NO | PRI | NULL | |
|
||||
| created | Creation date of this entry | datetime | NO | | 0001-01-01 00:00:00 | |
|
||||
| success | Date of the last successful delivery | datetime | NO | | 0001-01-01 00:00:00 | |
|
||||
| failure | Date of the last failed delivery | datetime | NO | | 0001-01-01 00:00:00 | |
|
||||
| previous | Previous delivery date | datetime | NO | | 0001-01-01 00:00:00 | |
|
||||
| archive | Is the inbox archived? | boolean | NO | | 0 | |
|
||||
| shared | Is it a shared inbox? | boolean | NO | | 0 | |
|
||||
|
||||
Indexes
|
||||
------------
|
||||
|
||||
| Name | Fields |
|
||||
| ------- | ------ |
|
||||
| PRIMARY | url |
|
||||
|
||||
|
||||
Return to [database documentation](help/database)
|
||||
|
|
@ -1,18 +1,40 @@
|
|||
Table intro
|
||||
===========
|
||||
|
||||
| Field | Description | Type | Null | Key | Default | Extra |
|
||||
|------------|------------------|------------------|------|-----|---------------------|----------------|
|
||||
| id | sequential ID | int(10) unsigned | NO | PRI | NULL | auto_increment |
|
||||
| uid | | int(10) unsigned | NO | | 0 | |
|
||||
| fid | | int(11) | NO | | 0 | |
|
||||
| contact-id | | int(11) | NO | | 0 | |
|
||||
| knowyou | | tinyint(1) | NO | | 0 | |
|
||||
| duplex | | tinyint(1) | NO | | 0 | |
|
||||
| note | | text | NO | | NULL | |
|
||||
| hash | | varchar(255) | NO | | | |
|
||||
| datetime | | datetime | NO | | 0001-01-01 00:00:00 | |
|
||||
| blocked | | tinyint(1) | NO | | 1 | |
|
||||
| ignore | | tinyint(1) | NO | | 0 | |
|
||||
|
||||
|
||||
Fields
|
||||
------
|
||||
|
||||
| Field | Description | Type | Null | Key | Default | Extra |
|
||||
| ---------- | ------------- | ------------------ | ---- | --- | ------------------- | -------------- |
|
||||
| id | sequential ID | int unsigned | NO | PRI | NULL | auto_increment |
|
||||
| uid | User id | mediumint unsigned | NO | | 0 | |
|
||||
| fid | | int unsigned | YES | | NULL | |
|
||||
| contact-id | | int unsigned | NO | | 0 | |
|
||||
| knowyou | | boolean | NO | | 0 | |
|
||||
| duplex | | boolean | NO | | 0 | |
|
||||
| note | | text | YES | | NULL | |
|
||||
| hash | | varchar(255) | NO | | | |
|
||||
| datetime | | datetime | NO | | 0001-01-01 00:00:00 | |
|
||||
| blocked | | boolean | NO | | 1 | |
|
||||
| ignore | | boolean | NO | | 0 | |
|
||||
|
||||
Indexes
|
||||
------------
|
||||
|
||||
| Name | Fields |
|
||||
| ---------- | ---------- |
|
||||
| PRIMARY | id |
|
||||
| contact-id | contact-id |
|
||||
| uid | uid |
|
||||
|
||||
Foreign Keys
|
||||
------------
|
||||
|
||||
| Field | Target Table | Target Field |
|
||||
|-------|--------------|--------------|
|
||||
| uid | [user](help/database/db_user) | uid |
|
||||
| contact-id | [contact](help/database/db_contact) | id |
|
||||
|
||||
Return to [database documentation](help/database)
|
||||
|
|
|
|||
25
doc/database/db_item-uri.md
Normal file
25
doc/database/db_item-uri.md
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
Table item-uri
|
||||
===========
|
||||
|
||||
URI and GUID for items
|
||||
|
||||
Fields
|
||||
------
|
||||
|
||||
| Field | Description | Type | Null | Key | Default | Extra |
|
||||
| ----- | ------------------------------- | -------------- | ---- | --- | ------- | -------------- |
|
||||
| id | | int unsigned | NO | PRI | NULL | auto_increment |
|
||||
| uri | URI of an item | varbinary(255) | NO | | NULL | |
|
||||
| guid | A unique identifier for an item | varbinary(255) | YES | | NULL | |
|
||||
|
||||
Indexes
|
||||
------------
|
||||
|
||||
| Name | Fields |
|
||||
| ------- | ----------- |
|
||||
| PRIMARY | id |
|
||||
| uri | UNIQUE, uri |
|
||||
| guid | guid |
|
||||
|
||||
|
||||
Return to [database documentation](help/database)
|
||||
|
|
@ -1,72 +0,0 @@
|
|||
Table item
|
||||
==========
|
||||
|
||||
| Field | Description | Type | Null | Key | Default | Extra |
|
||||
|---------------|------------------------------------------------------------------------------------------------------------------------------------------------------------|---------------------|------|-----|---------------------|----------------|
|
||||
| id | sequential ID | int(10) unsigned | NO | PRI | NULL | auto_increment |
|
||||
| guid | A unique identifier for this item | varchar(255) | NO | MUL | | |
|
||||
| uri | | varchar(255) | NO | MUL | | |
|
||||
| uid | user.id which owns this copy of the item | int(10) unsigned | NO | MUL | 0 | |
|
||||
| contact-id | contact.id | int(11) | NO | MUL | 0 | |
|
||||
| gcontact-id | ID of the global contact | int(11) | NO | MUL | 0 | |
|
||||
| type | | varchar(255) | NO | | | |
|
||||
| wall | This item was posted to the wall of uid | tinyint(1) | NO | MUL | 0 | |
|
||||
| gravity | | tinyint(1) | NO | | 0 | |
|
||||
| parent | item.id of the parent to this item if it is a reply of some form; otherwise this must be set to the id of this item | int(10) unsigned | NO | MUL | 0 | |
|
||||
| parent-uri | uri of the parent to this item | varchar(255) | NO | MUL | | |
|
||||
| extid | | varchar(255 | NO | MUL | | |
|
||||
| thr-parent | If the parent of this item is not the top-level item in the conversation, the uri of the immediate parent; otherwise set to parent-uri | varchar(255) | NO | | | |
|
||||
| created | Creation timestamp. | datetime | NO | | 0001-01-01 00:00:00 | |
|
||||
| edited | Date of last edit (default is created) | datetime | NO | | 0001-01-01 00:00:00 | |
|
||||
| commented | Date of last comment/reply to this item | datetime | NO | | 0001-01-01 00:00:00 | |
|
||||
| received | datetime | datetime | NO | | 0001-01-01 00:00:00 | |
|
||||
| changed | Date that something in the conversation changed, indicating clients should fetch the conversation again | datetime | NO | | 0001-01-01 00:00:00 | |
|
||||
| owner-name | Name of the owner of this item | varchar(255) | NO | | | |
|
||||
| owner-link | Link to the profile page of the owner of this item | varchar(255) | NO | | | |
|
||||
| owner-avatar | Link to the avatar picture of the owner of this item | varchar(255) | NO | | | |
|
||||
| owner-id | Link to the contact table with uid=0 of the owner of this item | int(11) | NO | MUL | 0 | |
|
||||
| author-name | Name of the author of this item | varchar(255) | NO | | | |
|
||||
| author-link | Link to the profile page of the author of this item | varchar(255) | NO | | | |
|
||||
| author-avatar | Link to the avatar picture of the author of this item | varchar(255) | NO | | | |
|
||||
| author-id | Link to the contact table with uid=0 of the author of this item | int(11) | NO | MUL | 0 | |
|
||||
| title | item title | varchar(255) | NO | | | |
|
||||
| body | item body content | mediumtext | NO | | NULL | |
|
||||
| app | application which generated this item | varchar(255) | NO | | | |
|
||||
| verb | ActivityStreams verb | varchar(255) | NO | | | |
|
||||
| object-type | ActivityStreams object type | varchar(255) | NO | | | |
|
||||
| object | JSON encoded object structure unless it is an implied object (normal post) | text | NO | | NULL | |
|
||||
| target-type | ActivityStreams target type if applicable (URI) | varchar(255) | NO | | | |
|
||||
| target | JSON encoded target structure if used | text | NO | | NULL | |
|
||||
| postopts | External post connectors add their network name to this comma-separated string to identify that they should be delivered to these networks during delivery | text | NO | | NULL | |
|
||||
| plink | permalink or URL toa displayable copy of the message at its source | varchar(255) | NO | | | |
|
||||
| resource-id | Used to link other tables to items, it identifies the linked resource (e.g. photo) and if set must also set resource_type | varchar(255) | NO | MUL | | |
|
||||
| event-id | Used to link to the event.id | int(11) | NO | | 0 | |
|
||||
| tag | | mediumtext | NO | | NULL | |
|
||||
| attach | JSON structure representing attachments to this item | mediumtext | NO | | NULL | |
|
||||
| inform | | mediumtext | NO | | NULL | |
|
||||
| file | | mediumtext | NO | | NULL | |
|
||||
| location | text location where this item originated | varchar(255) | NO | | | |
|
||||
| coord | longitude/latitude pair representing location where this item originated | varchar(255) | NO | | | |
|
||||
| allow_cid | Access Control - list of allowed contact.id '<19><78>' | mediumtext | NO | | NULL | |
|
||||
| allow_gid | Access Control - list of allowed groups | mediumtext | NO | | NULL | |
|
||||
| deny_cid | Access Control - list of denied contact.id | mediumtext | NO | | NULL | |
|
||||
| deny_gid | Access Control - list of denied groups | mediumtext | NO | | NULL | |
|
||||
| private | distribution is restricted | tinyint(1) | NO | | 0 | |
|
||||
| pubmail | | tinyint(1) | NO | | 0 | |
|
||||
| moderated | | tinyint(1) | NO | | 0 | |
|
||||
| visible | | tinyint(1) | NO | | 0 | |
|
||||
| spam | | tinyint(1) | NO | | 0 | |
|
||||
| starred | item has been favourited | tinyint(1) | NO | | 0 | |
|
||||
| bookmark | item has been bookmarked | tinyint(1) | NO | | 0 | |
|
||||
| unseen | item has not been seen | tinyint(1) | NO | | 1 | |
|
||||
| deleted | item has been deleted | tinyint(1) | NO | MUL | 0 | |
|
||||
| origin | item originated at this site | tinyint(1) | NO | | 0 | |
|
||||
| forum_mode | | tinyint(1) | NO | | 0 | |
|
||||
| last-child | | tinyint(1) unsigned | NO | | 1 | |
|
||||
| mention | The owner of this item was mentioned in it | tinyint(1) | NO | | 0 | |
|
||||
| network | Network from where the item comes from | varchar(32) | NO | | | |
|
||||
| rendered-hash | | varchar(32) | NO | | | |
|
||||
| rendered-html | item.body converted to html | mediumtext | NO | | NULL | |
|
||||
| global | | tinyint(1) | NO | | 0 | |
|
||||
|
||||
Return to [database documentation](help/database)
|
||||
|
|
@ -1,11 +1,26 @@
|
|||
Table locks
|
||||
===========
|
||||
|
||||
| Field | Description | Type | Null | Key | Default | Extra |
|
||||
|---------|------------------|------------------|------|-----|---------------------|----------------|
|
||||
| id | sequential ID | int(11) | NO | PRI | NULL | auto_increment |
|
||||
| name | | varchar(128) | NO | | | |
|
||||
| locked | | tinyint(1) | NO | | 0 | |
|
||||
| pid | Process ID | int(10) unsigned | NO | | 0 | |
|
||||
|
||||
|
||||
Fields
|
||||
------
|
||||
|
||||
| Field | Description | Type | Null | Key | Default | Extra |
|
||||
| ------- | ---------------------------- | ------------ | ---- | --- | ------------------- | -------------- |
|
||||
| id | sequential ID | int unsigned | NO | PRI | NULL | auto_increment |
|
||||
| name | | varchar(128) | NO | | | |
|
||||
| locked | | boolean | NO | | 0 | |
|
||||
| pid | Process ID | int unsigned | NO | | 0 | |
|
||||
| expires | datetime of cache expiration | datetime | NO | | 0001-01-01 00:00:00 | |
|
||||
|
||||
Indexes
|
||||
------------
|
||||
|
||||
| Name | Fields |
|
||||
| ------------ | ------------- |
|
||||
| PRIMARY | id |
|
||||
| name_expires | name, expires |
|
||||
|
||||
|
||||
Return to [database documentation](help/database)
|
||||
|
|
|
|||
|
|
@ -1,24 +1,61 @@
|
|||
Table mail
|
||||
==========
|
||||
===========
|
||||
|
||||
| Field | Description | Type | Null | Key | Default | Extra |
|
||||
| ---------- | -------------------------------------------- | ---------------- | ---- | --- | ------------------- | --------------- |
|
||||
| id | sequential ID | int(10) unsigned | NO | PRI | NULL | auto_increment |
|
||||
| uid | user.id of the owner of this data | int(10) unsigned | NO | MUL | 0 | |
|
||||
| guid | A unique identifier for this private message | int(10) unsigned | NO | MUL | | |
|
||||
| from-name | name of the sender | varchar(255) | NO | | | |
|
||||
| from-photo | contact photo link of the sender | varchar(255) | NO | | | |
|
||||
| from-url | profile linke of the sender | varchar(255) | NO | | | |
|
||||
| contact-id | contact.id | varchar(255) | NO | | | |
|
||||
| convid | conv.id | int(11) unsigned | NO | MUL | 0 | |
|
||||
| title | | varchar(255) | NO | | | |
|
||||
| body | | mediumtext | NO | | NULL | |
|
||||
| seen | if message visited it is 1 | varchar(255) | NO | | 0 | |
|
||||
| reply | | varchar(255) | NO | MUL | 0 | |
|
||||
| replied | | varchar(255) | NO | | 0 | |
|
||||
| unknown | if sender not in the contact table this is 1 | varchar(255) | NO | | 0 | |
|
||||
| uri | | varchar(255) | NO | MUL | | |
|
||||
| parent-uri | | varchar(255) | NO | MUL | | |
|
||||
| created | creation time of the private message | datetime | NO | | 0001-01-01 00:00:00 | |
|
||||
private messages
|
||||
|
||||
Fields
|
||||
------
|
||||
|
||||
| Field | Description | Type | Null | Key | Default | Extra |
|
||||
| ------------- | -------------------------------------------------------------- | ------------------ | ---- | --- | ------------------- | -------------- |
|
||||
| id | sequential ID | int unsigned | NO | PRI | NULL | auto_increment |
|
||||
| uid | Owner User id | mediumint unsigned | NO | | 0 | |
|
||||
| guid | A unique identifier for this private message | varchar(255) | NO | | | |
|
||||
| from-name | name of the sender | varchar(255) | NO | | | |
|
||||
| from-photo | contact photo link of the sender | varchar(255) | NO | | | |
|
||||
| from-url | profile linke of the sender | varchar(255) | NO | | | |
|
||||
| contact-id | contact.id | varchar(255) | YES | | NULL | |
|
||||
| author-id | Link to the contact table with uid=0 of the author of the mail | int unsigned | YES | | NULL | |
|
||||
| convid | conv.id | int unsigned | YES | | NULL | |
|
||||
| title | | varchar(255) | NO | | | |
|
||||
| body | | mediumtext | YES | | NULL | |
|
||||
| seen | if message visited it is 1 | boolean | NO | | 0 | |
|
||||
| reply | | boolean | NO | | 0 | |
|
||||
| replied | | boolean | NO | | 0 | |
|
||||
| unknown | if sender not in the contact table this is 1 | boolean | NO | | 0 | |
|
||||
| uri | | varchar(255) | NO | | | |
|
||||
| uri-id | Item-uri id of the related mail | int unsigned | YES | | NULL | |
|
||||
| parent-uri | | varchar(255) | NO | | | |
|
||||
| parent-uri-id | Item-uri id of the parent of the related mail | int unsigned | YES | | NULL | |
|
||||
| thr-parent | | varchar(255) | YES | | NULL | |
|
||||
| thr-parent-id | Id of the item-uri table that contains the thread parent uri | int unsigned | YES | | NULL | |
|
||||
| created | creation time of the private message | datetime | NO | | 0001-01-01 00:00:00 | |
|
||||
|
||||
Indexes
|
||||
------------
|
||||
|
||||
| Name | Fields |
|
||||
| ------------- | -------------- |
|
||||
| PRIMARY | id |
|
||||
| uid_seen | uid, seen |
|
||||
| convid | convid |
|
||||
| uri | uri(64) |
|
||||
| parent-uri | parent-uri(64) |
|
||||
| contactid | contact-id(32) |
|
||||
| author-id | author-id |
|
||||
| uri-id | uri-id |
|
||||
| parent-uri-id | parent-uri-id |
|
||||
| thr-parent-id | thr-parent-id |
|
||||
|
||||
Foreign Keys
|
||||
------------
|
||||
|
||||
| Field | Target Table | Target Field |
|
||||
|-------|--------------|--------------|
|
||||
| uid | [user](help/database/db_user) | uid |
|
||||
| author-id | [contact](help/database/db_contact) | id |
|
||||
| uri-id | [item-uri](help/database/db_item-uri) | id |
|
||||
| parent-uri-id | [item-uri](help/database/db_item-uri) | id |
|
||||
| thr-parent-id | [item-uri](help/database/db_item-uri) | id |
|
||||
|
||||
Return to [database documentation](help/database)
|
||||
|
|
|
|||
|
|
@ -1,20 +1,40 @@
|
|||
Table mailacct
|
||||
==============
|
||||
===========
|
||||
|
||||
| Field | Description | Type | Null | Key | Default | Extra |
|
||||
|--------------|------------------|--------------|------|-----|---------------------|----------------|
|
||||
| id | sequential ID | int(11) | NO | PRI | NULL | auto_increment |
|
||||
| uid | | int(11) | NO | | 0 | |
|
||||
| server | | varchar(255) | NO | | | |
|
||||
| port | | int(11) | NO | | 0 | |
|
||||
| ssltype | | varchar(16) | NO | | | |
|
||||
| mailbox | | varchar(255) | NO | | | |
|
||||
| user | | varchar(255) | NO | | | |
|
||||
| pass | | text | NO | | NULL | |
|
||||
| reply_to | | varchar(255) | NO | | | |
|
||||
| action | | int(11) | NO | | 0 | |
|
||||
| movetofolder | | varchar(255) | NO | | | |
|
||||
| pubmail | | tinyint(1) | NO | | 0 | |
|
||||
| last_check | | datetime | NO | | 0001-01-01 00:00:00 | |
|
||||
Mail account data for fetching mails
|
||||
|
||||
Fields
|
||||
------
|
||||
|
||||
| Field | Description | Type | Null | Key | Default | Extra |
|
||||
| ------------ | ------------- | ------------------ | ---- | --- | ------------------- | -------------- |
|
||||
| id | sequential ID | int unsigned | NO | PRI | NULL | auto_increment |
|
||||
| uid | User id | mediumint unsigned | NO | | 0 | |
|
||||
| server | | varchar(255) | NO | | | |
|
||||
| port | | smallint unsigned | NO | | 0 | |
|
||||
| ssltype | | varchar(16) | NO | | | |
|
||||
| mailbox | | varchar(255) | NO | | | |
|
||||
| user | | varchar(255) | NO | | | |
|
||||
| pass | | text | YES | | NULL | |
|
||||
| reply_to | | varchar(255) | NO | | | |
|
||||
| action | | tinyint unsigned | NO | | 0 | |
|
||||
| movetofolder | | varchar(255) | NO | | | |
|
||||
| pubmail | | boolean | NO | | 0 | |
|
||||
| last_check | | datetime | NO | | 0001-01-01 00:00:00 | |
|
||||
|
||||
Indexes
|
||||
------------
|
||||
|
||||
| Name | Fields |
|
||||
| ------- | ------ |
|
||||
| PRIMARY | id |
|
||||
| uid | uid |
|
||||
|
||||
Foreign Keys
|
||||
------------
|
||||
|
||||
| Field | Target Table | Target Field |
|
||||
|-------|--------------|--------------|
|
||||
| uid | [user](help/database/db_user) | uid |
|
||||
|
||||
Return to [database documentation](help/database)
|
||||
|
|
|
|||
|
|
@ -1,10 +1,32 @@
|
|||
Table manage
|
||||
============
|
||||
===========
|
||||
|
||||
| Field | Description | Type | Null | Key | Default | Extra |
|
||||
| ----- | ------------- | ------- | ---- | --- | ------- | --------------- |
|
||||
| id | sequential ID | int(11) | NO | PRI | NULL | auto_increment |
|
||||
| uid | user.id | int(11) | NO | MUL | 0 | |
|
||||
| mid | | int(11) | NO | | 0 | |
|
||||
table of accounts that can manage each other
|
||||
|
||||
Fields
|
||||
------
|
||||
|
||||
| Field | Description | Type | Null | Key | Default | Extra |
|
||||
| ----- | ------------- | ------------------ | ---- | --- | ------- | -------------- |
|
||||
| id | sequential ID | int unsigned | NO | PRI | NULL | auto_increment |
|
||||
| uid | User id | mediumint unsigned | NO | | 0 | |
|
||||
| mid | User id | mediumint unsigned | NO | | 0 | |
|
||||
|
||||
Indexes
|
||||
------------
|
||||
|
||||
| Name | Fields |
|
||||
| ------- | ---------------- |
|
||||
| PRIMARY | id |
|
||||
| uid_mid | UNIQUE, uid, mid |
|
||||
| mid | mid |
|
||||
|
||||
Foreign Keys
|
||||
------------
|
||||
|
||||
| Field | Target Table | Target Field |
|
||||
|-------|--------------|--------------|
|
||||
| uid | [user](help/database/db_user) | uid |
|
||||
| mid | [user](help/database/db_user) | uid |
|
||||
|
||||
Return to [database documentation](help/database)
|
||||
|
|
|
|||
45
doc/database/db_notification.md
Normal file
45
doc/database/db_notification.md
Normal file
|
|
@ -0,0 +1,45 @@
|
|||
Table notification
|
||||
===========
|
||||
|
||||
notifications
|
||||
|
||||
Fields
|
||||
------
|
||||
|
||||
| Field | Description | Type | Null | Key | Default | Extra |
|
||||
| ------------- | ------------------------------------------------------------------------------ | ------------------ | ---- | --- | ------- | -------------- |
|
||||
| id | sequential ID | int unsigned | NO | PRI | NULL | auto_increment |
|
||||
| uid | Owner User id | mediumint unsigned | YES | | NULL | |
|
||||
| vid | Id of the verb table entry that contains the activity verbs | smallint unsigned | YES | | NULL | |
|
||||
| type | | tinyint unsigned | YES | | NULL | |
|
||||
| actor-id | Link to the contact table with uid=0 of the actor that caused the notification | int unsigned | YES | | NULL | |
|
||||
| target-uri-id | Item-uri id of the related post | int unsigned | YES | | NULL | |
|
||||
| parent-uri-id | Item-uri id of the parent of the related post | int unsigned | YES | | NULL | |
|
||||
| created | | datetime | YES | | NULL | |
|
||||
| seen | | boolean | YES | | 0 | |
|
||||
|
||||
Indexes
|
||||
------------
|
||||
|
||||
| Name | Fields |
|
||||
| ----------------------------------- | ----------------------------------------------- |
|
||||
| PRIMARY | id |
|
||||
| uid_vid_type_actor-id_target-uri-id | UNIQUE, uid, vid, type, actor-id, target-uri-id |
|
||||
| vid | vid |
|
||||
| actor-id | actor-id |
|
||||
| target-uri-id | target-uri-id |
|
||||
| parent-uri-id | parent-uri-id |
|
||||
| seen_uid | seen, uid |
|
||||
|
||||
Foreign Keys
|
||||
------------
|
||||
|
||||
| Field | Target Table | Target Field |
|
||||
|-------|--------------|--------------|
|
||||
| uid | [user](help/database/db_user) | uid |
|
||||
| vid | [verb](help/database/db_verb) | id |
|
||||
| actor-id | [contact](help/database/db_contact) | id |
|
||||
| target-uri-id | [item-uri](help/database/db_item-uri) | id |
|
||||
| parent-uri-id | [item-uri](help/database/db_item-uri) | id |
|
||||
|
||||
Return to [database documentation](help/database)
|
||||
|
|
@ -1,12 +1,37 @@
|
|||
Table notify-threads
|
||||
====================
|
||||
===========
|
||||
|
||||
| Field | Description | Type | Null | Key | Default | Extra |
|
||||
|--------------------|------------------|------------------|------|-----|---------|----------------|
|
||||
| id | sequential ID | int(11) | NO | PRI | NULL | auto_increment |
|
||||
| notify-id | | int(11) | NO | | 0 | |
|
||||
| master-parent-item | | int(10) unsigned | NO | MUL | 0 | |
|
||||
| parent-item | | int(10) unsigned | NO | | 0 | |
|
||||
| receiver-uid | | int(11) | NO | MUL | 0 | |
|
||||
|
||||
|
||||
Fields
|
||||
------
|
||||
|
||||
| Field | Description | Type | Null | Key | Default | Extra |
|
||||
| -------------------- | --------------------------------------------- | ------------------ | ---- | --- | ------- | -------------- |
|
||||
| id | sequential ID | int unsigned | NO | PRI | NULL | auto_increment |
|
||||
| notify-id | | int unsigned | NO | | 0 | |
|
||||
| master-parent-item | Deprecated | int unsigned | YES | | NULL | |
|
||||
| master-parent-uri-id | Item-uri id of the parent of the related post | int unsigned | YES | | NULL | |
|
||||
| parent-item | | int unsigned | NO | | 0 | |
|
||||
| receiver-uid | User id | mediumint unsigned | NO | | 0 | |
|
||||
|
||||
Indexes
|
||||
------------
|
||||
|
||||
| Name | Fields |
|
||||
| -------------------- | -------------------- |
|
||||
| PRIMARY | id |
|
||||
| master-parent-uri-id | master-parent-uri-id |
|
||||
| receiver-uid | receiver-uid |
|
||||
| notify-id | notify-id |
|
||||
|
||||
Foreign Keys
|
||||
------------
|
||||
|
||||
| Field | Target Table | Target Field |
|
||||
|-------|--------------|--------------|
|
||||
| notify-id | [notify](help/database/db_notify) | id |
|
||||
| master-parent-uri-id | [item-uri](help/database/db_item-uri) | id |
|
||||
| receiver-uid | [user](help/database/db_user) | uid |
|
||||
|
||||
Return to [database documentation](help/database)
|
||||
|
|
|
|||
|
|
@ -1,24 +1,51 @@
|
|||
Table notify
|
||||
============
|
||||
===========
|
||||
|
||||
| Field | Description | Type | Null | Key | Default | Extra |
|
||||
| ---------- | --------------------------------- | ------------ | ---- | --- | ------------------- | --------------- |
|
||||
| id | sequential ID | int(11) | NO | PRI | NULL | auto_increment |
|
||||
| hash | | varchar(64) | NO | | | |
|
||||
| type | | int(11) | NO | | 0 | |
|
||||
| name | | varchar(255) | NO | | | |
|
||||
| url | | varchar(255) | NO | | | |
|
||||
| photo | | varchar(255) | NO | | | |
|
||||
| date | | datetime | NO | | 0001-01-01 00:00:00 | |
|
||||
| msg | | mediumtext | YES | | NULL | |
|
||||
| uid | user.id of the owner of this data | int(11) | NO | MUL | 0 | |
|
||||
| link | | varchar(255) | NO | | | |
|
||||
| iid | item.id | int(11) | NO | | 0 | |
|
||||
| parent | | int(11) | NO | | 0 | |
|
||||
| seen | | tinyint(1) | NO | | 0 | |
|
||||
| verb | | varchar(255) | NO | | | |
|
||||
| otype | | varchar(16) | NO | | | |
|
||||
| name_cache | Cached bbcode parsing of name | tinytext | YES | | NULL | |
|
||||
| msg_cache | Cached bbcode parsing of msg | mediumtext | YES | | NULL | |
|
||||
notifications
|
||||
|
||||
Fields
|
||||
------
|
||||
|
||||
| Field | Description | Type | Null | Key | Default | Extra |
|
||||
| ------------- | --------------------------------------------- | ------------------ | ---- | --- | ------------------- | -------------- |
|
||||
| id | sequential ID | int unsigned | NO | PRI | NULL | auto_increment |
|
||||
| type | | smallint unsigned | NO | | 0 | |
|
||||
| name | | varchar(255) | NO | | | |
|
||||
| url | | varchar(255) | NO | | | |
|
||||
| photo | | varchar(255) | NO | | | |
|
||||
| date | | datetime | NO | | 0001-01-01 00:00:00 | |
|
||||
| msg | | mediumtext | YES | | NULL | |
|
||||
| uid | Owner User id | mediumint unsigned | NO | | 0 | |
|
||||
| link | | varchar(255) | NO | | | |
|
||||
| iid | | int unsigned | YES | | NULL | |
|
||||
| parent | | int unsigned | YES | | NULL | |
|
||||
| uri-id | Item-uri id of the related post | int unsigned | YES | | NULL | |
|
||||
| parent-uri-id | Item-uri id of the parent of the related post | int unsigned | YES | | NULL | |
|
||||
| seen | | boolean | NO | | 0 | |
|
||||
| verb | | varchar(100) | NO | | | |
|
||||
| otype | | varchar(10) | NO | | | |
|
||||
| name_cache | Cached bbcode parsing of name | tinytext | YES | | NULL | |
|
||||
| msg_cache | Cached bbcode parsing of msg | mediumtext | YES | | NULL | |
|
||||
|
||||
Indexes
|
||||
------------
|
||||
|
||||
| Name | Fields |
|
||||
| ------------- | -------------------- |
|
||||
| PRIMARY | id |
|
||||
| seen_uid_date | seen, uid, date |
|
||||
| uid_date | uid, date |
|
||||
| uid_type_link | uid, type, link(190) |
|
||||
| uri-id | uri-id |
|
||||
| parent-uri-id | parent-uri-id |
|
||||
|
||||
Foreign Keys
|
||||
------------
|
||||
|
||||
| Field | Target Table | Target Field |
|
||||
|-------|--------------|--------------|
|
||||
| uid | [user](help/database/db_user) | uid |
|
||||
| uri-id | [item-uri](help/database/db_item-uri) | id |
|
||||
| parent-uri-id | [item-uri](help/database/db_item-uri) | id |
|
||||
|
||||
Return to [database documentation](help/database)
|
||||
|
|
|
|||
|
|
@ -1,11 +1,25 @@
|
|||
Table oembed
|
||||
============
|
||||
===========
|
||||
|
||||
cache for OEmbed queries
|
||||
|
||||
Fields
|
||||
------
|
||||
|
||||
| Field | Description | Type | Null | Key | Default | Extra |
|
||||
| -------- | ------------------------------ | ------------------ | ---- | --- | ------------------- | ----- |
|
||||
| url | page url | varbinary(255) | NO | PRI | NULL | |
|
||||
| maxwidth | Maximum width passed to Oembed | mediumint unsigned | NO | PRI | NULL | |
|
||||
| content | OEmbed data of the page | mediumtext | YES | | NULL | |
|
||||
| created | datetime of creation | datetime | NO | | 0001-01-01 00:00:00 | |
|
||||
|
||||
Indexes
|
||||
------------
|
||||
|
||||
| Name | Fields |
|
||||
| ------- | ------------- |
|
||||
| PRIMARY | url, maxwidth |
|
||||
| created | created |
|
||||
|
||||
| Field | Description | Type | Null | Key | Default | Extra |
|
||||
| ------------ | ---------------------------------- | ------------ | ---- | --- | ------------------- | ----- |
|
||||
| url | page url | varchar(255) | NO | PRI | NULL | |
|
||||
| maxwidth | Maximum width passed to Oembed | int(11) | NO | PRI | 0 | |
|
||||
| content | OEmbed data of the page | text | NO | | NULL | |
|
||||
| created | datetime of creation | datetime | NO | MUL | 0001-01-01 00:00:00 | |
|
||||
|
||||
Return to [database documentation](help/database)
|
||||
|
|
|
|||
33
doc/database/db_openwebauth-token.md
Normal file
33
doc/database/db_openwebauth-token.md
Normal file
|
|
@ -0,0 +1,33 @@
|
|||
Table openwebauth-token
|
||||
===========
|
||||
|
||||
Store OpenWebAuth token to verify contacts
|
||||
|
||||
Fields
|
||||
------
|
||||
|
||||
| Field | Description | Type | Null | Key | Default | Extra |
|
||||
| ------- | -------------------------- | ------------------ | ---- | --- | ------------------- | -------------- |
|
||||
| id | sequential ID | int unsigned | NO | PRI | NULL | auto_increment |
|
||||
| uid | User id - currently unused | mediumint unsigned | NO | | 0 | |
|
||||
| type | Verify type | varchar(32) | NO | | | |
|
||||
| token | A generated token | varchar(255) | NO | | | |
|
||||
| meta | | varchar(255) | NO | | | |
|
||||
| created | datetime of creation | datetime | NO | | 0001-01-01 00:00:00 | |
|
||||
|
||||
Indexes
|
||||
------------
|
||||
|
||||
| Name | Fields |
|
||||
| ------- | ------ |
|
||||
| PRIMARY | id |
|
||||
| uid | uid |
|
||||
|
||||
Foreign Keys
|
||||
------------
|
||||
|
||||
| Field | Target Table | Target Field |
|
||||
|-------|--------------|--------------|
|
||||
| uid | [user](help/database/db_user) | uid |
|
||||
|
||||
Return to [database documentation](help/database)
|
||||
|
|
@ -1,12 +1,29 @@
|
|||
Table parsed_url
|
||||
================
|
||||
===========
|
||||
|
||||
cache for 'parse_url' queries
|
||||
|
||||
Fields
|
||||
------
|
||||
|
||||
| Field | Description | Type | Null | Key | Default | Extra |
|
||||
| -------- | --------------------------------- | ---------- | ---- | --- | ------------------- | ----- |
|
||||
| url_hash | page url hash | binary(64) | NO | PRI | NULL | |
|
||||
| guessing | is the 'guessing' mode active? | boolean | NO | PRI | 0 | |
|
||||
| oembed | is the data the result of oembed? | boolean | NO | PRI | 0 | |
|
||||
| url | page url | text | NO | | NULL | |
|
||||
| content | page data | mediumtext | YES | | NULL | |
|
||||
| created | datetime of creation | datetime | NO | | 0001-01-01 00:00:00 | |
|
||||
| expires | datetime of expiration | datetime | NO | | 0001-01-01 00:00:00 | |
|
||||
|
||||
Indexes
|
||||
------------
|
||||
|
||||
| Name | Fields |
|
||||
| ------- | -------------------------- |
|
||||
| PRIMARY | url_hash, guessing, oembed |
|
||||
| created | created |
|
||||
| expires | expires |
|
||||
|
||||
| Field | Description | Type | Null | Key | Default | Extra |
|
||||
| ------------ | ---------------------------------- | ------------ | ---- | --- | ------------------- | ----- |
|
||||
| url | page url | varchar(255) | NO | PRI | NULL | |
|
||||
| guessing | is the "guessing" mode active? | tinyint(1) | NO | PRI | 0 | |
|
||||
| oembed | is the data the result of oembed? | tinyint(1) | NO | PRI | 0 | |
|
||||
| content | page data | text | NO | | NULL | |
|
||||
| created | datetime of creation | datetime | NO | MUL | 0001-01-01 00:00:00 | |
|
||||
|
||||
Return to [database documentation](help/database)
|
||||
|
|
|
|||
|
|
@ -1,12 +1,32 @@
|
|||
Table pconfic
|
||||
=============
|
||||
Table pconfig
|
||||
===========
|
||||
|
||||
| Field | Description | Type | Null | Key | Default | Extra |
|
||||
|-------|-------------|------------|------|-----|---------|----------------|
|
||||
| id | | int(11) | NO | PRI | NULL | auto_increment |
|
||||
| uid | | int(11) | NO | MUL | 0 | |
|
||||
| cat | | char(255) | NO | | | |
|
||||
| k | | char(255) | NO | | | |
|
||||
| v | | mediumtext | NO | | NULL | |
|
||||
personal (per user) configuration storage
|
||||
|
||||
Fields
|
||||
------
|
||||
|
||||
| Field | Description | Type | Null | Key | Default | Extra |
|
||||
| ----- | ----------- | ------------------ | ---- | --- | ------- | -------------- |
|
||||
| id | Primary key | int unsigned | NO | PRI | NULL | auto_increment |
|
||||
| uid | User id | mediumint unsigned | NO | | 0 | |
|
||||
| cat | Category | varchar(50) | NO | | | |
|
||||
| k | Key | varchar(100) | NO | | | |
|
||||
| v | Value | mediumtext | YES | | NULL | |
|
||||
|
||||
Indexes
|
||||
------------
|
||||
|
||||
| Name | Fields |
|
||||
| --------- | ------------------- |
|
||||
| PRIMARY | id |
|
||||
| uid_cat_k | UNIQUE, uid, cat, k |
|
||||
|
||||
Foreign Keys
|
||||
------------
|
||||
|
||||
| Field | Target Table | Target Field |
|
||||
|-------|--------------|--------------|
|
||||
| uid | [user](help/database/db_user) | uid |
|
||||
|
||||
Return to [database documentation](help/database)
|
||||
|
|
|
|||
33
doc/database/db_permissionset.md
Normal file
33
doc/database/db_permissionset.md
Normal file
|
|
@ -0,0 +1,33 @@
|
|||
Table permissionset
|
||||
===========
|
||||
|
||||
|
||||
|
||||
Fields
|
||||
------
|
||||
|
||||
| Field | Description | Type | Null | Key | Default | Extra |
|
||||
| --------- | ------------------------------------------------------ | ------------------ | ---- | --- | ------- | -------------- |
|
||||
| id | sequential ID | int unsigned | NO | PRI | NULL | auto_increment |
|
||||
| uid | Owner id of this permission set | mediumint unsigned | NO | | 0 | |
|
||||
| allow_cid | Access Control - list of allowed contact.id '<19><78>' | mediumtext | YES | | NULL | |
|
||||
| allow_gid | Access Control - list of allowed groups | mediumtext | YES | | NULL | |
|
||||
| deny_cid | Access Control - list of denied contact.id | mediumtext | YES | | NULL | |
|
||||
| deny_gid | Access Control - list of denied groups | mediumtext | YES | | NULL | |
|
||||
|
||||
Indexes
|
||||
------------
|
||||
|
||||
| Name | Fields |
|
||||
| ----------------------------------------- | ------------------------------------------------------------- |
|
||||
| PRIMARY | id |
|
||||
| uid_allow_cid_allow_gid_deny_cid_deny_gid | uid, allow_cid(50), allow_gid(30), deny_cid(50), deny_gid(30) |
|
||||
|
||||
Foreign Keys
|
||||
------------
|
||||
|
||||
| Field | Target Table | Target Field |
|
||||
|-------|--------------|--------------|
|
||||
| uid | [user](help/database/db_user) | uid |
|
||||
|
||||
Return to [database documentation](help/database)
|
||||
|
|
@ -1,29 +1,60 @@
|
|||
Table photo
|
||||
===========
|
||||
|
||||
| Field | Description | Type | Null | Key | Default | Extra |
|
||||
| ----------- | ------------------------------------------------------ | ---------------- | ---- | --- | ------------------- | --------------- |
|
||||
| id | sequential ID | int(10) unsigned | NO | PRI | NULL | auto_increment |
|
||||
| uid | user.id of the owner of this data | int(10) unsigned | NO | MUL | 0 | |
|
||||
| contact-id | contact.id | int(10) unsigned | NO | | 0 | |
|
||||
| guid | A unique identifier for this photo | varchar(64) | NO | MUL | | |
|
||||
| resource-id | | varchar(255) | NO | MUL | | |
|
||||
| created | creation date | datetime | NO | | 0001-01-01 00:00:00 | |
|
||||
| edited | last edited date | datetime | NO | | 0001-01-01 00:00:00 | |
|
||||
| title | | varchar(255) | NO | | | |
|
||||
| desc | | text | NO | | NULL | |
|
||||
| album | The name of the album to which the photo belongs | varchar(255) | NO | | | |
|
||||
| filename | | varchar(255) | NO | | | |
|
||||
| type | image type | varchar(128) | NO | | image/jpeg | |
|
||||
| height | | smallint(6) | NO | | 0 | |
|
||||
| width | | smallint(6) | NO | | 0 | |
|
||||
| size | | int(10) unsigned | NO | | 0 | |
|
||||
| data | | mediumblob | NO | | NULL | |
|
||||
| scale | | tinyint(3) | NO | | 0 | |
|
||||
| profile | | tinyint(1) | NO | | 0 | |
|
||||
| allow_cid | Access Control - list of allowed contact.id '<19><78>' | mediumtext | NO | | NULL | |
|
||||
| allow_gid | Access Control - list of allowed groups | mediumtext | NO | | NULL | |
|
||||
| deny_cid | Access Control - list of denied contact.id | mediumtext | NO | | NULL | |
|
||||
| deny_gid | Access Control - list of denied groups | mediumtext | NO | | NULL | |
|
||||
photo storage
|
||||
|
||||
Fields
|
||||
------
|
||||
|
||||
| Field | Description | Type | Null | Key | Default | Extra |
|
||||
| ------------- | ------------------------------------------------------ | ------------------ | ---- | --- | ------------------- | -------------- |
|
||||
| id | sequential ID | int unsigned | NO | PRI | NULL | auto_increment |
|
||||
| uid | Owner User id | mediumint unsigned | NO | | 0 | |
|
||||
| contact-id | contact.id | int unsigned | NO | | 0 | |
|
||||
| guid | A unique identifier for this photo | char(16) | NO | | | |
|
||||
| resource-id | | char(32) | NO | | | |
|
||||
| hash | hash value of the photo | char(32) | YES | | NULL | |
|
||||
| created | creation date | datetime | NO | | 0001-01-01 00:00:00 | |
|
||||
| edited | last edited date | datetime | NO | | 0001-01-01 00:00:00 | |
|
||||
| title | | varchar(255) | NO | | | |
|
||||
| desc | | text | YES | | NULL | |
|
||||
| album | The name of the album to which the photo belongs | varchar(255) | NO | | | |
|
||||
| filename | | varchar(255) | NO | | | |
|
||||
| type | | varchar(30) | NO | | image/jpeg | |
|
||||
| height | | smallint unsigned | NO | | 0 | |
|
||||
| width | | smallint unsigned | NO | | 0 | |
|
||||
| datasize | | int unsigned | NO | | 0 | |
|
||||
| data | | mediumblob | NO | | NULL | |
|
||||
| scale | | tinyint unsigned | NO | | 0 | |
|
||||
| profile | | boolean | NO | | 0 | |
|
||||
| allow_cid | Access Control - list of allowed contact.id '<19><78>' | mediumtext | YES | | NULL | |
|
||||
| allow_gid | Access Control - list of allowed groups | mediumtext | YES | | NULL | |
|
||||
| deny_cid | Access Control - list of denied contact.id | mediumtext | YES | | NULL | |
|
||||
| deny_gid | Access Control - list of denied groups | mediumtext | YES | | NULL | |
|
||||
| accessible | Make photo publicly accessible, ignoring permissions | boolean | NO | | 0 | |
|
||||
| backend-class | Storage backend class | tinytext | YES | | NULL | |
|
||||
| backend-ref | Storage backend data reference | text | YES | | NULL | |
|
||||
| updated | | datetime | NO | | 0001-01-01 00:00:00 | |
|
||||
|
||||
Indexes
|
||||
------------
|
||||
|
||||
| Name | Fields |
|
||||
| ----------------------------- | ------------------------------------ |
|
||||
| PRIMARY | id |
|
||||
| contactid | contact-id |
|
||||
| uid_contactid | uid, contact-id |
|
||||
| uid_profile | uid, profile |
|
||||
| uid_album_scale_created | uid, album(32), scale, created |
|
||||
| uid_album_resource-id_created | uid, album(32), resource-id, created |
|
||||
| resource-id | resource-id |
|
||||
|
||||
Foreign Keys
|
||||
------------
|
||||
|
||||
| Field | Target Table | Target Field |
|
||||
|-------|--------------|--------------|
|
||||
| uid | [user](help/database/db_user) | uid |
|
||||
| contact-id | [contact](help/database/db_contact) | id |
|
||||
|
||||
Return to [database documentation](help/database)
|
||||
|
|
|
|||
|
|
@ -1,19 +0,0 @@
|
|||
Table poll
|
||||
==========
|
||||
|
||||
| Field | Description | Type | Null | Key | Default | Extra |
|
||||
|-------|-------------|------------|------|-----|---------|----------------|
|
||||
| id | | int(11) | NO | PRI | NULL | auto_increment |
|
||||
| uid | | int(11) | NO | MUL | 0 | |
|
||||
| q0 | | mediumtext | NO | | NULL | |
|
||||
| q1 | | mediumtext | NO | | NULL | |
|
||||
| q2 | | mediumtext | NO | | NULL | |
|
||||
| q3 | | mediumtext | NO | | NULL | |
|
||||
| q4 | | mediumtext | NO | | NULL | |
|
||||
| q5 | | mediumtext | NO | | NULL | |
|
||||
| q6 | | mediumtext | NO | | NULL | |
|
||||
| q7 | | mediumtext | NO | | NULL | |
|
||||
| q8 | | mediumtext | NO | | NULL | |
|
||||
| q9 | | mediumtext | NO | | NULL | |
|
||||
|
||||
Return to [database documentation](help/database)
|
||||
|
|
@ -1,10 +0,0 @@
|
|||
Table poll_result
|
||||
=================
|
||||
|
||||
| Field | Description | Type | Null | Key | Default | Extra |
|
||||
|---------|------------------|---------|------|-----|---------|----------------|
|
||||
| id | sequential ID | int(11) | NO | PRI | NULL | auto_increment |
|
||||
| poll_id | | int(11) | NO | MUL | 0 | |
|
||||
| choice | | int(11) | NO | MUL | 0 | |
|
||||
|
||||
Return to [database documentation](help/database)
|
||||
34
doc/database/db_post-category.md
Normal file
34
doc/database/db_post-category.md
Normal file
|
|
@ -0,0 +1,34 @@
|
|||
Table post-category
|
||||
===========
|
||||
|
||||
post relation to categories
|
||||
|
||||
Fields
|
||||
------
|
||||
|
||||
| Field | Description | Type | Null | Key | Default | Extra |
|
||||
| ------ | --------------------------------------------------------- | ------------------ | ---- | --- | ------- | ----- |
|
||||
| uri-id | Id of the item-uri table entry that contains the item uri | int unsigned | NO | PRI | NULL | |
|
||||
| uid | User id | mediumint unsigned | NO | PRI | 0 | |
|
||||
| type | | tinyint unsigned | NO | PRI | 0 | |
|
||||
| tid | | int unsigned | NO | PRI | 0 | |
|
||||
|
||||
Indexes
|
||||
------------
|
||||
|
||||
| Name | Fields |
|
||||
| ------- | ---------------------- |
|
||||
| PRIMARY | uri-id, uid, type, tid |
|
||||
| uri-id | tid |
|
||||
| uid | uid |
|
||||
|
||||
Foreign Keys
|
||||
------------
|
||||
|
||||
| Field | Target Table | Target Field |
|
||||
|-------|--------------|--------------|
|
||||
| uri-id | [item-uri](help/database/db_item-uri) | id |
|
||||
| uid | [user](help/database/db_user) | uid |
|
||||
| tid | [tag](help/database/db_tag) | id |
|
||||
|
||||
Return to [database documentation](help/database)
|
||||
46
doc/database/db_post-content.md
Normal file
46
doc/database/db_post-content.md
Normal file
|
|
@ -0,0 +1,46 @@
|
|||
Table post-content
|
||||
===========
|
||||
|
||||
Content for all posts
|
||||
|
||||
Fields
|
||||
------
|
||||
|
||||
| Field | Description | Type | Null | Key | Default | Extra |
|
||||
| --------------- | ------------------------------------------------------------------------------------------------------------------------- | ------------ | ---- | --- | ------- | ----- |
|
||||
| uri-id | Id of the item-uri table entry that contains the item uri | int unsigned | NO | PRI | NULL | |
|
||||
| title | item title | varchar(255) | NO | | | |
|
||||
| content-warning | | varchar(255) | NO | | | |
|
||||
| body | item body content | mediumtext | YES | | NULL | |
|
||||
| raw-body | Body without embedded media links | mediumtext | YES | | NULL | |
|
||||
| location | text location where this item originated | varchar(255) | NO | | | |
|
||||
| coord | longitude/latitude pair representing location where this item originated | varchar(255) | NO | | | |
|
||||
| language | Language information about this post | text | YES | | NULL | |
|
||||
| app | application which generated this item | varchar(255) | NO | | | |
|
||||
| rendered-hash | | varchar(32) | NO | | | |
|
||||
| rendered-html | item.body converted to html | mediumtext | YES | | NULL | |
|
||||
| object-type | ActivityStreams object type | varchar(100) | NO | | | |
|
||||
| object | JSON encoded object structure unless it is an implied object (normal post) | text | YES | | NULL | |
|
||||
| target-type | ActivityStreams target type if applicable (URI) | varchar(100) | NO | | | |
|
||||
| target | JSON encoded target structure if used | text | YES | | NULL | |
|
||||
| resource-id | Used to link other tables to items, it identifies the linked resource (e.g. photo) and if set must also set resource_type | varchar(32) | NO | | | |
|
||||
| plink | permalink or URL to a displayable copy of the message at its source | varchar(255) | NO | | | |
|
||||
|
||||
Indexes
|
||||
------------
|
||||
|
||||
| Name | Fields |
|
||||
| -------------------------- | -------------------------------------- |
|
||||
| PRIMARY | uri-id |
|
||||
| plink | plink(191) |
|
||||
| resource-id | resource-id |
|
||||
| title-content-warning-body | FULLTEXT, title, content-warning, body |
|
||||
|
||||
Foreign Keys
|
||||
------------
|
||||
|
||||
| Field | Target Table | Target Field |
|
||||
|-------|--------------|--------------|
|
||||
| uri-id | [item-uri](help/database/db_item-uri) | id |
|
||||
|
||||
Return to [database documentation](help/database)
|
||||
37
doc/database/db_post-delivery-data.md
Normal file
37
doc/database/db_post-delivery-data.md
Normal file
|
|
@ -0,0 +1,37 @@
|
|||
Table post-delivery-data
|
||||
===========
|
||||
|
||||
Delivery data for items
|
||||
|
||||
Fields
|
||||
------
|
||||
|
||||
| Field | Description | Type | Null | Key | Default | Extra |
|
||||
| ------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------ | ---- | --- | ------- | ----- |
|
||||
| uri-id | Id of the item-uri table entry that contains the item uri | int unsigned | NO | PRI | NULL | |
|
||||
| postopts | External post connectors add their network name to this comma-separated string to identify that they should be delivered to these networks during delivery | text | YES | | NULL | |
|
||||
| inform | Additional receivers of the linked item | mediumtext | YES | | NULL | |
|
||||
| queue_count | Initial number of delivery recipients, used as item.delivery_queue_count | mediumint | NO | | 0 | |
|
||||
| queue_done | Number of successful deliveries, used as item.delivery_queue_done | mediumint | NO | | 0 | |
|
||||
| queue_failed | Number of unsuccessful deliveries, used as item.delivery_queue_failed | mediumint | NO | | 0 | |
|
||||
| activitypub | Number of successful deliveries via ActivityPub | mediumint | NO | | 0 | |
|
||||
| dfrn | Number of successful deliveries via DFRN | mediumint | NO | | 0 | |
|
||||
| legacy_dfrn | Number of successful deliveries via legacy DFRN | mediumint | NO | | 0 | |
|
||||
| diaspora | Number of successful deliveries via Diaspora | mediumint | NO | | 0 | |
|
||||
| ostatus | Number of successful deliveries via OStatus | mediumint | NO | | 0 | |
|
||||
|
||||
Indexes
|
||||
------------
|
||||
|
||||
| Name | Fields |
|
||||
| ------- | ------ |
|
||||
| PRIMARY | uri-id |
|
||||
|
||||
Foreign Keys
|
||||
------------
|
||||
|
||||
| Field | Target Table | Target Field |
|
||||
|-------|--------------|--------------|
|
||||
| uri-id | [item-uri](help/database/db_item-uri) | id |
|
||||
|
||||
Return to [database documentation](help/database)
|
||||
46
doc/database/db_post-media.md
Normal file
46
doc/database/db_post-media.md
Normal file
|
|
@ -0,0 +1,46 @@
|
|||
Table post-media
|
||||
===========
|
||||
|
||||
Attached media
|
||||
|
||||
Fields
|
||||
------
|
||||
|
||||
| Field | Description | Type | Null | Key | Default | Extra |
|
||||
| --------------- | --------------------------------------------------------- | ----------------- | ---- | --- | ------- | -------------- |
|
||||
| id | sequential ID | int unsigned | NO | PRI | NULL | auto_increment |
|
||||
| uri-id | Id of the item-uri table entry that contains the item uri | int unsigned | NO | | NULL | |
|
||||
| url | Media URL | varbinary(511) | NO | | NULL | |
|
||||
| type | Media type | tinyint unsigned | NO | | 0 | |
|
||||
| mimetype | | varchar(60) | YES | | NULL | |
|
||||
| height | Height of the media | smallint unsigned | YES | | NULL | |
|
||||
| width | Width of the media | smallint unsigned | YES | | NULL | |
|
||||
| size | Media size | int unsigned | YES | | NULL | |
|
||||
| preview | Preview URL | varbinary(255) | YES | | NULL | |
|
||||
| preview-height | Height of the preview picture | smallint unsigned | YES | | NULL | |
|
||||
| preview-width | Width of the preview picture | smallint unsigned | YES | | NULL | |
|
||||
| description | | text | YES | | NULL | |
|
||||
| name | Name of the media | varchar(255) | YES | | NULL | |
|
||||
| author-url | URL of the author of the media | varbinary(255) | YES | | NULL | |
|
||||
| author-name | Name of the author of the media | varchar(255) | YES | | NULL | |
|
||||
| author-image | Image of the author of the media | varbinary(255) | YES | | NULL | |
|
||||
| publisher-url | URL of the publisher of the media | varbinary(255) | YES | | NULL | |
|
||||
| publisher-name | Name of the publisher of the media | varchar(255) | YES | | NULL | |
|
||||
| publisher-image | Image of the publisher of the media | varbinary(255) | YES | | NULL | |
|
||||
|
||||
Indexes
|
||||
------------
|
||||
|
||||
| Name | Fields |
|
||||
| ---------- | ------------------- |
|
||||
| PRIMARY | id |
|
||||
| uri-id-url | UNIQUE, uri-id, url |
|
||||
|
||||
Foreign Keys
|
||||
------------
|
||||
|
||||
| Field | Target Table | Target Field |
|
||||
|-------|--------------|--------------|
|
||||
| uri-id | [item-uri](help/database/db_item-uri) | id |
|
||||
|
||||
Return to [database documentation](help/database)
|
||||
34
doc/database/db_post-tag.md
Normal file
34
doc/database/db_post-tag.md
Normal file
|
|
@ -0,0 +1,34 @@
|
|||
Table post-tag
|
||||
===========
|
||||
|
||||
post relation to tags
|
||||
|
||||
Fields
|
||||
------
|
||||
|
||||
| Field | Description | Type | Null | Key | Default | Extra |
|
||||
| ------ | --------------------------------------------------------- | ---------------- | ---- | --- | ------- | ----- |
|
||||
| uri-id | Id of the item-uri table entry that contains the item uri | int unsigned | NO | PRI | NULL | |
|
||||
| type | | tinyint unsigned | NO | PRI | 0 | |
|
||||
| tid | | int unsigned | NO | PRI | 0 | |
|
||||
| cid | Contact id of the mentioned public contact | int unsigned | NO | PRI | 0 | |
|
||||
|
||||
Indexes
|
||||
------------
|
||||
|
||||
| Name | Fields |
|
||||
| ------- | ---------------------- |
|
||||
| PRIMARY | uri-id, type, tid, cid |
|
||||
| tid | tid |
|
||||
| cid | cid |
|
||||
|
||||
Foreign Keys
|
||||
------------
|
||||
|
||||
| Field | Target Table | Target Field |
|
||||
|-------|--------------|--------------|
|
||||
| uri-id | [item-uri](help/database/db_item-uri) | id |
|
||||
| tid | [tag](help/database/db_tag) | id |
|
||||
| cid | [contact](help/database/db_contact) | id |
|
||||
|
||||
Return to [database documentation](help/database)
|
||||
70
doc/database/db_post-thread-user.md
Normal file
70
doc/database/db_post-thread-user.md
Normal file
|
|
@ -0,0 +1,70 @@
|
|||
Table post-thread-user
|
||||
===========
|
||||
|
||||
Thread related data per user
|
||||
|
||||
Fields
|
||||
------
|
||||
|
||||
| Field | Description | Type | Null | Key | Default | Extra |
|
||||
| ------------ | ------------------------------------------------------------------------------------------------------- | ------------------ | ---- | --- | ------------------- | ----- |
|
||||
| uri-id | Id of the item-uri table entry that contains the item uri | int unsigned | NO | PRI | NULL | |
|
||||
| owner-id | Item owner | int unsigned | NO | | 0 | |
|
||||
| author-id | Item author | int unsigned | NO | | 0 | |
|
||||
| causer-id | Link to the contact table with uid=0 of the contact that caused the item creation | int unsigned | YES | | NULL | |
|
||||
| network | | char(4) | NO | | | |
|
||||
| created | | datetime | NO | | 0001-01-01 00:00:00 | |
|
||||
| received | | datetime | NO | | 0001-01-01 00:00:00 | |
|
||||
| changed | Date that something in the conversation changed, indicating clients should fetch the conversation again | datetime | NO | | 0001-01-01 00:00:00 | |
|
||||
| commented | | datetime | NO | | 0001-01-01 00:00:00 | |
|
||||
| uid | Owner id which owns this copy of the item | mediumint unsigned | NO | PRI | 0 | |
|
||||
| pinned | The thread is pinned on the profile page | boolean | NO | | 0 | |
|
||||
| starred | | boolean | NO | | 0 | |
|
||||
| ignored | Ignore updates for this thread | boolean | NO | | 0 | |
|
||||
| wall | This item was posted to the wall of uid | boolean | NO | | 0 | |
|
||||
| mention | | boolean | NO | | 0 | |
|
||||
| pubmail | | boolean | NO | | 0 | |
|
||||
| forum_mode | | tinyint unsigned | NO | | 0 | |
|
||||
| contact-id | contact.id | int unsigned | NO | | 0 | |
|
||||
| unseen | post has not been seen | boolean | NO | | 1 | |
|
||||
| hidden | Marker to hide the post from the user | boolean | NO | | 0 | |
|
||||
| origin | item originated at this site | boolean | NO | | 0 | |
|
||||
| psid | ID of the permission set of this post | int unsigned | YES | | NULL | |
|
||||
| post-user-id | Id of the post-user table | int unsigned | YES | | NULL | |
|
||||
|
||||
Indexes
|
||||
------------
|
||||
|
||||
| Name | Fields |
|
||||
| ------------- | -------------- |
|
||||
| PRIMARY | uid, uri-id |
|
||||
| uri-id | uri-id |
|
||||
| owner-id | owner-id |
|
||||
| author-id | author-id |
|
||||
| causer-id | causer-id |
|
||||
| uid | uid |
|
||||
| contact-id | contact-id |
|
||||
| psid | psid |
|
||||
| post-user-id | post-user-id |
|
||||
| commented | commented |
|
||||
| uid_received | uid, received |
|
||||
| uid_pinned | uid, pinned |
|
||||
| uid_commented | uid, commented |
|
||||
| uid_starred | uid, starred |
|
||||
| uid_mention | uid, mention |
|
||||
|
||||
Foreign Keys
|
||||
------------
|
||||
|
||||
| Field | Target Table | Target Field |
|
||||
|-------|--------------|--------------|
|
||||
| uri-id | [item-uri](help/database/db_item-uri) | id |
|
||||
| owner-id | [contact](help/database/db_contact) | id |
|
||||
| author-id | [contact](help/database/db_contact) | id |
|
||||
| causer-id | [contact](help/database/db_contact) | id |
|
||||
| uid | [user](help/database/db_user) | uid |
|
||||
| contact-id | [contact](help/database/db_contact) | id |
|
||||
| psid | [permissionset](help/database/db_permissionset) | id |
|
||||
| post-user-id | [post-user](help/database/db_post-user) | id |
|
||||
|
||||
Return to [database documentation](help/database)
|
||||
43
doc/database/db_post-thread.md
Normal file
43
doc/database/db_post-thread.md
Normal file
|
|
@ -0,0 +1,43 @@
|
|||
Table post-thread
|
||||
===========
|
||||
|
||||
Thread related data
|
||||
|
||||
Fields
|
||||
------
|
||||
|
||||
| Field | Description | Type | Null | Key | Default | Extra |
|
||||
| --------- | ------------------------------------------------------------------------------------------------------- | ------------ | ---- | --- | ------------------- | ----- |
|
||||
| uri-id | Id of the item-uri table entry that contains the item uri | int unsigned | NO | PRI | NULL | |
|
||||
| owner-id | Item owner | int unsigned | NO | | 0 | |
|
||||
| author-id | Item author | int unsigned | NO | | 0 | |
|
||||
| causer-id | Link to the contact table with uid=0 of the contact that caused the item creation | int unsigned | YES | | NULL | |
|
||||
| network | | char(4) | NO | | | |
|
||||
| created | | datetime | NO | | 0001-01-01 00:00:00 | |
|
||||
| received | | datetime | NO | | 0001-01-01 00:00:00 | |
|
||||
| changed | Date that something in the conversation changed, indicating clients should fetch the conversation again | datetime | NO | | 0001-01-01 00:00:00 | |
|
||||
| commented | | datetime | NO | | 0001-01-01 00:00:00 | |
|
||||
|
||||
Indexes
|
||||
------------
|
||||
|
||||
| Name | Fields |
|
||||
| --------- | --------- |
|
||||
| PRIMARY | uri-id |
|
||||
| owner-id | owner-id |
|
||||
| author-id | author-id |
|
||||
| causer-id | causer-id |
|
||||
| received | received |
|
||||
| commented | commented |
|
||||
|
||||
Foreign Keys
|
||||
------------
|
||||
|
||||
| Field | Target Table | Target Field |
|
||||
|-------|--------------|--------------|
|
||||
| uri-id | [item-uri](help/database/db_item-uri) | id |
|
||||
| owner-id | [contact](help/database/db_contact) | id |
|
||||
| author-id | [contact](help/database/db_contact) | id |
|
||||
| causer-id | [contact](help/database/db_contact) | id |
|
||||
|
||||
Return to [database documentation](help/database)
|
||||
31
doc/database/db_post-user-notification.md
Normal file
31
doc/database/db_post-user-notification.md
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
Table post-user-notification
|
||||
===========
|
||||
|
||||
User post notifications
|
||||
|
||||
Fields
|
||||
------
|
||||
|
||||
| Field | Description | Type | Null | Key | Default | Extra |
|
||||
| ----------------- | --------------------------------------------------------- | ------------------ | ---- | --- | ------- | ----- |
|
||||
| uri-id | Id of the item-uri table entry that contains the item uri | int unsigned | NO | PRI | NULL | |
|
||||
| uid | Owner id which owns this copy of the item | mediumint unsigned | NO | PRI | NULL | |
|
||||
| notification-type | | tinyint unsigned | NO | | 0 | |
|
||||
|
||||
Indexes
|
||||
------------
|
||||
|
||||
| Name | Fields |
|
||||
| ------- | ----------- |
|
||||
| PRIMARY | uid, uri-id |
|
||||
| uri-id | uri-id |
|
||||
|
||||
Foreign Keys
|
||||
------------
|
||||
|
||||
| Field | Target Table | Target Field |
|
||||
|-------|--------------|--------------|
|
||||
| uri-id | [item-uri](help/database/db_item-uri) | id |
|
||||
| uid | [user](help/database/db_user) | uid |
|
||||
|
||||
Return to [database documentation](help/database)
|
||||
86
doc/database/db_post-user.md
Normal file
86
doc/database/db_post-user.md
Normal file
|
|
@ -0,0 +1,86 @@
|
|||
Table post-user
|
||||
===========
|
||||
|
||||
User specific post data
|
||||
|
||||
Fields
|
||||
------
|
||||
|
||||
| Field | Description | Type | Null | Key | Default | Extra |
|
||||
| ----------------- | --------------------------------------------------------------------------------- | ------------------ | ---- | --- | ------------------- | -------------- |
|
||||
| id | | int unsigned | NO | PRI | NULL | auto_increment |
|
||||
| uri-id | Id of the item-uri table entry that contains the item uri | int unsigned | NO | | NULL | |
|
||||
| parent-uri-id | Id of the item-uri table that contains the parent uri | int unsigned | YES | | NULL | |
|
||||
| thr-parent-id | Id of the item-uri table that contains the thread parent uri | int unsigned | YES | | NULL | |
|
||||
| external-id | Id of the item-uri table entry that contains the external uri | int unsigned | YES | | NULL | |
|
||||
| created | Creation timestamp. | datetime | NO | | 0001-01-01 00:00:00 | |
|
||||
| edited | Date of last edit (default is created) | datetime | NO | | 0001-01-01 00:00:00 | |
|
||||
| received | datetime | datetime | NO | | 0001-01-01 00:00:00 | |
|
||||
| gravity | | tinyint unsigned | NO | | 0 | |
|
||||
| network | Network from where the item comes from | char(4) | NO | | | |
|
||||
| owner-id | Link to the contact table with uid=0 of the owner of this item | int unsigned | NO | | 0 | |
|
||||
| author-id | Link to the contact table with uid=0 of the author of this item | int unsigned | NO | | 0 | |
|
||||
| causer-id | Link to the contact table with uid=0 of the contact that caused the item creation | int unsigned | YES | | NULL | |
|
||||
| post-type | Post type (personal note, image, article, ...) | tinyint unsigned | NO | | 0 | |
|
||||
| post-reason | Reason why the post arrived at the user | tinyint unsigned | NO | | 0 | |
|
||||
| vid | Id of the verb table entry that contains the activity verbs | smallint unsigned | YES | | NULL | |
|
||||
| private | 0=public, 1=private, 2=unlisted | tinyint unsigned | NO | | 0 | |
|
||||
| global | | boolean | NO | | 0 | |
|
||||
| visible | | boolean | NO | | 0 | |
|
||||
| deleted | item has been marked for deletion | boolean | NO | | 0 | |
|
||||
| uid | Owner id which owns this copy of the item | mediumint unsigned | NO | | NULL | |
|
||||
| protocol | Protocol used to deliver the item for this user | tinyint unsigned | YES | | NULL | |
|
||||
| contact-id | contact.id | int unsigned | NO | | 0 | |
|
||||
| event-id | Used to link to the event.id | int unsigned | YES | | NULL | |
|
||||
| unseen | post has not been seen | boolean | NO | | 1 | |
|
||||
| hidden | Marker to hide the post from the user | boolean | NO | | 0 | |
|
||||
| notification-type | | tinyint unsigned | NO | | 0 | |
|
||||
| wall | This item was posted to the wall of uid | boolean | NO | | 0 | |
|
||||
| origin | item originated at this site | boolean | NO | | 0 | |
|
||||
| psid | ID of the permission set of this post | int unsigned | YES | | NULL | |
|
||||
|
||||
Indexes
|
||||
------------
|
||||
|
||||
| Name | Fields |
|
||||
| -------------------- | ----------------------- |
|
||||
| PRIMARY | id |
|
||||
| uid_uri-id | UNIQUE, uid, uri-id |
|
||||
| uri-id | uri-id |
|
||||
| parent-uri-id | parent-uri-id |
|
||||
| thr-parent-id | thr-parent-id |
|
||||
| external-id | external-id |
|
||||
| owner-id | owner-id |
|
||||
| author-id | author-id |
|
||||
| causer-id | causer-id |
|
||||
| vid | vid |
|
||||
| contact-id | contact-id |
|
||||
| event-id | event-id |
|
||||
| psid | psid |
|
||||
| author-id_uid | author-id, uid |
|
||||
| author-id_received | author-id, received |
|
||||
| parent-uri-id_uid | parent-uri-id, uid |
|
||||
| uid_contactid | uid, contact-id |
|
||||
| uid_unseen_contactid | uid, unseen, contact-id |
|
||||
| uid_unseen | uid, unseen |
|
||||
| uid_hidden_uri-id | uid, hidden, uri-id |
|
||||
|
||||
Foreign Keys
|
||||
------------
|
||||
|
||||
| Field | Target Table | Target Field |
|
||||
|-------|--------------|--------------|
|
||||
| uri-id | [item-uri](help/database/db_item-uri) | id |
|
||||
| parent-uri-id | [item-uri](help/database/db_item-uri) | id |
|
||||
| thr-parent-id | [item-uri](help/database/db_item-uri) | id |
|
||||
| external-id | [item-uri](help/database/db_item-uri) | id |
|
||||
| owner-id | [contact](help/database/db_contact) | id |
|
||||
| author-id | [contact](help/database/db_contact) | id |
|
||||
| causer-id | [contact](help/database/db_contact) | id |
|
||||
| vid | [verb](help/database/db_verb) | id |
|
||||
| uid | [user](help/database/db_user) | uid |
|
||||
| contact-id | [contact](help/database/db_contact) | id |
|
||||
| event-id | [event](help/database/db_event) | id |
|
||||
| psid | [permissionset](help/database/db_permissionset) | id |
|
||||
|
||||
Return to [database documentation](help/database)
|
||||
58
doc/database/db_post.md
Normal file
58
doc/database/db_post.md
Normal file
|
|
@ -0,0 +1,58 @@
|
|||
Table post
|
||||
===========
|
||||
|
||||
Structure for all posts
|
||||
|
||||
Fields
|
||||
------
|
||||
|
||||
| Field | Description | Type | Null | Key | Default | Extra |
|
||||
| ------------- | --------------------------------------------------------------------------------- | ----------------- | ---- | --- | ------------------- | ----- |
|
||||
| uri-id | Id of the item-uri table entry that contains the item uri | int unsigned | NO | PRI | NULL | |
|
||||
| parent-uri-id | Id of the item-uri table that contains the parent uri | int unsigned | YES | | NULL | |
|
||||
| thr-parent-id | Id of the item-uri table that contains the thread parent uri | int unsigned | YES | | NULL | |
|
||||
| external-id | Id of the item-uri table entry that contains the external uri | int unsigned | YES | | NULL | |
|
||||
| created | Creation timestamp. | datetime | NO | | 0001-01-01 00:00:00 | |
|
||||
| edited | Date of last edit (default is created) | datetime | NO | | 0001-01-01 00:00:00 | |
|
||||
| received | datetime | datetime | NO | | 0001-01-01 00:00:00 | |
|
||||
| gravity | | tinyint unsigned | NO | | 0 | |
|
||||
| network | Network from where the item comes from | char(4) | NO | | | |
|
||||
| owner-id | Link to the contact table with uid=0 of the owner of this item | int unsigned | NO | | 0 | |
|
||||
| author-id | Link to the contact table with uid=0 of the author of this item | int unsigned | NO | | 0 | |
|
||||
| causer-id | Link to the contact table with uid=0 of the contact that caused the item creation | int unsigned | YES | | NULL | |
|
||||
| post-type | Post type (personal note, image, article, ...) | tinyint unsigned | NO | | 0 | |
|
||||
| vid | Id of the verb table entry that contains the activity verbs | smallint unsigned | YES | | NULL | |
|
||||
| private | 0=public, 1=private, 2=unlisted | tinyint unsigned | NO | | 0 | |
|
||||
| global | | boolean | NO | | 0 | |
|
||||
| visible | | boolean | NO | | 0 | |
|
||||
| deleted | item has been marked for deletion | boolean | NO | | 0 | |
|
||||
|
||||
Indexes
|
||||
------------
|
||||
|
||||
| Name | Fields |
|
||||
| ------------- | ------------- |
|
||||
| PRIMARY | uri-id |
|
||||
| parent-uri-id | parent-uri-id |
|
||||
| thr-parent-id | thr-parent-id |
|
||||
| external-id | external-id |
|
||||
| owner-id | owner-id |
|
||||
| author-id | author-id |
|
||||
| causer-id | causer-id |
|
||||
| vid | vid |
|
||||
|
||||
Foreign Keys
|
||||
------------
|
||||
|
||||
| Field | Target Table | Target Field |
|
||||
|-------|--------------|--------------|
|
||||
| uri-id | [item-uri](help/database/db_item-uri) | id |
|
||||
| parent-uri-id | [item-uri](help/database/db_item-uri) | id |
|
||||
| thr-parent-id | [item-uri](help/database/db_item-uri) | id |
|
||||
| external-id | [item-uri](help/database/db_item-uri) | id |
|
||||
| owner-id | [contact](help/database/db_contact) | id |
|
||||
| author-id | [contact](help/database/db_contact) | id |
|
||||
| causer-id | [contact](help/database/db_contact) | id |
|
||||
| vid | [verb](help/database/db_verb) | id |
|
||||
|
||||
Return to [database documentation](help/database)
|
||||
24
doc/database/db_process.md
Normal file
24
doc/database/db_process.md
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
Table process
|
||||
===========
|
||||
|
||||
Currently running system processes
|
||||
|
||||
Fields
|
||||
------
|
||||
|
||||
| Field | Description | Type | Null | Key | Default | Extra |
|
||||
| ------- | ----------- | ------------- | ---- | --- | ------------------- | ----- |
|
||||
| pid | | int unsigned | NO | PRI | NULL | |
|
||||
| command | | varbinary(32) | NO | | | |
|
||||
| created | | datetime | NO | | 0001-01-01 00:00:00 | |
|
||||
|
||||
Indexes
|
||||
------------
|
||||
|
||||
| Name | Fields |
|
||||
| ------- | ------- |
|
||||
| PRIMARY | pid |
|
||||
| command | command |
|
||||
|
||||
|
||||
Return to [database documentation](help/database)
|
||||
|
|
@ -1,48 +1,70 @@
|
|||
Table profile
|
||||
=============
|
||||
===========
|
||||
|
||||
| Field | Description | Type | Null | Key | Default | Extra |
|
||||
|--------------|-----------------------------------------------|--------------|------|-----|---------------------|----------------|
|
||||
| id | sequential ID | int(11) | NO | PRI | NULL | auto_increment |
|
||||
| uid | user.id of the owner of this data | int(11) | NO | | 0 | |
|
||||
| profile-name | Name of the profile | varchar(255) | NO | | | |
|
||||
| is-default | Mark this profile as default profile | tinyint(1) | NO | | 0 | |
|
||||
| hide-friends | Hide friend list from viewers of this profile | tinyint(1) | NO | | 0 | |
|
||||
| name | | varchar(255) | NO | | | |
|
||||
| pdesc | Deprecated | varchar(255) | NO | | | |
|
||||
| dob | Day of birth | varchar(32) | NO | | 0001-01-01 | |
|
||||
| address | | varchar(255) | NO | | | |
|
||||
| locality | | varchar(255) | NO | | | |
|
||||
| region | | varchar(255) | NO | | | |
|
||||
| postal-code | | varchar(32) | NO | | | |
|
||||
| country-name | | varchar(255) | NO | | | |
|
||||
| hometown | Deprecated | varchar(255) | NO | MUL | | |
|
||||
| gender | Deprecated | varchar(32) | NO | | | |
|
||||
| marital | Deprecated | varchar(255) | NO | | | |
|
||||
| with | Deprecated | text | NO | | NULL | |
|
||||
| howlong | Deprecated | datetime | NO | | 0001-01-01 00:00:00 | |
|
||||
| sexual | Deprecated | varchar(255) | NO | | | |
|
||||
| politic | Deprecated | varchar(255) | NO | | | |
|
||||
| religion | Deprecated | varchar(255) | NO | | | |
|
||||
| pub_keywords | | text | NO | | NULL | |
|
||||
| prv_keywords | | text | NO | | NULL | |
|
||||
| likes | Deprecated | text | NO | | NULL | |
|
||||
| dislikes | Deprecated | text | NO | | NULL | |
|
||||
| about | Profile description | text | NO | | | |
|
||||
| summary | Deprecated | varchar(255) | NO | | | |
|
||||
| music | Deprecated | text | NO | | NULL | |
|
||||
| book | Deprecated | text | NO | | NULL | |
|
||||
| tv | Deprecated | text | NO | | NULL | |
|
||||
| film | Deprecated | text | NO | | NULL | |
|
||||
| interest | Deprecated | text | NO | | NULL | |
|
||||
| romance | Deprecated | text | NO | | NULL | |
|
||||
| work | Deprecated | text | NO | | NULL | |
|
||||
| education | Deprecated | text | NO | | NULL | |
|
||||
| contact | Deprecated | text | NO | | NULL | |
|
||||
| homepage | | varchar(255) | NO | | | |
|
||||
| photo | | varchar(255) | NO | | | |
|
||||
| thumb | | varchar(255) | NO | | | |
|
||||
| publish | publish default profile in local directory | tinyint(1) | NO | | 0 | |
|
||||
| net-publish | publish profile in global directory | tinyint(1) | NO | | 0 | |
|
||||
user profiles data
|
||||
|
||||
Fields
|
||||
------
|
||||
|
||||
| Field | Description | Type | Null | Key | Default | Extra |
|
||||
| ------------ | --------------------------------------------- | ------------------ | ---- | --- | ---------- | -------------- |
|
||||
| id | sequential ID | int unsigned | NO | PRI | NULL | auto_increment |
|
||||
| uid | Owner User id | mediumint unsigned | NO | | 0 | |
|
||||
| profile-name | Deprecated | varchar(255) | YES | | NULL | |
|
||||
| is-default | Deprecated | boolean | YES | | NULL | |
|
||||
| hide-friends | Hide friend list from viewers of this profile | boolean | NO | | 0 | |
|
||||
| name | | varchar(255) | NO | | | |
|
||||
| pdesc | Deprecated | varchar(255) | YES | | NULL | |
|
||||
| dob | Day of birth | varchar(32) | NO | | 0000-00-00 | |
|
||||
| address | | varchar(255) | NO | | | |
|
||||
| locality | | varchar(255) | NO | | | |
|
||||
| region | | varchar(255) | NO | | | |
|
||||
| postal-code | | varchar(32) | NO | | | |
|
||||
| country-name | | varchar(255) | NO | | | |
|
||||
| hometown | Deprecated | varchar(255) | YES | | NULL | |
|
||||
| gender | Deprecated | varchar(32) | YES | | NULL | |
|
||||
| marital | Deprecated | varchar(255) | YES | | NULL | |
|
||||
| with | Deprecated | text | YES | | NULL | |
|
||||
| howlong | Deprecated | datetime | YES | | NULL | |
|
||||
| sexual | Deprecated | varchar(255) | YES | | NULL | |
|
||||
| politic | Deprecated | varchar(255) | YES | | NULL | |
|
||||
| religion | Deprecated | varchar(255) | YES | | NULL | |
|
||||
| pub_keywords | | text | YES | | NULL | |
|
||||
| prv_keywords | | text | YES | | NULL | |
|
||||
| likes | Deprecated | text | YES | | NULL | |
|
||||
| dislikes | Deprecated | text | YES | | NULL | |
|
||||
| about | Profile description | text | YES | | NULL | |
|
||||
| summary | Deprecated | varchar(255) | YES | | NULL | |
|
||||
| music | Deprecated | text | YES | | NULL | |
|
||||
| book | Deprecated | text | YES | | NULL | |
|
||||
| tv | Deprecated | text | YES | | NULL | |
|
||||
| film | Deprecated | text | YES | | NULL | |
|
||||
| interest | Deprecated | text | YES | | NULL | |
|
||||
| romance | Deprecated | text | YES | | NULL | |
|
||||
| work | Deprecated | text | YES | | NULL | |
|
||||
| education | Deprecated | text | YES | | NULL | |
|
||||
| contact | Deprecated | text | YES | | NULL | |
|
||||
| homepage | | varchar(255) | NO | | | |
|
||||
| xmpp | | varchar(255) | NO | | | |
|
||||
| photo | | varchar(255) | NO | | | |
|
||||
| thumb | | varchar(255) | NO | | | |
|
||||
| publish | publish default profile in local directory | boolean | NO | | 0 | |
|
||||
| net-publish | publish profile in global directory | boolean | NO | | 0 | |
|
||||
|
||||
Indexes
|
||||
------------
|
||||
|
||||
| Name | Fields |
|
||||
| -------------- | ---------------------- |
|
||||
| PRIMARY | id |
|
||||
| uid_is-default | uid, is-default |
|
||||
| pub_keywords | FULLTEXT, pub_keywords |
|
||||
|
||||
Foreign Keys
|
||||
------------
|
||||
|
||||
| Field | Target Table | Target Field |
|
||||
|-------|--------------|--------------|
|
||||
| uid | [user](help/database/db_user) | uid |
|
||||
|
||||
Return to [database documentation](help/database)
|
||||
|
|
|
|||
|
|
@ -1,13 +1,35 @@
|
|||
Table profile_check
|
||||
===================
|
||||
===========
|
||||
|
||||
| Field | Description | Type | Null | Key | Default | Extra |
|
||||
| -------- | ------------- | ---------------- | ---- | --- | ------- | --------------- |
|
||||
| id | sequential ID | int(10) unsigned | NO | PRI | NULL | auto_increment |
|
||||
| uid | user.id | int(10) unsigned | NO | | 0 | |
|
||||
| cid | contact.id | int(10) unsigned | NO | | 0 | |
|
||||
| dfrn_id | | varchar(255) | NO | | | |
|
||||
| sec | | varchar(255) | NO | | 0 | |
|
||||
| expire | | int(11) | NO | | NULL | |
|
||||
DFRN remote auth use
|
||||
|
||||
Fields
|
||||
------
|
||||
|
||||
| Field | Description | Type | Null | Key | Default | Extra |
|
||||
| ------- | ------------- | ------------------ | ---- | --- | ------- | -------------- |
|
||||
| id | sequential ID | int unsigned | NO | PRI | NULL | auto_increment |
|
||||
| uid | User id | mediumint unsigned | NO | | 0 | |
|
||||
| cid | contact.id | int unsigned | NO | | 0 | |
|
||||
| dfrn_id | | varchar(255) | NO | | | |
|
||||
| sec | | varchar(255) | NO | | | |
|
||||
| expire | | int unsigned | NO | | 0 | |
|
||||
|
||||
Indexes
|
||||
------------
|
||||
|
||||
| Name | Fields |
|
||||
| ------- | ------ |
|
||||
| PRIMARY | id |
|
||||
| uid | uid |
|
||||
| cid | cid |
|
||||
|
||||
Foreign Keys
|
||||
------------
|
||||
|
||||
| Field | Target Table | Target Field |
|
||||
|-------|--------------|--------------|
|
||||
| uid | [user](help/database/db_user) | uid |
|
||||
| cid | [contact](help/database/db_contact) | id |
|
||||
|
||||
Return to [database documentation](help/database)
|
||||
|
|
|
|||
38
doc/database/db_profile_field.md
Normal file
38
doc/database/db_profile_field.md
Normal file
|
|
@ -0,0 +1,38 @@
|
|||
Table profile_field
|
||||
===========
|
||||
|
||||
Custom profile fields
|
||||
|
||||
Fields
|
||||
------
|
||||
|
||||
| Field | Description | Type | Null | Key | Default | Extra |
|
||||
| ------- | ----------------------------------------------------------- | ------------------ | ---- | --- | ------------------- | -------------- |
|
||||
| id | sequential ID | int unsigned | NO | PRI | NULL | auto_increment |
|
||||
| uid | Owner user id | mediumint unsigned | NO | | 0 | |
|
||||
| order | Field ordering per user | mediumint unsigned | NO | | 1 | |
|
||||
| psid | ID of the permission set of this profile field - 0 = public | int unsigned | YES | | NULL | |
|
||||
| label | Label of the field | varchar(255) | NO | | | |
|
||||
| value | Value of the field | text | YES | | NULL | |
|
||||
| created | creation time | datetime | NO | | 0001-01-01 00:00:00 | |
|
||||
| edited | last edit time | datetime | NO | | 0001-01-01 00:00:00 | |
|
||||
|
||||
Indexes
|
||||
------------
|
||||
|
||||
| Name | Fields |
|
||||
| ------- | ------ |
|
||||
| PRIMARY | id |
|
||||
| uid | uid |
|
||||
| order | order |
|
||||
| psid | psid |
|
||||
|
||||
Foreign Keys
|
||||
------------
|
||||
|
||||
| Field | Target Table | Target Field |
|
||||
|-------|--------------|--------------|
|
||||
| uid | [user](help/database/db_user) | uid |
|
||||
| psid | [permissionset](help/database/db_permissionset) | id |
|
||||
|
||||
Return to [database documentation](help/database)
|
||||
|
|
@ -1,10 +1,38 @@
|
|||
Table push_subscriber
|
||||
=====================
|
||||
===========
|
||||
|
||||
| Field | Description | Type | Null | Key | Default | Extra |
|
||||
|---------|------------------|---------|------|-----|---------|----------------|
|
||||
| id | sequential ID | int(11) | NO | PRI | NULL | auto_increment |
|
||||
| poll_id | | int(11) | NO | MUL | 0 | |
|
||||
| choice | | int(11) | NO | MUL | 0 | |
|
||||
Used for OStatus: Contains feed subscribers
|
||||
|
||||
Fields
|
||||
------
|
||||
|
||||
| Field | Description | Type | Null | Key | Default | Extra |
|
||||
| ------------ | --------------------------------- | ------------------ | ---- | --- | ------------------- | -------------- |
|
||||
| id | sequential ID | int unsigned | NO | PRI | NULL | auto_increment |
|
||||
| uid | User id | mediumint unsigned | NO | | 0 | |
|
||||
| callback_url | | varchar(255) | NO | | | |
|
||||
| topic | | varchar(255) | NO | | | |
|
||||
| nickname | | varchar(255) | NO | | | |
|
||||
| push | Retrial counter | tinyint | NO | | 0 | |
|
||||
| last_update | Date of last successful trial | datetime | NO | | 0001-01-01 00:00:00 | |
|
||||
| next_try | Next retrial date | datetime | NO | | 0001-01-01 00:00:00 | |
|
||||
| renewed | Date of last subscription renewal | datetime | NO | | 0001-01-01 00:00:00 | |
|
||||
| secret | | varchar(255) | NO | | | |
|
||||
|
||||
Indexes
|
||||
------------
|
||||
|
||||
| Name | Fields |
|
||||
| -------- | -------- |
|
||||
| PRIMARY | id |
|
||||
| next_try | next_try |
|
||||
| uid | uid |
|
||||
|
||||
Foreign Keys
|
||||
------------
|
||||
|
||||
| Field | Target Table | Target Field |
|
||||
|-------|--------------|--------------|
|
||||
| uid | [user](help/database/db_user) | uid |
|
||||
|
||||
Return to [database documentation](help/database)
|
||||
|
|
|
|||
|
|
@ -1,14 +0,0 @@
|
|||
Table queue
|
||||
===========
|
||||
|
||||
| Field | Description | Type | Null | Key | Default | Extra |
|
||||
|---------|------------------|-------------|------|-----|---------------------|----------------|
|
||||
| id | sequential ID | int(11) | NO | PRI | NULL | auto_increment |
|
||||
| cid | | int(11) | NO | MUL | 0 | |
|
||||
| network | | varchar(32) | NO | MUL | | |
|
||||
| created | | datetime | NO | MUL | 0001-01-01 00:00:00 | |
|
||||
| last | | datetime | NO | MUL | 0001-01-01 00:00:00 | |
|
||||
| content | | mediumtext | NO | | NULL | |
|
||||
| batch | | tinyint(1) | NO | MUL | 0 | |
|
||||
|
||||
Return to [database documentation](help/database)
|
||||
|
|
@ -1,13 +1,34 @@
|
|||
Table register
|
||||
==============
|
||||
===========
|
||||
|
||||
| Field | Description | Type | Null | Key | Default | Extra |
|
||||
| -------- | ------------- | ---------------- | ---- | --- | ------------------- | --------------- |
|
||||
| id | sequential ID | int(11) unsigned | NO | PRI | NULL | auto_increment |
|
||||
| hash | | varchar(255) | NO | | | |
|
||||
| created | | datetime | NO | | 0001-01-01 00:00:00 | |
|
||||
| uid | user.id | int(11) unsigned | NO | | | |
|
||||
| password | | varchar(255) | NO | | | |
|
||||
| language | | varchar(16) | NO | | | |
|
||||
registrations requiring admin approval
|
||||
|
||||
Fields
|
||||
------
|
||||
|
||||
| Field | Description | Type | Null | Key | Default | Extra |
|
||||
| -------- | ------------- | ------------------ | ---- | --- | ------------------- | -------------- |
|
||||
| id | sequential ID | int unsigned | NO | PRI | NULL | auto_increment |
|
||||
| hash | | varchar(255) | NO | | | |
|
||||
| created | | datetime | NO | | 0001-01-01 00:00:00 | |
|
||||
| uid | User id | mediumint unsigned | NO | | 0 | |
|
||||
| password | | varchar(255) | NO | | | |
|
||||
| language | | varchar(16) | NO | | | |
|
||||
| note | | text | YES | | NULL | |
|
||||
|
||||
Indexes
|
||||
------------
|
||||
|
||||
| Name | Fields |
|
||||
| ------- | ------ |
|
||||
| PRIMARY | id |
|
||||
| uid | uid |
|
||||
|
||||
Foreign Keys
|
||||
------------
|
||||
|
||||
| Field | Target Table | Target Field |
|
||||
|-------|--------------|--------------|
|
||||
| uid | [user](help/database/db_user) | uid |
|
||||
|
||||
Return to [database documentation](help/database)
|
||||
|
|
|
|||
|
|
@ -1,10 +1,31 @@
|
|||
Table search
|
||||
============
|
||||
===========
|
||||
|
||||
| Field | Description | Type | Null | Key | Default | Extra |
|
||||
|-------|------------------|--------------|------|-----|---------|----------------|
|
||||
| id | sequential ID | int(11) | NO | PRI | NULL | auto_increment |
|
||||
| uid | | int(11) | NO | MUL | 0 | |
|
||||
| term | | varchar(255) | NO | MUL | | |
|
||||
|
||||
|
||||
Fields
|
||||
------
|
||||
|
||||
| Field | Description | Type | Null | Key | Default | Extra |
|
||||
| ----- | ------------- | ------------------ | ---- | --- | ------- | -------------- |
|
||||
| id | sequential ID | int unsigned | NO | PRI | NULL | auto_increment |
|
||||
| uid | User id | mediumint unsigned | NO | | 0 | |
|
||||
| term | | varchar(255) | NO | | | |
|
||||
|
||||
Indexes
|
||||
------------
|
||||
|
||||
| Name | Fields |
|
||||
| -------- | ------------- |
|
||||
| PRIMARY | id |
|
||||
| uid_term | uid, term(64) |
|
||||
| term | term(64) |
|
||||
|
||||
Foreign Keys
|
||||
------------
|
||||
|
||||
| Field | Target Table | Target Field |
|
||||
|-------|--------------|--------------|
|
||||
| uid | [user](help/database/db_user) | uid |
|
||||
|
||||
Return to [database documentation](help/database)
|
||||
|
|
|
|||
|
|
@ -1,11 +1,26 @@
|
|||
Table session
|
||||
=============
|
||||
===========
|
||||
|
||||
web session storage
|
||||
|
||||
Fields
|
||||
------
|
||||
|
||||
| Field | Description | Type | Null | Key | Default | Extra |
|
||||
| ------ | ------------- | --------------- | ---- | --- | ------- | -------------- |
|
||||
| id | sequential ID | bigint unsigned | NO | PRI | NULL | auto_increment |
|
||||
| sid | | varbinary(255) | NO | | | |
|
||||
| data | | text | YES | | NULL | |
|
||||
| expire | | int unsigned | NO | | 0 | |
|
||||
|
||||
Indexes
|
||||
------------
|
||||
|
||||
| Name | Fields |
|
||||
| ------- | ------- |
|
||||
| PRIMARY | id |
|
||||
| sid | sid(64) |
|
||||
| expire | expire |
|
||||
|
||||
| Field | Description | Type | Null | Key | Default | Extra |
|
||||
| ------ | ------------- | ------------------- | ---- | --- | ------- | --------------- |
|
||||
| id | sequential ID | bigint(20) unsigned | NO | PRI | NULL | auto_increment |
|
||||
| sid | | varchar(255) | NO | MUL | | |
|
||||
| data | | text | NO | | NULL | |
|
||||
| expire | | int(10) unsigned | NO | MUL | 0 | |
|
||||
|
||||
Return to [database documentation](help/database)
|
||||
|
|
|
|||
|
|
@ -1,12 +0,0 @@
|
|||
Table sign
|
||||
==========
|
||||
|
||||
| Field | Description | Type | Null | Key | Default | Extra |
|
||||
| ------------ | ------------- | ---------------- | ---- | --- | ------- | --------------- |
|
||||
| id | sequential ID | int(10) unsigned | NO | PRI | NULL | auto_increment |
|
||||
| iid | item.id | int(10) unsigned | NO | MUL | 0 | |
|
||||
| signed_text | | mediumtext | NO | | NULL | |
|
||||
| signature | | text | NO | | NULL | |
|
||||
| signer | | varchar(255) | NO | | | |
|
||||
|
||||
Return to [database documentation](help/database)
|
||||
22
doc/database/db_storage.md
Normal file
22
doc/database/db_storage.md
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
Table storage
|
||||
===========
|
||||
|
||||
Data stored by Database storage backend
|
||||
|
||||
Fields
|
||||
------
|
||||
|
||||
| Field | Description | Type | Null | Key | Default | Extra |
|
||||
| ----- | ------------------------------ | ------------ | ---- | --- | ------- | -------------- |
|
||||
| id | Auto incremented image data id | int unsigned | NO | PRI | NULL | auto_increment |
|
||||
| data | file data | longblob | NO | | NULL | |
|
||||
|
||||
Indexes
|
||||
------------
|
||||
|
||||
| Name | Fields |
|
||||
| ------- | ------ |
|
||||
| PRIMARY | id |
|
||||
|
||||
|
||||
Return to [database documentation](help/database)
|
||||
25
doc/database/db_tag.md
Normal file
25
doc/database/db_tag.md
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
Table tag
|
||||
===========
|
||||
|
||||
tags and mentions
|
||||
|
||||
Fields
|
||||
------
|
||||
|
||||
| Field | Description | Type | Null | Key | Default | Extra |
|
||||
| ----- | ----------- | -------------- | ---- | --- | ------- | -------------- |
|
||||
| id | | int unsigned | NO | PRI | NULL | auto_increment |
|
||||
| name | | varchar(96) | NO | | | |
|
||||
| url | | varbinary(255) | NO | | | |
|
||||
|
||||
Indexes
|
||||
------------
|
||||
|
||||
| Name | Fields |
|
||||
| ------------- | ----------------- |
|
||||
| PRIMARY | id |
|
||||
| type_name_url | UNIQUE, name, url |
|
||||
| url | url |
|
||||
|
||||
|
||||
Return to [database documentation](help/database)
|
||||
|
|
@ -1,19 +0,0 @@
|
|||
Table term
|
||||
==========
|
||||
|
||||
| Field | Description | Type | Null | Key | Default | Extra |
|
||||
|----------| ------------- |---------------------|------|-----|---------------------|----------------|
|
||||
| tid | | int(10) unsigned | NO | PRI | NULL | auto_increment |
|
||||
| oid | | int(10) unsigned | NO | MUL | 0 | |
|
||||
| otype | | tinyint(3) unsigned | NO | MUL | 0 | |
|
||||
| type | | tinyint(3) unsigned | NO | MUL | 0 | |
|
||||
| term | | varchar(255) | NO | | | |
|
||||
| url | | varchar(255) | NO | | | |
|
||||
| aid | | int(10) unsigned | NO | | 0 | |
|
||||
| uid | | int(10) unsigned | NO | MUL | 0 | |
|
||||
| guid | | varchar(255) | NO | MUL | | |
|
||||
| created | | datetime | NO | | 0001-01-01 00:00:00 | |
|
||||
| received | | datetime | NO | | 0001-01-01 00:00:00 | |
|
||||
| global | | tinyint(1) | NO | | 0 | |
|
||||
|
||||
Return to [database documentation](help/database)
|
||||
|
|
@ -1,33 +0,0 @@
|
|||
Table thread
|
||||
============
|
||||
|
||||
| Field | Description | Type | Null | Key | Default | Extra |
|
||||
|-------------|------------------|------------------|------|-----|---------------------|-------|
|
||||
| iid | sequential ID | int(10) unsigned | NO | PRI | 0 | |
|
||||
| uid | | int(10) unsigned | NO | MUL | 0 | |
|
||||
| contact-id | | int(11) unsigned | NO | | 0 | |
|
||||
| gcontact-id | Global Contact | int(11) unsigned | NO | | 0 | |
|
||||
| owner-id | Item owner | int(11) unsigned | NO | MUL | 0 | |
|
||||
| author-id | Item author | int(11) unsigned | NO | MUL | 0 | |
|
||||
| created | | datetime | NO | MUL | 0001-01-01 00:00:00 | |
|
||||
| edited | | datetime | NO | | 0001-01-01 00:00:00 | |
|
||||
| commented | | datetime | NO | MUL | 0001-01-01 00:00:00 | |
|
||||
| received | | datetime | NO | | 0001-01-01 00:00:00 | |
|
||||
| changed | | datetime | NO | | 0001-01-01 00:00:00 | |
|
||||
| wall | | tinyint(1) | NO | MUL | 0 | |
|
||||
| private | | tinyint(1) | NO | | 0 | |
|
||||
| pubmail | | tinyint(1) | NO | | 0 | |
|
||||
| moderated | | tinyint(1) | NO | | 0 | |
|
||||
| visible | | tinyint(1) | NO | | 0 | |
|
||||
| spam | | tinyint(1) | NO | | 0 | |
|
||||
| starred | | tinyint(1) | NO | | 0 | |
|
||||
| ignored | | tinyint(1) | NO | | 0 | |
|
||||
| bookmark | | tinyint(1) | NO | | 0 | |
|
||||
| unseen | | tinyint(1) | NO | | 1 | |
|
||||
| deleted | | tinyint(1) | NO | | 0 | |
|
||||
| origin | | tinyint(1) | NO | | 0 | |
|
||||
| forum_mode | | tinyint(1) | NO | | 0 | |
|
||||
| mention | | tinyint(1) | NO | | 0 | |
|
||||
| network | | varchar(32) | NO | | | |
|
||||
|
||||
Return to [database documentation](help/database)
|
||||
|
|
@ -1,13 +1,35 @@
|
|||
Table tokens
|
||||
============
|
||||
===========
|
||||
|
||||
| Field | Description | Type | Null | Key | Default | Extra |
|
||||
| ---------- | ----------- | ------------ | ---- | --- | ------- | ----- |
|
||||
| id | | varchar(40) | NO | PRI | NULL | |
|
||||
| secret | | text | NO | | NULL | |
|
||||
| client_id | | varchar(20) | NO | | | |
|
||||
| expires | | int(11) | NO | | 0 | |
|
||||
| scope | | varchar(200) | NO | | | |
|
||||
| uid | | int(11) | NO | | 0 | |
|
||||
OAuth usage
|
||||
|
||||
Fields
|
||||
------
|
||||
|
||||
| Field | Description | Type | Null | Key | Default | Extra |
|
||||
| --------- | ----------- | ------------------ | ---- | --- | ------- | ----- |
|
||||
| id | | varchar(40) | NO | PRI | NULL | |
|
||||
| secret | | text | YES | | NULL | |
|
||||
| client_id | | varchar(20) | NO | | | |
|
||||
| expires | | int | NO | | 0 | |
|
||||
| scope | | varchar(200) | NO | | | |
|
||||
| uid | User id | mediumint unsigned | NO | | 0 | |
|
||||
|
||||
Indexes
|
||||
------------
|
||||
|
||||
| Name | Fields |
|
||||
| --------- | --------- |
|
||||
| PRIMARY | id |
|
||||
| client_id | client_id |
|
||||
| uid | uid |
|
||||
|
||||
Foreign Keys
|
||||
------------
|
||||
|
||||
| Field | Target Table | Target Field |
|
||||
|-------|--------------|--------------|
|
||||
| client_id | [clients](help/database/db_clients) | client_id |
|
||||
| uid | [user](help/database/db_user) | uid |
|
||||
|
||||
Return to [database documentation](help/database)
|
||||
|
|
|
|||
33
doc/database/db_user-contact.md
Normal file
33
doc/database/db_user-contact.md
Normal file
|
|
@ -0,0 +1,33 @@
|
|||
Table user-contact
|
||||
===========
|
||||
|
||||
User specific public contact data
|
||||
|
||||
Fields
|
||||
------
|
||||
|
||||
| Field | Description | Type | Null | Key | Default | Extra |
|
||||
| --------- | ------------------------------------------- | ------------------ | ---- | --- | ------- | ----- |
|
||||
| cid | Contact id of the linked public contact | int unsigned | NO | PRI | 0 | |
|
||||
| uid | User id | mediumint unsigned | NO | PRI | 0 | |
|
||||
| blocked | Contact is completely blocked for this user | boolean | YES | | NULL | |
|
||||
| ignored | Posts from this contact are ignored | boolean | YES | | NULL | |
|
||||
| collapsed | Posts from this contact are collapsed | boolean | YES | | NULL | |
|
||||
|
||||
Indexes
|
||||
------------
|
||||
|
||||
| Name | Fields |
|
||||
| ------- | -------- |
|
||||
| PRIMARY | uid, cid |
|
||||
| cid | cid |
|
||||
|
||||
Foreign Keys
|
||||
------------
|
||||
|
||||
| Field | Target Table | Target Field |
|
||||
|-------|--------------|--------------|
|
||||
| cid | [contact](help/database/db_contact) | id |
|
||||
| uid | [user](help/database/db_user) | uid |
|
||||
|
||||
Return to [database documentation](help/database)
|
||||
|
|
@ -1,77 +1,75 @@
|
|||
Table user
|
||||
==========
|
||||
===========
|
||||
|
||||
| Field | Description | Type | Null | Key | Default | Extra |
|
||||
|--------------------------|-----------------------------------------------------------------------------------------|---------------------|------|-----|---------------------|----------------|
|
||||
| uid | sequential ID | int(11) | NO | PRI | NULL | auto_increment |
|
||||
| guid | A unique identifier for this user | varchar(64) | NO | | | |
|
||||
| username | Name that this user is known by | varchar(255) | NO | | | |
|
||||
| password | encrypted password | varchar(255) | NO | | | |
|
||||
| nickname | nick- and user name | varchar(255) | NO | MUL | | |
|
||||
| email | the users email address | varchar(255) | NO | | | |
|
||||
| openid | | varchar(255) | NO | | | |
|
||||
| timezone | PHP-legal timezone | varchar(128) | NO | | | |
|
||||
| language | default language | varchar(32) | NO | | en | |
|
||||
| register_date | timestamp of registration | datetime | NO | | 0001-01-01 00:00:00 | |
|
||||
| login_date | timestamp of last login | datetime | NO | | 0001-01-01 00:00:00 | |
|
||||
| default-location | Default for item.location | varchar(255) | NO | | | |
|
||||
| allow_location | 1 allows to display the location | tinyint(1) | NO | | 0 | |
|
||||
| theme | user theme preference | varchar(255) | NO | | | |
|
||||
| pubkey | RSA public key 4096 bit | text | NO | | NULL | |
|
||||
| prvkey | RSA private key 4096 bit | text | NO | | NULL | |
|
||||
| spubkey | | text | NO | | NULL | |
|
||||
| sprvkey | | text | NO | | NULL | |
|
||||
| verified | user is verified through email | tinyint(1) unsigned | NO | | 0 | |
|
||||
| blocked | 1 for user is blocked | tinyint(1) unsigned | NO | | 0 | |
|
||||
| blockwall | Prohibit contacts to post to the profile page of the user | tinyint(1) unsigned | NO | | 0 | |
|
||||
| hidewall | Hide profile details from unkown viewers | tinyint(1) unsigned | NO | | 0 | |
|
||||
| blocktags | Prohibit contacts to tag the post of this user | tinyint(1) unsigned | NO | | 0 | |
|
||||
| unkmail | Permit unknown people to send private mails to this user | tinyint(1) | NO | | 0 | |
|
||||
| cntunkmail | | int(11) | NO | | 10 | |
|
||||
| notify-flags | email notification options | int(11) unsigned | NO | | 65535 | |
|
||||
| page-flags | page/profile type | int(11) unsigned | NO | | 0 | |
|
||||
| prvnets | | tinyint(1) | NO | | 0 | |
|
||||
| pwdreset | | varchar(255) | NO | | | |
|
||||
| maxreq | | int(11) | NO | | 10 | |
|
||||
| expire | | int(11) unsigned | NO | | 0 | |
|
||||
| account_removed | if 1 the account is removed | tinyint(1) | NO | | 0 | |
|
||||
| account_expired | | tinyint(1) | NO | | 0 | |
|
||||
| account_expires_on | timestamp when account expires and will be deleted | datetime | NO | | 0001-01-01 00:00:00 | |
|
||||
| expire_notification_sent | timestamp of last warning of account expiration | datetime | NO | | 0001-01-01 00:00:00 | |
|
||||
| def_gid | | int(11) | NO | | 0 | |
|
||||
| allow_cid | default permission for this user | mediumtext | NO | | NULL | |
|
||||
| allow_gid | default permission for this user | mediumtext | NO | | NULL | |
|
||||
| deny_cid | default permission for this user | mediumtext | NO | | NULL | |
|
||||
| deny_gid | default permission for this user | mediumtext | NO | | NULL | |
|
||||
| openidserver | | text | NO | | NULL | |
|
||||
The local users
|
||||
|
||||
```
|
||||
/**
|
||||
* page-flags
|
||||
*/
|
||||
define ( 'PAGE_NORMAL', 0 );
|
||||
define ( 'PAGE_SOAPBOX', 1 );
|
||||
define ( 'PAGE_COMMUNITY', 2 );
|
||||
define ( 'PAGE_FREELOVE', 3 );
|
||||
define ( 'PAGE_BLOG', 4 );
|
||||
define ( 'PAGE_PRVGROUP', 5 );
|
||||
Fields
|
||||
------
|
||||
|
||||
/**
|
||||
* notify-flags
|
||||
*/
|
||||
define ( 'NOTIFY_INTRO', 0x0001 );
|
||||
define ( 'NOTIFY_CONFIRM', 0x0002 );
|
||||
define ( 'NOTIFY_WALL', 0x0004 );
|
||||
define ( 'NOTIFY_COMMENT', 0x0008 );
|
||||
define ( 'NOTIFY_MAIL', 0x0010 );
|
||||
define ( 'NOTIFY_SUGGEST', 0x0020 );
|
||||
define ( 'NOTIFY_PROFILE', 0x0040 );
|
||||
define ( 'NOTIFY_TAGSELF', 0x0080 );
|
||||
define ( 'NOTIFY_TAGSHARE', 0x0100 );
|
||||
define ( 'NOTIFY_POKE', 0x0200 );
|
||||
define ( 'NOTIFY_SHARE', 0x0400 );
|
||||
| Field | Description | Type | Null | Key | Default | Extra |
|
||||
| ------------------------ | --------------------------------------------------------- | ------------------ | ---- | --- | ------------------- | -------------- |
|
||||
| uid | sequential ID | mediumint unsigned | NO | PRI | NULL | auto_increment |
|
||||
| parent-uid | The parent user that has full control about this user | mediumint unsigned | YES | | NULL | |
|
||||
| guid | A unique identifier for this user | varchar(64) | NO | | | |
|
||||
| username | Name that this user is known by | varchar(255) | NO | | | |
|
||||
| password | encrypted password | varchar(255) | NO | | | |
|
||||
| legacy_password | Is the password hash double-hashed? | boolean | NO | | 0 | |
|
||||
| nickname | nick- and user name | varchar(255) | NO | | | |
|
||||
| email | the users email address | varchar(255) | NO | | | |
|
||||
| openid | | varchar(255) | NO | | | |
|
||||
| timezone | PHP-legal timezone | varchar(128) | NO | | | |
|
||||
| language | default language | varchar(32) | NO | | en | |
|
||||
| register_date | timestamp of registration | datetime | NO | | 0001-01-01 00:00:00 | |
|
||||
| login_date | timestamp of last login | datetime | NO | | 0001-01-01 00:00:00 | |
|
||||
| default-location | Default for item.location | varchar(255) | NO | | | |
|
||||
| allow_location | 1 allows to display the location | boolean | NO | | 0 | |
|
||||
| theme | user theme preference | varchar(255) | NO | | | |
|
||||
| pubkey | RSA public key 4096 bit | text | YES | | NULL | |
|
||||
| prvkey | RSA private key 4096 bit | text | YES | | NULL | |
|
||||
| spubkey | | text | YES | | NULL | |
|
||||
| sprvkey | | text | YES | | NULL | |
|
||||
| verified | user is verified through email | boolean | NO | | 0 | |
|
||||
| blocked | 1 for user is blocked | boolean | NO | | 0 | |
|
||||
| blockwall | Prohibit contacts to post to the profile page of the user | boolean | NO | | 0 | |
|
||||
| hidewall | Hide profile details from unkown viewers | boolean | NO | | 0 | |
|
||||
| blocktags | Prohibit contacts to tag the post of this user | boolean | NO | | 0 | |
|
||||
| unkmail | Permit unknown people to send private mails to this user | boolean | NO | | 0 | |
|
||||
| cntunkmail | | int unsigned | NO | | 10 | |
|
||||
| notify-flags | email notification options | smallint unsigned | NO | | 65535 | |
|
||||
| page-flags | page/profile type | tinyint unsigned | NO | | 0 | |
|
||||
| account-type | | tinyint unsigned | NO | | 0 | |
|
||||
| prvnets | | boolean | NO | | 0 | |
|
||||
| pwdreset | Password reset request token | varchar(255) | YES | | NULL | |
|
||||
| pwdreset_time | Timestamp of the last password reset request | datetime | YES | | NULL | |
|
||||
| maxreq | | int unsigned | NO | | 10 | |
|
||||
| expire | | int unsigned | NO | | 0 | |
|
||||
| account_removed | if 1 the account is removed | boolean | NO | | 0 | |
|
||||
| account_expired | | boolean | NO | | 0 | |
|
||||
| account_expires_on | timestamp when account expires and will be deleted | datetime | NO | | 0001-01-01 00:00:00 | |
|
||||
| expire_notification_sent | timestamp of last warning of account expiration | datetime | NO | | 0001-01-01 00:00:00 | |
|
||||
| def_gid | | int unsigned | NO | | 0 | |
|
||||
| allow_cid | default permission for this user | mediumtext | YES | | NULL | |
|
||||
| allow_gid | default permission for this user | mediumtext | YES | | NULL | |
|
||||
| deny_cid | default permission for this user | mediumtext | YES | | NULL | |
|
||||
| deny_gid | default permission for this user | mediumtext | YES | | NULL | |
|
||||
| openidserver | | text | YES | | NULL | |
|
||||
|
||||
define ( 'NOTIFY_SYSTEM', 0x8000 );
|
||||
```
|
||||
Indexes
|
||||
------------
|
||||
|
||||
| Name | Fields |
|
||||
| ---------- | ------------ |
|
||||
| PRIMARY | uid |
|
||||
| nickname | nickname(32) |
|
||||
| parent-uid | parent-uid |
|
||||
| guid | guid |
|
||||
| email | email(64) |
|
||||
|
||||
Foreign Keys
|
||||
------------
|
||||
|
||||
| Field | Target Table | Target Field |
|
||||
|-------|--------------|--------------|
|
||||
| parent-uid | [user](help/database/db_user) | uid |
|
||||
|
||||
Return to [database documentation](help/database)
|
||||
|
|
|
|||
|
|
@ -1,9 +1,23 @@
|
|||
Table userd
|
||||
===========
|
||||
|
||||
| Field | Description | Type | Null | Key | Default | Extra |
|
||||
|----------|------------------|--------------|------|-----|---------|----------------|
|
||||
| id | sequential ID | int(11) | NO | PRI | NULL | auto_increment |
|
||||
| username | | varchar(255) | NO | MUL | NULL | |
|
||||
Deleted usernames
|
||||
|
||||
Fields
|
||||
------
|
||||
|
||||
| Field | Description | Type | Null | Key | Default | Extra |
|
||||
| -------- | ------------- | ------------ | ---- | --- | ------- | -------------- |
|
||||
| id | sequential ID | int unsigned | NO | PRI | NULL | auto_increment |
|
||||
| username | | varchar(255) | NO | | NULL | |
|
||||
|
||||
Indexes
|
||||
------------
|
||||
|
||||
| Name | Fields |
|
||||
| -------- | ------------ |
|
||||
| PRIMARY | id |
|
||||
| username | username(32) |
|
||||
|
||||
|
||||
Return to [database documentation](help/database)
|
||||
|
|
|
|||
23
doc/database/db_verb.md
Normal file
23
doc/database/db_verb.md
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
Table verb
|
||||
===========
|
||||
|
||||
Activity Verbs
|
||||
|
||||
Fields
|
||||
------
|
||||
|
||||
| Field | Description | Type | Null | Key | Default | Extra |
|
||||
| ----- | ----------- | ----------------- | ---- | --- | ------- | -------------- |
|
||||
| id | | smallint unsigned | NO | PRI | NULL | auto_increment |
|
||||
| name | | varchar(100) | NO | | | |
|
||||
|
||||
Indexes
|
||||
------------
|
||||
|
||||
| Name | Fields |
|
||||
| ------- | ------ |
|
||||
| PRIMARY | id |
|
||||
| name | name |
|
||||
|
||||
|
||||
Return to [database documentation](help/database)
|
||||
22
doc/database/db_worker-ipc.md
Normal file
22
doc/database/db_worker-ipc.md
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
Table worker-ipc
|
||||
===========
|
||||
|
||||
Inter process communication between the frontend and the worker
|
||||
|
||||
Fields
|
||||
------
|
||||
|
||||
| Field | Description | Type | Null | Key | Default | Extra |
|
||||
| ----- | ------------------------- | ------- | ---- | --- | ------- | ----- |
|
||||
| key | | int | NO | PRI | NULL | |
|
||||
| jobs | Flag for outstanding jobs | boolean | YES | | NULL | |
|
||||
|
||||
Indexes
|
||||
------------
|
||||
|
||||
| Name | Fields |
|
||||
| ------- | ------ |
|
||||
| PRIMARY | key |
|
||||
|
||||
|
||||
Return to [database documentation](help/database)
|
||||
|
|
@ -1,14 +1,38 @@
|
|||
Table workerqueue
|
||||
=================
|
||||
===========
|
||||
|
||||
Background tasks queue entries
|
||||
|
||||
Fields
|
||||
------
|
||||
|
||||
| Field | Description | Type | Null | Key | Default | Extra |
|
||||
| --------- | ------------------------------------------------------- | ---------------- | ---- | --- | ------------------- | -------------- |
|
||||
| id | Auto incremented worker task id | int unsigned | NO | PRI | NULL | auto_increment |
|
||||
| command | Task command | varchar(100) | YES | | NULL | |
|
||||
| parameter | Task parameter | mediumtext | YES | | NULL | |
|
||||
| priority | Task priority | tinyint unsigned | NO | | 0 | |
|
||||
| created | Creation date | datetime | NO | | 0001-01-01 00:00:00 | |
|
||||
| pid | Process id of the worker | int unsigned | NO | | 0 | |
|
||||
| executed | Execution date | datetime | NO | | 0001-01-01 00:00:00 | |
|
||||
| next_try | Next retrial date | datetime | NO | | 0001-01-01 00:00:00 | |
|
||||
| retrial | Retrial counter | tinyint | NO | | 0 | |
|
||||
| done | Marked 1 when the task was done - will be deleted later | boolean | NO | | 0 | |
|
||||
|
||||
Indexes
|
||||
------------
|
||||
|
||||
| Name | Fields |
|
||||
| ----------------------------- | -------------------------------- |
|
||||
| PRIMARY | id |
|
||||
| command | command |
|
||||
| done_command_parameter | done, command, parameter(64) |
|
||||
| done_executed | done, executed |
|
||||
| done_priority_retrial_created | done, priority, retrial, created |
|
||||
| done_priority_next_try | done, priority, next_try |
|
||||
| done_pid_next_try | done, pid, next_try |
|
||||
| done_pid_retrial | done, pid, retrial |
|
||||
| done_pid_priority_created | done, pid, priority, created |
|
||||
|
||||
| Field | Description | Type | Null | Key | Default | Extra |
|
||||
|-----------|------------------|---------------------|------|-----|---------------------|----------------|
|
||||
| id | sequential ID | int(11) | NO | PRI | NULL | auto_increment |
|
||||
| parameter | | text | NO | | NULL | |
|
||||
| priority | | tinyint(3) unsigned | NO | | 0 | |
|
||||
| created | | datetime | NO | MUL | 0001-01-01 00:00:00 | |
|
||||
| pid | | int(11) | NO | | 0 | |
|
||||
| executed | | datetime | NO | | 0001-01-01 00:00:00 | |
|
||||
| done | set to 1 if done | tinyint(1) | NO | | 0 | |
|
||||
|
||||
Return to [database documentation](help/database)
|
||||
|
|
|
|||
|
|
@ -36,9 +36,10 @@ Wenn Du Deinen Account nicht nutzen kannst, kannst Du einen Account auf einer ö
|
|||
Wenn du dir keinen weiteren Friendica Account einrichten willst, kannst du auch gerne über einen der folgenden alternativen Kanäle Hilfe suchen:
|
||||
|
||||
* Friendica Support Forum: [@helpers@forum.friendi.ca](https://forum.friendi.ca/~helpers)
|
||||
* XMPP: support(at)forum.friendi.ca
|
||||
* IRC: [#friendica at freenode.net](https://webchat.freenode.net/?settings=#friendica)
|
||||
* Matrix: [#friendica-en:matrix.org](https://matrix.to/#/#friendica-en:matrix.org) or [#friendi.ca:matrix.org](https://matrix.to/#/#friendi.ca:matrix.org)
|
||||
* Chats der Friendica Community (die IRC, Matrix und XMPP Räume sind mit einer Brücke verbunden) Logs dieser öffentlichen Chaträume können [hier aus dem IRC](https://gnusociarg.nsupdate.info/2021/%23frie) und [hier aus der Matrix](https://view.matrix.org/alias/%23friendi.ca:matrix.org/) gefunden werden.
|
||||
* XMPP: support(at)forum.friendi.ca
|
||||
* IRC: #friendica aut libera.chat oder [#friendica auf freenode.net](https://webchat.freenode.net/?settings=#friendica)
|
||||
* Matrix: [#friendica-en:matrix.org](https://matrix.to/#/#friendica-en:matrix.org) or [#friendi.ca:matrix.org](https://matrix.to/#/#friendi.ca:matrix.org)
|
||||
* [Mailing List](http://mailman.friendi.ca/mailman/listinfo/support-friendi.ca)
|
||||
<!--- * [XMPP](xmpp:support@forum.friendi.ca?join)
|
||||
https://github.com/github/markup/issues/202
|
||||
|
|
@ -193,26 +194,63 @@ Beispiel: Friendica Support
|
|||
|
||||
Friendica verwendet eine [Twitter/GNU Social](help/api) kompatible API.
|
||||
Das bedeutet, dass du jeden Twitter/GNU Social Client verwenden kannst in dem du den API Pfad entsprechend änderst.
|
||||
Seit der Version 2021.06 unterstützt Friendica außerdem die [Mastodon API](help/API-Mastodon) die mit vielen Mastodon-Clients läuft.
|
||||
|
||||
Hier ist eine Liste von Clients bei denen dies möglich ist, bzw. die speziell für Friendica entwickelt werden:
|
||||
Hier ist eine Liste von Clients, die speziell für Friendica entwickelt werden oder die mit Friendica kompatibel sind:
|
||||
|
||||
* Android
|
||||
* [Friendiqa](https://git.friendi.ca/lubuwest/Friendiqa) (Gibt es im Google Playstore oder als [binary Repository](https://freunde.ma-nic.de/display/3e98eba8185a13c5bdbf3d1539646854) für F-Droid)
|
||||
* [Fedilab](https://gitlab.com/tom79/mastalab) (Gibt es im F-Droid und dem Google Play Store)
|
||||
* [DiCa](https://dica.mixi.cool/) (Gibt es bei Google Play)
|
||||
* AndStatus
|
||||
* Twidere
|
||||
* Mustard and Mustard-Mod
|
||||
* SailfishOS
|
||||
* [Friendly](https://openrepos.net/content/fabrixxm/friendly#comment-form)
|
||||
* Linux
|
||||
* Hotot
|
||||
* Choqok
|
||||
* MacOS X
|
||||
* Hotot
|
||||
* Windows
|
||||
* [Friendica Mobile](https://www.microsoft.com/de-DE/store/p/friendica-mobile/9nblggh0fhmn?rtc=1) für Windows 10
|
||||
* Hotot
|
||||
#### Android
|
||||
|
||||
* [AndStatus](http://andstatus.org) ([F-Droid](https://f-droid.org/repository/browse/?fdid=org.andstatus.app), [Google Play](https://play.google.com/store/apps/details?id=org.andstatus.app))
|
||||
* [B4X for Pleroma & Mastodon](https://github.com/AnywhereSoftware/B4X-Pleroma)
|
||||
* [DiCa](https://dica.mixi.cool/) (Gibt es bei Google Play)
|
||||
* [Fedi](https://play.google.com/store/apps/details?id=com.fediverse.app)
|
||||
* [Fedilab](https://fedilab.app) ([F-Droid](https://f-droid.org/app/fr.gouv.etalab.mastodon), [Google Play](https://play.google.com/store/apps/details?id=app.fedilab.android))
|
||||
* [Friendiqa](https://git.friendi.ca/lubuwest/Friendiqa) (Gibt es im Google Playstore oder als [binary Repository](https://freunde.ma-nic.de/display/3e98eba8185a13c5bdbf3d1539646854) für F-Droid)
|
||||
* [Husky](https://husky.fwgs.ru)
|
||||
* [Roma](https://play.google.com/store/apps/details?id=tech.bigfig.roma)
|
||||
* [Subway Tooter](https://github.com/tateisu/SubwayTooter)
|
||||
* [Tooot](https://tooot.app/)
|
||||
* [Tusky](https://tusky.app)
|
||||
* [Twidere](https://dimension.im/) ([F-Droid](https://f-droid.org/repository/browse/?fdid=org.mariotaku.twidere), [Google Play](https://play.google.com/store/apps/details?id=com.twidere.twiderex), [GitHub](https://github.com/TwidereProject/Twidere-Android))
|
||||
* [TwidereX](https://github.com/TwidereProject/TwidereX-Android)
|
||||
* [twitlatte](https://github.com/moko256/twitlatte)
|
||||
* [Yuito](https://github.com/accelforce/Yuito)
|
||||
|
||||
#### SailfishOS
|
||||
|
||||
* [Friendly](https://openrepos.net/content/fabrixxm/friendly#comment-form)
|
||||
|
||||
#### iOS
|
||||
|
||||
- [Amaroq](https://github.com/ReticentJohn/Amaroq/tree/master)
|
||||
- [B4X for Pleroma & Mastodon](https://github.com/AnywhereSoftware/B4X-Pleroma)
|
||||
- [Fedi](https://apps.apple.com/de/app/fedi-for-pleroma-and-mastodon/id1478806281)
|
||||
- [Roma](https://apps.apple.com/de/app/roma-for-pleroma-and-mastodon/id1445328699)
|
||||
- [StarPterano](https://apps.apple.com/de/app/starpterano/id1436972796)
|
||||
- [Stella](https://apps.apple.com/us/app/stella-for-mastodon-twitter/id921372048?l=ms)
|
||||
- [Tooot](https://tooot.app/)
|
||||
- [Tootle](https://apps.apple.com/de/app/tootle-for-mastodon/id1236013466) Der eingegene Hostname muss in Groß-/Kleinschreibung mit dem Hostnamen des Systems übereinstimmen. Die aktuelle Version stürzt bei Benachrichtungen bom Typ "status" ab.
|
||||
|
||||
#### Linux
|
||||
|
||||
* [Choqok](https://choqok.kde.org)
|
||||
* [Whalebird](https://whalebird.social)
|
||||
* [TheDesk](https://ja.mstdn.wiki/TheDesk)
|
||||
* [Toot](https://toot.readthedocs.io/en/latest/)
|
||||
* [Tootle](https://github.com/bleakgrey/tootle)
|
||||
|
||||
#### MacOS
|
||||
|
||||
- [Mastonaut](https://mastonaut.app/)
|
||||
|
||||
#### Windows
|
||||
|
||||
* [Friendica Mobile](https://www.microsoft.com/de-DE/store/p/friendica-mobile/9nblggh0fhmn?rtc=1) für Windows 10
|
||||
|
||||
#### Web
|
||||
|
||||
- [Halcyon](https://www.halcyon.social/)
|
||||
- [Pinafore](https://github.com/nolanlawson/pinafore)
|
||||
|
||||
Admin
|
||||
--------
|
||||
|
|
|
|||
|
|
@ -54,7 +54,7 @@ Friendica - Dokumentation und Ressourcen
|
|||
* [Class Autoloading](help/autoloader) (EN)
|
||||
* [Using Composer](help/Composer) (EN)
|
||||
* [Code-Referenz (mit doxygen generiert - setzt Cookies)](doc/html/)
|
||||
* [Twitter/GNU Social API Functions](help/api) (EN)
|
||||
* [API Dokumentation](help/api) (EN)
|
||||
* [Translation of Friendica](help/translations) (EN)
|
||||
* [Run tests](help/Tests) (EN)
|
||||
|
||||
|
|
@ -64,9 +64,10 @@ Friendica - Dokumentation und Ressourcen
|
|||
* Support Kanäle
|
||||
* Friendica Support Forum: [@helpers@forum.friendi.ca](https://forum.friendi.ca/~helpers)
|
||||
* [Mailing Listen Archiv](http://mailman.friendi.ca/mailman/listinfo/support-friendi.ca) zum Abonnieren der Liste eine E-Mail an ``support-request(at)friendi.ca?subject=subscribe`` senden
|
||||
* XMPP/Jabber MUC: support(at)forum.friendi.ca
|
||||
* IRC: [#friendica auf irc.freenode.net](https://webchat.freenode.net/?settings=#friendica)
|
||||
* Matrix: [#friendi.ca](https://matrix.to/#/#friendi.ca:matrix.org) oder [#friendica-en](https://matrix.to/#/#friendica-en:matrix.org) auf matrix.org
|
||||
* Chats der Friendica Community (die IRC, Matrix und XMPP Räume sind mit einer Brücke verbunden) Logs dieser öffentlichen Chaträume können [hier aus dem IRC](https://gnusociarg.nsupdate.info/2021/%23frie) und [hier aus der Matrix](https://view.matrix.org/alias/%23friendi.ca:matrix.org/) gefunden werden.
|
||||
* XMPP/Jabber MUC: support(at)forum.friendi.ca
|
||||
* IRC: #friendica auf libera.chat oder [#friendica auf irc.freenode.net](https://webchat.freenode.net/?settings=#friendica)
|
||||
* Matrix: [#friendi.ca](https://matrix.to/#/#friendi.ca:matrix.org) oder [#friendica-en](https://matrix.to/#/#friendica-en:matrix.org) auf matrix.org
|
||||
|
||||
**Über diese Seite**
|
||||
|
||||
|
|
|
|||
|
|
@ -42,6 +42,7 @@ use Friendica\Model\Mail;
|
|||
use Friendica\Model\Notification;
|
||||
use Friendica\Model\Photo;
|
||||
use Friendica\Model\Post;
|
||||
use Friendica\Model\Profile;
|
||||
use Friendica\Model\User;
|
||||
use Friendica\Model\Verb;
|
||||
use Friendica\Network\HTTPException;
|
||||
|
|
@ -57,6 +58,7 @@ use Friendica\Object\Image;
|
|||
use Friendica\Protocol\Activity;
|
||||
use Friendica\Protocol\Diaspora;
|
||||
use Friendica\Security\FKOAuth1;
|
||||
use Friendica\Security\OAuth;
|
||||
use Friendica\Security\OAuth1\OAuthRequest;
|
||||
use Friendica\Security\OAuth1\OAuthUtil;
|
||||
use Friendica\Util\DateTimeFormat;
|
||||
|
|
@ -88,6 +90,11 @@ $called_api = [];
|
|||
*/
|
||||
function api_user()
|
||||
{
|
||||
$user = OAuth::getCurrentUserID();
|
||||
if (!empty($user)) {
|
||||
return $user;
|
||||
}
|
||||
|
||||
if (!empty($_SESSION['allow_api'])) {
|
||||
return local_user();
|
||||
}
|
||||
|
|
@ -175,7 +182,6 @@ function api_register_func($path, $func, $auth = false, $method = API_METHOD_ANY
|
|||
* Simple Auth allow username in form of <pre>user@server</pre>, ignoring server part
|
||||
*
|
||||
* @param App $a App
|
||||
* @param bool $do_login try to log in when not logged in, otherwise quit silently
|
||||
* @throws ForbiddenException
|
||||
* @throws InternalServerErrorException
|
||||
* @throws UnauthorizedException
|
||||
|
|
@ -186,7 +192,7 @@ function api_register_func($path, $func, $auth = false, $method = API_METHOD_ANY
|
|||
* 'authenticated' => return status,
|
||||
* 'user_record' => return authenticated user record
|
||||
*/
|
||||
function api_login(App $a, bool $do_login = true)
|
||||
function api_login(App $a)
|
||||
{
|
||||
$_SESSION["allow_api"] = false;
|
||||
|
||||
|
|
@ -219,10 +225,6 @@ function api_login(App $a, bool $do_login = true)
|
|||
Logger::warning(API_LOG_PREFIX . 'OAuth error', ['module' => 'api', 'action' => 'login', 'exception' => $e->getMessage()]);
|
||||
}
|
||||
|
||||
if (!$do_login) {
|
||||
return;
|
||||
}
|
||||
|
||||
Logger::debug(API_LOG_PREFIX . 'failed', ['module' => 'api', 'action' => 'login', 'parameters' => $_SERVER]);
|
||||
header('WWW-Authenticate: Basic realm="Friendica"');
|
||||
throw new UnauthorizedException("This API requires login");
|
||||
|
|
@ -264,9 +266,6 @@ function api_login(App $a, bool $do_login = true)
|
|||
}
|
||||
|
||||
if (!DBA::isResult($record)) {
|
||||
if (!$do_login) {
|
||||
return;
|
||||
}
|
||||
Logger::debug(API_LOG_PREFIX . 'failed', ['module' => 'api', 'action' => 'login', 'parameters' => $_SERVER]);
|
||||
header('WWW-Authenticate: Basic realm="Friendica"');
|
||||
//header('HTTP/1.0 401 Unauthorized');
|
||||
|
|
@ -602,7 +601,7 @@ function api_get_user(App $a, $contact_id = null)
|
|||
api_login($a);
|
||||
return false;
|
||||
} else {
|
||||
$user = $_SESSION['uid'];
|
||||
$user = api_user();
|
||||
$extra_query = "AND `contact`.`uid` = %d AND `contact`.`self` ";
|
||||
}
|
||||
}
|
||||
|
|
@ -1186,12 +1185,12 @@ function api_statuses_update($type)
|
|||
INNER JOIN `user` ON `user`.`uid` = `photo`.`uid` WHERE `resource-id` IN
|
||||
(SELECT `resource-id` FROM `photo` WHERE `id` = ?) AND `photo`.`uid` = ?
|
||||
ORDER BY `photo`.`width` DESC LIMIT 2", $id, api_user()));
|
||||
|
||||
|
||||
if (!empty($media)) {
|
||||
$ressources[] = $media[0]['resource-id'];
|
||||
$phototypes = Images::supportedTypes();
|
||||
$ext = $phototypes[$media[0]['type']];
|
||||
|
||||
|
||||
$attachment = ['type' => Post\Media::IMAGE, 'mimetype' => $media[0]['type'],
|
||||
'url' => DI::baseUrl() . '/photo/' . $media[0]['resource-id'] . '-' . $media[0]['scale'] . '.' . $ext,
|
||||
'size' => $media[0]['datasize'],
|
||||
|
|
@ -1199,7 +1198,7 @@ function api_statuses_update($type)
|
|||
'description' => $media[0]['desc'] ?? '',
|
||||
'width' => $media[0]['width'],
|
||||
'height' => $media[0]['height']];
|
||||
|
||||
|
||||
if (count($media) > 1) {
|
||||
$attachment['preview'] = DI::baseUrl() . '/photo/' . $media[1]['resource-id'] . '-' . $media[1]['scale'] . '.' . $ext;
|
||||
$attachment['preview-width'] = $media[1]['width'];
|
||||
|
|
@ -4554,12 +4553,7 @@ function api_account_update_profile_image($type)
|
|||
Contact::updateSelfFromUserID(api_user(), true);
|
||||
|
||||
// Update global directory in background
|
||||
$url = DI::baseUrl() . '/profile/' . DI::app()->user['nickname'];
|
||||
if ($url && strlen(DI::config()->get('system', 'directory'))) {
|
||||
Worker::add(PRIORITY_LOW, "Directory", $url);
|
||||
}
|
||||
|
||||
Worker::add(PRIORITY_LOW, 'ProfileUpdate', api_user());
|
||||
Profile::publishUpdate(api_user());
|
||||
|
||||
// output for client
|
||||
if ($data) {
|
||||
|
|
@ -4610,11 +4604,7 @@ function api_account_update_profile($type)
|
|||
DBA::update('contact', ['about' => $_POST['description']], ['id' => $api_user['id']]);
|
||||
}
|
||||
|
||||
Worker::add(PRIORITY_LOW, 'ProfileUpdate', $local_user);
|
||||
// Update global directory in background
|
||||
if ($api_user['url'] && strlen(DI::config()->get('system', 'directory'))) {
|
||||
Worker::add(PRIORITY_LOW, "Directory", $api_user['url']);
|
||||
}
|
||||
Profile::publishUpdate($local_user);
|
||||
|
||||
return api_account_verify_credentials($type);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -42,6 +42,7 @@ use Friendica\Object\Thread;
|
|||
use Friendica\Protocol\Activity;
|
||||
use Friendica\Util\Crypto;
|
||||
use Friendica\Util\DateTimeFormat;
|
||||
use Friendica\Util\Proxy;
|
||||
use Friendica\Util\Strings;
|
||||
use Friendica\Util\Temporal;
|
||||
use Friendica\Util\XML;
|
||||
|
|
@ -603,7 +604,7 @@ function conversation(App $a, array $items, $mode, $update, $preview = false, $o
|
|||
'name' => $profile_name,
|
||||
'sparkle' => $sparkle,
|
||||
'lock' => false,
|
||||
'thumb' => DI::baseUrl()->remove($item['author-avatar']),
|
||||
'thumb' => DI::baseUrl()->remove(Contact::getAvatarUrlForUrl($item['author-link'], $item['uid'], Proxy::SIZE_THUMB)),
|
||||
'title' => $title,
|
||||
'body_html' => $body_html,
|
||||
'tags' => $tags['tags'],
|
||||
|
|
@ -623,7 +624,7 @@ function conversation(App $a, array $items, $mode, $update, $preview = false, $o
|
|||
'indent' => '',
|
||||
'owner_name' => '',
|
||||
'owner_url' => '',
|
||||
'owner_photo' => DI::baseUrl()->remove($item['owner-avatar']),
|
||||
'owner_photo' => DI::baseUrl()->remove(Contact::getAvatarUrlForUrl($item['owner-link'], $item['uid'], Proxy::SIZE_THUMB)),
|
||||
'plink' => Item::getPlink($item),
|
||||
'edpost' => false,
|
||||
'isstarred' => 'unstarred',
|
||||
|
|
@ -737,8 +738,6 @@ function conversation_fetch_comments($thread_items, bool $pinned, array $activit
|
|||
}
|
||||
}
|
||||
|
||||
$name = $row['causer-contact-type'] == Contact::TYPE_RELAY ? $row['causer-link'] : $row['causer-name'];
|
||||
|
||||
switch ($row['post-reason']) {
|
||||
case Item::PR_TO:
|
||||
$row['direction'] = ['direction' => 7, 'title' => DI::l10n()->t('You had been addressed (%s).', 'to')];
|
||||
|
|
@ -769,9 +768,9 @@ function conversation_fetch_comments($thread_items, bool $pinned, array $activit
|
|||
if (($row['gravity'] == GRAVITY_PARENT) && !empty($row['causer-id'])) {
|
||||
$causer = ['uid' => 0, 'id' => $row['causer-id'],
|
||||
'network' => $row['causer-network'], 'url' => $row['causer-link']];
|
||||
$row['reshared'] = DI::l10n()->t('%s reshared this.', '<a href="'. htmlentities(Contact::magicLinkByContact($causer)) .'">' . htmlentities($name) . '</a>');
|
||||
$row['reshared'] = DI::l10n()->t('%s reshared this.', '<a href="'. htmlentities(Contact::magicLinkByContact($causer)) .'">' . htmlentities($row['causer-name']) . '</a>');
|
||||
}
|
||||
$row['direction'] = ['direction' => 3, 'title' => (empty($row['causer-id']) ? DI::l10n()->t('Reshared') : DI::l10n()->t('Reshared by %s', $name))];
|
||||
$row['direction'] = ['direction' => 3, 'title' => (empty($row['causer-id']) ? DI::l10n()->t('Reshared') : DI::l10n()->t('Reshared by %s <%s>', $row['causer-name'], $row['causer-link']))];
|
||||
break;
|
||||
case Item::PR_COMMENT:
|
||||
$row['direction'] = ['direction' => 5, 'title' => DI::l10n()->t('%s is participating in this thread.', $row['author-name'])];
|
||||
|
|
@ -783,10 +782,10 @@ function conversation_fetch_comments($thread_items, bool $pinned, array $activit
|
|||
$row['direction'] = ['direction' => 9, 'title' => DI::l10n()->t('Global')];
|
||||
break;
|
||||
case Item::PR_RELAY:
|
||||
$row['direction'] = ['direction' => 10, 'title' => (empty($row['causer-id']) ? DI::l10n()->t('Relayed') : DI::l10n()->t('Relayed by %s.', $name))];
|
||||
$row['direction'] = ['direction' => 10, 'title' => (empty($row['causer-id']) ? DI::l10n()->t('Relayed') : DI::l10n()->t('Relayed by %s <%s>', $row['causer-name'], $row['causer-link']))];
|
||||
break;
|
||||
case Item::PR_FETCHED:
|
||||
$row['direction'] = ['direction' => 2, 'title' => (empty($row['causer-id']) ? DI::l10n()->t('Fetched') : DI::l10n()->t('Fetched because of %s', $name))];
|
||||
$row['direction'] = ['direction' => 2, 'title' => (empty($row['causer-id']) ? DI::l10n()->t('Fetched') : DI::l10n()->t('Fetched because of %s <%s>', $row['causer-name'], $row['causer-link']))];
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -184,9 +184,9 @@ function notification($params)
|
|||
// First go for the general message
|
||||
|
||||
// "George Bull's post"
|
||||
if ($params['activity']['origin_comment']) {
|
||||
if (!empty($params['activity']['origin_comment'])) {
|
||||
$message = $l10n->t('%1$s replied to you on %2$s\'s %3$s %4$s');
|
||||
} elseif ($params['activity']['explicit_tagged']) {
|
||||
} elseif (!empty($params['activity']['explicit_tagged'])) {
|
||||
$message = $l10n->t('%1$s tagged you on %2$s\'s %3$s %4$s');
|
||||
} else {
|
||||
$message = $l10n->t('%1$s commented on %2$s\'s %3$s %4$s');
|
||||
|
|
@ -197,10 +197,10 @@ function notification($params)
|
|||
// Then look for the special cases
|
||||
|
||||
// "your post"
|
||||
if ($params['activity']['origin_thread']) {
|
||||
if ($params['activity']['origin_comment']) {
|
||||
if (!empty($params['activity']['origin_thread'])) {
|
||||
if (!empty($params['activity']['origin_comment'])) {
|
||||
$message = $l10n->t('%1$s replied to you on your %2$s %3$s');
|
||||
} elseif ($params['activity']['explicit_tagged']) {
|
||||
} elseif (!empty($params['activity']['explicit_tagged'])) {
|
||||
$message = $l10n->t('%1$s tagged you on your %2$s %3$s');
|
||||
} else {
|
||||
$message = $l10n->t('%1$s commented on your %2$s %3$s');
|
||||
|
|
@ -209,9 +209,9 @@ function notification($params)
|
|||
$dest_str = sprintf($message, $params['source_name'], $item_post_type, $title);
|
||||
// "their post"
|
||||
} elseif ($item['author-link'] == $params['source_link']) {
|
||||
if ($params['activity']['origin_comment']) {
|
||||
if (!empty($params['activity']['origin_comment'])) {
|
||||
$message = $l10n->t('%1$s replied to you on their %2$s %3$s');
|
||||
} elseif ($params['activity']['explicit_tagged']) {
|
||||
} elseif (!empty($params['activity']['explicit_tagged'])) {
|
||||
$message = $l10n->t('%1$s tagged you on their %2$s %3$s');
|
||||
} else {
|
||||
$message = $l10n->t('%1$s commented on their %2$s %3$s');
|
||||
|
|
@ -224,7 +224,7 @@ function notification($params)
|
|||
// So, we cannot have different subjects for notifications of the same thread.
|
||||
// Before this we have the name of the replier on the subject rendering
|
||||
// different subjects for messages on the same thread.
|
||||
if ($params['activity']['explicit_tagged']) {
|
||||
if (!empty($params['activity']['explicit_tagged'])) {
|
||||
$subject = $l10n->t('%s %s tagged you', $subjectPrefix, $params['source_name']);
|
||||
|
||||
$preamble = $l10n->t('%1$s tagged you at %2$s', $params['source_name'], $sitename);
|
||||
|
|
|
|||
|
|
@ -34,7 +34,7 @@ use Friendica\DI;
|
|||
use Friendica\Model\Contact;
|
||||
use Friendica\Model\Event;
|
||||
use Friendica\Model\Item;
|
||||
use Friendica\Model\Profile;
|
||||
use Friendica\Model\User;
|
||||
use Friendica\Module\BaseProfile;
|
||||
use Friendica\Network\HTTPException;
|
||||
use Friendica\Util\DateTimeFormat;
|
||||
|
|
@ -67,7 +67,7 @@ function cal_init(App $a)
|
|||
return;
|
||||
}
|
||||
|
||||
$a->profile = Profile::getByNickname($nick, $a->profile_uid);
|
||||
$a->profile = User::getOwnerDataByNick($nick);
|
||||
if (empty($a->profile)) {
|
||||
throw new HTTPException\NotFoundException(DI::l10n()->t('User not found.'));
|
||||
}
|
||||
|
|
@ -84,7 +84,7 @@ function cal_init(App $a)
|
|||
'$about' => BBCode::convert($a->profile['about']),
|
||||
]);
|
||||
|
||||
$cal_widget = Widget\CalendarExport::getHTML();
|
||||
$cal_widget = Widget\CalendarExport::getHTML($user['uid']);
|
||||
|
||||
if (empty(DI::page()['aside'])) {
|
||||
DI::page()['aside'] = '';
|
||||
|
|
|
|||
|
|
@ -128,6 +128,7 @@ function dfrn_poll_init(App $a)
|
|||
$_SESSION['visitor_handle'] = $r[0]['addr'];
|
||||
$_SESSION['visitor_visiting'] = $r[0]['uid'];
|
||||
$_SESSION['my_url'] = $r[0]['url'];
|
||||
$_SESSION['remote_comment'] = $r[0]['subscribe'];
|
||||
|
||||
Session::setVisitorsContacts();
|
||||
|
||||
|
|
@ -497,8 +498,10 @@ function dfrn_poll_content(App $a)
|
|||
$_SESSION['authenticated'] = 1;
|
||||
$_SESSION['visitor_id'] = $r[0]['id'];
|
||||
$_SESSION['visitor_home'] = $r[0]['url'];
|
||||
$_SESSION['visitor_handle'] = $r[0]['addr'];
|
||||
$_SESSION['visitor_visiting'] = $r[0]['uid'];
|
||||
$_SESSION['my_url'] = $r[0]['url'];
|
||||
$_SESSION['remote_comment'] = $r[0]['subscribe'];
|
||||
|
||||
Session::setVisitorsContacts();
|
||||
|
||||
|
|
|
|||
|
|
@ -236,6 +236,7 @@ function display_content(App $a, $update = false, $update_uid = 0)
|
|||
}
|
||||
|
||||
if (!DI::pConfig()->get(local_user(), 'system', 'detailed_notif')) {
|
||||
DBA::update('notification', ['seen' => true], ['parent-uri-id' => $item['parent-uri-id'], 'uid' => local_user()]);
|
||||
DBA::update('notify', ['seen' => true], ['parent-uri-id' => $item['parent-uri-id'], 'uid' => local_user()]);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -59,7 +59,7 @@ function events_init(App $a)
|
|||
DI::page()['aside'] = '';
|
||||
}
|
||||
|
||||
$cal_widget = CalendarExport::getHTML();
|
||||
$cal_widget = CalendarExport::getHTML(local_user());
|
||||
|
||||
DI::page()['aside'] .= $cal_widget;
|
||||
|
||||
|
|
|
|||
78
mod/item.php
78
mod/item.php
|
|
@ -40,6 +40,7 @@ use Friendica\Core\System;
|
|||
use Friendica\Core\Worker;
|
||||
use Friendica\Database\DBA;
|
||||
use Friendica\DI;
|
||||
use Friendica\Model\APContact;
|
||||
use Friendica\Model\Attach;
|
||||
use Friendica\Model\Contact;
|
||||
use Friendica\Model\Conversation;
|
||||
|
|
@ -410,21 +411,22 @@ function item_post(App $a) {
|
|||
}
|
||||
}
|
||||
|
||||
$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 (!empty($success['contact']['prv']) || ($tag_type == Tag::TAG_CHARACTER[Tag::EXCLUSIVE_MENTION])) {
|
||||
$private_forum = $success['contact']['prv'];
|
||||
$only_to_forum = ($tag_type == Tag::TAG_CHARACTER[Tag::EXCLUSIVE_MENTION]);
|
||||
$private_id = $success['contact']['id'];
|
||||
$forum_contact = $success['contact'];
|
||||
} 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'];
|
||||
if ($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 (!empty($success['contact']['prv']) || ($tag_type == Tag::TAG_CHARACTER[Tag::EXCLUSIVE_MENTION])) {
|
||||
$private_forum = $success['contact']['prv'];
|
||||
$only_to_forum = ($tag_type == Tag::TAG_CHARACTER[Tag::EXCLUSIVE_MENTION]);
|
||||
$private_id = $success['contact']['id'];
|
||||
$forum_contact = $success['contact'];
|
||||
} 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'];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -434,21 +436,34 @@ function item_post(App $a) {
|
|||
$original_contact_id = $contact_id;
|
||||
|
||||
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;
|
||||
// we tagged a forum in a top level post. Now we change the post
|
||||
$private = $private_forum ? Item::PRIVATE : Item::UNLISTED;
|
||||
|
||||
$str_group_allow = '';
|
||||
$str_contact_deny = '';
|
||||
$str_group_deny = '';
|
||||
if ($private_forum) {
|
||||
$str_contact_allow = '<' . $private_id . '>';
|
||||
} else {
|
||||
$str_contact_allow = '';
|
||||
if ($only_to_forum) {
|
||||
$postopts = '';
|
||||
}
|
||||
|
||||
if (!$private_forum) {
|
||||
$str_contact_allow = '';
|
||||
$str_group_allow = '';
|
||||
$str_contact_deny = '';
|
||||
$str_group_deny = '';
|
||||
}
|
||||
|
||||
if ($private_forum || !APContact::getByURL($forum_contact['url'])) {
|
||||
$str_group_allow = '';
|
||||
$str_contact_deny = '';
|
||||
$str_group_deny = '';
|
||||
if ($private_forum) {
|
||||
$str_contact_allow = '<' . $private_id . '>';
|
||||
} else {
|
||||
$str_contact_allow = '';
|
||||
}
|
||||
$contact_id = $private_id;
|
||||
$contact_record = $forum_contact;
|
||||
$_REQUEST['origin'] = false;
|
||||
$wall = 0;
|
||||
}
|
||||
$contact_id = $private_id;
|
||||
$contact_record = $forum_contact;
|
||||
$_REQUEST['origin'] = false;
|
||||
$wall = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
@ -713,13 +728,6 @@ function item_post(App $a) {
|
|||
unset($datarray['self']);
|
||||
unset($datarray['api_source']);
|
||||
|
||||
if ($origin) {
|
||||
$signed = Diaspora::createCommentSignature($uid, $datarray);
|
||||
if (!empty($signed)) {
|
||||
$datarray['diaspora_signed_text'] = json_encode($signed);
|
||||
}
|
||||
}
|
||||
|
||||
$post_id = Item::insert($datarray);
|
||||
|
||||
if (!$post_id) {
|
||||
|
|
|
|||
|
|
@ -66,54 +66,27 @@ function match_content(App $a)
|
|||
$params = [];
|
||||
$tags = trim($profile['pub_keywords'] . ' ' . $profile['prv_keywords']);
|
||||
|
||||
if (DI::mode()->isMobile()) {
|
||||
$limit = DI::pConfig()->get(local_user(), 'system', 'itemspage_mobile_network',
|
||||
DI::config()->get('system', 'itemspage_network_mobile'));
|
||||
} else {
|
||||
$limit = DI::pConfig()->get(local_user(), 'system', 'itemspage_network',
|
||||
DI::config()->get('system', 'itemspage_network'));
|
||||
}
|
||||
|
||||
$params['s'] = $tags;
|
||||
$params['n'] = 100;
|
||||
|
||||
if (strlen(DI::config()->get('system', 'directory'))) {
|
||||
$host = Search::getGlobalDirectory();
|
||||
} else {
|
||||
$host = DI::baseUrl();
|
||||
}
|
||||
|
||||
$msearch_json = DI::httpRequest()->post($host . '/msearch', $params)->getBody();
|
||||
|
||||
$msearch = json_decode($msearch_json);
|
||||
|
||||
$start = $_GET['start'] ?? 0;
|
||||
$entries = [];
|
||||
$paginate = '';
|
||||
|
||||
if (!empty($msearch->results)) {
|
||||
for ($i = $start;count($entries) < 10 && $i < $msearch->total; $i++) {
|
||||
$profile = $msearch->results[$i];
|
||||
|
||||
// Already known contact
|
||||
if (!$profile || Contact::getIdForURL($profile->url, local_user())) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$contact = Contact::getByURLForUser($profile->url, local_user());
|
||||
if (!empty($contact)) {
|
||||
$entries[] = ModuleContact::getContactTemplateVars($contact);
|
||||
}
|
||||
foreach ([Search::getGlobalDirectory(), DI::baseUrl()] as $server) {
|
||||
if (empty($server)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$data = [
|
||||
'class' => 'pager',
|
||||
'first' => [
|
||||
'url' => 'match',
|
||||
'text' => DI::l10n()->t('first'),
|
||||
'class' => 'previous' . ($start == 0 ? 'disabled' : '')
|
||||
],
|
||||
'next' => [
|
||||
'url' => 'match?start=' . $i,
|
||||
'text' => DI::l10n()->t('next'),
|
||||
'class' => 'next' . ($i >= $msearch->total ? ' disabled' : '')
|
||||
]
|
||||
];
|
||||
|
||||
$tpl = Renderer::getMarkupTemplate('paginate.tpl');
|
||||
$paginate = Renderer::replaceMacros($tpl, ['pager' => $data]);
|
||||
$msearch = json_decode(DI::httpRequest()->post($server . '/msearch', $params)->getBody());
|
||||
if (!empty($msearch)) {
|
||||
$entries = match_get_contacts($msearch, $entries, $limit);
|
||||
}
|
||||
}
|
||||
|
||||
if (empty($entries)) {
|
||||
|
|
@ -123,9 +96,37 @@ function match_content(App $a)
|
|||
$tpl = Renderer::getMarkupTemplate('viewcontact_template.tpl');
|
||||
$o = Renderer::replaceMacros($tpl, [
|
||||
'$title' => DI::l10n()->t('Profile Match'),
|
||||
'$contacts' => $entries,
|
||||
'$paginate' => $paginate
|
||||
'$contacts' => array_slice($entries, 0, $limit),
|
||||
]);
|
||||
|
||||
return $o;
|
||||
}
|
||||
|
||||
function match_get_contacts($msearch, $entries, $limit)
|
||||
{
|
||||
if (empty($msearch->results)) {
|
||||
return $entries;
|
||||
}
|
||||
|
||||
foreach ($msearch->results as $profile) {
|
||||
if (!$profile) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Already known contact
|
||||
$contact = Contact::getByURL($profile->url, null, ['rel'], local_user());
|
||||
if (!empty($contact) && in_array($contact['rel'], [Contact::FRIEND, Contact::SHARING])) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$contact = Contact::getByURLForUser($profile->url, local_user());
|
||||
if (!empty($contact)) {
|
||||
$entries[$contact['id']] = ModuleContact::getContactTemplateVars($contact);
|
||||
}
|
||||
|
||||
if (count($entries) == $limit) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
return $entries;
|
||||
}
|
||||
|
|
@ -37,7 +37,6 @@ use Friendica\Model\Contact;
|
|||
use Friendica\Model\Item;
|
||||
use Friendica\Model\Photo;
|
||||
use Friendica\Model\Post;
|
||||
use Friendica\Model\Profile;
|
||||
use Friendica\Model\Tag;
|
||||
use Friendica\Model\User;
|
||||
use Friendica\Module\BaseProfile;
|
||||
|
|
@ -73,7 +72,7 @@ function photos_init(App $a) {
|
|||
$a->profile_uid = $user['uid'];
|
||||
$is_owner = (local_user() && (local_user() == $a->profile_uid));
|
||||
|
||||
$profile = Profile::getByNickname($nick, $a->profile_uid);
|
||||
$profile = User::getOwnerDataByNick($nick);
|
||||
|
||||
$account_type = Contact::getAccountType($profile);
|
||||
|
||||
|
|
@ -1275,7 +1274,7 @@ function photos_content(App $a)
|
|||
}
|
||||
|
||||
if (!empty($link_item['parent']) && !empty($link_item['uid'])) {
|
||||
$condition = ["`parent` = ? AND `gravity` != ?", $link_item['parent'], GRAVITY_PARENT];
|
||||
$condition = ["`parent` = ? AND `gravity` = ?", $link_item['parent'], GRAVITY_COMMENT];
|
||||
$total = Post::count($condition);
|
||||
|
||||
$pager = new Pager(DI::l10n(), DI::args()->getQueryString());
|
||||
|
|
|
|||
|
|
@ -33,6 +33,7 @@ use Friendica\Model\Post;
|
|||
use Friendica\Model\Verb;
|
||||
use Friendica\Protocol\Activity;
|
||||
use Friendica\Util\DateTimeFormat;
|
||||
use Friendica\Util\Proxy;
|
||||
use Friendica\Util\Temporal;
|
||||
use Friendica\Util\XML;
|
||||
|
||||
|
|
@ -340,13 +341,9 @@ function ping_init(App $a)
|
|||
usort($notifications, $sort_function);
|
||||
|
||||
array_walk($notifications, function (&$notification) {
|
||||
if (empty($notification['photo'])) {
|
||||
$contact = Contact::getByURL($notification['url'], false, ['micro', 'id', 'avatar']);
|
||||
$notification['photo'] = Contact::getMicro($contact, $notification['photo']);
|
||||
}
|
||||
|
||||
$notification['photo'] = Contact::getAvatarUrlForUrl($notification['url'], local_user(), Proxy::SIZE_MICRO);
|
||||
$notification['timestamp'] = DateTimeFormat::local($notification['date']);
|
||||
$notification['date'] = Temporal::getRelativeDate($notification['date']);
|
||||
$notification['date'] = Temporal::getRelativeDate($notification['date']);
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -30,9 +30,9 @@ use Friendica\Core\Renderer;
|
|||
use Friendica\Core\Worker;
|
||||
use Friendica\Database\DBA;
|
||||
use Friendica\DI;
|
||||
use Friendica\Model\Contact;
|
||||
use Friendica\Model\Group;
|
||||
use Friendica\Model\Notification;
|
||||
use Friendica\Model\Profile;
|
||||
use Friendica\Model\User;
|
||||
use Friendica\Module\BaseSettings;
|
||||
use Friendica\Module\Security\Login;
|
||||
|
|
@ -326,7 +326,7 @@ function settings_post(App $a)
|
|||
$detailed_notif = (($_POST['detailed_notif'] == 1) ? 1 : 0);
|
||||
|
||||
$notify_ignored = (($_POST['notify_ignored'] == 1) ? 1 : 0);
|
||||
|
||||
|
||||
$notify = 0;
|
||||
|
||||
if (!empty($_POST['notify1'])) {
|
||||
|
|
@ -447,38 +447,15 @@ function settings_post(App $a)
|
|||
$fields['openidserver'] = '';
|
||||
}
|
||||
|
||||
if (!DBA::update('user', $fields, ['uid' => local_user()])) {
|
||||
$profile_fields = ['publish' => $publish, 'net-publish' => $net_publish, 'hide-friends' => $hide_friends];
|
||||
|
||||
if (!User::update($fields, local_user()) || !Profile::update($profile_fields, local_user())) {
|
||||
notice(DI::l10n()->t('Settings were not updated.'));
|
||||
}
|
||||
|
||||
// clear session language
|
||||
unset($_SESSION['language']);
|
||||
|
||||
q("UPDATE `profile`
|
||||
SET `publish` = %d,
|
||||
`name` = '%s',
|
||||
`net-publish` = %d,
|
||||
`hide-friends` = %d
|
||||
WHERE `uid` = %d",
|
||||
intval($publish),
|
||||
DBA::escape($username),
|
||||
intval($net_publish),
|
||||
intval($hide_friends),
|
||||
intval(local_user())
|
||||
);
|
||||
|
||||
Contact::updateSelfFromUserID(local_user());
|
||||
|
||||
if (($old_visibility != $net_publish) || ($page_flags != $old_page_flags)) {
|
||||
// Update global directory in background
|
||||
$url = $_SESSION['my_url'];
|
||||
if ($url && strlen(DI::config()->get('system', 'directory'))) {
|
||||
Worker::add(PRIORITY_LOW, "Directory", $url);
|
||||
}
|
||||
}
|
||||
|
||||
Worker::add(PRIORITY_LOW, 'ProfileUpdate', local_user());
|
||||
|
||||
DI::baseUrl()->redirect('settings');
|
||||
return; // NOTREACHED
|
||||
}
|
||||
|
|
@ -525,21 +502,20 @@ function settings_content(App $a)
|
|||
}
|
||||
|
||||
if (($a->argc > 1) && ($a->argv[1] === 'addon')) {
|
||||
$settings_addons = "";
|
||||
$addon_settings_forms = [];
|
||||
|
||||
$r = q("SELECT * FROM `hook` WHERE `hook` = 'addon_settings' ");
|
||||
if (!DBA::isResult($r)) {
|
||||
$settings_addons = DI::l10n()->t('No Addon settings configured');
|
||||
foreach (DI::dba()->selectToArray('hook', ['file', 'function'], ['hook' => 'addon_settings']) as $hook) {
|
||||
$data = '';
|
||||
Hook::callSingle(DI::app(), 'addon_settings', [$hook['file'], $hook['function']], $data);
|
||||
$addon_settings_forms[] = $data;
|
||||
}
|
||||
|
||||
Hook::callAll('addon_settings', $settings_addons);
|
||||
|
||||
|
||||
$tpl = Renderer::getMarkupTemplate('settings/addons.tpl');
|
||||
$o .= Renderer::replaceMacros($tpl, [
|
||||
'$form_security_token' => BaseModule::getFormSecurityToken("settings_addon"),
|
||||
'$title' => DI::l10n()->t('Addon Settings'),
|
||||
'$settings_addons' => $settings_addons
|
||||
'$no_addons_settings_configured' => DI::l10n()->t('No Addon settings configured'),
|
||||
'$addon_settings_forms' => $addon_settings_forms,
|
||||
]);
|
||||
return $o;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -81,25 +81,27 @@ function tagrm_content(App $a)
|
|||
{
|
||||
$o = '';
|
||||
|
||||
$photo_return = $_SESSION['photo_return'] ?? '';
|
||||
|
||||
if (!local_user()) {
|
||||
DI::baseUrl()->redirect($_SESSION['photo_return']);
|
||||
DI::baseUrl()->redirect($photo_return);
|
||||
// NOTREACHED
|
||||
}
|
||||
|
||||
if ($a->argc == 3) {
|
||||
update_tags($a->argv[1], [Strings::escapeTags(trim(hex2bin($a->argv[2])))]);
|
||||
DI::baseUrl()->redirect($_SESSION['photo_return']);
|
||||
DI::baseUrl()->redirect($photo_return);
|
||||
}
|
||||
|
||||
$item_id = (($a->argc > 1) ? intval($a->argv[1]) : 0);
|
||||
if (!$item_id) {
|
||||
DI::baseUrl()->redirect($_SESSION['photo_return']);
|
||||
DI::baseUrl()->redirect($photo_return);
|
||||
// NOTREACHED
|
||||
}
|
||||
|
||||
$item = Post::selectFirst(['uri-id'], ['id' => $item_id, 'uid' => local_user()]);
|
||||
if (!DBA::isResult($item)) {
|
||||
DI::baseUrl()->redirect($_SESSION['photo_return']);
|
||||
DI::baseUrl()->redirect($photo_return);
|
||||
}
|
||||
|
||||
$tag_text = Tag::getCSVByURIId($item['uri-id']);
|
||||
|
|
@ -107,7 +109,7 @@ function tagrm_content(App $a)
|
|||
$arr = explode(',', $tag_text);
|
||||
|
||||
if (empty($arr)) {
|
||||
DI::baseUrl()->redirect($_SESSION['photo_return']);
|
||||
DI::baseUrl()->redirect($photo_return);
|
||||
}
|
||||
|
||||
$o .= '<h3>' . DI::l10n()->t('Remove Item Tag') . '</h3>';
|
||||
|
|
|
|||
|
|
@ -158,4 +158,4 @@ function unfollow_process(string $url)
|
|||
}
|
||||
|
||||
DI::baseUrl()->redirect($return_path);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -43,4 +43,4 @@ function update_notes_content(App $a) {
|
|||
$text = notes_content($a, $profile_uid);
|
||||
|
||||
System::htmlUpdateExit($text);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -30,7 +30,6 @@ use Friendica\DI;
|
|||
use Friendica\Model\Attach;
|
||||
use Friendica\Model\Contact;
|
||||
use Friendica\Model\Item;
|
||||
use Friendica\Model\Profile;
|
||||
use Friendica\Model\User;
|
||||
use Friendica\Module\BaseProfile;
|
||||
use Friendica\Security\Security;
|
||||
|
|
@ -56,7 +55,7 @@ function videos_init(App $a)
|
|||
$a->data['user'] = $user[0];
|
||||
$a->profile_uid = $user[0]['uid'];
|
||||
|
||||
$profile = Profile::getByNickname($nick, $a->profile_uid);
|
||||
$profile = User::getOwnerDataByNick($nick);
|
||||
|
||||
$account_type = Contact::getAccountType($profile);
|
||||
|
||||
|
|
|
|||
|
|
@ -29,6 +29,7 @@ return [
|
|||
// ****************************************************************
|
||||
|
||||
'config' => [
|
||||
'hostname' => 'friendica.local',
|
||||
'admin_email' => 'admin@friendica.local',
|
||||
'sitename' => 'Friendica Social Network',
|
||||
'register_policy' => \Friendica\Module\Register::OPEN,
|
||||
|
|
@ -38,5 +39,6 @@ return [
|
|||
'default_timezone' => 'UTC',
|
||||
'language' => 'en',
|
||||
'basepath' => '/vagrant',
|
||||
'ssl_policy' => \Friendica\App\BaseURL::SSL_POLICY_SELFSIGN,
|
||||
],
|
||||
];
|
||||
|
|
|
|||
24
mods/phpdoc-config.xml
Normal file
24
mods/phpdoc-config.xml
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<phpdocumentor xmlns="https://www.phpdoc.org" configVersion="3.0">
|
||||
<paths>
|
||||
<output>../doc/api</output>
|
||||
<cache>../doc/cache</cache>
|
||||
</paths>
|
||||
<version number="3.0">
|
||||
<api>
|
||||
<source dsn="../">
|
||||
<path>src</path>
|
||||
<path>mod</path>
|
||||
<path>include</path>
|
||||
<path>static</path>
|
||||
<path>bin</path>
|
||||
<path>view</path>
|
||||
</source>
|
||||
<ignore>
|
||||
<path>vendor/**/*</path>
|
||||
<path>asset/**/*</path>
|
||||
<path>bin/dev/**/*</path>
|
||||
</ignore>
|
||||
</api>
|
||||
</version>
|
||||
</phpdocumentor>
|
||||
|
|
@ -34,6 +34,7 @@ use Friendica\Core\L10n;
|
|||
use Friendica\Core\System;
|
||||
use Friendica\Core\Theme;
|
||||
use Friendica\Database\Database;
|
||||
use Friendica\Model\Contact;
|
||||
use Friendica\Model\Profile;
|
||||
use Friendica\Module\Special\HTTPException as ModuleHTTPException;
|
||||
use Friendica\Network\HTTPException;
|
||||
|
|
@ -464,6 +465,11 @@ class App
|
|||
if (Core\Session::get('visitor_home') != $_GET["zrl"]) {
|
||||
Core\Session::set('my_url', $_GET['zrl']);
|
||||
Core\Session::set('authenticated', 0);
|
||||
|
||||
$remote_contact = Contact::getByURL($_GET['zrl'], false, ['subscribe']);
|
||||
if (!empty($remote_contact['subscribe'])) {
|
||||
$_SESSION['remote_comment'] = $remote_contact['subscribe'];
|
||||
}
|
||||
}
|
||||
|
||||
Model\Profile::zrlInit($this);
|
||||
|
|
|
|||
|
|
@ -232,7 +232,7 @@ class BaseURL
|
|||
{
|
||||
$parsed = @parse_url($url);
|
||||
|
||||
if (empty($parsed)) {
|
||||
if (empty($parsed) || empty($parsed['host'])) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -63,7 +63,6 @@ class Module
|
|||
'outbox',
|
||||
'poco',
|
||||
'post',
|
||||
'proxy',
|
||||
'pubsub',
|
||||
'pubsubhubbub',
|
||||
'receive',
|
||||
|
|
@ -265,6 +264,38 @@ class Module
|
|||
$logger->debug('index.php: page not found.', ['request_uri' => $server['REQUEST_URI'], 'address' => $server['REMOTE_ADDR'], 'query' => $server['QUERY_STRING']]);
|
||||
}
|
||||
|
||||
// @see https://github.com/tootsuite/mastodon/blob/c3aef491d66aec743a3a53e934a494f653745b61/config/initializers/cors.rb
|
||||
if (substr($_REQUEST['pagename'] ?? '', 0, 12) == '.well-known/') {
|
||||
header('Access-Control-Allow-Origin: *');
|
||||
header('Access-Control-Allow-Headers: *');
|
||||
header('Access-Control-Allow-Methods: ' . Router::GET);
|
||||
header('Access-Control-Allow-Credentials: false');
|
||||
} elseif (substr($_REQUEST['pagename'] ?? '', 0, 8) == 'profile/') {
|
||||
header('Access-Control-Allow-Origin: *');
|
||||
header('Access-Control-Allow-Headers: *');
|
||||
header('Access-Control-Allow-Methods: ' . Router::GET);
|
||||
header('Access-Control-Allow-Credentials: false');
|
||||
} elseif (substr($_REQUEST['pagename'] ?? '', 0, 4) == 'api/') {
|
||||
header('Access-Control-Allow-Origin: *');
|
||||
header('Access-Control-Allow-Headers: *');
|
||||
header('Access-Control-Allow-Methods: ' . implode(',', Router::ALLOWED_METHODS));
|
||||
header('Access-Control-Allow-Credentials: false');
|
||||
header('Access-Control-Expose-Headers: Link');
|
||||
} elseif (substr($_REQUEST['pagename'] ?? '', 0, 11) == 'oauth/token') {
|
||||
header('Access-Control-Allow-Origin: *');
|
||||
header('Access-Control-Allow-Headers: *');
|
||||
header('Access-Control-Allow-Methods: ' . Router::POST);
|
||||
header('Access-Control-Allow-Credentials: false');
|
||||
}
|
||||
|
||||
// @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods/OPTIONS
|
||||
// @todo Check allowed methods per requested path
|
||||
if ($server['REQUEST_METHOD'] === Router::OPTIONS) {
|
||||
header('HTTP/1.1 204 No Content');
|
||||
header('Allow: ' . implode(',', Router::ALLOWED_METHODS));
|
||||
exit();
|
||||
}
|
||||
|
||||
$placeholder = '';
|
||||
|
||||
$profiler->set(microtime(true), 'ready');
|
||||
|
|
|
|||
|
|
@ -44,11 +44,12 @@ use Friendica\Network\HTTPException;
|
|||
*/
|
||||
class Router
|
||||
{
|
||||
const DELETE = 'DELETE';
|
||||
const GET = 'GET';
|
||||
const PATCH = 'PATCH';
|
||||
const POST = 'POST';
|
||||
const PUT = 'PUT';
|
||||
const DELETE = 'DELETE';
|
||||
const GET = 'GET';
|
||||
const PATCH = 'PATCH';
|
||||
const POST = 'POST';
|
||||
const PUT = 'PUT';
|
||||
const OPTIONS = 'OPTIONS';
|
||||
|
||||
const ALLOWED_METHODS = [
|
||||
self::DELETE,
|
||||
|
|
@ -56,6 +57,7 @@ class Router
|
|||
self::PATCH,
|
||||
self::POST,
|
||||
self::PUT,
|
||||
self::OPTIONS
|
||||
];
|
||||
|
||||
/** @var RouteCollector */
|
||||
|
|
|
|||
17
src/Collection/Api/Mastodon/Mentions.php
Normal file
17
src/Collection/Api/Mastodon/Mentions.php
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
<?php
|
||||
|
||||
namespace Friendica\Collection\Api\Mastodon;
|
||||
|
||||
use Friendica\BaseCollection;
|
||||
use Friendica\Object\Api\Mastodon\Mention;
|
||||
|
||||
class Mentions extends BaseCollection
|
||||
{
|
||||
/**
|
||||
* @return Mention
|
||||
*/
|
||||
public function current(): Mention
|
||||
{
|
||||
return parent::current();
|
||||
}
|
||||
}
|
||||
|
|
@ -30,7 +30,6 @@ use Friendica\Core\Installer;
|
|||
use Friendica\Core\Theme;
|
||||
use Friendica\Database\Database;
|
||||
use Friendica\Util\BasePath;
|
||||
use Friendica\Util\ConfigFileLoader;
|
||||
use RuntimeException;
|
||||
|
||||
class AutomaticInstallation extends Console
|
||||
|
|
@ -66,7 +65,7 @@ Options
|
|||
-H|--dbhost <host> The host of the mysql/mariadb database (env MYSQL_HOST)
|
||||
-p|--dbport <port> The port of the mysql/mariadb database (env MYSQL_PORT)
|
||||
-d|--dbdata <database> The name of the mysql/mariadb database (env MYSQL_DATABASE)
|
||||
-U|--dbuser <username> The username of the mysql/mariadb database login (env MYSQL_USER or MYSQL_USERNAME)
|
||||
-u|--dbuser <username> The username of the mysql/mariadb database login (env MYSQL_USER or MYSQL_USERNAME)
|
||||
-P|--dbpass <password> The password of the mysql/mariadb database login (env MYSQL_PASSWORD)
|
||||
-U|--url <url> The full base URL of Friendica - f.e. 'https://friendica.local/sub' (env FRIENDICA_URL)
|
||||
-B|--phppath <php_path> The path of the PHP binary (env FRIENDICA_PHP_PATH)
|
||||
|
|
@ -112,7 +111,7 @@ HELP;
|
|||
protected function doExecute()
|
||||
{
|
||||
// Initialise the app
|
||||
$this->out("Initializing setup...\n");
|
||||
$this->out("Initializing setup...");
|
||||
|
||||
$installer = new Installer();
|
||||
|
||||
|
|
@ -121,10 +120,10 @@ HELP;
|
|||
$basepath = new BasePath($basePathConf);
|
||||
$installer->setUpCache($configCache, $basepath->getPath());
|
||||
|
||||
$this->out(" Complete!\n\n");
|
||||
$this->out(" Complete!\n");
|
||||
|
||||
// Check Environment
|
||||
$this->out("Checking environment...\n");
|
||||
$this->out("Checking environment...");
|
||||
|
||||
$installer->resetChecks();
|
||||
|
||||
|
|
@ -133,24 +132,26 @@ HELP;
|
|||
throw new RuntimeException($errorMessage);
|
||||
}
|
||||
|
||||
$this->out(" Complete!\n\n");
|
||||
$this->out(" Complete!\n");
|
||||
|
||||
// if a config file is set,
|
||||
$config_file = $this->getOption(['f', 'file']);
|
||||
|
||||
if (!empty($config_file)) {
|
||||
|
||||
$this->out("Loading config file '$config_file'...");
|
||||
if (!file_exists($config_file)) {
|
||||
throw new RuntimeException("ERROR: Config file does not exist.\n");
|
||||
throw new RuntimeException("ERROR: Config file does not exist.");
|
||||
}
|
||||
|
||||
//reload the config cache
|
||||
$loader = new ConfigFileLoader($config_file);
|
||||
$loader->setupCache($configCache);
|
||||
|
||||
//append config file to the config cache
|
||||
$config = include($config_file);
|
||||
if (!is_array($config)) {
|
||||
throw new Exception('Error loading config file ' . $config_file);
|
||||
}
|
||||
$configCache->load($config, Cache::SOURCE_FILE);
|
||||
} else {
|
||||
// Creating config file
|
||||
$this->out("Creating config file...\n");
|
||||
$this->out("Creating config file...");
|
||||
|
||||
$save_db = $this->getOption(['s', 'savedb'], false);
|
||||
|
||||
|
|
@ -161,7 +162,7 @@ HELP;
|
|||
$this->getOption(['d', 'dbdata'],
|
||||
($save_db) ? getenv('MYSQL_DATABASE') : ''));
|
||||
$configCache->set('database', 'username',
|
||||
$this->getOption(['U', 'dbuser'],
|
||||
$this->getOption(['u', 'dbuser'],
|
||||
($save_db) ? getenv('MYSQL_USER') . getenv('MYSQL_USERNAME') : ''));
|
||||
$configCache->set('database', 'password',
|
||||
$this->getOption(['P', 'dbpass'],
|
||||
|
|
@ -202,10 +203,10 @@ HELP;
|
|||
$installer->createConfig($configCache);
|
||||
}
|
||||
|
||||
$this->out("Complete!\n\n");
|
||||
$this->out(" Complete!\n");
|
||||
|
||||
// Check database connection
|
||||
$this->out("Checking database...\n");
|
||||
$this->out("Checking database...");
|
||||
|
||||
$installer->resetChecks();
|
||||
|
||||
|
|
@ -214,7 +215,7 @@ HELP;
|
|||
throw new RuntimeException($errorMessage);
|
||||
}
|
||||
|
||||
$this->out(" Complete!\n\n");
|
||||
$this->out(" Complete!\n");
|
||||
|
||||
// Install database
|
||||
$this->out("Inserting data into database...\n");
|
||||
|
|
@ -228,24 +229,24 @@ HELP;
|
|||
|
||||
if (!empty($config_file) && $config_file != 'config' . DIRECTORY_SEPARATOR . 'local.config.php') {
|
||||
// Copy config file
|
||||
$this->out("Copying config file...\n");
|
||||
if (!copy($basePathConf . DIRECTORY_SEPARATOR . $config_file, $basePathConf . DIRECTORY_SEPARATOR . 'config' . DIRECTORY_SEPARATOR . 'local.config.php')) {
|
||||
$this->out("Copying config file...");
|
||||
if (!copy($config_file, $basePathConf . DIRECTORY_SEPARATOR . 'config' . DIRECTORY_SEPARATOR . 'local.config.php')) {
|
||||
throw new RuntimeException("ERROR: Saving config file failed. Please copy '$config_file' to '" . $basePathConf . "'" . DIRECTORY_SEPARATOR . "config" . DIRECTORY_SEPARATOR . "local.config.php' manually.\n");
|
||||
}
|
||||
}
|
||||
|
||||
$this->out(" Complete!\n\n");
|
||||
$this->out(" Complete!\n");
|
||||
|
||||
// Install theme
|
||||
$this->out("Installing theme\n");
|
||||
$this->out("Installing theme");
|
||||
if (!empty($this->config->get('system', 'theme'))) {
|
||||
Theme::install($this->config->get('system', 'theme'));
|
||||
$this->out(" Complete\n\n");
|
||||
$this->out(" Complete\n");
|
||||
} else {
|
||||
$this->out(" Theme setting is empty. Please check the file 'config/local.config.php'\n\n");
|
||||
$this->out(" Theme setting is empty. Please check the file 'config/local.config.php'\n");
|
||||
}
|
||||
|
||||
$this->out("\nInstallation is finished\n");
|
||||
$this->out("\nInstallation is finished");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -120,6 +120,7 @@ HELP;
|
|||
$output = ob_get_clean();
|
||||
break;
|
||||
case "dumpsql":
|
||||
DBStructure::writeStructure();
|
||||
ob_start();
|
||||
DBStructure::printStructure($basePath);
|
||||
$output = ob_get_clean();
|
||||
|
|
|
|||
|
|
@ -127,16 +127,6 @@ class Item
|
|||
$tag_type = substr($tag, 0, 1);
|
||||
//is it already replaced?
|
||||
if (strpos($tag, '[url=')) {
|
||||
// Checking for the alias that is used for OStatus
|
||||
$pattern = '/[@!]\[url\=(.*?)\](.*?)\[\/url\]/ism';
|
||||
if (preg_match($pattern, $tag, $matches)) {
|
||||
$data = Contact::getByURL($matches[1], false, ['alias', 'nick']);
|
||||
|
||||
if ($data['alias'] != '') {
|
||||
$newtag = '@[url=' . $data['alias'] . ']' . $data['nick'] . '[/url]';
|
||||
}
|
||||
}
|
||||
|
||||
return $replaced;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -953,6 +953,10 @@ class BBCode
|
|||
*/
|
||||
public static function fetchShareAttributes($text)
|
||||
{
|
||||
// See Issue https://github.com/friendica/friendica/issues/10454
|
||||
// Hashtags in usernames are expanded to links. This here is a quick fix.
|
||||
$text = preg_replace('/([@!#])\[url\=.*?\](.*?)\[\/url\]/ism', '$1$2', $text);
|
||||
|
||||
$attributes = [];
|
||||
if (!preg_match("/(.*?)\[share(.*?)\](.*)\[\/share\]/ism", $text, $matches)) {
|
||||
return $attributes;
|
||||
|
|
@ -997,7 +1001,7 @@ class BBCode
|
|||
$attributes[$field] = html_entity_decode($matches[2] ?? '', ENT_QUOTES, 'UTF-8');
|
||||
}
|
||||
|
||||
$author_contact = Contact::getByURL($attributes['profile'], false, ['url', 'addr', 'name', 'micro']);
|
||||
$author_contact = Contact::getByURL($attributes['profile'], false, ['id', 'url', 'addr', 'name', 'micro']);
|
||||
$author_contact['url'] = ($author_contact['url'] ?? $attributes['profile']);
|
||||
$author_contact['addr'] = ($author_contact['addr'] ?? '') ?: Protocol::getAddrFromProfileUrl($attributes['profile']);
|
||||
|
||||
|
|
@ -1005,7 +1009,9 @@ class BBCode
|
|||
$attributes['avatar'] = ($author_contact['micro'] ?? '') ?: $attributes['avatar'];
|
||||
$attributes['profile'] = ($author_contact['url'] ?? '') ?: $attributes['profile'];
|
||||
|
||||
if ($attributes['avatar']) {
|
||||
if (!empty($author_contact['id'])) {
|
||||
$attributes['avatar'] = Contact::getAvatarUrlForId($author_contact['id'], ProxyUtils::SIZE_THUMB);
|
||||
} elseif ($attributes['avatar']) {
|
||||
$attributes['avatar'] = ProxyUtils::proxifyUrl($attributes['avatar'], false, ProxyUtils::SIZE_THUMB);
|
||||
}
|
||||
|
||||
|
|
@ -1039,7 +1045,9 @@ class BBCode
|
|||
|
||||
switch ($simplehtml) {
|
||||
case self::API:
|
||||
$text = ($is_quote_share? '<br>' : '') . '<p>' . html_entity_decode('♲ ', ENT_QUOTES, 'UTF-8') . ' ' . $author_contact['addr'] . ': </p>' . "\n" . $content;
|
||||
$text = ($is_quote_share? '<br>' : '') .
|
||||
'<p><b><a href="' . $attributes['link'] . '">' . html_entity_decode('♲ ', ENT_QUOTES, 'UTF-8') . ' ' . $author_contact['addr'] . "</a>:</b> </p>\n" .
|
||||
'<blockquote class="shared_content">' . $content . '</blockquote>';
|
||||
break;
|
||||
case self::DIASPORA:
|
||||
if (stripos(Strings::normaliseLink($attributes['link']), 'http://twitter.com/') === 0) {
|
||||
|
|
@ -2194,9 +2202,7 @@ class BBCode
|
|||
}
|
||||
}
|
||||
|
||||
$success = Item::replaceTag($body, $inform, $profile_uid, $tag, $network);
|
||||
|
||||
if ($success['replaced']) {
|
||||
if (($success = Item::replaceTag($body, $inform, $profile_uid, $tag, $network)) && $success['replaced']) {
|
||||
$tagged[] = $tag;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -21,9 +21,9 @@
|
|||
|
||||
namespace Friendica\Content\Widget;
|
||||
|
||||
use Friendica\Content\Feature;
|
||||
use Friendica\Core\Renderer;
|
||||
use Friendica\DI;
|
||||
use Friendica\Model\User;
|
||||
|
||||
/**
|
||||
* TagCloud widget
|
||||
|
|
@ -34,36 +34,27 @@ class CalendarExport
|
|||
{
|
||||
/**
|
||||
* Get the events widget.
|
||||
* @param int $uid
|
||||
*
|
||||
* @return string Formated HTML of the calendar widget.
|
||||
* @throws \Friendica\Network\HTTPException\InternalServerErrorException
|
||||
*/
|
||||
public static function getHTML() {
|
||||
$a = DI::app();
|
||||
|
||||
if (empty($a->data['user'])) {
|
||||
return;
|
||||
public static function getHTML(int $uid = 0) {
|
||||
if (empty($uid)) {
|
||||
return '';
|
||||
}
|
||||
|
||||
$owner_uid = intval($a->data['user']['uid']);
|
||||
|
||||
// The permission testing is a little bit tricky because we have to respect many cases.
|
||||
|
||||
// It's not the private events page (we don't get the $owner_uid for /events).
|
||||
if (!local_user() && !$owner_uid) {
|
||||
return;
|
||||
$user = User::getById($uid, ['nickname']);
|
||||
if (empty($user['nickname'])) {
|
||||
return '';
|
||||
}
|
||||
|
||||
// $a->data is only available if the profile page is visited. If the visited page is not part
|
||||
// of the profile page it should be the personal /events page. So we can use $a->user.
|
||||
$user = ($a->data['user']['nickname'] ?? '') ?: $a->user['nickname'];
|
||||
|
||||
$tpl = Renderer::getMarkupTemplate("widget/events.tpl");
|
||||
$return = Renderer::replaceMacros($tpl, [
|
||||
'$etitle' => DI::l10n()->t("Export"),
|
||||
'$export_ical' => DI::l10n()->t("Export calendar as ical"),
|
||||
'$export_csv' => DI::l10n()->t("Export calendar as csv"),
|
||||
'$user' => $user
|
||||
'$user' => $user['nickname']
|
||||
]);
|
||||
|
||||
return $return;
|
||||
|
|
|
|||
|
|
@ -127,8 +127,8 @@ class TagCloud
|
|||
private static function tagCalc(array $arr)
|
||||
{
|
||||
$tags = [];
|
||||
$min = 1e9;
|
||||
$max = -1e9;
|
||||
$min = 1000000000.0;
|
||||
$max = -1000000000.0;
|
||||
$x = 0;
|
||||
|
||||
if (!$arr) {
|
||||
|
|
@ -145,7 +145,7 @@ class TagCloud
|
|||
}
|
||||
|
||||
usort($tags, 'self::tagsSort');
|
||||
$range = max(.01, $max - $min) * 1.0001;
|
||||
$range = max(0.01, $max - $min) * 1.0001;
|
||||
|
||||
for ($x = 0; $x < count($tags); $x ++) {
|
||||
$tags[$x][2] = 1 + floor(9 * ($tags[$x][1] - $min) / $range);
|
||||
|
|
|
|||
|
|
@ -172,6 +172,8 @@ HELP;
|
|||
|
||||
Friendica\DI::init($this->dice);
|
||||
|
||||
Renderer::registerTemplateEngine('Friendica\Render\FriendicaSmartyEngine');
|
||||
|
||||
/** @var Console $subconsole */
|
||||
$subconsole = $this->dice->create($className, [$subargs]);
|
||||
|
||||
|
|
|
|||
|
|
@ -465,7 +465,7 @@ class Installer
|
|||
|
||||
$status = $this->checkFunction('proc_open',
|
||||
DI::l10n()->t('Program execution functions'),
|
||||
DI::l10n()->t('Error: Program execution functions required but not enabled.'),
|
||||
DI::l10n()->t('Error: Program execution functions (proc_open) required but not enabled.'),
|
||||
true
|
||||
);
|
||||
$returnVal = $returnVal ? $status : false;
|
||||
|
|
|
|||
|
|
@ -116,16 +116,17 @@ class Session
|
|||
$session = DI::session();
|
||||
|
||||
$session->set('remote', []);
|
||||
$remote = [];
|
||||
|
||||
$remote_contacts = DBA::select('contact', ['id', 'uid'], ['nurl' => Strings::normaliseLink($session->get('my_url')), 'rel' => [Contact::FOLLOWER, Contact::FRIEND], 'self' => false]);
|
||||
while ($contact = DBA::fetch($remote_contacts)) {
|
||||
if (($contact['uid'] == 0) || Contact\User::isBlocked($contact['id'], $contact['uid'])) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$session->set('remote', [$contact['uid'] => $contact['id']]);
|
||||
$remote[$contact['uid']] = $contact['id'];
|
||||
}
|
||||
DBA::close($remote_contacts);
|
||||
$session->set('remote', $remote);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -25,6 +25,7 @@ use Exception;
|
|||
use Friendica\Core\Config\IConfig;
|
||||
use Friendica\Database\Database;
|
||||
use Friendica\Model\Storage;
|
||||
use Friendica\Network\IHTTPRequest;
|
||||
use Psr\Log\LoggerInterface;
|
||||
|
||||
|
||||
|
|
@ -60,6 +61,8 @@ class StorageManager
|
|||
private $logger;
|
||||
/** @var L10n */
|
||||
private $l10n;
|
||||
/** @var IHTTPRequest */
|
||||
private $httpRequest;
|
||||
|
||||
/** @var Storage\IStorage */
|
||||
private $currentBackend;
|
||||
|
|
@ -70,12 +73,13 @@ class StorageManager
|
|||
* @param LoggerInterface $logger
|
||||
* @param L10n $l10n
|
||||
*/
|
||||
public function __construct(Database $dba, IConfig $config, LoggerInterface $logger, L10n $l10n)
|
||||
public function __construct(Database $dba, IConfig $config, LoggerInterface $logger, L10n $l10n, IHTTPRequest $httpRequest)
|
||||
{
|
||||
$this->dba = $dba;
|
||||
$this->config = $config;
|
||||
$this->logger = $logger;
|
||||
$this->l10n = $l10n;
|
||||
$this->dba = $dba;
|
||||
$this->config = $config;
|
||||
$this->logger = $logger;
|
||||
$this->l10n = $l10n;
|
||||
$this->httpRequest = $httpRequest;
|
||||
$this->backends = $config->get('storage', 'backends', self::DEFAULT_BACKENDS);
|
||||
|
||||
$currentName = $this->config->get('storage', 'name', '');
|
||||
|
|
@ -126,6 +130,9 @@ class StorageManager
|
|||
case Storage\SystemResource::getName():
|
||||
$this->backendInstances[$name] = new Storage\SystemResource();
|
||||
break;
|
||||
case Storage\ExternalResource::getName():
|
||||
$this->backendInstances[$name] = new Storage\ExternalResource($this->httpRequest);
|
||||
break;
|
||||
default:
|
||||
$data = [
|
||||
'name' => $name,
|
||||
|
|
@ -158,7 +165,7 @@ class StorageManager
|
|||
public function isValidBackend(string $name = null, bool $onlyUserBackend = false)
|
||||
{
|
||||
return array_key_exists($name, $this->backends) ||
|
||||
(!$onlyUserBackend && $name === Storage\SystemResource::getName());
|
||||
(!$onlyUserBackend && in_array($name, [Storage\SystemResource::getName(), Storage\ExternalResource::getName()]));
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -213,6 +213,8 @@ class Update
|
|||
if ($sendMail) {
|
||||
self::updateSuccessful($stored, $current);
|
||||
}
|
||||
} else {
|
||||
Logger::warning('Update lock could not be acquired');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
24
src/DI.php
24
src/DI.php
|
|
@ -287,14 +287,6 @@ abstract class DI
|
|||
return self::$dice->create(Factory\Api\Mastodon\Error::class);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Factory\Api\Mastodon\Field
|
||||
*/
|
||||
public static function mstdnField()
|
||||
{
|
||||
return self::$dice->create(Factory\Api\Mastodon\Field::class);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Factory\Api\Mastodon\FollowRequest
|
||||
*/
|
||||
|
|
@ -327,14 +319,6 @@ abstract class DI
|
|||
return self::$dice->create(Factory\Api\Mastodon\ListEntity::class);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Factory\Api\Mastodon\Mention
|
||||
*/
|
||||
public static function mstdnMention()
|
||||
{
|
||||
return self::$dice->create(Factory\Api\Mastodon\Mention::class);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Factory\Api\Mastodon\Notification
|
||||
*/
|
||||
|
|
@ -343,14 +327,6 @@ abstract class DI
|
|||
return self::$dice->create(Factory\Api\Mastodon\Notification::class);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Factory\Api\Mastodon\Tag
|
||||
*/
|
||||
public static function mstdnTag()
|
||||
{
|
||||
return self::$dice->create(Factory\Api\Mastodon\Tag::class);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Factory\Api\Twitter\User
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -24,6 +24,7 @@ namespace Friendica\Database;
|
|||
use Exception;
|
||||
use Friendica\Core\Hook;
|
||||
use Friendica\Core\Logger;
|
||||
use Friendica\Core\Renderer;
|
||||
use Friendica\DI;
|
||||
use Friendica\Model\Item;
|
||||
use Friendica\Model\User;
|
||||
|
|
@ -159,6 +160,108 @@ class DBStructure
|
|||
return DI::l10n()->t('Errors encountered performing database changes: ') . $message . EOL;
|
||||
}
|
||||
|
||||
public static function writeStructure()
|
||||
{
|
||||
$tables = [];
|
||||
foreach (self::definition(null) as $name => $definition) {
|
||||
$indexes = [[
|
||||
'name' => 'Name',
|
||||
'fields' => 'Fields',
|
||||
],
|
||||
[
|
||||
'name' => '-',
|
||||
'fields' => '-',
|
||||
]];
|
||||
|
||||
$lengths = ['name' => 4, 'fields' => 6];
|
||||
foreach ($definition['indexes'] as $key => $value) {
|
||||
$fieldlist = implode(', ', $value);
|
||||
$indexes[] = ['name' => $key, 'fields' => $fieldlist];
|
||||
$lengths['name'] = max($lengths['name'], strlen($key));
|
||||
$lengths['fields'] = max($lengths['fields'], strlen($fieldlist));
|
||||
}
|
||||
|
||||
array_walk_recursive($indexes, function(&$value, $key) use ($lengths)
|
||||
{
|
||||
$value = str_pad($value, $lengths[$key], $value === '-' ? '-' : ' ');
|
||||
});
|
||||
|
||||
$foreign = [];
|
||||
$fields = [[
|
||||
'name' => 'Field',
|
||||
'comment' => 'Description',
|
||||
'type' => 'Type',
|
||||
'null' => 'Null',
|
||||
'primary' => 'Key',
|
||||
'default' => 'Default',
|
||||
'extra' => 'Extra',
|
||||
],
|
||||
[
|
||||
'name' => '-',
|
||||
'comment' => '-',
|
||||
'type' => '-',
|
||||
'null' => '-',
|
||||
'primary' => '-',
|
||||
'default' => '-',
|
||||
'extra' => '-',
|
||||
]];
|
||||
$lengths = [
|
||||
'name' => 5,
|
||||
'comment' => 11,
|
||||
'type' => 4,
|
||||
'null' => 4,
|
||||
'primary' => 3,
|
||||
'default' => 7,
|
||||
'extra' => 5,
|
||||
];
|
||||
foreach ($definition['fields'] as $key => $value) {
|
||||
$field = [];
|
||||
$field['name'] = $key;
|
||||
$field['comment'] = $value['comment'] ?? '';
|
||||
$field['type'] = $value['type'];
|
||||
$field['null'] = ($value['not null'] ?? false) ? 'NO' : 'YES';
|
||||
$field['primary'] = ($value['primary'] ?? false) ? 'PRI' : '';
|
||||
$field['default'] = $value['default'] ?? 'NULL';
|
||||
$field['extra'] = $value['extra'] ?? '';
|
||||
|
||||
foreach ($field as $fieldname => $fieldvalue) {
|
||||
$lengths[$fieldname] = max($lengths[$fieldname] ?? 0, strlen($fieldvalue));
|
||||
}
|
||||
$fields[] = $field;
|
||||
|
||||
if (!empty($value['foreign'])) {
|
||||
$foreign[] = [
|
||||
'field' => $key,
|
||||
'targettable' => array_keys($value['foreign'])[0],
|
||||
'targetfield' => array_values($value['foreign'])[0]
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
array_walk_recursive($fields, function(&$value, $key) use ($lengths)
|
||||
{
|
||||
$value = str_pad($value, $lengths[$key], $value === '-' ? '-' : ' ');
|
||||
});
|
||||
|
||||
$tables[] = ['name' => $name, 'comment' => $definition['comment']];
|
||||
$content = Renderer::replaceMacros(Renderer::getMarkupTemplate('structure.tpl'), [
|
||||
'$name' => $name,
|
||||
'$comment' => $definition['comment'],
|
||||
'$fields' => $fields,
|
||||
'$indexes' => $indexes,
|
||||
'$foreign' => $foreign,
|
||||
]);
|
||||
$filename = DI::basePath() . '/doc/database/db_' . $name . '.md';
|
||||
file_put_contents($filename, $content);
|
||||
}
|
||||
asort($tables);
|
||||
$content = Renderer::replaceMacros(Renderer::getMarkupTemplate('tables.tpl'), [
|
||||
'$tables' => $tables,
|
||||
]);
|
||||
$filename = DI::basePath() . '/doc/database.md';
|
||||
file_put_contents($filename, $content);
|
||||
}
|
||||
|
||||
public static function printStructure($basePath)
|
||||
{
|
||||
$database = self::definition($basePath, false);
|
||||
|
|
@ -241,6 +344,12 @@ class DBStructure
|
|||
// Assign all field that are present in the table
|
||||
foreach ($fieldnames as $field) {
|
||||
if (isset($data[$field])) {
|
||||
// Limit the length of varchar, varbinary, char and binrary fields
|
||||
if (is_string($data[$field]) && preg_match("/char\((\d*)\)/", $definition[$table]['fields'][$field]['type'], $result)) {
|
||||
$data[$field] = mb_substr($data[$field], 0, $result[1]);
|
||||
} elseif (is_string($data[$field]) && preg_match("/binary\((\d*)\)/", $definition[$table]['fields'][$field]['type'], $result)) {
|
||||
$data[$field] = substr($data[$field], 0, $result[1]);
|
||||
}
|
||||
$fields[$field] = $data[$field];
|
||||
}
|
||||
}
|
||||
|
|
@ -1200,7 +1309,7 @@ class DBStructure
|
|||
if ($verbose) {
|
||||
echo "Zero contact added\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
} elseif (self::existsTable('contact') && $verbose) {
|
||||
echo "Zero contact already added\n";
|
||||
} elseif ($verbose) {
|
||||
|
|
@ -1224,7 +1333,7 @@ class DBStructure
|
|||
|
||||
if (self::existsTable('permissionset')) {
|
||||
if (!DBA::exists('permissionset', ['id' => 0])) {
|
||||
DBA::insert('permissionset', ['allow_cid' => '', 'allow_gid' => '', 'deny_cid' => '', 'deny_gid' => '']);
|
||||
DBA::insert('permissionset', ['allow_cid' => '', 'allow_gid' => '', 'deny_cid' => '', 'deny_gid' => '']);
|
||||
$lastid = DBA::lastInsertId();
|
||||
if ($lastid != 0) {
|
||||
DBA::update('permissionset', ['id' => 0], ['id' => $lastid]);
|
||||
|
|
@ -1259,7 +1368,7 @@ class DBStructure
|
|||
} elseif ($verbose) {
|
||||
echo "permissionset: Table not found\n";
|
||||
}
|
||||
|
||||
|
||||
if (!self::existsForeignKeyForField('tokens', 'client_id')) {
|
||||
$tokens = DBA::p("SELECT `tokens`.`id` FROM `tokens`
|
||||
LEFT JOIN `clients` ON `clients`.`client_id` = `tokens`.`client_id`
|
||||
|
|
|
|||
|
|
@ -29,34 +29,36 @@ use Friendica\Model\Contact;
|
|||
use Friendica\Network\HTTPException;
|
||||
use Friendica\Repository\PermissionSet;
|
||||
use Friendica\Repository\ProfileField;
|
||||
use ImagickException;
|
||||
use Psr\Log\LoggerInterface;
|
||||
|
||||
class Account extends BaseFactory
|
||||
{
|
||||
/** @var BaseURL */
|
||||
protected $baseUrl;
|
||||
private $baseUrl;
|
||||
/** @var ProfileField */
|
||||
protected $profileField;
|
||||
private $profileFieldRepo;
|
||||
/** @var Field */
|
||||
protected $mstdnField;
|
||||
private $mstdnFieldFactory;
|
||||
|
||||
public function __construct(LoggerInterface $logger, BaseURL $baseURL, ProfileField $profileField, Field $mstdnField)
|
||||
public function __construct(LoggerInterface $logger, BaseURL $baseURL, ProfileField $profileFieldRepo, Field $mstdnFieldFactory)
|
||||
{
|
||||
parent::__construct($logger);
|
||||
|
||||
$this->baseUrl = $baseURL;
|
||||
$this->profileField = $profileField;
|
||||
$this->mstdnField = $mstdnField;
|
||||
$this->baseUrl = $baseURL;
|
||||
$this->profileFieldRepo = $profileFieldRepo;
|
||||
$this->mstdnFieldFactory = $mstdnFieldFactory;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $contactId
|
||||
* @param int $uid Public contact (=0) or owner user id
|
||||
*
|
||||
* @return \Friendica\Object\Api\Mastodon\Account
|
||||
* @throws HTTPException\InternalServerErrorException
|
||||
* @throws \ImagickException
|
||||
* @throws ImagickException|HTTPException\NotFoundException
|
||||
*/
|
||||
public function createFromContactId(int $contactId, $uid = 0)
|
||||
public function createFromContactId(int $contactId, $uid = 0): \Friendica\Object\Api\Mastodon\Account
|
||||
{
|
||||
$cdata = Contact::getPublicAndUserContacID($contactId, $uid);
|
||||
if (!empty($cdata)) {
|
||||
|
|
@ -64,7 +66,7 @@ class Account extends BaseFactory
|
|||
$userContact = Contact::getById($cdata['user']);
|
||||
} else {
|
||||
$publicContact = Contact::getById($contactId);
|
||||
$userContact = [];
|
||||
$userContact = [];
|
||||
}
|
||||
|
||||
if (empty($publicContact)) {
|
||||
|
|
@ -75,8 +77,8 @@ class Account extends BaseFactory
|
|||
|
||||
$self_contact = Contact::selectFirst(['uid'], ['nurl' => $publicContact['nurl'], 'self' => true]);
|
||||
if (!empty($self_contact['uid'])) {
|
||||
$profileFields = $this->profileField->select(['uid' => $self_contact['uid'], 'psid' => PermissionSet::PUBLIC]);
|
||||
$fields = $this->mstdnField->createFromProfileFields($profileFields);
|
||||
$profileFields = $this->profileFieldRepo->select(['uid' => $self_contact['uid'], 'psid' => PermissionSet::PUBLIC]);
|
||||
$fields = $this->mstdnFieldFactory->createFromProfileFields($profileFields);
|
||||
} else {
|
||||
$fields = new Fields();
|
||||
}
|
||||
|
|
@ -87,18 +89,17 @@ class Account extends BaseFactory
|
|||
/**
|
||||
* @param int $userId
|
||||
* @return \Friendica\Object\Api\Mastodon\Account
|
||||
* @throws HTTPException\InternalServerErrorException
|
||||
* @throws \ImagickException
|
||||
* @throws ImagickException|HTTPException\InternalServerErrorException
|
||||
*/
|
||||
public function createFromUserId(int $userId)
|
||||
public function createFromUserId(int $userId): \Friendica\Object\Api\Mastodon\Account
|
||||
{
|
||||
$publicContact = Contact::selectFirst([], ['uid' => $userId, 'self' => true]);
|
||||
|
||||
$profileFields = $this->profileField->select(['uid' => $userId, 'psid' => PermissionSet::PUBLIC]);
|
||||
$fields = $this->mstdnField->createFromProfileFields($profileFields);
|
||||
$profileFields = $this->profileFieldRepo->select(['uid' => $userId, 'psid' => PermissionSet::PUBLIC]);
|
||||
$fields = $this->mstdnFieldFactory->createFromProfileFields($profileFields);
|
||||
|
||||
$apcontact = APContact::getByURL($publicContact['url'], false);
|
||||
$apContact = APContact::getByURL($publicContact['url'], false);
|
||||
|
||||
return new \Friendica\Object\Api\Mastodon\Account($this->baseUrl, $publicContact, $fields, $apcontact);
|
||||
return new \Friendica\Object\Api\Mastodon\Account($this->baseUrl, $publicContact, $fields, $apContact);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -22,28 +22,41 @@
|
|||
namespace Friendica\Factory\Api\Mastodon;
|
||||
|
||||
use Friendica\BaseFactory;
|
||||
use Friendica\Database\DBA;
|
||||
use Friendica\Database\Database;
|
||||
use Friendica\Network\HTTPException\InternalServerErrorException;
|
||||
use Psr\Log\LoggerInterface;
|
||||
|
||||
class Application extends BaseFactory
|
||||
{
|
||||
/** @var Database */
|
||||
private $dba;
|
||||
|
||||
public function __construct(LoggerInterface $logger, Database $dba)
|
||||
{
|
||||
parent::__construct($logger);
|
||||
$this->dba = $dba;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $id Application ID
|
||||
*
|
||||
* @return \Friendica\Object\Api\Mastodon\Application
|
||||
*
|
||||
* @throws InternalServerErrorException
|
||||
*/
|
||||
public function createFromApplicationId(int $id)
|
||||
public function createFromApplicationId(int $id): \Friendica\Object\Api\Mastodon\Application
|
||||
{
|
||||
$application = DBA::selectFirst('application', ['client_id', 'client_secret', 'id', 'name', 'redirect_uri', 'website'], ['id' => $id]);
|
||||
if (!DBA::isResult($application)) {
|
||||
return [];
|
||||
$application = $this->dba->selectFirst('application', ['client_id', 'client_secret', 'id', 'name', 'redirect_uri', 'website'], ['id' => $id]);
|
||||
if (!$this->dba->isResult($application)) {
|
||||
throw new InternalServerErrorException(sprintf("ID '%s' not found", $id));
|
||||
}
|
||||
|
||||
$object = new \Friendica\Object\Api\Mastodon\Application(
|
||||
return new \Friendica\Object\Api\Mastodon\Application(
|
||||
$application['name'],
|
||||
$application['client_id'],
|
||||
$application['client_secret'],
|
||||
$application['id'],
|
||||
$application['redirect_uri'],
|
||||
$application['website']);
|
||||
|
||||
return $object->toArray();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -23,11 +23,9 @@ namespace Friendica\Factory\Api\Mastodon;
|
|||
|
||||
use Friendica\App\BaseURL;
|
||||
use Friendica\BaseFactory;
|
||||
use Friendica\DI;
|
||||
use Friendica\Model\Photo;
|
||||
use Friendica\Network\HTTPException;
|
||||
use Friendica\Model\Post;
|
||||
use Friendica\Repository\ProfileField;
|
||||
use Friendica\Util\Images;
|
||||
use Friendica\Util\Proxy;
|
||||
use Psr\Log\LoggerInterface;
|
||||
|
|
@ -35,32 +33,24 @@ use Psr\Log\LoggerInterface;
|
|||
class Attachment extends BaseFactory
|
||||
{
|
||||
/** @var BaseURL */
|
||||
protected $baseUrl;
|
||||
/** @var ProfileField */
|
||||
protected $profileField;
|
||||
/** @var Field */
|
||||
protected $mstdnField;
|
||||
private $baseUrl;
|
||||
|
||||
public function __construct(LoggerInterface $logger, BaseURL $baseURL, ProfileField $profileField, Field $mstdnField)
|
||||
public function __construct(LoggerInterface $logger, BaseURL $baseURL)
|
||||
{
|
||||
parent::__construct($logger);
|
||||
|
||||
$this->baseUrl = $baseURL;
|
||||
$this->profileField = $profileField;
|
||||
$this->mstdnField = $mstdnField;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $uriId Uri-ID of the attachments
|
||||
* @return array
|
||||
* @throws HTTPException\InternalServerErrorException
|
||||
* @throws \ImagickException
|
||||
*/
|
||||
public function createFromUriId(int $uriId)
|
||||
public function createFromUriId(int $uriId): array
|
||||
{
|
||||
$attachments = [];
|
||||
foreach (Post\Media::getByURIId($uriId, [Post\Media::AUDIO, Post\Media::VIDEO, Post\Media::IMAGE]) as $attachment) {
|
||||
|
||||
$filetype = !empty($attachment['mimetype']) ? strtolower(substr($attachment['mimetype'], 0, strpos($attachment['mimetype'], '/'))) : '';
|
||||
|
||||
if (($filetype == 'audio') || ($attachment['type'] == Post\Media::AUDIO)) {
|
||||
|
|
@ -77,20 +67,19 @@ class Attachment extends BaseFactory
|
|||
|
||||
$remote = $attachment['url'];
|
||||
if ($type == 'image') {
|
||||
if (Proxy::isLocalImage($attachment['url'])) {
|
||||
$url = $attachment['url'];
|
||||
$preview = $attachment['preview'] ?? $url;
|
||||
$remote = '';
|
||||
} else {
|
||||
$url = Proxy::proxifyUrl($attachment['url']);
|
||||
$preview = Proxy::proxifyUrl($attachment['url'], false, Proxy::SIZE_SMALL);
|
||||
}
|
||||
$url = Post\Media::getPreviewUrlForId($attachment['id']);
|
||||
$preview = Post\Media::getPreviewUrlForId($attachment['id'], Proxy::SIZE_SMALL);
|
||||
} else {
|
||||
$url = '';
|
||||
$preview = '';
|
||||
$url = $attachment['url'];
|
||||
|
||||
if (!empty($attachment['preview'])) {
|
||||
$preview = Post\Media::getPreviewUrlForId($attachment['id'], Proxy::SIZE_SMALL);
|
||||
} else {
|
||||
$preview = '';
|
||||
}
|
||||
}
|
||||
|
||||
$object = new \Friendica\Object\Api\Mastodon\Attachment($attachment, $type, $url, $preview, $remote);
|
||||
$object = new \Friendica\Object\Api\Mastodon\Attachment($attachment, $type, $url, $preview, $remote);
|
||||
$attachments[] = $object->toArray();
|
||||
}
|
||||
|
||||
|
|
@ -99,27 +88,27 @@ class Attachment extends BaseFactory
|
|||
|
||||
/**
|
||||
* @param int $id id of the photo
|
||||
*
|
||||
* @return array
|
||||
* @throws HTTPException\InternalServerErrorException
|
||||
* @throws \ImagickException
|
||||
*/
|
||||
public function createFromPhoto(int $id)
|
||||
public function createFromPhoto(int $id): array
|
||||
{
|
||||
$photo = Photo::selectFirst(['resource-id', 'uid', 'id', 'title', 'type'], ['id' => $id]);
|
||||
if (empty($photo)) {
|
||||
return null;
|
||||
return [];
|
||||
}
|
||||
|
||||
$attachment = ['id' => $photo['id'], 'description' => $photo['title']];
|
||||
|
||||
$phototypes = Images::supportedTypes();
|
||||
$ext = $phototypes[$photo['type']];
|
||||
$photoTypes = Images::supportedTypes();
|
||||
$ext = $photoTypes[$photo['type']];
|
||||
|
||||
$url = DI::baseUrl() . '/photo/' . $photo['resource-id'] . '-0.' . $ext;
|
||||
$url = $this->baseUrl . '/photo/' . $photo['resource-id'] . '-0.' . $ext;
|
||||
|
||||
$preview = Photo::selectFirst(['scale'], ["`resource-id` = ? AND `uid` = ? AND `scale` > ?", $photo['resource-id'], $photo['uid'], 0], ['order' => ['scale']]);
|
||||
if (empty($scale)) {
|
||||
$preview_url = DI::baseUrl() . '/photo/' . $photo['resource-id'] . '-' . $preview['scale'] . '.' . $ext;
|
||||
$preview_url = $this->baseUrl . '/photo/' . $photo['resource-id'] . '-' . $preview['scale'] . '.' . $ext;
|
||||
} else {
|
||||
$preview_url = '';
|
||||
}
|
||||
|
|
|
|||
|
|
@ -31,11 +31,12 @@ class Card extends BaseFactory
|
|||
{
|
||||
/**
|
||||
* @param int $uriId Uri-ID of the item
|
||||
*
|
||||
* @return \Friendica\Object\Api\Mastodon\Card
|
||||
* @throws HTTPException\InternalServerErrorException
|
||||
* @throws \ImagickException
|
||||
* @throws \ImagickException*@throws \Exception
|
||||
*/
|
||||
public function createFromUriId(int $uriId)
|
||||
public function createFromUriId(int $uriId): \Friendica\Object\Api\Mastodon\Card
|
||||
{
|
||||
$item = Post::selectFirst(['body'], ['uri-id' => $uriId]);
|
||||
if (!empty($item['body'])) {
|
||||
|
|
|
|||
|
|
@ -22,13 +22,33 @@
|
|||
namespace Friendica\Factory\Api\Mastodon;
|
||||
|
||||
use Friendica\BaseFactory;
|
||||
use Friendica\Database\DBA;
|
||||
use Friendica\DI;
|
||||
use Friendica\Database\Database;
|
||||
use Friendica\Model\Contact;
|
||||
use Friendica\Network\HTTPException;
|
||||
use ImagickException;
|
||||
use Psr\Log\LoggerInterface;
|
||||
|
||||
class Conversation extends BaseFactory
|
||||
{
|
||||
public function CreateFromConvId(int $id)
|
||||
/** @var Database */
|
||||
private $dba;
|
||||
/** @var Status */
|
||||
private $mstdnStatusFactory;
|
||||
/** @var Account */
|
||||
private $mstdnAccountFactory;
|
||||
|
||||
public function __construct(LoggerInterface $logger, Database $dba, Status $mstdnStatusFactory, Account $mstdnAccountFactoryFactory)
|
||||
{
|
||||
parent::__construct($logger);
|
||||
$this->dba = $dba;
|
||||
$this->mstdnStatusFactory = $mstdnStatusFactory;
|
||||
$this->mstdnAccountFactory = $mstdnAccountFactoryFactory;
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws ImagickException|HTTPException\InternalServerErrorException|HTTPException\NotFoundException
|
||||
*/
|
||||
public function CreateFromConvId(int $id): \Friendica\Object\Api\Mastodon\Conversation
|
||||
{
|
||||
$accounts = [];
|
||||
$unread = false;
|
||||
|
|
@ -36,8 +56,8 @@ class Conversation extends BaseFactory
|
|||
|
||||
$ids = [];
|
||||
|
||||
$mails = DBA::select('mail', ['id', 'from-url', 'uid', 'seen'], ['convid' => $id], ['order' => ['id' => true]]);
|
||||
while ($mail = DBA::fetch($mails)) {
|
||||
$mails = $this->dba->select('mail', ['id', 'from-url', 'uid', 'seen'], ['convid' => $id], ['order' => ['id' => true]]);
|
||||
while ($mail = $this->dba->fetch($mails)) {
|
||||
if (!$mail['seen']) {
|
||||
$unread = true;
|
||||
}
|
||||
|
|
@ -50,10 +70,10 @@ class Conversation extends BaseFactory
|
|||
$ids[] = $id;
|
||||
|
||||
if (empty($last_status)) {
|
||||
$last_status = DI::mstdnStatus()->createFromMailId($mail['id']);
|
||||
$last_status = $this->mstdnStatusFactory->createFromMailId($mail['id']);
|
||||
}
|
||||
|
||||
$accounts[] = DI::mstdnAccount()->createFromContactId($id, 0);
|
||||
$accounts[] = $this->mstdnAccountFactory->createFromContactId($id, 0);
|
||||
}
|
||||
|
||||
return new \Friendica\Object\Api\Mastodon\Conversation($id, $accounts, $unread, $last_status);
|
||||
|
|
|
|||
|
|
@ -26,7 +26,7 @@ use Friendica\Collection\Api\Mastodon\Emojis;
|
|||
|
||||
class Emoji extends BaseFactory
|
||||
{
|
||||
public function create(string $shortcode, string $url)
|
||||
public function create(string $shortcode, string $url): \Friendica\Object\Api\Mastodon\Emoji
|
||||
{
|
||||
return new \Friendica\Object\Api\Mastodon\Emoji($shortcode, $url);
|
||||
}
|
||||
|
|
@ -35,7 +35,7 @@ class Emoji extends BaseFactory
|
|||
* @param array $smilies
|
||||
* @return Emojis
|
||||
*/
|
||||
public function createCollectionFromSmilies(array $smilies)
|
||||
public function createCollectionFromSmilies(array $smilies): Emojis
|
||||
{
|
||||
$prototype = null;
|
||||
|
||||
|
|
@ -47,7 +47,7 @@ class Emoji extends BaseFactory
|
|||
|
||||
if ($prototype === null) {
|
||||
$prototype = $this->create($shortcode, $url);
|
||||
$emojis[] = $prototype;
|
||||
$emojis[] = $prototype;
|
||||
} else {
|
||||
$emojis[] = \Friendica\Object\Api\Mastodon\Emoji::createFromPrototype($prototype, $shortcode, $url);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -21,65 +21,82 @@
|
|||
|
||||
namespace Friendica\Factory\Api\Mastodon;
|
||||
|
||||
use Friendica\App\Arguments;
|
||||
use Friendica\BaseFactory;
|
||||
use Friendica\Core\Logger;
|
||||
use Friendica\Core\L10n;
|
||||
use Friendica\Core\System;
|
||||
use Friendica\DI;
|
||||
use Psr\Log\LoggerInterface;
|
||||
|
||||
/** @todo A Factory shouldn't return something to the frontpage, it's for creating content, not showing it */
|
||||
class Error extends BaseFactory
|
||||
{
|
||||
/** @var Arguments */
|
||||
private $args;
|
||||
/** @var string[] The $_SERVER array */
|
||||
private $server;
|
||||
/** @var L10n */
|
||||
private $l10n;
|
||||
|
||||
public function __construct(LoggerInterface $logger, Arguments $args, L10n $l10n, array $server)
|
||||
{
|
||||
parent::__construct($logger);
|
||||
$this->args = $args;
|
||||
$this->server = $server;
|
||||
$this->l10n = $l10n;
|
||||
}
|
||||
|
||||
private function logError(int $errorno, string $error)
|
||||
{
|
||||
Logger::info('API Error', ['no' => $errorno, 'error' => $error, 'method' => $_SERVER['REQUEST_METHOD'] ?? '', 'command' => DI::args()->getQueryString(), 'user-agent' => $_SERVER['HTTP_USER_AGENT'] ?? '']);
|
||||
$this->logger->info('API Error', ['no' => $errorno, 'error' => $error, 'method' => $this->server['REQUEST_METHOD'] ?? '', 'command' => $this->args->getQueryString(), 'user-agent' => $this->server['HTTP_USER_AGENT'] ?? '']);
|
||||
}
|
||||
|
||||
public function RecordNotFound()
|
||||
{
|
||||
$error = DI::l10n()->t('Record not found');
|
||||
$error = $this->l10n->t('Record not found');
|
||||
$error_description = '';
|
||||
$errorobj = New \Friendica\Object\Api\Mastodon\Error($error, $error_description);
|
||||
$errorObj = new \Friendica\Object\Api\Mastodon\Error($error, $error_description);
|
||||
|
||||
$this->logError(404, $error);
|
||||
System::jsonError(404, $errorobj->toArray());
|
||||
System::jsonError(404, $errorObj->toArray());
|
||||
}
|
||||
|
||||
public function UnprocessableEntity(string $error = '')
|
||||
{
|
||||
$error = $error ?: DI::l10n()->t('Unprocessable Entity');
|
||||
$error = $error ?: $this->l10n->t('Unprocessable Entity');
|
||||
$error_description = '';
|
||||
$errorobj = New \Friendica\Object\Api\Mastodon\Error($error, $error_description);
|
||||
$errorObj = new \Friendica\Object\Api\Mastodon\Error($error, $error_description);
|
||||
|
||||
$this->logError(422, $error);
|
||||
System::jsonError(422, $errorobj->toArray());
|
||||
System::jsonError(422, $errorObj->toArray());
|
||||
}
|
||||
|
||||
public function Unauthorized(string $error = '')
|
||||
{
|
||||
$error = $error ?: DI::l10n()->t('Unauthorized');
|
||||
$error = $error ?: $this->l10n->t('Unauthorized');
|
||||
$error_description = '';
|
||||
$errorobj = New \Friendica\Object\Api\Mastodon\Error($error, $error_description);
|
||||
$errorObj = new \Friendica\Object\Api\Mastodon\Error($error, $error_description);
|
||||
|
||||
$this->logError(401, $error);
|
||||
System::jsonError(401, $errorobj->toArray());
|
||||
System::jsonError(401, $errorObj->toArray());
|
||||
}
|
||||
|
||||
public function Forbidden(string $error = '')
|
||||
{
|
||||
$error = $error ?: DI::l10n()->t('Token is not authorized with a valid user or is missing a required scope');
|
||||
$error = $error ?: $this->l10n->t('Token is not authorized with a valid user or is missing a required scope');
|
||||
$error_description = '';
|
||||
$errorobj = New \Friendica\Object\Api\Mastodon\Error($error, $error_description);
|
||||
$errorObj = new \Friendica\Object\Api\Mastodon\Error($error, $error_description);
|
||||
|
||||
$this->logError(403, $error);
|
||||
System::jsonError(403, $errorobj->toArray());
|
||||
System::jsonError(403, $errorObj->toArray());
|
||||
}
|
||||
|
||||
public function InternalError(string $error = '')
|
||||
{
|
||||
$error = $error ?: DI::l10n()->t('Internal Server Error');
|
||||
$error = $error ?: $this->l10n->t('Internal Server Error');
|
||||
$error_description = '';
|
||||
$errorobj = New \Friendica\Object\Api\Mastodon\Error($error, $error_description);
|
||||
$errorObj = new \Friendica\Object\Api\Mastodon\Error($error, $error_description);
|
||||
|
||||
$this->logError(500, $error);
|
||||
System::jsonError(500, $errorobj->toArray());
|
||||
System::jsonError(500, $errorObj->toArray());
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -32,10 +32,10 @@ class Field extends BaseFactory
|
|||
{
|
||||
/**
|
||||
* @param ProfileField $profileField
|
||||
* @return \Friendica\Api\Entity\Mastodon\Field
|
||||
* @return \Friendica\Object\Api\Mastodon\Field
|
||||
* @throws HTTPException\InternalServerErrorException
|
||||
*/
|
||||
public function createFromProfileField(ProfileField $profileField)
|
||||
public function createFromProfileField(ProfileField $profileField): \Friendica\Object\Api\Mastodon\Field
|
||||
{
|
||||
return new \Friendica\Object\Api\Mastodon\Field($profileField->label, BBCode::convert($profileField->value, false, BBCode::ACTIVITYPUB));
|
||||
}
|
||||
|
|
@ -45,7 +45,7 @@ class Field extends BaseFactory
|
|||
* @return Fields
|
||||
* @throws HTTPException\InternalServerErrorException
|
||||
*/
|
||||
public function createFromProfileFields(ProfileFields $profileFields)
|
||||
public function createFromProfileFields(ProfileFields $profileFields): Fields
|
||||
{
|
||||
$fields = [];
|
||||
|
||||
|
|
|
|||
|
|
@ -27,12 +27,13 @@ use Friendica\Model\APContact;
|
|||
use Friendica\Model\Contact;
|
||||
use Friendica\Model\Introduction;
|
||||
use Friendica\Network\HTTPException;
|
||||
use ImagickException;
|
||||
use Psr\Log\LoggerInterface;
|
||||
|
||||
class FollowRequest extends BaseFactory
|
||||
{
|
||||
/** @var BaseURL */
|
||||
protected $baseUrl;
|
||||
private $baseUrl;
|
||||
|
||||
public function __construct(LoggerInterface $logger, BaseURL $baseURL)
|
||||
{
|
||||
|
|
@ -44,10 +45,9 @@ class FollowRequest extends BaseFactory
|
|||
/**
|
||||
* @param Introduction $introduction
|
||||
* @return \Friendica\Object\Api\Mastodon\FollowRequest
|
||||
* @throws HTTPException\InternalServerErrorException
|
||||
* @throws \ImagickException
|
||||
* @throws ImagickException|HTTPException\InternalServerErrorException
|
||||
*/
|
||||
public function createFromIntroduction(Introduction $introduction)
|
||||
public function createFromIntroduction(Introduction $introduction): \Friendica\Object\Api\Mastodon\FollowRequest
|
||||
{
|
||||
$cdata = Contact::getPublicAndUserContacID($introduction->{'contact-id'}, $introduction->uid);
|
||||
|
||||
|
|
@ -57,10 +57,10 @@ class FollowRequest extends BaseFactory
|
|||
}
|
||||
|
||||
$publicContact = Contact::getById($cdata['public']);
|
||||
$userContact = Contact::getById($cdata['user']);
|
||||
$userContact = Contact::getById($cdata['user']);
|
||||
|
||||
$apcontact = APContact::getByURL($publicContact['url'], false);
|
||||
$apContact = APContact::getByURL($publicContact['url'], false);
|
||||
|
||||
return new \Friendica\Object\Api\Mastodon\FollowRequest($this->baseUrl, $introduction->id, $publicContact, $apcontact, $userContact);
|
||||
return new \Friendica\Object\Api\Mastodon\FollowRequest($this->baseUrl, $introduction->id, $publicContact, $apContact, $userContact);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -22,13 +22,27 @@
|
|||
namespace Friendica\Factory\Api\Mastodon;
|
||||
|
||||
use Friendica\BaseFactory;
|
||||
use Friendica\Database\DBA;
|
||||
use Friendica\Database\Database;
|
||||
use Friendica\Network\HTTPException\InternalServerErrorException;
|
||||
use Psr\Log\LoggerInterface;
|
||||
|
||||
class ListEntity extends BaseFactory
|
||||
{
|
||||
public function createFromGroupId(int $id)
|
||||
/** @var Database */
|
||||
private $dba;
|
||||
|
||||
public function __construct(LoggerInterface $logger, Database $dba)
|
||||
{
|
||||
$group = DBA::selectFirst('group', ['name'], ['id' => $id, 'deleted' => false]);
|
||||
parent::__construct($logger);
|
||||
$this->dba = $dba;
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws InternalServerErrorException
|
||||
*/
|
||||
public function createFromGroupId(int $id): \Friendica\Object\Api\Mastodon\ListEntity
|
||||
{
|
||||
$group = $this->dba->selectFirst('group', ['name'], ['id' => $id, 'deleted' => false]);
|
||||
return new \Friendica\Object\Api\Mastodon\ListEntity($id, $group['name'] ?? '', 'list');
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -23,44 +23,36 @@ namespace Friendica\Factory\Api\Mastodon;
|
|||
|
||||
use Friendica\App\BaseURL;
|
||||
use Friendica\BaseFactory;
|
||||
use Friendica\Collection\Api\Mastodon\Mentions;
|
||||
use Friendica\Model\Contact;
|
||||
use Friendica\Model\Tag;
|
||||
use Friendica\Network\HTTPException;
|
||||
use Friendica\Repository\ProfileField;
|
||||
use Psr\Log\LoggerInterface;
|
||||
|
||||
class Mention extends BaseFactory
|
||||
{
|
||||
/** @var BaseURL */
|
||||
protected $baseUrl;
|
||||
/** @var ProfileField */
|
||||
protected $profileField;
|
||||
/** @var Field */
|
||||
protected $mstdnField;
|
||||
private $baseUrl;
|
||||
|
||||
public function __construct(LoggerInterface $logger, BaseURL $baseURL, ProfileField $profileField, Field $mstdnField)
|
||||
public function __construct(LoggerInterface $logger, BaseURL $baseURL)
|
||||
{
|
||||
parent::__construct($logger);
|
||||
|
||||
$this->baseUrl = $baseURL;
|
||||
$this->profileField = $profileField;
|
||||
$this->mstdnField = $mstdnField;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $uriId Uri-ID of the item
|
||||
* @return array
|
||||
* @return Mentions
|
||||
* @throws HTTPException\InternalServerErrorException
|
||||
* @throws \ImagickException
|
||||
*/
|
||||
public function createFromUriId(int $uriId)
|
||||
public function createFromUriId(int $uriId): Mentions
|
||||
{
|
||||
$mentions = [];
|
||||
$tags = Tag::getByURIId($uriId, [Tag::MENTION, Tag::EXCLUSIVE_MENTION, Tag::IMPLICIT_MENTION]);
|
||||
$mentions = new Mentions();
|
||||
$tags = Tag::getByURIId($uriId, [Tag::MENTION, Tag::EXCLUSIVE_MENTION, Tag::IMPLICIT_MENTION]);
|
||||
foreach ($tags as $tag) {
|
||||
$contact = Contact::getByURL($tag['url'], false);
|
||||
$mention = new \Friendica\Object\Api\Mastodon\Mention($this->baseUrl, $tag, $contact);
|
||||
$mentions[] = $mention->toArray();
|
||||
$contact = Contact::getByURL($tag['url'], false);
|
||||
$mentions[] = new \Friendica\Object\Api\Mastodon\Mention($this->baseUrl, $tag, $contact);
|
||||
}
|
||||
return $mentions;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -22,25 +22,36 @@
|
|||
namespace Friendica\Factory\Api\Mastodon;
|
||||
|
||||
use Friendica\BaseFactory;
|
||||
use Friendica\Database\DBA;
|
||||
use Friendica\DI;
|
||||
use Friendica\Database\Database;
|
||||
use Friendica\Model\Contact;
|
||||
use Friendica\Model\Notification as ModelNotification;
|
||||
use Friendica\Model\Post;
|
||||
use Friendica\Model\Verb;
|
||||
use Friendica\Protocol\Activity;
|
||||
use Psr\Log\LoggerInterface;
|
||||
|
||||
class Notification extends BaseFactory
|
||||
{
|
||||
public function createFromNotifyId(int $id)
|
||||
/** @var Database */
|
||||
private $dba;
|
||||
/** @var Account */
|
||||
private $mstdnAccountFactory;
|
||||
/** @var Status */
|
||||
private $mstdnStatusFactory;
|
||||
|
||||
public function __construct(LoggerInterface $logger, Database $dba, Account $mstdnAccountFactory, Status $mstdnStatusFactoryFactory)
|
||||
{
|
||||
$notification = DBA::selectFirst('notify', [], ['id' => $id]);
|
||||
if (!DBA::isResult($notification)) {
|
||||
parent::__construct($logger);
|
||||
$this->dba = $dba;
|
||||
$this->mstdnAccountFactory = $mstdnAccountFactory;
|
||||
$this->mstdnStatusFactory = $mstdnStatusFactoryFactory;
|
||||
}
|
||||
|
||||
public function createFromNotificationId(int $id)
|
||||
{
|
||||
$notification = $this->dba->selectFirst('notification', [], ['id' => $id]);
|
||||
if (!$this->dba->isResult($notification)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$cid = Contact::getIdForURL($notification['url'], 0, false);
|
||||
if (empty($cid)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
/*
|
||||
follow = Someone followed you
|
||||
follow_request = Someone requested to follow you
|
||||
|
|
@ -51,32 +62,30 @@ class Notification extends BaseFactory
|
|||
status = Someone you enabled notifications for has posted a status
|
||||
*/
|
||||
|
||||
switch ($notification['type']) {
|
||||
case ModelNotification\Type::INTRO:
|
||||
$type = 'follow_request';
|
||||
break;
|
||||
|
||||
case ModelNotification\Type::WALL:
|
||||
case ModelNotification\Type::COMMENT:
|
||||
case ModelNotification\Type::MAIL:
|
||||
case ModelNotification\Type::TAG_SELF:
|
||||
case ModelNotification\Type::POKE:
|
||||
$type = 'mention';
|
||||
break;
|
||||
|
||||
case ModelNotification\Type::SHARE:
|
||||
$type = 'status';
|
||||
break;
|
||||
|
||||
default:
|
||||
return null;
|
||||
if (($notification['vid'] == Verb::getID(Activity::FOLLOW)) && ($notification['type'] == Post\UserNotification::NOTIF_NONE)) {
|
||||
$contact = Contact::getById($notification['actor-id'], ['pending']);
|
||||
$type = $contact['pending'] ? $type = 'follow_request' : 'follow';
|
||||
} elseif (($notification['vid'] == Verb::getID(Activity::ANNOUNCE)) &&
|
||||
in_array($notification['type'], [Post\UserNotification::NOTIF_DIRECT_COMMENT, Post\UserNotification::NOTIF_DIRECT_THREAD_COMMENT])) {
|
||||
$type = 'reblog';
|
||||
} elseif (in_array($notification['vid'], [Verb::getID(Activity::LIKE), Verb::getID(Activity::DISLIKE)]) &&
|
||||
in_array($notification['type'], [Post\UserNotification::NOTIF_DIRECT_COMMENT, Post\UserNotification::NOTIF_DIRECT_THREAD_COMMENT])) {
|
||||
$type = 'favourite';
|
||||
} elseif ($notification['type'] == Post\UserNotification::NOTIF_SHARED) {
|
||||
$type = 'status';
|
||||
} elseif (in_array($notification['type'], [Post\UserNotification::NOTIF_EXPLICIT_TAGGED,
|
||||
Post\UserNotification::NOTIF_IMPLICIT_TAGGED, Post\UserNotification::NOTIF_DIRECT_COMMENT,
|
||||
Post\UserNotification::NOTIF_DIRECT_THREAD_COMMENT, Post\UserNotification::NOTIF_THREAD_COMMENT])) {
|
||||
$type = 'mention';
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
|
||||
$account = DI::mstdnAccount()->createFromContactId($cid);
|
||||
$account = $this->mstdnAccountFactory->createFromContactId($notification['actor-id'], $notification['uid']);
|
||||
|
||||
if (!empty($notification['uri-id'])) {
|
||||
if (!empty($notification['target-uri-id'])) {
|
||||
try {
|
||||
$status = DI::mstdnStatus()->createFromUriId($notification['uri-id'], $notification['uid']);
|
||||
$status = $this->mstdnStatusFactory->createFromUriId($notification['target-uri-id'], $notification['uid']);
|
||||
} catch (\Throwable $th) {
|
||||
$status = null;
|
||||
}
|
||||
|
|
@ -84,6 +93,6 @@ class Notification extends BaseFactory
|
|||
$status = null;
|
||||
}
|
||||
|
||||
return new \Friendica\Object\Api\Mastodon\Notification($id, $type, $notification['date'], $account, $status);
|
||||
return new \Friendica\Object\Api\Mastodon\Notification($id, $type, $notification['created'], $account, $status);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@
|
|||
|
||||
namespace Friendica\Factory\Api\Mastodon;
|
||||
|
||||
use Exception;
|
||||
use Friendica\Object\Api\Mastodon\Relationship as RelationshipEntity;
|
||||
use Friendica\BaseFactory;
|
||||
use Friendica\Model\Contact;
|
||||
|
|
@ -31,9 +32,9 @@ class Relationship extends BaseFactory
|
|||
* @param int $contactId Contact ID (public or user contact)
|
||||
* @param int $uid User ID
|
||||
* @return RelationshipEntity
|
||||
* @throws \Exception
|
||||
* @throws Exception
|
||||
*/
|
||||
public function createFromContactId(int $contactId, int $uid)
|
||||
public function createFromContactId(int $contactId, int $uid): RelationshipEntity
|
||||
{
|
||||
$cdata = Contact::getPublicAndUserContacID($contactId, $uid);
|
||||
if (!empty($cdata)) {
|
||||
|
|
|
|||
|
|
@ -21,46 +21,59 @@
|
|||
|
||||
namespace Friendica\Factory\Api\Mastodon;
|
||||
|
||||
use Friendica\App\BaseURL;
|
||||
use Friendica\BaseFactory;
|
||||
use Friendica\Content\ContactSelector;
|
||||
use Friendica\Content\Text\BBCode;
|
||||
use Friendica\Database\DBA;
|
||||
use Friendica\DI;
|
||||
use Friendica\Database\Database;
|
||||
use Friendica\Model\Post;
|
||||
use Friendica\Model\Verb;
|
||||
use Friendica\Network\HTTPException;
|
||||
use Friendica\Protocol\Activity;
|
||||
use Friendica\Protocol\ActivityPub;
|
||||
use Friendica\Repository\ProfileField;
|
||||
use ImagickException;
|
||||
use Psr\Log\LoggerInterface;
|
||||
|
||||
class Status extends BaseFactory
|
||||
{
|
||||
/** @var BaseURL */
|
||||
protected $baseUrl;
|
||||
/** @var ProfileField */
|
||||
protected $profileField;
|
||||
/** @var Field */
|
||||
protected $mstdnField;
|
||||
/** @var Database */
|
||||
private $dba;
|
||||
/** @var Account */
|
||||
private $mstdnAccountFactory;
|
||||
/** @var Mention */
|
||||
private $mstdnMentionFactory;
|
||||
/** @var Tag */
|
||||
private $mstdnTagFactory;
|
||||
/** @var Card */
|
||||
private $mstdnCardFactory;
|
||||
/** @var Attachment */
|
||||
private $mstdnAttachementFactory;
|
||||
/** @var Error */
|
||||
private $mstdnErrorFactory;
|
||||
|
||||
public function __construct(LoggerInterface $logger, BaseURL $baseURL, ProfileField $profileField, Field $mstdnField)
|
||||
public function __construct(LoggerInterface $logger, Database $dba,
|
||||
Account $mstdnAccountFactory, Mention $mstdnMentionFactory,
|
||||
Tag $mstdnTagFactory, Card $mstdnCardFactory,
|
||||
Attachment $mstdnAttachementFactory, Error $mstdnErrorFactory)
|
||||
{
|
||||
parent::__construct($logger);
|
||||
|
||||
$this->baseUrl = $baseURL;
|
||||
$this->profileField = $profileField;
|
||||
$this->mstdnField = $mstdnField;
|
||||
$this->dba = $dba;
|
||||
$this->mstdnAccountFactory = $mstdnAccountFactory;
|
||||
$this->mstdnMentionFactory = $mstdnMentionFactory;
|
||||
$this->mstdnTagFactory = $mstdnTagFactory;
|
||||
$this->mstdnCardFactory = $mstdnCardFactory;
|
||||
$this->mstdnAttachementFactory = $mstdnAttachementFactory;
|
||||
$this->mstdnErrorFactory = $mstdnErrorFactory;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $uriId Uri-ID of the item
|
||||
* @param int $uid Item user
|
||||
*
|
||||
* @return \Friendica\Object\Api\Mastodon\Status
|
||||
* @throws HTTPException\InternalServerErrorException
|
||||
* @throws \ImagickException
|
||||
* @throws ImagickException|HTTPException\NotFoundException
|
||||
*/
|
||||
public function createFromUriId(int $uriId, $uid = 0)
|
||||
public function createFromUriId(int $uriId, $uid = 0): \Friendica\Object\Api\Mastodon\Status
|
||||
{
|
||||
$fields = ['uri-id', 'uid', 'author-id', 'author-link', 'starred', 'app', 'title', 'body', 'raw-body', 'created', 'network',
|
||||
'thr-parent-id', 'parent-author-id', 'language', 'uri', 'plink', 'private', 'vid', 'gravity'];
|
||||
|
|
@ -69,29 +82,53 @@ class Status extends BaseFactory
|
|||
throw new HTTPException\NotFoundException('Item with URI ID ' . $uriId . 'not found' . ($uid ? ' for user ' . $uid : '.'));
|
||||
}
|
||||
|
||||
$account = DI::mstdnAccount()->createFromContactId($item['author-id']);
|
||||
$account = $this->mstdnAccountFactory->createFromContactId($item['author-id']);
|
||||
|
||||
$counts = new \Friendica\Object\Api\Mastodon\Status\Counts(
|
||||
Post::count(['thr-parent-id' => $uriId, 'gravity' => GRAVITY_COMMENT, 'deleted' => false], [], false),
|
||||
Post::count(['thr-parent-id' => $uriId, 'gravity' => GRAVITY_ACTIVITY, 'vid' => Verb::getID(Activity::ANNOUNCE), 'deleted' => false], [], false),
|
||||
Post::count(['thr-parent-id' => $uriId, 'gravity' => GRAVITY_ACTIVITY, 'vid' => Verb::getID(Activity::LIKE), 'deleted' => false], [], false)
|
||||
Post::countPosts(['thr-parent-id' => $uriId, 'gravity' => GRAVITY_COMMENT, 'deleted' => false], []),
|
||||
Post::countPosts([
|
||||
'thr-parent-id' => $uriId,
|
||||
'gravity' => GRAVITY_ACTIVITY,
|
||||
'vid' => Verb::getID(Activity::ANNOUNCE),
|
||||
'deleted' => false
|
||||
], []),
|
||||
Post::countPosts([
|
||||
'thr-parent-id' => $uriId,
|
||||
'gravity' => GRAVITY_ACTIVITY,
|
||||
'vid' => Verb::getID(Activity::LIKE),
|
||||
'deleted' => false
|
||||
], [])
|
||||
);
|
||||
|
||||
$userAttributes = new \Friendica\Object\Api\Mastodon\Status\UserAttributes(
|
||||
Post::exists(['thr-parent-id' => $uriId, 'uid' => $uid, 'origin' => true, 'gravity' => GRAVITY_ACTIVITY, 'vid' => Verb::getID(Activity::LIKE), 'deleted' => false]),
|
||||
Post::exists(['thr-parent-id' => $uriId, 'uid' => $uid, 'origin' => true, 'gravity' => GRAVITY_ACTIVITY, 'vid' => Verb::getID(Activity::ANNOUNCE), 'deleted' => false]),
|
||||
Post::exists([
|
||||
'thr-parent-id' => $uriId,
|
||||
'uid' => $uid,
|
||||
'origin' => true,
|
||||
'gravity' => GRAVITY_ACTIVITY,
|
||||
'vid' => Verb::getID(Activity::LIKE)
|
||||
, 'deleted' => false
|
||||
]),
|
||||
Post::exists([
|
||||
'thr-parent-id' => $uriId,
|
||||
'uid' => $uid,
|
||||
'origin' => true,
|
||||
'gravity' => GRAVITY_ACTIVITY,
|
||||
'vid' => Verb::getID(Activity::ANNOUNCE),
|
||||
'deleted' => false
|
||||
]),
|
||||
Post\ThreadUser::getIgnored($uriId, $uid),
|
||||
(bool)$item['starred'],
|
||||
(bool)($item['starred'] && ($item['gravity'] == GRAVITY_PARENT)),
|
||||
Post\ThreadUser::getPinned($uriId, $uid)
|
||||
);
|
||||
|
||||
$sensitive = DBA::exists('tag-view', ['uri-id' => $uriId, 'name' => 'nsfw']);
|
||||
$sensitive = $this->dba->exists('tag-view', ['uri-id' => $uriId, 'name' => 'nsfw']);
|
||||
$application = new \Friendica\Object\Api\Mastodon\Application($item['app'] ?: ContactSelector::networkToName($item['network'], $item['author-link']));
|
||||
|
||||
$mentions = DI::mstdnMention()->createFromUriId($uriId);
|
||||
$tags = DI::mstdnTag()->createFromUriId($uriId);
|
||||
$card = DI::mstdnCard()->createFromUriId($uriId);
|
||||
$attachments = DI::mstdnAttachment()->createFromUriId($uriId);
|
||||
$mentions = $this->mstdnMentionFactory->createFromUriId($uriId)->getArrayCopy();
|
||||
$tags = $this->mstdnTagFactory->createFromUriId($uriId);
|
||||
$card = $this->mstdnCardFactory->createFromUriId($uriId);
|
||||
$attachments = $this->mstdnAttachementFactory->createFromUriId($uriId);
|
||||
|
||||
$shared = BBCode::fetchShareAttributes($item['body']);
|
||||
if (!empty($shared['guid'])) {
|
||||
|
|
@ -99,21 +136,21 @@ class Status extends BaseFactory
|
|||
|
||||
$shared_uri_id = $shared_item['uri-id'] ?? 0;
|
||||
|
||||
$mentions = array_merge($mentions, DI::mstdnMention()->createFromUriId($shared_uri_id));
|
||||
$tags = array_merge($tags, DI::mstdnTag()->createFromUriId($shared_uri_id));
|
||||
$attachments = array_merge($attachments, DI::mstdnAttachment()->createFromUriId($shared_uri_id));
|
||||
$mentions = array_merge($mentions, $this->mstdnMentionFactory->createFromUriId($shared_uri_id)->getArrayCopy());
|
||||
$tags = array_merge($tags, $this->mstdnTagFactory->createFromUriId($shared_uri_id));
|
||||
$attachments = array_merge($attachments, $this->mstdnAttachementFactory->createFromUriId($shared_uri_id));
|
||||
|
||||
if (empty($card->toArray())) {
|
||||
$card = DI::mstdnCard()->createFromUriId($shared_uri_id);
|
||||
$card = $this->mstdnCardFactory->createFromUriId($shared_uri_id);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if ($item['vid'] == Verb::getID(Activity::ANNOUNCE)) {
|
||||
$reshare = $this->createFromUriId($item['thr-parent-id'], $uid)->toArray();
|
||||
$reshared_item = Post::selectFirst(['title', 'body'], ['uri-id' => $item['thr-parent-id'], 'uid' => [0, $uid]]);
|
||||
$reshare = $this->createFromUriId($item['thr-parent-id'], $uid)->toArray();
|
||||
$reshared_item = Post::selectFirst(['title', 'body'], ['uri-id' => $item['thr-parent-id'],'uid' => [0, $uid]]);
|
||||
$item['title'] = $reshared_item['title'] ?? $item['title'];
|
||||
$item['body'] = $reshared_item['body'] ?? $item['body'];
|
||||
$item['body'] = $reshared_item['body'] ?? $item['body'];
|
||||
} else {
|
||||
$reshare = [];
|
||||
}
|
||||
|
|
@ -123,20 +160,23 @@ class Status extends BaseFactory
|
|||
|
||||
/**
|
||||
* @param int $uriId id of the mail
|
||||
*
|
||||
* @return \Friendica\Object\Api\Mastodon\Status
|
||||
* @throws HTTPException\InternalServerErrorException
|
||||
* @throws \ImagickException
|
||||
* @throws ImagickException|HTTPException\NotFoundException
|
||||
*/
|
||||
public function createFromMailId(int $id)
|
||||
public function createFromMailId(int $id): \Friendica\Object\Api\Mastodon\Status
|
||||
{
|
||||
$item = ActivityPub\Transmitter::ItemArrayFromMail($id, true);
|
||||
if (empty($item)) {
|
||||
DI::mstdnError()->RecordNotFound();
|
||||
$this->mstdnErrorFactory->RecordNotFound();
|
||||
}
|
||||
|
||||
$account = DI::mstdnAccount()->createFromContactId($item['author-id']);
|
||||
$account = $this->mstdnAccountFactory->createFromContactId($item['author-id']);
|
||||
|
||||
$counts = new \Friendica\Object\Api\Mastodon\Status\Counts(0, 0, 0);
|
||||
$replies = $this->dba->count('mail', ['thr-parent-id' => $item['uri-id'], 'reply' => true]);
|
||||
|
||||
$counts = new \Friendica\Object\Api\Mastodon\Status\Counts($replies, 0, 0);
|
||||
|
||||
$userAttributes = new \Friendica\Object\Api\Mastodon\Status\UserAttributes(false, false, false, false, false);
|
||||
|
||||
|
|
|
|||
|
|
@ -25,39 +25,31 @@ use Friendica\App\BaseURL;
|
|||
use Friendica\BaseFactory;
|
||||
use Friendica\Model\Tag as TagModel;
|
||||
use Friendica\Network\HTTPException;
|
||||
use Friendica\Repository\ProfileField;
|
||||
use Psr\Log\LoggerInterface;
|
||||
|
||||
class Tag extends BaseFactory
|
||||
{
|
||||
/** @var BaseURL */
|
||||
protected $baseUrl;
|
||||
/** @var ProfileField */
|
||||
protected $profileField;
|
||||
/** @var Field */
|
||||
protected $mstdnField;
|
||||
private $baseUrl;
|
||||
|
||||
public function __construct(LoggerInterface $logger, BaseURL $baseURL, ProfileField $profileField, Field $mstdnField)
|
||||
public function __construct(LoggerInterface $logger, BaseURL $baseURL)
|
||||
{
|
||||
parent::__construct($logger);
|
||||
|
||||
$this->baseUrl = $baseURL;
|
||||
$this->profileField = $profileField;
|
||||
$this->mstdnField = $mstdnField;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $uriId Uri-ID of the item
|
||||
* @return array
|
||||
* @throws HTTPException\InternalServerErrorException
|
||||
* @throws \ImagickException
|
||||
*/
|
||||
public function createFromUriId(int $uriId)
|
||||
public function createFromUriId(int $uriId): array
|
||||
{
|
||||
$hashtags = [];
|
||||
$tags = TagModel::getByURIId($uriId, [TagModel::HASHTAG]);
|
||||
$tags = TagModel::getByURIId($uriId, [TagModel::HASHTAG]);
|
||||
foreach ($tags as $tag) {
|
||||
$hashtag = new \Friendica\Object\Api\Mastodon\Tag($this->baseUrl, $tag);
|
||||
$hashtag = new \Friendica\Object\Api\Mastodon\Tag($this->baseUrl, $tag);
|
||||
$hashtags[] = $hashtag->toArray();
|
||||
}
|
||||
return $hashtags;
|
||||
|
|
|
|||
|
|
@ -139,7 +139,7 @@ class Introduction extends BaseFactory
|
|||
'madeby_zrl' => Contact::magicLink($notification['url']),
|
||||
'madeby_addr' => $notification['addr'],
|
||||
'contact_id' => $notification['contact-id'],
|
||||
'photo' => (!empty($notification['fphoto']) ? Proxy::proxifyUrl($notification['fphoto'], false, Proxy::SIZE_SMALL) : Contact::DEFAULT_AVATAR_PHOTO),
|
||||
'photo' => Contact::getAvatarUrlForUrl($notification['furl'], 0, Proxy::SIZE_SMALL),
|
||||
'name' => $notification['fname'],
|
||||
'url' => $notification['furl'],
|
||||
'zrl' => Contact::magicLink($notification['furl']),
|
||||
|
|
|
|||
|
|
@ -32,6 +32,7 @@ use Friendica\Core\PConfig\IPConfig;
|
|||
use Friendica\Core\Protocol;
|
||||
use Friendica\Core\Session\ISession;
|
||||
use Friendica\Database\Database;
|
||||
use Friendica\Model\Contact;
|
||||
use Friendica\Model\Post;
|
||||
use Friendica\Module\BaseNotifications;
|
||||
use Friendica\Network\HTTPException\InternalServerErrorException;
|
||||
|
|
@ -239,7 +240,7 @@ class Notification extends BaseFactory
|
|||
$formattedNotifications[] = new \Friendica\Object\Notification\Notification([
|
||||
'label' => 'notification',
|
||||
'link' => $this->baseUrl->get(true) . '/notification/' . $notification->id,
|
||||
'image' => Proxy::proxifyUrl($notification->photo, false, Proxy::SIZE_MICRO),
|
||||
'image' => Contact::getAvatarUrlForUrl($notification->url, $notification->uid, Proxy::SIZE_MICRO),
|
||||
'url' => $notification->url,
|
||||
'text' => strip_tags(BBCode::convert($notification->msg)),
|
||||
'when' => DateTimeFormat::local($notification->date, 'r'),
|
||||
|
|
|
|||
|
|
@ -26,6 +26,7 @@ use Friendica\Core\Cache\Duration;
|
|||
use Friendica\Core\Logger;
|
||||
use Friendica\Core\System;
|
||||
use Friendica\Database\DBA;
|
||||
use Friendica\Database\DBStructure;
|
||||
use Friendica\DI;
|
||||
use Friendica\Network\Probe;
|
||||
use Friendica\Protocol\ActivityNamespace;
|
||||
|
|
@ -210,6 +211,11 @@ class APContact
|
|||
$apcontact['photo'] = JsonLD::fetchElement($compacted['as:icon'], 'as:url', '@id');
|
||||
}
|
||||
|
||||
$apcontact['header'] = JsonLD::fetchElement($compacted, 'as:image', '@id');
|
||||
if (is_array($apcontact['header']) || !empty($compacted['as:image']['as:url']['@id'])) {
|
||||
$apcontact['header'] = JsonLD::fetchElement($compacted['as:image'], 'as:url', '@id');
|
||||
}
|
||||
|
||||
if (empty($apcontact['alias'])) {
|
||||
$apcontact['alias'] = JsonLD::fetchElement($compacted, 'as:url', '@id');
|
||||
if (is_array($apcontact['alias'])) {
|
||||
|
|
@ -278,6 +284,8 @@ class APContact
|
|||
}
|
||||
}
|
||||
|
||||
$apcontact['discoverable'] = JsonLD::fetchElement($compacted, 'toot:discoverable', '@value');
|
||||
|
||||
// To-Do
|
||||
|
||||
// Unhandled
|
||||
|
|
@ -349,6 +357,9 @@ class APContact
|
|||
DBA::delete('apcontact', ['url' => $url]);
|
||||
}
|
||||
|
||||
// Limit the length on incoming fields
|
||||
$apcontact = DBStructure::getFieldsForTable('apcontact', $apcontact);
|
||||
|
||||
if (DBA::exists('apcontact', ['url' => $apcontact['url']])) {
|
||||
DBA::update('apcontact', $apcontact, ['url' => $apcontact['url']]);
|
||||
} else {
|
||||
|
|
@ -357,7 +368,7 @@ class APContact
|
|||
|
||||
Logger::info('Updated profile', ['url' => $url]);
|
||||
|
||||
return $apcontact;
|
||||
return DBA::selectFirst('apcontact', [], ['url' => $apcontact['url']]) ?: [];
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -271,7 +271,7 @@ class Contact
|
|||
|
||||
// Update the contact in the background if needed
|
||||
$updated = max($contact['success_update'], $contact['created'], $contact['updated'], $contact['last-update'], $contact['failure_update']);
|
||||
if (($updated < DateTimeFormat::utc('now -7 days')) && in_array($contact['network'], Protocol::FEDERATED)) {
|
||||
if (($updated < DateTimeFormat::utc('now -7 days')) && in_array($contact['network'], Protocol::FEDERATED) && !self::isLocalById($contact['id'])) {
|
||||
Worker::add(PRIORITY_LOW, "UpdateContact", $contact['id']);
|
||||
}
|
||||
|
||||
|
|
@ -566,18 +566,13 @@ class Contact
|
|||
*/
|
||||
public static function createSelfFromUserId($uid)
|
||||
{
|
||||
// Only create the entry if it doesn't exist yet
|
||||
if (DBA::exists('contact', ['uid' => $uid, 'self' => true])) {
|
||||
return true;
|
||||
}
|
||||
|
||||
$user = DBA::selectFirst('user', ['uid', 'username', 'nickname', 'pubkey', 'prvkey'],
|
||||
['uid' => $uid, 'account_expired' => false]);
|
||||
if (!DBA::isResult($user)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$return = DBA::insert('contact', [
|
||||
$contact = [
|
||||
'uid' => $user['uid'],
|
||||
'created' => DateTimeFormat::utcNow(),
|
||||
'self' => 1,
|
||||
|
|
@ -602,7 +597,23 @@ class Contact
|
|||
'uri-date' => DateTimeFormat::utcNow(),
|
||||
'avatar-date' => DateTimeFormat::utcNow(),
|
||||
'closeness' => 0
|
||||
]);
|
||||
];
|
||||
|
||||
$return = true;
|
||||
|
||||
// Only create the entry if it doesn't exist yet
|
||||
if (!DBA::exists('contact', ['uid' => $uid, 'self' => true])) {
|
||||
$return = DBA::insert('contact', $contact);
|
||||
}
|
||||
|
||||
// Create the public contact
|
||||
if (!DBA::exists('contact', ['nurl' => $contact['nurl'], 'uid' => 0])) {
|
||||
$contact['self'] = false;
|
||||
$contact['uid'] = 0;
|
||||
$contact['prvkey'] = null;
|
||||
|
||||
DBA::insert('contact', $contact, Database::INSERT_IGNORE);
|
||||
}
|
||||
|
||||
return $return;
|
||||
}
|
||||
|
|
@ -612,29 +623,30 @@ class Contact
|
|||
*
|
||||
* @param int $uid
|
||||
* @param boolean $update_avatar Force the avatar update
|
||||
* @return bool "true" if updated
|
||||
* @throws HTTPException\InternalServerErrorException
|
||||
*/
|
||||
public static function updateSelfFromUserID($uid, $update_avatar = false)
|
||||
{
|
||||
$fields = ['id', 'name', 'nick', 'location', 'about', 'keywords', 'avatar', 'prvkey', 'pubkey',
|
||||
'xmpp', 'contact-type', 'forum', 'prv', 'avatar-date', 'url', 'nurl', 'unsearchable',
|
||||
'photo', 'thumb', 'micro', 'addr', 'request', 'notify', 'poll', 'confirm', 'poco'];
|
||||
'photo', 'thumb', 'micro', 'addr', 'request', 'notify', 'poll', 'confirm', 'poco', 'network'];
|
||||
$self = DBA::selectFirst('contact', $fields, ['uid' => $uid, 'self' => true]);
|
||||
if (!DBA::isResult($self)) {
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
|
||||
$fields = ['nickname', 'page-flags', 'account-type', 'prvkey', 'pubkey'];
|
||||
$user = DBA::selectFirst('user', $fields, ['uid' => $uid, 'account_expired' => false]);
|
||||
if (!DBA::isResult($user)) {
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
|
||||
$fields = ['name', 'photo', 'thumb', 'about', 'address', 'locality', 'region',
|
||||
'country-name', 'pub_keywords', 'xmpp', 'net-publish'];
|
||||
$profile = DBA::selectFirst('profile', $fields, ['uid' => $uid]);
|
||||
if (!DBA::isResult($profile)) {
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
|
||||
$file_suffix = 'jpg';
|
||||
|
|
@ -643,7 +655,7 @@ class Contact
|
|||
'avatar-date' => $self['avatar-date'], 'location' => Profile::formatLocation($profile),
|
||||
'about' => $profile['about'], 'keywords' => $profile['pub_keywords'],
|
||||
'contact-type' => $user['account-type'], 'prvkey' => $user['prvkey'],
|
||||
'pubkey' => $user['pubkey'], 'xmpp' => $profile['xmpp']];
|
||||
'pubkey' => $user['pubkey'], 'xmpp' => $profile['xmpp'], 'network' => Protocol::DFRN];
|
||||
|
||||
// it seems as if ported accounts can have wrong values, so we make sure that now everything is fine.
|
||||
$fields['url'] = DI::baseUrl() . '/profile/' . $user['nickname'];
|
||||
|
|
@ -704,6 +716,8 @@ class Contact
|
|||
DBA::update('contact', $fields, ['id' => $self['id']]);
|
||||
|
||||
// Update the public contact as well
|
||||
$fields['prvkey'] = null;
|
||||
$fields['self'] = false;
|
||||
DBA::update('contact', $fields, ['uid' => 0, 'nurl' => $self['nurl']]);
|
||||
|
||||
// Update the profile
|
||||
|
|
@ -711,6 +725,8 @@ class Contact
|
|||
'thumb' => DI::baseUrl() . '/photo/avatar/' . $uid .'.' . $file_suffix];
|
||||
DBA::update('profile', $fields, ['uid' => $uid]);
|
||||
}
|
||||
|
||||
return $update;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -1087,7 +1103,7 @@ class Contact
|
|||
if (($uid == 0) && (empty($data['network']) || ($data['network'] == Protocol::PHANTOM))) {
|
||||
// Fetch data for the public contact via the first found personal contact
|
||||
/// @todo Check if this case can happen at all (possibly with mail accounts?)
|
||||
$fields = ['name', 'nick', 'url', 'addr', 'alias', 'avatar', 'contact-type',
|
||||
$fields = ['name', 'nick', 'url', 'addr', 'alias', 'avatar', 'header', 'contact-type',
|
||||
'keywords', 'location', 'about', 'unsearchable', 'batch', 'notify', 'poll',
|
||||
'request', 'confirm', 'poco', 'subscribe', 'network', 'baseurl', 'gsid'];
|
||||
|
||||
|
|
@ -1485,15 +1501,15 @@ class Contact
|
|||
{
|
||||
if (!empty($contact)) {
|
||||
$contact = self::checkAvatarCacheByArray($contact, $no_update);
|
||||
if (!empty($contact[$field])) {
|
||||
$avatar = $contact[$field];
|
||||
if (!empty($contact['id'])) {
|
||||
return self::getAvatarUrlForId($contact['id'], $size, $contact['updated'] ?? '');
|
||||
} elseif (!empty($contact[$field])) {
|
||||
return $contact[$field];
|
||||
} elseif (!empty($contact['avatar'])) {
|
||||
$avatar = $contact['avatar'];
|
||||
}
|
||||
}
|
||||
|
||||
if ($no_update && empty($avatar) && !empty($contact['avatar'])) {
|
||||
$avatar = $contact['avatar'];
|
||||
}
|
||||
|
||||
if (empty($avatar)) {
|
||||
$avatar = self::getDefaultAvatar([], $size);
|
||||
}
|
||||
|
|
@ -1598,7 +1614,7 @@ class Contact
|
|||
*
|
||||
* @param array $contact contact array
|
||||
* @param string $size Size of the avatar picture
|
||||
* @return void
|
||||
* @return string avatar URL
|
||||
*/
|
||||
public static function getDefaultAvatar(array $contact, string $size)
|
||||
{
|
||||
|
|
@ -1646,6 +1662,99 @@ class Contact
|
|||
return DI::baseUrl() . $default;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get avatar link for given contact id
|
||||
*
|
||||
* @param integer $cid contact id
|
||||
* @param string $size One of the ProxyUtils::SIZE_* constants
|
||||
* @param string $updated Contact update date
|
||||
* @return string avatar link
|
||||
*/
|
||||
public static function getAvatarUrlForId(int $cid, string $size = '', string $updated = ''):string
|
||||
{
|
||||
// We have to fetch the "updated" variable when it wasn't provided
|
||||
// The parameter can be provided to improve performance
|
||||
if (empty($updated)) {
|
||||
$contact = self::getById($cid, ['updated']);
|
||||
$updated = $contact['updated'] ?? '';
|
||||
}
|
||||
|
||||
$url = DI::baseUrl() . '/photo/contact/';
|
||||
switch ($size) {
|
||||
case Proxy::SIZE_MICRO:
|
||||
$url .= Proxy::PIXEL_MICRO . '/';
|
||||
break;
|
||||
case Proxy::SIZE_THUMB:
|
||||
$url .= Proxy::PIXEL_THUMB . '/';
|
||||
break;
|
||||
case Proxy::SIZE_SMALL:
|
||||
$url .= Proxy::PIXEL_SMALL . '/';
|
||||
break;
|
||||
case Proxy::SIZE_MEDIUM:
|
||||
$url .= Proxy::PIXEL_MEDIUM . '/';
|
||||
break;
|
||||
case Proxy::SIZE_LARGE:
|
||||
$url .= Proxy::PIXEL_LARGE . '/';
|
||||
break;
|
||||
}
|
||||
return $url . $cid . ($updated ? '?ts=' . strtotime($updated) : '');
|
||||
}
|
||||
|
||||
/**
|
||||
* Get avatar link for given contact URL
|
||||
*
|
||||
* @param string $url contact url
|
||||
* @param integer $uid user id
|
||||
* @param string $size One of the ProxyUtils::SIZE_* constants
|
||||
* @return string avatar link
|
||||
*/
|
||||
public static function getAvatarUrlForUrl(string $url, int $uid, string $size = ''):string
|
||||
{
|
||||
$condition = ["`nurl` = ? AND ((`uid` = ? AND `network` IN (?, ?)) OR `uid` = ?)",
|
||||
Strings::normaliseLink($url), $uid, Protocol::FEED, Protocol::MAIL, 0];
|
||||
$contact = self::selectFirst(['id', 'updated'], $condition);
|
||||
return self::getAvatarUrlForId($contact['id'] ?? 0, $size, $contact['updated'] ?? '');
|
||||
}
|
||||
|
||||
/**
|
||||
* Get header link for given contact id
|
||||
*
|
||||
* @param integer $cid contact id
|
||||
* @param string $size One of the ProxyUtils::SIZE_* constants
|
||||
* @param string $updated Contact update date
|
||||
* @return string header link
|
||||
*/
|
||||
public static function getHeaderUrlForId(int $cid, string $size = '', string $updated = ''):string
|
||||
{
|
||||
// We have to fetch the "updated" variable when it wasn't provided
|
||||
// The parameter can be provided to improve performance
|
||||
if (empty($updated)) {
|
||||
$contact = self::getById($cid, ['updated']);
|
||||
$updated = $contact['updated'] ?? '';
|
||||
}
|
||||
|
||||
$url = DI::baseUrl() . '/photo/header/';
|
||||
switch ($size) {
|
||||
case Proxy::SIZE_MICRO:
|
||||
$url .= Proxy::PIXEL_MICRO . '/';
|
||||
break;
|
||||
case Proxy::SIZE_THUMB:
|
||||
$url .= Proxy::PIXEL_THUMB . '/';
|
||||
break;
|
||||
case Proxy::SIZE_SMALL:
|
||||
$url .= Proxy::PIXEL_SMALL . '/';
|
||||
break;
|
||||
case Proxy::SIZE_MEDIUM:
|
||||
$url .= Proxy::PIXEL_MEDIUM . '/';
|
||||
break;
|
||||
case Proxy::SIZE_LARGE:
|
||||
$url .= Proxy::PIXEL_LARGE . '/';
|
||||
break;
|
||||
}
|
||||
|
||||
return $url . $cid . ($updated ? '?ts=' . strtotime($updated) : '');
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the avatar links in a contact only if needed
|
||||
*
|
||||
|
|
@ -1933,14 +2042,23 @@ class Contact
|
|||
// These fields aren't updated by this routine:
|
||||
// 'xmpp', 'sensitive'
|
||||
|
||||
$fields = ['uid', 'avatar', 'name', 'nick', 'location', 'keywords', 'about', 'subscribe', 'manually-approve',
|
||||
'unsearchable', 'url', 'addr', 'batch', 'notify', 'poll', 'request', 'confirm', 'poco',
|
||||
$fields = ['uid', 'avatar', 'header', 'name', 'nick', 'location', 'keywords', 'about', 'subscribe',
|
||||
'manually-approve', 'unsearchable', 'url', 'addr', 'batch', 'notify', 'poll', 'request', 'confirm', 'poco',
|
||||
'network', 'alias', 'baseurl', 'gsid', 'forum', 'prv', 'contact-type', 'pubkey', 'last-item'];
|
||||
$contact = DBA::selectFirst('contact', $fields, ['id' => $id]);
|
||||
if (!DBA::isResult($contact)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (self::isLocal($ret['url'])) {
|
||||
if ($contact['uid'] == 0) {
|
||||
Logger::info('Local contacts are not updated here.');
|
||||
} else {
|
||||
self::updateFromPublicContact($id, $contact);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!empty($ret['account-type']) && $ret['account-type'] == User::ACCOUNT_TYPE_DELETED) {
|
||||
Logger::info('Deleted account', ['id' => $id, 'url' => $ret['url'], 'ret' => $ret]);
|
||||
self::remove($id);
|
||||
|
|
@ -2072,6 +2190,26 @@ class Contact
|
|||
return true;
|
||||
}
|
||||
|
||||
private static function updateFromPublicContact(int $id, array $contact)
|
||||
{
|
||||
$public = self::getByURL($contact['url'], false);
|
||||
|
||||
$fields = [];
|
||||
|
||||
foreach ($contact as $field => $value) {
|
||||
if ($field == 'uid') {
|
||||
continue;
|
||||
}
|
||||
if ($public[$field] != $value) {
|
||||
$fields[$field] = $public[$field];
|
||||
}
|
||||
}
|
||||
if (!empty($fields)) {
|
||||
DBA::update('contact', $fields, ['id' => $id, 'self' => false]);
|
||||
Logger::info('Updating local contact', ['id' => $id]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param integer $url contact url
|
||||
* @return integer Contact id
|
||||
|
|
@ -2180,8 +2318,10 @@ class Contact
|
|||
}
|
||||
|
||||
if (!empty($arr['contact']['name'])) {
|
||||
$probed = false;
|
||||
$ret = $arr['contact'];
|
||||
} else {
|
||||
$probed = true;
|
||||
$ret = Probe::uri($url, $network, $user['uid']);
|
||||
}
|
||||
|
||||
|
|
@ -2325,6 +2465,10 @@ class Contact
|
|||
// pull feed and consume it, which should subscribe to the hub.
|
||||
if ($contact['network'] == Protocol::OSTATUS) {
|
||||
Worker::add(PRIORITY_HIGH, 'OnePoll', $contact_id, 'force');
|
||||
}
|
||||
|
||||
if ($probed) {
|
||||
self::updateFromProbeArray($contact_id, $ret);
|
||||
} else {
|
||||
Worker::add(PRIORITY_HIGH, 'UpdateContact', $contact_id);
|
||||
}
|
||||
|
|
@ -2518,6 +2662,8 @@ class Contact
|
|||
// Ensure to always have the correct network type, independent from the connection request method
|
||||
self::updateFromProbe($contact['id']);
|
||||
|
||||
Post\UserNotification::insertNotication($contact['id'], Verb::getID(Activity::FOLLOW), $importer['uid']);
|
||||
|
||||
return true;
|
||||
} else {
|
||||
// send email notification to owner?
|
||||
|
|
@ -2549,6 +2695,8 @@ class Contact
|
|||
|
||||
self::updateAvatar($contact_id, $photo, true);
|
||||
|
||||
Post\UserNotification::insertNotication($contact_id, Verb::getID(Activity::FOLLOW), $importer['uid']);
|
||||
|
||||
$contact_record = DBA::selectFirst('contact', ['id', 'network', 'name', 'url', 'photo'], ['id' => $contact_id]);
|
||||
|
||||
/// @TODO Encapsulate this into a function/method
|
||||
|
|
|
|||
|
|
@ -78,19 +78,22 @@ class Relation
|
|||
{
|
||||
$contact = Contact::getByURL($url);
|
||||
if (empty($contact)) {
|
||||
Logger::info('Contact not found', ['url' => $url]);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!self::isDiscoverable($url, $contact)) {
|
||||
Logger::info('Contact is not discoverable', ['url' => $url]);
|
||||
return;
|
||||
}
|
||||
|
||||
$uid = User::getIdForURL($url);
|
||||
if (!empty($uid)) {
|
||||
// Fetch the followers/followings locally
|
||||
Logger::info('Fetch the followers/followings locally', ['url' => $url]);
|
||||
$followers = self::getContacts($uid, [Contact::FOLLOWER, Contact::FRIEND]);
|
||||
$followings = self::getContacts($uid, [Contact::SHARING, Contact::FRIEND]);
|
||||
} else {
|
||||
} elseif (!Contact::isLocal($url)) {
|
||||
Logger::info('Fetch the followers/followings by polling the endpoints', ['url' => $url]);
|
||||
$apcontact = APContact::getByURL($url, false);
|
||||
|
||||
if (!empty($apcontact['followers']) && is_string($apcontact['followers'])) {
|
||||
|
|
@ -104,6 +107,10 @@ class Relation
|
|||
} else {
|
||||
$followings = [];
|
||||
}
|
||||
} else {
|
||||
Logger::notice('Contact seems to be local but could not be found here', ['url' => $url]);
|
||||
$followers = [];
|
||||
$followings = [];
|
||||
}
|
||||
|
||||
if (empty($followers) && empty($followings)) {
|
||||
|
|
|
|||
|
|
@ -586,10 +586,10 @@ class Event
|
|||
$last_date = '';
|
||||
$fmt = DI::l10n()->t('l, F j');
|
||||
foreach ($event_result as $event) {
|
||||
$item = Post::selectFirst(['plink', 'author-name', 'author-avatar', 'author-link'], ['id' => $event['itemid']]);
|
||||
$item = Post::selectFirst(['plink', 'author-name', 'author-avatar', 'author-link', 'private'], ['id' => $event['itemid']]);
|
||||
if (!DBA::isResult($item)) {
|
||||
// Using default values when no item had been found
|
||||
$item = ['plink' => '', 'author-name' => '', 'author-avatar' => '', 'author-link' => ''];
|
||||
$item = ['plink' => '', 'author-name' => '', 'author-avatar' => '', 'author-link' => '', 'private' => Item::PUBLIC];
|
||||
}
|
||||
|
||||
$event = array_merge($event, $item);
|
||||
|
|
|
|||
|
|
@ -802,6 +802,7 @@ class GServer
|
|||
/**
|
||||
* Parses Nodeinfo 2
|
||||
*
|
||||
* @see https://git.feneas.org/jaywink/nodeinfo2
|
||||
* @param string $nodeinfo_url address of the nodeinfo path
|
||||
* @return array Server data
|
||||
* @throws \Friendica\Network\HTTPException\InternalServerErrorException
|
||||
|
|
@ -850,7 +851,9 @@ class GServer
|
|||
if (!empty($nodeinfo['protocols'])) {
|
||||
$protocols = [];
|
||||
foreach ($nodeinfo['protocols'] as $protocol) {
|
||||
$protocols[$protocol] = true;
|
||||
if (is_string($protocol)) {
|
||||
$protocols[$protocol] = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (!empty($protocols['dfrn'])) {
|
||||
|
|
|
|||
|
|
@ -159,6 +159,10 @@ class Item
|
|||
$fields['vid'] = Verb::getID($fields['verb']);
|
||||
}
|
||||
|
||||
if (!empty($fields['edited'])) {
|
||||
$previous = Post::selectFirst(['edited'], $condition);
|
||||
}
|
||||
|
||||
$rows = Post::update($fields, $condition);
|
||||
if (is_bool($rows)) {
|
||||
return $rows;
|
||||
|
|
@ -180,16 +184,18 @@ class Item
|
|||
if (!empty($fields['body'])) {
|
||||
Post\Media::insertFromAttachmentData($item['uri-id'], $fields['body']);
|
||||
|
||||
if ($item['author-network'] != Protocol::DFRN) {
|
||||
Post\Media::insertFromRelevantUrl($item['uri-id'], $fields['body']);
|
||||
}
|
||||
|
||||
$content_fields = ['raw-body' => trim($fields['raw-body'] ?? $fields['body'])];
|
||||
|
||||
// Remove all media attachments from the body and store them in the post-media table
|
||||
// @todo On shared postings (Diaspora style and commented reshare) don't fetch content from the shared part
|
||||
$content_fields['raw-body'] = Post\Media::insertFromBody($item['uri-id'], $content_fields['raw-body']);
|
||||
$content_fields['raw-body'] = self::setHashtags($content_fields['raw-body']);
|
||||
|
||||
if ($item['author-network'] != Protocol::DFRN) {
|
||||
Post\Media::insertFromRelevantUrl($item['uri-id'], $content_fields['raw-body']);
|
||||
}
|
||||
|
||||
Post\Content::update($item['uri-id'], $content_fields);
|
||||
}
|
||||
|
||||
if (!empty($fields['file'])) {
|
||||
|
|
@ -201,8 +207,8 @@ class Item
|
|||
}
|
||||
|
||||
// We only need to notfiy others when it is an original entry from us.
|
||||
// Only call the notifier when the item has some content relevant change.
|
||||
if ($item['origin'] && in_array('edited', array_keys($fields))) {
|
||||
// Only call the notifier when the item had been edited and records had been changed.
|
||||
if ($item['origin'] && !empty($fields['edited']) && ($previous['edited'] != $fields['edited'])) {
|
||||
$notify_items[] = $item['id'];
|
||||
}
|
||||
}
|
||||
|
|
@ -516,7 +522,7 @@ class Item
|
|||
public static function isValid(array $item)
|
||||
{
|
||||
// When there is no content then we don't post it
|
||||
if (($item['body'] . $item['title'] == '') && !Post\Media::existsByURIId($item['uri-id'])) {
|
||||
if (($item['body'] . $item['title'] == '') && (empty($item['uri-id']) || !Post\Media::existsByURIId($item['uri-id']))) {
|
||||
Logger::notice('No body, no title.');
|
||||
return false;
|
||||
}
|
||||
|
|
@ -991,14 +997,14 @@ class Item
|
|||
|
||||
Post\Media::insertFromAttachmentData($item['uri-id'], $item['body']);
|
||||
|
||||
if (!DBA::exists('contact', ['id' => $item['author-id'], 'network' => Protocol::DFRN])) {
|
||||
Post\Media::insertFromRelevantUrl($item['uri-id'], $item['body']);
|
||||
}
|
||||
|
||||
// Remove all media attachments from the body and store them in the post-media table
|
||||
$item['raw-body'] = Post\Media::insertFromBody($item['uri-id'], $item['raw-body']);
|
||||
$item['raw-body'] = self::setHashtags($item['raw-body']);
|
||||
|
||||
if (!DBA::exists('contact', ['id' => $item['author-id'], 'network' => Protocol::DFRN])) {
|
||||
Post\Media::insertFromRelevantUrl($item['uri-id'], $item['raw-body']);
|
||||
}
|
||||
|
||||
// Check for hashtags in the body and repair or add hashtag links
|
||||
$item['body'] = self::setHashtags($item['body']);
|
||||
|
||||
|
|
@ -1018,6 +1024,30 @@ class Item
|
|||
|
||||
if (empty($item['event-id'])) {
|
||||
unset($item['event-id']);
|
||||
|
||||
$ev = Event::fromBBCode($item['body']);
|
||||
if ((!empty($ev['desc']) || !empty($ev['summary'])) && !empty($ev['start'])) {
|
||||
Logger::info('Event found.');
|
||||
$ev['cid'] = $item['contact-id'];
|
||||
$ev['uid'] = $item['uid'];
|
||||
$ev['uri'] = $item['uri'];
|
||||
$ev['edited'] = $item['edited'];
|
||||
$ev['private'] = $item['private'];
|
||||
$ev['guid'] = $item['guid'];
|
||||
$ev['plink'] = $item['plink'];
|
||||
$ev['network'] = $item['network'];
|
||||
$ev['protocol'] = $item['protocol'];
|
||||
$ev['direction'] = $item['direction'];
|
||||
$ev['source'] = $item['source'];
|
||||
|
||||
$event = DBA::selectFirst('event', ['id'], ['uri' => $item['uri'], 'uid' => $item['uid']]);
|
||||
if (DBA::isResult($event)) {
|
||||
$ev['id'] = $event['id'];
|
||||
}
|
||||
|
||||
$item['event-id'] = Event::store($ev);
|
||||
Logger::info('Event was stored', ['id' => $item['event-id']]);
|
||||
}
|
||||
}
|
||||
|
||||
if (empty($item['causer-id'])) {
|
||||
|
|
@ -1034,7 +1064,14 @@ class Item
|
|||
Post\Content::insert($item['uri-id'], $item);
|
||||
}
|
||||
|
||||
// Diaspora signature
|
||||
// Create Diaspora signature
|
||||
if ($item['origin'] && empty($item['diaspora_signed_text']) && ($item['gravity'] != GRAVITY_PARENT)) {
|
||||
$signed = Diaspora::createCommentSignature($uid, $item);
|
||||
if (!empty($signed)) {
|
||||
$item['diaspora_signed_text'] = json_encode($signed);
|
||||
}
|
||||
}
|
||||
|
||||
if (!empty($item['diaspora_signed_text'])) {
|
||||
DBA::replace('diaspora-interaction', ['uri-id' => $item['uri-id'], 'interaction' => $item['diaspora_signed_text']]);
|
||||
}
|
||||
|
|
@ -1194,13 +1231,10 @@ class Item
|
|||
Logger::info('The resharer is no forum: quit', ['resharer' => $item['author-id'], 'owner' => $parent['owner-id'], 'author' => $parent['author-id'], 'uid' => $item['uid']]);
|
||||
return;
|
||||
}
|
||||
self::update(['post-reason' => self::PR_ANNOUNCEMENT, 'causer-id' => $item['author-id']], ['id' => $parent['id']]);
|
||||
Logger::info('Set announcement post-reason', ['uri-id' => $item['uri-id'], 'thr-parent-id' => $item['thr-parent-id'], 'uid' => $item['uid']]);
|
||||
return;
|
||||
}
|
||||
|
||||
self::update(['owner-id' => $item['author-id'], 'contact-id' => $cid], ['id' => $parent['id']]);
|
||||
Logger::info('Change owner of the parent', ['uri-id' => $item['uri-id'], 'thr-parent-id' => $item['thr-parent-id'], 'uid' => $item['uid'], 'owner-id' => $item['author-id'], 'contact-id' => $cid]);
|
||||
self::update(['post-reason' => self::PR_ANNOUNCEMENT, 'causer-id' => $item['author-id']], ['id' => $parent['id']]);
|
||||
Logger::info('Set announcement post-reason', ['uri-id' => $item['uri-id'], 'thr-parent-id' => $item['thr-parent-id'], 'uid' => $item['uid']]);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -1322,19 +1356,26 @@ class Item
|
|||
/**
|
||||
* Store a public item defined by their URI-ID for the given users
|
||||
*
|
||||
* @param integer $uri_id URI-ID of the given item
|
||||
* @param integer $uid The user that will receive the item entry
|
||||
* @param array $fields Additional fields to be stored
|
||||
* @param integer $uri_id URI-ID of the given item
|
||||
* @param integer $uid The user that will receive the item entry
|
||||
* @param array $fields Additional fields to be stored
|
||||
* @param integer $source_uid User id of the source post
|
||||
* @return integer stored item id
|
||||
*/
|
||||
public static function storeForUserByUriId(int $uri_id, int $uid, array $fields = [])
|
||||
public static function storeForUserByUriId(int $uri_id, int $uid, array $fields = [], int $source_uid = 0)
|
||||
{
|
||||
$item = Post::selectFirst(self::ITEM_FIELDLIST, ['uri-id' => $uri_id, 'uid' => 0]);
|
||||
if (!DBA::isResult($item)) {
|
||||
if ($uid == $source_uid) {
|
||||
Logger::warning('target UID must not be be equal to the source UID', ['uri-id' => $uri_id, 'uid' => $uid]);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (($item['private'] == self::PRIVATE) || !in_array($item['network'], Protocol::FEDERATED)) {
|
||||
$item = Post::selectFirst(self::ITEM_FIELDLIST, ['uri-id' => $uri_id, 'uid' => $source_uid]);
|
||||
if (!DBA::isResult($item)) {
|
||||
Logger::warning('Item could not be fetched', ['uri-id' => $uri_id, 'uid' => $source_uid]);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (($source_uid == 0) && (($item['private'] == self::PRIVATE) || !in_array($item['network'], Protocol::FEDERATED))) {
|
||||
Logger::notice('Item is private or not from a federated network. It will not be stored for the user.', ['uri-id' => $uri_id, 'uid' => $uid, 'private' => $item['private'], 'network' => $item['network']]);
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -1343,8 +1384,25 @@ class Item
|
|||
|
||||
$item = array_merge($item, $fields);
|
||||
|
||||
$is_reshare = ($item['gravity'] == GRAVITY_ACTIVITY) && ($item['verb'] == Activity::ANNOUNCE);
|
||||
|
||||
if ((($item['gravity'] == GRAVITY_PARENT) || $is_reshare) &&
|
||||
DI::pConfig()->get($uid, 'system', 'accept_only_sharer') &&
|
||||
!Contact::isSharingByURL($item['author-link'], $uid) &&
|
||||
!Contact::isSharingByURL($item['owner-link'], $uid)) {
|
||||
Logger::info('Contact is not a follower, thread will not be stored', ['author' => $item['author-link'], 'uid' => $uid]);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if ((($item['gravity'] == GRAVITY_COMMENT) || $is_reshare) && !Post::exists(['uri-id' => $item['thr-parent-id'], 'uid' => $uid])) {
|
||||
// Only do an auto complete with the source uid "0" to prevent privavy problems
|
||||
$causer = $item['causer-id'] ?: $item['author-id'];
|
||||
$result = self::storeForUserByUriId($item['thr-parent-id'], $uid, ['causer-id' => $causer, 'post-reason' => self::PR_FETCHED]);
|
||||
Logger::info('Fetched thread parent', ['uri-id' => $item['thr-parent-id'], 'uid' => $uid, 'causer' => $causer, 'result' => $result]);
|
||||
}
|
||||
|
||||
$stored = self::storeForUser($item, $uid);
|
||||
Logger::info('Public item stored for user', ['uri-id' => $item['uri-id'], 'uid' => $uid, 'stored' => $stored]);
|
||||
Logger::info('Item stored for user', ['uri-id' => $item['uri-id'], 'uid' => $uid, 'source-uid' => $source_uid, 'stored' => $stored]);
|
||||
return $stored;
|
||||
}
|
||||
|
||||
|
|
@ -1364,11 +1422,18 @@ class Item
|
|||
}
|
||||
|
||||
unset($item['id']);
|
||||
unset($item['parent']);
|
||||
unset($item['mention']);
|
||||
unset($item['starred']);
|
||||
unset($item['unseen']);
|
||||
unset($item['psid']);
|
||||
unset($item['pinned']);
|
||||
unset($item['ignored']);
|
||||
unset($item['pubmail']);
|
||||
unset($item['forum_mode']);
|
||||
|
||||
unset($item['event-id']);
|
||||
unset($item['hidden']);
|
||||
unset($item['notification-type']);
|
||||
|
||||
$item['uid'] = $uid;
|
||||
$item['origin'] = 0;
|
||||
|
|
@ -1394,8 +1459,6 @@ class Item
|
|||
$item['contact-id'] = $self['id'];
|
||||
}
|
||||
|
||||
/// @todo Handling of "event-id"
|
||||
|
||||
$notify = false;
|
||||
if ($item['gravity'] == GRAVITY_PARENT) {
|
||||
$contact = DBA::selectFirst('contact', [], ['id' => $item['contact-id'], 'self' => false]);
|
||||
|
|
@ -1407,9 +1470,9 @@ class Item
|
|||
$distributed = self::insert($item, $notify, true);
|
||||
|
||||
if (!$distributed) {
|
||||
Logger::info("Distributed public item wasn't stored", ['uri-id' => $item['uri-id'], 'user' => $uid]);
|
||||
Logger::info("Distributed item wasn't stored", ['uri-id' => $item['uri-id'], 'user' => $uid]);
|
||||
} else {
|
||||
Logger::info('Distributed public item was stored', ['uri-id' => $item['uri-id'], 'user' => $uid, 'stored' => $distributed]);
|
||||
Logger::info('Distributed item was stored', ['uri-id' => $item['uri-id'], 'user' => $uid, 'stored' => $distributed]);
|
||||
}
|
||||
return $distributed;
|
||||
}
|
||||
|
|
@ -1850,6 +1913,15 @@ class Item
|
|||
return false;
|
||||
}
|
||||
|
||||
self::performActivity($item['id'], 'announce', $uid);
|
||||
|
||||
/**
|
||||
* All the following lines are only needed for private forums and compatibility to older systems without AP support.
|
||||
* A possible way would be that the followers list of a forum would always be readable by all followers.
|
||||
* So this would mean that the comment distribution could be done exactly for the intended audience.
|
||||
* Or possibly we could store the receivers that had been in the "announce" message above and use this.
|
||||
*/
|
||||
|
||||
// now change this copy of the post to a forum head message and deliver to all the tgroup members
|
||||
$self = DBA::selectFirst('contact', ['id', 'name', 'url', 'thumb'], ['uid' => $uid, 'self' => true]);
|
||||
if (!DBA::isResult($self)) {
|
||||
|
|
@ -1859,8 +1931,13 @@ class Item
|
|||
$owner_id = Contact::getIdForURL($self['url']);
|
||||
|
||||
// also reset all the privacy bits to the forum default permissions
|
||||
|
||||
$private = ($user['allow_cid'] || $user['allow_gid'] || $user['deny_cid'] || $user['deny_gid']) ? self::PRIVATE : self::PUBLIC;
|
||||
if ($user['allow_cid'] || $user['allow_gid'] || $user['deny_cid'] || $user['deny_gid']) {
|
||||
$private = self::PRIVATE;
|
||||
} elseif (DI::pConfig()->get($user['uid'], 'system', 'unlisted')) {
|
||||
$private = self::UNLISTED;
|
||||
} else {
|
||||
$private = self::PUBLIC;
|
||||
}
|
||||
|
||||
$psid = PermissionSet::getIdFromACL(
|
||||
$user['uid'],
|
||||
|
|
@ -1878,8 +1955,6 @@ class Item
|
|||
|
||||
Worker::add(['priority' => PRIORITY_HIGH, 'dont_fork' => true], 'Notifier', Delivery::POST, (int)$item['uri-id'], (int)$item['uid']);
|
||||
|
||||
self::performActivity($item['id'], 'announce', $uid);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
@ -2667,6 +2742,23 @@ class Item
|
|||
}
|
||||
|
||||
$body = $item['body'] ?? '';
|
||||
$shared = BBCode::fetchShareAttributes($body);
|
||||
if (!empty($shared['guid'])) {
|
||||
$shared_item = Post::selectFirst(['uri-id', 'plink'], ['guid' => $shared['guid']]);
|
||||
$shared_uri_id = $shared_item['uri-id'] ?? 0;
|
||||
$shared_links = [strtolower($shared_item['plink'] ?? '')];
|
||||
$shared_attachments = Post\Media::splitAttachments($shared_uri_id, $shared['guid']);
|
||||
$shared_links = array_merge($shared_links, array_column($shared_attachments['visual'], 'url'));
|
||||
$shared_links = array_merge($shared_links, array_column($shared_attachments['link'], 'url'));
|
||||
$shared_links = array_merge($shared_links, array_column($shared_attachments['additional'], 'url'));
|
||||
$item['body'] = self::replaceVisualAttachments($shared_attachments, $item['body']);
|
||||
} else {
|
||||
$shared_uri_id = 0;
|
||||
$shared_links = [];
|
||||
}
|
||||
$attachments = Post\Media::splitAttachments($item['uri-id'], $item['guid'] ?? '', $shared_links);
|
||||
$item['body'] = self::replaceVisualAttachments($attachments, $item['body'] ?? '');
|
||||
|
||||
$item['body'] = preg_replace("/\s*\[attachment .*?\].*?\[\/attachment\]\s*/ism", "\n", $item['body']);
|
||||
self::putInCache($item);
|
||||
$item['body'] = $body;
|
||||
|
|
@ -2689,25 +2781,13 @@ class Item
|
|||
return $s;
|
||||
}
|
||||
|
||||
$shared = BBCode::fetchShareAttributes($item['body']);
|
||||
if (!empty($shared['guid'])) {
|
||||
$shared_item = Post::selectFirst(['uri-id', 'plink'], ['guid' => $shared['guid']]);
|
||||
$shared_uri_id = $shared_item['uri-id'] ?? 0;
|
||||
$shared_links = [strtolower($shared_item['plink'] ?? '')];
|
||||
$attachments = Post\Media::splitAttachments($shared_uri_id, $shared['guid']);
|
||||
$s = self::addVisualAttachments($attachments, $item, $s, true);
|
||||
$s = self::addLinkAttachment($attachments, $body, $s, true, []);
|
||||
$s = self::addNonVisualAttachments($attachments, $item, $s, true);
|
||||
$shared_links = array_merge($shared_links, array_column($attachments['visual'], 'url'));
|
||||
$shared_links = array_merge($shared_links, array_column($attachments['link'], 'url'));
|
||||
$shared_links = array_merge($shared_links, array_column($attachments['additional'], 'url'));
|
||||
if (!empty($shared_attachments)) {
|
||||
$s = self::addVisualAttachments($shared_attachments, $item, $s, true);
|
||||
$s = self::addLinkAttachment($shared_attachments, $body, $s, true, []);
|
||||
$s = self::addNonVisualAttachments($shared_attachments, $item, $s, true);
|
||||
$body = preg_replace("/\s*\[share .*?\].*?\[\/share\]\s*/ism", '', $body);
|
||||
} else {
|
||||
$shared_uri_id = 0;
|
||||
$shared_links = [];
|
||||
}
|
||||
|
||||
$attachments = Post\Media::splitAttachments($item['uri-id'], $item['guid'] ?? '', $shared_links);
|
||||
$s = self::addVisualAttachments($attachments, $item, $s, false);
|
||||
$s = self::addLinkAttachment($attachments, $body, $s, false, $shared_links);
|
||||
$s = self::addNonVisualAttachments($attachments, $item, $s, false);
|
||||
|
|
@ -2739,9 +2819,10 @@ class Item
|
|||
*
|
||||
* @param string $body
|
||||
* @param string $url
|
||||
* @param int $type
|
||||
* @return bool
|
||||
*/
|
||||
public static function containsLink(string $body, string $url)
|
||||
public static function containsLink(string $body, string $url, int $type = 0)
|
||||
{
|
||||
// Make sure that for example site parameters aren't used when testing if the link is contained in the body
|
||||
$urlparts = parse_url($url);
|
||||
|
|
@ -2749,6 +2830,12 @@ class Item
|
|||
unset($urlparts['fragment']);
|
||||
$url = Network::unparseURL($urlparts);
|
||||
|
||||
// Remove media links to only search in embedded content
|
||||
// @todo Check images for image link, audio for audio links, ...
|
||||
if (in_array($type, [Post\Media::AUDIO, Post\Media::VIDEO, Post\Media::IMAGE])) {
|
||||
$body = preg_replace("/\[url=[^\[\]]*\](.*)\[\/url\]/Usi", ' $1 ', $body);
|
||||
}
|
||||
|
||||
if (strpos($body, $url)) {
|
||||
return true;
|
||||
}
|
||||
|
|
@ -2761,6 +2848,28 @@ class Item
|
|||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Replace visual attachments in the body
|
||||
*
|
||||
* @param array $attachments
|
||||
* @param string $body
|
||||
* @return string modified body
|
||||
*/
|
||||
private static function replaceVisualAttachments(array $attachments, string $body)
|
||||
{
|
||||
$stamp1 = microtime(true);
|
||||
|
||||
foreach ($attachments['visual'] as $attachment) {
|
||||
if (!empty($attachment['preview'])) {
|
||||
$body = str_replace($attachment['preview'], Post\Media::getPreviewUrlForId($attachment['id'], Proxy::SIZE_LARGE), $body);
|
||||
} elseif ($attachment['filetype'] == 'image') {
|
||||
$body = str_replace($attachment['url'], Post\Media::getUrlForId($attachment['id']), $body);
|
||||
}
|
||||
}
|
||||
DI::profiler()->saveTimestamp($stamp1, 'rendering');
|
||||
return $body;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add visual attachments to the content
|
||||
*
|
||||
|
|
@ -2777,16 +2886,12 @@ class Item
|
|||
|
||||
// @todo In the future we should make a single for the template engine with all media in it. This allows more flexibilty.
|
||||
foreach ($attachments['visual'] as $attachment) {
|
||||
if (self::containsLink($item['body'], $attachment['url'])) {
|
||||
if (self::containsLink($item['body'], $attachment['url'], $attachment['type'])) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$author = ['uid' => 0, 'id' => $item['author-id'],
|
||||
'network' => $item['author-network'], 'url' => $item['author-link']];
|
||||
$the_url = Contact::magicLinkByContact($author, $attachment['url']);
|
||||
|
||||
if (!empty($attachment['preview'])) {
|
||||
$preview_url = Proxy::proxifyUrl(Contact::magicLinkByContact($author, $attachment['preview']));
|
||||
$preview_url = Post\Media::getPreviewUrlForId($attachment['id'], Proxy::SIZE_LARGE);
|
||||
} else {
|
||||
$preview_url = '';
|
||||
}
|
||||
|
|
@ -2796,13 +2901,13 @@ class Item
|
|||
$media = Renderer::replaceMacros(Renderer::getMarkupTemplate('video_top.tpl'), [
|
||||
'$video' => [
|
||||
'id' => $attachment['id'],
|
||||
'src' => $the_url,
|
||||
'src' => $attachment['url'],
|
||||
'name' => $attachment['name'] ?: $attachment['url'],
|
||||
'preview' => $preview_url,
|
||||
'mime' => $attachment['mimetype'],
|
||||
],
|
||||
]);
|
||||
if ($item['post-type'] == Item::PT_VIDEO) {
|
||||
if (($item['post-type'] ?? null) == Item::PT_VIDEO) {
|
||||
$leading .= $media;
|
||||
} else {
|
||||
$trailing .= $media;
|
||||
|
|
@ -2811,25 +2916,22 @@ class Item
|
|||
$media = Renderer::replaceMacros(Renderer::getMarkupTemplate('content/audio.tpl'), [
|
||||
'$audio' => [
|
||||
'id' => $attachment['id'],
|
||||
'src' => $the_url,
|
||||
'name' => $attachment['name'] ?: $attachment['url'],
|
||||
'src' => $attachment['url'],
|
||||
'name' => $attachment['name'] ?: $attachment['url'],
|
||||
'mime' => $attachment['mimetype'],
|
||||
],
|
||||
]);
|
||||
if ($item['post-type'] == Item::PT_AUDIO) {
|
||||
if (($item['post-type'] ?? null) == Item::PT_AUDIO) {
|
||||
$leading .= $media;
|
||||
} else {
|
||||
$trailing .= $media;
|
||||
}
|
||||
} elseif ($attachment['filetype'] == 'image') {
|
||||
if (empty($preview_url) && (max($attachment['width'], $attachment['height']) > 600)) {
|
||||
$preview_url = Proxy::proxifyUrl($the_url, false, ($attachment['width'] > $attachment['height']) ? Proxy::SIZE_MEDIUM : Proxy::SIZE_LARGE);
|
||||
}
|
||||
$media = Renderer::replaceMacros(Renderer::getMarkupTemplate('content/image.tpl'), [
|
||||
'$image' => [
|
||||
'src' => Proxy::proxifyUrl($the_url),
|
||||
'preview' => $preview_url,
|
||||
'attachment' => $attachment,
|
||||
'src' => Post\Media::getUrlForId($attachment['id']),
|
||||
'preview' => Post\Media::getPreviewUrlForId($attachment['id'], ($attachment['width'] > $attachment['height']) ? Proxy::SIZE_MEDIUM : Proxy::SIZE_LARGE),
|
||||
'attachment' => $attachment,
|
||||
],
|
||||
]);
|
||||
// On Diaspora posts the attached pictures are leading
|
||||
|
|
@ -2907,11 +3009,11 @@ class Item
|
|||
'type' => 'link',
|
||||
'url' => $attachment['url']];
|
||||
|
||||
if ($preview) {
|
||||
if ($preview && !empty($attachment['preview'])) {
|
||||
if ($attachment['preview-width'] >= 500) {
|
||||
$data['image'] = $attachment['preview'] ?? '';
|
||||
$data['image'] = Post\Media::getPreviewUrlForId($attachment['id'], Proxy::SIZE_MEDIUM);
|
||||
} else {
|
||||
$data['preview'] = $attachment['preview'] ?? '';
|
||||
$data['preview'] = Post\Media::getPreviewUrlForId($attachment['id'], Proxy::SIZE_MEDIUM);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -2955,7 +3057,7 @@ class Item
|
|||
|
||||
// @todo Use a template
|
||||
$rendered = BBCode::convertAttachment('', BBCode::INTERNAL, false, $data);
|
||||
} elseif (!self::containsLink($content, $data['url'])) {
|
||||
} elseif (!self::containsLink($content, $data['url'], Post\Media::HTML)) {
|
||||
$rendered = Renderer::replaceMacros(Renderer::getMarkupTemplate('content/link.tpl'), [
|
||||
'$url' => $data['url'],
|
||||
'$title' => $data['title'],
|
||||
|
|
@ -3288,18 +3390,18 @@ class Item
|
|||
{
|
||||
$shared = BBCode::fetchShareAttributes($item['body']);
|
||||
if (empty($shared['link'])) {
|
||||
return $item['body'];
|
||||
return $item['body'];
|
||||
}
|
||||
|
||||
|
||||
$id = self::fetchByLink($shared['link']);
|
||||
Logger::info('Fetched shared post', ['uri-id' => $item['uri-id'], 'id' => $id, 'author' => $shared['profile'], 'url' => $shared['link'], 'guid' => $shared['guid'], 'callstack' => System::callstack()]);
|
||||
if (!$id) {
|
||||
return $item['body'];
|
||||
return $item['body'];
|
||||
}
|
||||
|
||||
$shared_item = Post::selectFirst(['author-name', 'author-link', 'author-avatar', 'plink', 'created', 'guid', 'title', 'body'], ['id' => $id]);
|
||||
if (!DBA::isResult($shared_item)) {
|
||||
return $item['body'];
|
||||
return $item['body'];
|
||||
}
|
||||
|
||||
$shared_content = BBCode::getShareOpeningTag($shared_item['author-name'], $shared_item['author-link'], $shared_item['author-avatar'], $shared_item['plink'], $shared_item['created'], $shared_item['guid']);
|
||||
|
|
|
|||
|
|
@ -36,15 +36,14 @@ use Friendica\Worker\Delivery;
|
|||
class Mail
|
||||
{
|
||||
/**
|
||||
* Insert received private message
|
||||
* Insert private message
|
||||
*
|
||||
* @param array $msg
|
||||
* @param bool $notifiction
|
||||
* @return int|boolean Message ID or false on error
|
||||
*/
|
||||
public static function insert($msg)
|
||||
public static function insert($msg, $notifiction = true)
|
||||
{
|
||||
$user = User::getById($msg['uid']);
|
||||
|
||||
if (!isset($msg['reply'])) {
|
||||
$msg['reply'] = DBA::exists('mail', ['parent-uri' => $msg['parent-uri']]);
|
||||
}
|
||||
|
|
@ -63,6 +62,10 @@ class Mail
|
|||
|
||||
$msg['created'] = (!empty($msg['created']) ? DateTimeFormat::utc($msg['created']) : DateTimeFormat::utcNow());
|
||||
|
||||
$msg['author-id'] = Contact::getIdForURL($msg['from-url'], 0, false);
|
||||
$msg['uri-id'] = ItemURI::insert(['uri' => $msg['uri'], 'guid' => $msg['guid']]);
|
||||
$msg['parent-uri-id'] = ItemURI::getIdByURI($msg['parent-uri']);
|
||||
|
||||
DBA::lock('mail');
|
||||
|
||||
if (DBA::exists('mail', ['uri' => $msg['uri'], 'uid' => $msg['uid']])) {
|
||||
|
|
@ -71,6 +74,16 @@ class Mail
|
|||
return false;
|
||||
}
|
||||
|
||||
if ($msg['reply']) {
|
||||
$reply = DBA::selectFirst('mail', ['uri', 'uri-id'], ['parent-uri' => $msg['parent-uri'], 'reply' => false]);
|
||||
|
||||
$msg['thr-parent'] = $reply['uri'];
|
||||
$msg['thr-parent-id'] = $reply['uri-id'];
|
||||
} else {
|
||||
$msg['thr-parent'] = $msg['uri'];
|
||||
$msg['thr-parent-id'] = $msg['uri-id'];
|
||||
}
|
||||
|
||||
DBA::insert('mail', $msg);
|
||||
|
||||
$msg['id'] = DBA::lastInsertId();
|
||||
|
|
@ -81,19 +94,22 @@ class Mail
|
|||
DBA::update('conv', ['updated' => DateTimeFormat::utcNow()], ['id' => $msg['convid']]);
|
||||
}
|
||||
|
||||
// send notifications.
|
||||
$notif_params = [
|
||||
'type' => Notification\Type::MAIL,
|
||||
'otype' => Notification\ObjectType::MAIL,
|
||||
'verb' => Activity::POST,
|
||||
'uid' => $user['uid'],
|
||||
'cid' => $msg['contact-id'],
|
||||
'link' => DI::baseUrl() . '/message/' . $msg['id'],
|
||||
];
|
||||
if ($notifiction) {
|
||||
$user = User::getById($msg['uid']);
|
||||
// send notifications.
|
||||
$notif_params = [
|
||||
'type' => Notification\Type::MAIL,
|
||||
'otype' => Notification\ObjectType::MAIL,
|
||||
'verb' => Activity::POST,
|
||||
'uid' => $user['uid'],
|
||||
'cid' => $msg['contact-id'],
|
||||
'link' => DI::baseUrl() . '/message/' . $msg['id'],
|
||||
];
|
||||
|
||||
notification($notif_params);
|
||||
notification($notif_params);
|
||||
|
||||
Logger::info('Mail is processed, notification was sent.', ['id' => $msg['id'], 'uri' => $msg['uri']]);
|
||||
Logger::info('Mail is processed, notification was sent.', ['id' => $msg['id'], 'uri' => $msg['uri']]);
|
||||
}
|
||||
|
||||
return $msg['id'];
|
||||
}
|
||||
|
|
@ -181,9 +197,7 @@ class Mail
|
|||
$replyto = $convuri;
|
||||
}
|
||||
|
||||
$post_id = null;
|
||||
$success = DBA::insert(
|
||||
'mail',
|
||||
$post_id = self::insert(
|
||||
[
|
||||
'uid' => local_user(),
|
||||
'guid' => $guid,
|
||||
|
|
@ -200,13 +214,9 @@ class Mail
|
|||
'uri' => $uri,
|
||||
'parent-uri' => $replyto,
|
||||
'created' => DateTimeFormat::utcNow()
|
||||
]
|
||||
], false
|
||||
);
|
||||
|
||||
if ($success) {
|
||||
$post_id = DBA::lastInsertId();
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* When a photo was uploaded into the message using the (profile wall) ajax
|
||||
|
|
@ -287,8 +297,7 @@ class Mail
|
|||
return -4;
|
||||
}
|
||||
|
||||
DBA::insert(
|
||||
'mail',
|
||||
self::insert(
|
||||
[
|
||||
'uid' => $recipient['uid'],
|
||||
'guid' => $guid,
|
||||
|
|
@ -306,7 +315,7 @@ class Mail
|
|||
'parent-uri' => $me['url'],
|
||||
'created' => DateTimeFormat::utcNow(),
|
||||
'unknown' => 1
|
||||
]
|
||||
], false
|
||||
);
|
||||
|
||||
return 0;
|
||||
|
|
|
|||
|
|
@ -27,6 +27,7 @@ use Friendica\Core\System;
|
|||
use Friendica\Database\DBA;
|
||||
use Friendica\Database\DBStructure;
|
||||
use Friendica\DI;
|
||||
use Friendica\Model\Storage\ExternalResource;
|
||||
use Friendica\Model\Storage\SystemResource;
|
||||
use Friendica\Object\Image;
|
||||
use Friendica\Util\DateTimeFormat;
|
||||
|
|
@ -244,13 +245,17 @@ class Photo
|
|||
* Construct a photo array for a system resource image
|
||||
*
|
||||
* @param string $filename Image file name relative to code root
|
||||
* @param string $mimetype Image mime type. Defaults to "image/jpeg"
|
||||
* @param string $mimetype Image mime type. Is guessed by file name when empty.
|
||||
*
|
||||
* @return array
|
||||
* @throws \Exception
|
||||
*/
|
||||
public static function createPhotoForSystemResource($filename, $mimetype = "image/jpeg")
|
||||
public static function createPhotoForSystemResource($filename, $mimetype = '')
|
||||
{
|
||||
if (empty($mimetype)) {
|
||||
$mimetype = Images::guessTypeByExtension($filename);
|
||||
}
|
||||
|
||||
$fields = self::getFields();
|
||||
$values = array_fill(0, count($fields), "");
|
||||
|
||||
|
|
@ -263,6 +268,33 @@ class Photo
|
|||
return $photo;
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct a photo array for an external resource image
|
||||
*
|
||||
* @param string $url Image URL
|
||||
* @param int $uid User ID of the requesting person
|
||||
* @param string $mimetype Image mime type. Is guessed by file name when empty.
|
||||
*
|
||||
* @return array
|
||||
* @throws \Exception
|
||||
*/
|
||||
public static function createPhotoForExternalResource($url, $uid = 0, $mimetype = '')
|
||||
{
|
||||
if (empty($mimetype)) {
|
||||
$mimetype = Images::guessTypeByExtension($url);
|
||||
}
|
||||
|
||||
$fields = self::getFields();
|
||||
$values = array_fill(0, count($fields), "");
|
||||
|
||||
$photo = array_combine($fields, $values);
|
||||
$photo['backend-class'] = ExternalResource::NAME;
|
||||
$photo['backend-ref'] = json_encode(['url' => $url, 'uid' => $uid]);
|
||||
$photo['type'] = $mimetype;
|
||||
$photo['cacheable'] = true;
|
||||
|
||||
return $photo;
|
||||
}
|
||||
|
||||
/**
|
||||
* store photo metadata in db and binary in default backend
|
||||
|
|
|
|||
|
|
@ -124,24 +124,22 @@ class Post
|
|||
}
|
||||
|
||||
/**
|
||||
* Check if post data exists
|
||||
* Check if post-user-view records exists
|
||||
*
|
||||
* @param array $condition array of fields for condition
|
||||
* @param bool $user_mode true = post-user-view, false = post-view
|
||||
*
|
||||
* @return boolean Are there rows for that condition?
|
||||
* @throws \Exception
|
||||
*/
|
||||
public static function exists($condition, bool $user_mode = true) {
|
||||
return DBA::exists($user_mode ? 'post-user-view' : 'post-view', $condition);
|
||||
public static function exists($condition) {
|
||||
return DBA::exists('post-user-view', $condition);
|
||||
}
|
||||
|
||||
/**
|
||||
* Counts the posts satisfying the provided condition
|
||||
* Counts the post-user-view records satisfying the provided condition
|
||||
*
|
||||
* @param array $condition array of fields for condition
|
||||
* @param array $params Array of several parameters
|
||||
* @param bool $user_mode true = post-user-view, false = post-view
|
||||
*
|
||||
* @return int
|
||||
*
|
||||
|
|
@ -153,17 +151,39 @@ class Post
|
|||
* $count = Post::count($condition);
|
||||
* @throws \Exception
|
||||
*/
|
||||
public static function count(array $condition = [], array $params = [], bool $user_mode = true)
|
||||
public static function count(array $condition = [], array $params = [])
|
||||
{
|
||||
return DBA::count($user_mode ? 'post-user-view' : 'post-view', $condition, $params);
|
||||
return DBA::count('post-user-view', $condition, $params);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve a single record from the post table and returns it in an associative array
|
||||
* Counts the post-view records satisfying the provided condition
|
||||
*
|
||||
* @param array $condition array of fields for condition
|
||||
* @param array $params Array of several parameters
|
||||
*
|
||||
* @return int
|
||||
*
|
||||
* Example:
|
||||
* $condition = ["network" => 'dspr'];
|
||||
* or:
|
||||
* $condition = ["`network` IN (?, ?)", 1, 'dfrn', 'dspr'];
|
||||
*
|
||||
* $count = Post::count($condition);
|
||||
* @throws \Exception
|
||||
*/
|
||||
public static function countPosts(array $condition = [], array $params = [])
|
||||
{
|
||||
return DBA::count('post-view', $condition, $params);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve a single record from the post-user-view view and returns it in an associative array
|
||||
*
|
||||
* @param array $fields
|
||||
* @param array $condition
|
||||
* @param array $params
|
||||
* @param bool $user_mode true = post-user-view, false = post-view
|
||||
* @return bool|array
|
||||
* @throws \Exception
|
||||
* @see DBA::select
|
||||
|
|
@ -184,7 +204,32 @@ class Post
|
|||
}
|
||||
|
||||
/**
|
||||
* Retrieve a single record from the post-thread table and returns it in an associative array
|
||||
* Retrieve a single record from the post-view view and returns it in an associative array
|
||||
*
|
||||
* @param array $fields
|
||||
* @param array $condition
|
||||
* @param array $params
|
||||
* @return bool|array
|
||||
* @throws \Exception
|
||||
* @see DBA::select
|
||||
*/
|
||||
public static function selectFirstPost(array $fields = [], array $condition = [], $params = [])
|
||||
{
|
||||
$params['limit'] = 1;
|
||||
|
||||
$result = self::selectPosts($fields, $condition, $params);
|
||||
|
||||
if (is_bool($result)) {
|
||||
return $result;
|
||||
} else {
|
||||
$row = self::fetch($result);
|
||||
DBA::close($result);
|
||||
return $row;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve a single record from the post-thread-user-view view and returns it in an associative array
|
||||
*
|
||||
* @param array $fields
|
||||
* @param array $condition
|
||||
|
|
@ -209,7 +254,7 @@ class Post
|
|||
}
|
||||
|
||||
/**
|
||||
* Select rows from the post table and returns them as an array
|
||||
* Select rows from the post-user-view view and returns them as an array
|
||||
*
|
||||
* @param array $selected Array of selected fields, empty for all
|
||||
* @param array $condition Array of fields for condition
|
||||
|
|
@ -262,23 +307,37 @@ class Post
|
|||
}
|
||||
|
||||
/**
|
||||
* Select rows from the post table
|
||||
* Select rows from the post-user-view view
|
||||
*
|
||||
* @param array $selected Array of selected fields, empty for all
|
||||
* @param array $condition Array of fields for condition
|
||||
* @param array $params Array of several parameters
|
||||
* @param bool $user_mode true = post-user-view, false = post-view
|
||||
*
|
||||
* @return boolean|object
|
||||
* @throws \Exception
|
||||
*/
|
||||
public static function select(array $selected = [], array $condition = [], $params = [], bool $user_mode = true)
|
||||
public static function select(array $selected = [], array $condition = [], $params = [])
|
||||
{
|
||||
return self::selectView($user_mode ? 'post-user-view' : 'post-view', $selected, $condition, $params);
|
||||
return self::selectView('post-user-view', $selected, $condition, $params);
|
||||
}
|
||||
|
||||
/**
|
||||
* Select rows from the post table
|
||||
* Select rows from the post-view view
|
||||
*
|
||||
* @param array $selected Array of selected fields, empty for all
|
||||
* @param array $condition Array of fields for condition
|
||||
* @param array $params Array of several parameters
|
||||
*
|
||||
* @return boolean|object
|
||||
* @throws \Exception
|
||||
*/
|
||||
public static function selectPosts(array $selected = [], array $condition = [], $params = [])
|
||||
{
|
||||
return self::selectView('post-view', $selected, $condition, $params);
|
||||
}
|
||||
|
||||
/**
|
||||
* Select rows from the post-thread-user-view view
|
||||
*
|
||||
* @param array $selected Array of selected fields, empty for all
|
||||
* @param array $condition Array of fields for condition
|
||||
|
|
@ -335,7 +394,7 @@ class Post
|
|||
}
|
||||
|
||||
/**
|
||||
* Select rows from the post view for a given user
|
||||
* Select rows from the post-user-view view for a given user
|
||||
*
|
||||
* @param integer $uid User ID
|
||||
* @param array $selected Array of selected fields, empty for all
|
||||
|
|
@ -350,8 +409,24 @@ class Post
|
|||
return self::selectViewForUser('post-user-view', $uid, $selected, $condition, $params);
|
||||
}
|
||||
|
||||
/**
|
||||
* Select rows from the post view for a given user
|
||||
/**
|
||||
* Select rows from the post-view view for a given user
|
||||
*
|
||||
* @param integer $uid User ID
|
||||
* @param array $selected Array of selected fields, empty for all
|
||||
* @param array $condition Array of fields for condition
|
||||
* @param array $params Array of several parameters
|
||||
*
|
||||
* @return boolean|object
|
||||
* @throws \Exception
|
||||
*/
|
||||
public static function selectPostsForUser($uid, array $selected = [], array $condition = [], $params = [])
|
||||
{
|
||||
return self::selectViewForUser('post-view', $uid, $selected, $condition, $params);
|
||||
}
|
||||
|
||||
/**
|
||||
* Select rows from the post-thread-user-view view for a given user
|
||||
*
|
||||
* @param integer $uid User ID
|
||||
* @param array $selected Array of selected fields, empty for all
|
||||
|
|
@ -367,7 +442,7 @@ class Post
|
|||
}
|
||||
|
||||
/**
|
||||
* Retrieve a single record from the post view for a given user and returns it in an associative array
|
||||
* Retrieve a single record from the post-user-view view for a given user and returns it in an associative array
|
||||
*
|
||||
* @param integer $uid User ID
|
||||
* @param array $selected
|
||||
|
|
@ -393,7 +468,7 @@ class Post
|
|||
}
|
||||
|
||||
/**
|
||||
* Select pinned rows from the item table for a given user
|
||||
* Select pinned rows from the post-thread-user table for a given user
|
||||
*
|
||||
* @param integer $uid User ID
|
||||
* @param array $selected Array of selected fields, empty for all
|
||||
|
|
|
|||
|
|
@ -28,9 +28,12 @@ use Friendica\Database\Database;
|
|||
use Friendica\Database\DBA;
|
||||
use Friendica\DI;
|
||||
use Friendica\Model\Item;
|
||||
use Friendica\Model\Photo;
|
||||
use Friendica\Model\Post;
|
||||
use Friendica\Util\Images;
|
||||
use Friendica\Util\Network;
|
||||
use Friendica\Util\ParseUrl;
|
||||
use Friendica\Util\Proxy;
|
||||
use Friendica\Util\Strings;
|
||||
|
||||
/**
|
||||
|
|
@ -157,6 +160,10 @@ class Media
|
|||
*/
|
||||
public static function fetchAdditionalData(array $media)
|
||||
{
|
||||
if (Network::isLocalLink($media['url'])) {
|
||||
$media = self::fetchLocalData($media);
|
||||
}
|
||||
|
||||
// Fetch the mimetype or size if missing.
|
||||
if (empty($media['mimetype']) || empty($media['size'])) {
|
||||
$timeout = DI::config()->get('system', 'xrd_timeout');
|
||||
|
|
@ -215,6 +222,36 @@ class Media
|
|||
return $media;
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetch media data from local resources
|
||||
* @param array $media
|
||||
* @return array media with added data
|
||||
*/
|
||||
private static function fetchLocalData(array $media)
|
||||
{
|
||||
if (!preg_match('|.*?/photo/(.*[a-fA-F0-9])\-(.*[0-9])\..*[\w]|', $media['url'] ?? '', $matches)) {
|
||||
return $media;
|
||||
}
|
||||
$photo = Photo::selectFirst([], ['resource-id' => $matches[1], 'scale' => $matches[2]]);
|
||||
if (!empty($photo)) {
|
||||
$media['mimetype'] = $photo['type'];
|
||||
$media['size'] = $photo['datasize'];
|
||||
$media['width'] = $photo['width'];
|
||||
$media['height'] = $photo['height'];
|
||||
}
|
||||
|
||||
if (!preg_match('|.*?/photo/(.*[a-fA-F0-9])\-(.*[0-9])\..*[\w]|', $media['preview'] ?? '', $matches)) {
|
||||
return $media;
|
||||
}
|
||||
$photo = Photo::selectFirst([], ['resource-id' => $matches[1], 'scale' => $matches[2]]);
|
||||
if (!empty($photo)) {
|
||||
$media['preview-width'] = $photo['width'];
|
||||
$media['preview-height'] = $photo['height'];
|
||||
}
|
||||
|
||||
return $media;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add the detected type to the media array
|
||||
*
|
||||
|
|
@ -351,7 +388,7 @@ class Media
|
|||
|
||||
foreach ($attachments as $attachment) {
|
||||
// Only store attachments that are part of the unshared body
|
||||
if (strpos($unshared_body, $attachment['url']) !== false) {
|
||||
if (Item::containsLink($unshared_body, $attachment['url'], $attachment['type'])) {
|
||||
self::insert($attachment);
|
||||
}
|
||||
}
|
||||
|
|
@ -494,10 +531,10 @@ class Media
|
|||
|
||||
/**
|
||||
* Split the attachment media in the three segments "visual", "link" and "additional"
|
||||
*
|
||||
* @param int $uri_id
|
||||
*
|
||||
* @param int $uri_id
|
||||
* @param string $guid
|
||||
* @param array $links ist of links that shouldn't be added
|
||||
* @param array $links ist of links that shouldn't be added
|
||||
* @return array attachments
|
||||
*/
|
||||
public static function splitAttachments(int $uri_id, string $guid = '', array $links = [])
|
||||
|
|
@ -526,7 +563,7 @@ class Media
|
|||
continue 2;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (!empty($medium['preview'])) {
|
||||
$previews[] = $medium['preview'];
|
||||
}
|
||||
|
|
@ -600,7 +637,7 @@ class Media
|
|||
$body = preg_replace("/\s*\[attachment .*?\].*?\[\/attachment\]\s*/ism", '', $body);
|
||||
|
||||
foreach (self::getByURIId($uriid, [self::IMAGE, self::AUDIO, self::VIDEO]) as $media) {
|
||||
if (Item::containsLink($body, $media['url'])) {
|
||||
if (Item::containsLink($body, $media['url'], $media['type'])) {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
|
@ -631,4 +668,64 @@ class Media
|
|||
|
||||
return $body;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get preview link for given media id
|
||||
*
|
||||
* @param integer $id media id
|
||||
* @param string $size One of the ProxyUtils::SIZE_* constants
|
||||
* @return string preview link
|
||||
*/
|
||||
public static function getPreviewUrlForId(int $id, string $size = ''):string
|
||||
{
|
||||
$url = DI::baseUrl() . '/photo/preview/';
|
||||
switch ($size) {
|
||||
case Proxy::SIZE_MICRO:
|
||||
$url .= Proxy::PIXEL_MICRO . '/';
|
||||
break;
|
||||
case Proxy::SIZE_THUMB:
|
||||
$url .= Proxy::PIXEL_THUMB . '/';
|
||||
break;
|
||||
case Proxy::SIZE_SMALL:
|
||||
$url .= Proxy::PIXEL_SMALL . '/';
|
||||
break;
|
||||
case Proxy::SIZE_MEDIUM:
|
||||
$url .= Proxy::PIXEL_MEDIUM . '/';
|
||||
break;
|
||||
case Proxy::SIZE_LARGE:
|
||||
$url .= Proxy::PIXEL_LARGE . '/';
|
||||
break;
|
||||
}
|
||||
return $url . $id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get media link for given media id
|
||||
*
|
||||
* @param integer $id media id
|
||||
* @param string $size One of the ProxyUtils::SIZE_* constants
|
||||
* @return string media link
|
||||
*/
|
||||
public static function getUrlForId(int $id, string $size = ''):string
|
||||
{
|
||||
$url = DI::baseUrl() . '/photo/media/';
|
||||
switch ($size) {
|
||||
case Proxy::SIZE_MICRO:
|
||||
$url .= Proxy::PIXEL_MICRO . '/';
|
||||
break;
|
||||
case Proxy::SIZE_THUMB:
|
||||
$url .= Proxy::PIXEL_THUMB . '/';
|
||||
break;
|
||||
case Proxy::SIZE_SMALL:
|
||||
$url .= Proxy::PIXEL_SMALL . '/';
|
||||
break;
|
||||
case Proxy::SIZE_MEDIUM:
|
||||
$url .= Proxy::PIXEL_MEDIUM . '/';
|
||||
break;
|
||||
case Proxy::SIZE_LARGE:
|
||||
$url .= Proxy::PIXEL_LARGE . '/';
|
||||
break;
|
||||
}
|
||||
return $url . $id;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -33,7 +33,7 @@ use Friendica\Model\Post;
|
|||
use Friendica\Util\Strings;
|
||||
use Friendica\Model\Tag;
|
||||
use Friendica\Protocol\Activity;
|
||||
|
||||
use Friendica\Util\DateTimeFormat;
|
||||
|
||||
class UserNotification
|
||||
{
|
||||
|
|
@ -128,8 +128,8 @@ class UserNotification
|
|||
*/
|
||||
public static function setNotification(int $uri_id, int $uid)
|
||||
{
|
||||
$fields = ['id', 'uri-id', 'parent-uri-id', 'uid', 'body', 'parent', 'gravity',
|
||||
'private', 'contact-id', 'thr-parent', 'parent-uri-id', 'parent-uri', 'author-id', 'verb'];
|
||||
$fields = ['id', 'uri-id', 'parent-uri-id', 'uid', 'body', 'parent', 'gravity', 'vid', 'gravity',
|
||||
'private', 'contact-id', 'thr-parent', 'thr-parent-id', 'parent-uri-id', 'parent-uri', 'author-id', 'verb'];
|
||||
$item = Post::selectFirst($fields, ['uri-id' => $uri_id, 'uid' => $uid, 'origin' => false]);
|
||||
if (!DBA::isResult($item)) {
|
||||
return;
|
||||
|
|
@ -148,7 +148,7 @@ class UserNotification
|
|||
}
|
||||
|
||||
// Add every user who participated so far in this thread
|
||||
// This can only happen with participations on global items. (means: uid = 0)
|
||||
// This can only happen with participations on global items. (means: uid = 0)
|
||||
$users = DBA::p("SELECT DISTINCT(`contact-uid`) AS `uid` FROM `post-user-view`
|
||||
WHERE `contact-uid` != 0 AND `parent-uri-id` = ? AND `uid` = ?", $item['parent-uri-id'], $uid);
|
||||
while ($user = DBA::fetch($users)) {
|
||||
|
|
@ -177,6 +177,10 @@ class UserNotification
|
|||
|
||||
if (self::checkShared($item, $uid)) {
|
||||
$notification_type = $notification_type | self::NOTIF_SHARED;
|
||||
self::insertNoticationByItem(self::NOTIF_SHARED, $uid, $item);
|
||||
$notified = true;
|
||||
} else {
|
||||
$notified = false;
|
||||
}
|
||||
|
||||
$profiles = self::getProfileForUser($uid);
|
||||
|
|
@ -194,38 +198,64 @@ class UserNotification
|
|||
return;
|
||||
}
|
||||
|
||||
// Only create notifications for posts and comments, not for activities
|
||||
if (in_array($item['gravity'], [GRAVITY_PARENT, GRAVITY_COMMENT])) {
|
||||
if (self::checkImplicitMention($item, $profiles)) {
|
||||
$notification_type = $notification_type | self::NOTIF_IMPLICIT_TAGGED;
|
||||
}
|
||||
|
||||
if (self::checkExplicitMention($item, $profiles)) {
|
||||
$notification_type = $notification_type | self::NOTIF_EXPLICIT_TAGGED;
|
||||
}
|
||||
|
||||
if (self::checkCommentedThread($item, $contacts)) {
|
||||
$notification_type = $notification_type | self::NOTIF_THREAD_COMMENT;
|
||||
}
|
||||
|
||||
if (self::checkDirectComment($item, $contacts)) {
|
||||
$notification_type = $notification_type | self::NOTIF_DIRECT_COMMENT;
|
||||
}
|
||||
|
||||
if (self::checkDirectCommentedThread($item, $contacts)) {
|
||||
$notification_type = $notification_type | self::NOTIF_DIRECT_THREAD_COMMENT;
|
||||
}
|
||||
|
||||
if (self::checkCommentedParticipation($item, $contacts)) {
|
||||
$notification_type = $notification_type | self::NOTIF_COMMENT_PARTICIPATION;
|
||||
}
|
||||
|
||||
if (self::checkActivityParticipation($item, $contacts)) {
|
||||
$notification_type = $notification_type | self::NOTIF_ACTIVITY_PARTICIPATION;
|
||||
if (self::checkExplicitMention($item, $profiles)) {
|
||||
$notification_type = $notification_type | self::NOTIF_EXPLICIT_TAGGED;
|
||||
if (!$notified) {
|
||||
self::insertNoticationByItem( self::NOTIF_EXPLICIT_TAGGED, $uid, $item);
|
||||
$notified = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (empty($notification_type)) {
|
||||
if (self::checkImplicitMention($item, $profiles)) {
|
||||
$notification_type = $notification_type | self::NOTIF_IMPLICIT_TAGGED;
|
||||
if (!$notified) {
|
||||
self::insertNoticationByItem(self::NOTIF_IMPLICIT_TAGGED, $uid, $item);
|
||||
$notified = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (self::checkDirectComment($item, $contacts)) {
|
||||
$notification_type = $notification_type | self::NOTIF_DIRECT_COMMENT;
|
||||
if (!$notified) {
|
||||
self::insertNoticationByItem(self::NOTIF_DIRECT_COMMENT, $uid, $item);
|
||||
$notified = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (self::checkDirectCommentedThread($item, $contacts)) {
|
||||
$notification_type = $notification_type | self::NOTIF_DIRECT_THREAD_COMMENT;
|
||||
if (!$notified) {
|
||||
self::insertNoticationByItem(self::NOTIF_DIRECT_THREAD_COMMENT, $uid, $item);
|
||||
$notified = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (self::checkCommentedThread($item, $contacts)) {
|
||||
$notification_type = $notification_type | self::NOTIF_THREAD_COMMENT;
|
||||
if (!$notified) {
|
||||
self::insertNoticationByItem(self::NOTIF_THREAD_COMMENT, $uid, $item);
|
||||
$notified = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (self::checkCommentedParticipation($item, $contacts)) {
|
||||
$notification_type = $notification_type | self::NOTIF_COMMENT_PARTICIPATION;
|
||||
if (!$notified) {
|
||||
self::insertNoticationByItem(self::NOTIF_COMMENT_PARTICIPATION, $uid, $item);
|
||||
$notified = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (self::checkActivityParticipation($item, $contacts)) {
|
||||
$notification_type = $notification_type | self::NOTIF_ACTIVITY_PARTICIPATION;
|
||||
if (!$notified) {
|
||||
self::insertNoticationByItem(self::NOTIF_ACTIVITY_PARTICIPATION, $uid, $item);
|
||||
$notified = true;
|
||||
}
|
||||
}
|
||||
|
||||
// Only create notifications for posts and comments, not for activities
|
||||
if (empty($notification_type) || !in_array($item['gravity'], [GRAVITY_PARENT, GRAVITY_COMMENT])) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -236,6 +266,61 @@ class UserNotification
|
|||
self::update($item['uri-id'], $uid, $fields, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a notification entry for a given item array
|
||||
*
|
||||
* @param int $type User notification type
|
||||
* @param int $uid User ID
|
||||
* @param array $item Item array
|
||||
* @return boolean
|
||||
*/
|
||||
private static function insertNoticationByItem(int $type, int $uid, array $item)
|
||||
{
|
||||
if (($item['gravity'] == GRAVITY_ACTIVITY) &&
|
||||
!in_array($type, [self::NOTIF_DIRECT_COMMENT, self::NOTIF_DIRECT_THREAD_COMMENT])) {
|
||||
// Activities are only stored when performed on the user's post or comment
|
||||
return;
|
||||
}
|
||||
|
||||
$fields = [
|
||||
'uid' => $uid,
|
||||
'vid' => $item['vid'],
|
||||
'type' => $type,
|
||||
'actor-id' => $item['author-id'],
|
||||
'parent-uri-id' => $item['parent-uri-id'],
|
||||
'created' => DateTimeFormat::utcNow(),
|
||||
];
|
||||
|
||||
if ($item['gravity'] == GRAVITY_ACTIVITY) {
|
||||
$fields['target-uri-id'] = $item['thr-parent-id'];
|
||||
} else {
|
||||
$fields['target-uri-id'] = $item['uri-id'];
|
||||
}
|
||||
|
||||
return DBA::insert('notification', $fields);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a notification entry
|
||||
*
|
||||
* @param int $actor Contact ID of the actor
|
||||
* @param int $vid Verb ID
|
||||
* @param int $uid User ID
|
||||
* @return boolean
|
||||
*/
|
||||
public static function insertNotication(int $actor, int $vid, int $uid)
|
||||
{
|
||||
$fields = [
|
||||
'uid' => $uid,
|
||||
'vid' => $vid,
|
||||
'type' => self::NOTIF_NONE,
|
||||
'actor-id' => $actor,
|
||||
'created' => DateTimeFormat::utcNow(),
|
||||
];
|
||||
|
||||
return DBA::insert('notification', $fields);
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetch all profiles (contact URL) of a given user
|
||||
* @param int $uid User ID
|
||||
|
|
|
|||
|
|
@ -29,13 +29,16 @@ use Friendica\Core\Hook;
|
|||
use Friendica\Core\Logger;
|
||||
use Friendica\Core\Protocol;
|
||||
use Friendica\Core\Renderer;
|
||||
use Friendica\Core\Search;
|
||||
use Friendica\Core\Session;
|
||||
use Friendica\Core\System;
|
||||
use Friendica\Core\Worker;
|
||||
use Friendica\Database\DBA;
|
||||
use Friendica\DI;
|
||||
use Friendica\Protocol\Activity;
|
||||
use Friendica\Protocol\Diaspora;
|
||||
use Friendica\Util\DateTimeFormat;
|
||||
use Friendica\Util\HTTPSignature;
|
||||
use Friendica\Util\Network;
|
||||
use Friendica\Util\Proxy as ProxyUtils;
|
||||
use Friendica\Util\Strings;
|
||||
|
|
@ -84,6 +87,71 @@ class Profile
|
|||
return DBA::selectToArray('profile', $fields, ['uid' => $uid]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Update a profile entry and distribute the changes if needed
|
||||
*
|
||||
* @param array $fields
|
||||
* @param integer $uid
|
||||
* @return boolean
|
||||
*/
|
||||
public static function update(array $fields, int $uid): bool
|
||||
{
|
||||
$old_owner = User::getOwnerDataById($uid);
|
||||
if (empty($old_owner)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!DBA::update('profile', $fields, ['uid' => $uid])) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$update = Contact::updateSelfFromUserID($uid);
|
||||
|
||||
$owner = User::getOwnerDataById($uid);
|
||||
if (empty($owner)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ($old_owner['name'] != $owner['name']) {
|
||||
User::update(['username' => $owner['name']], $uid);
|
||||
}
|
||||
|
||||
$profile_fields = ['postal-code', 'dob', 'prv_keywords', 'homepage'];
|
||||
foreach ($profile_fields as $field) {
|
||||
if ($old_owner[$field] != $owner[$field]) {
|
||||
$update = true;
|
||||
}
|
||||
}
|
||||
|
||||
if ($update) {
|
||||
self::publishUpdate($uid, ($old_owner['net-publish'] != $owner['net-publish']));
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Publish a changed profile
|
||||
* @param int $uid
|
||||
* @param bool $force Force publishing to the directory
|
||||
*/
|
||||
public static function publishUpdate(int $uid, bool $force = false)
|
||||
{
|
||||
$owner = User::getOwnerDataById($uid);
|
||||
if (empty($owner)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ($owner['net-publish'] || $force) {
|
||||
// Update global directory in background
|
||||
if (Search::getGlobalDirectory()) {
|
||||
Worker::add(PRIORITY_LOW, 'Directory', $owner['url']);
|
||||
}
|
||||
}
|
||||
|
||||
Worker::add(PRIORITY_LOW, 'ProfileUpdate', $uid);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a formatted location string from the given profile array
|
||||
*
|
||||
|
|
@ -215,28 +283,6 @@ class Profile
|
|||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all profile data of a local user
|
||||
*
|
||||
* If the viewer is an authenticated remote viewer, the profile displayed is the
|
||||
* one that has been configured for his/her viewing in the Contact manager.
|
||||
* Passing a non-zero profile ID can also allow a preview of a selected profile
|
||||
* by the owner
|
||||
*
|
||||
* Includes all available profile data
|
||||
*
|
||||
* @param string $nickname nick
|
||||
* @param int $uid uid
|
||||
* @param int $profile_id ID of the profile
|
||||
* @return array
|
||||
* @throws \Exception
|
||||
*/
|
||||
public static function getByNickname($nickname, $uid = 0)
|
||||
{
|
||||
$profile = DBA::selectFirst('owner-view', [], ['nickname' => $nickname, 'uid' => $uid]);
|
||||
return $profile;
|
||||
}
|
||||
|
||||
/**
|
||||
* Formats a profile for display in the sidebar.
|
||||
*
|
||||
|
|
@ -263,8 +309,20 @@ class Profile
|
|||
$o = '';
|
||||
$location = false;
|
||||
|
||||
// This function can also use contact information in $profile
|
||||
$is_contact = !empty($profile['cid']);
|
||||
// This function can also use contact information in $profile, but the 'cid'
|
||||
// value is going to be coming from 'owner-view', which means it's the wrong
|
||||
// contact ID for the user viewing this page. Use 'nurl' to look up the
|
||||
// correct contact table entry for the logged-in user.
|
||||
$profile_contact = [];
|
||||
|
||||
if (!empty($profile['nurl'])) {
|
||||
if (local_user() && ($profile['uid'] ?? 0) != local_user()) {
|
||||
$profile_contact = Contact::getByURL($profile['nurl'], null, ['rel'], local_user());
|
||||
}
|
||||
if (!empty($profile['cid']) && self::getMyURL()) {
|
||||
$profile_contact = Contact::selectFirst(['rel'], ['id' => $profile['cid']]);
|
||||
}
|
||||
}
|
||||
|
||||
if (empty($profile['nickname'])) {
|
||||
Logger::warning('Received profile with no nickname', ['profile' => $profile, 'callstack' => System::callstack(10)]);
|
||||
|
|
@ -287,21 +345,23 @@ class Profile
|
|||
$profile_url = DI::baseUrl()->get() . '/profile/' . $profile['nickname'];
|
||||
}
|
||||
|
||||
if (!empty($profile['id'])) {
|
||||
$cid = $profile['id'];
|
||||
} else {
|
||||
$cid = Contact::getIdForURL($profile_url, false);
|
||||
}
|
||||
|
||||
$follow_link = null;
|
||||
$unfollow_link = null;
|
||||
$subscribe_feed_link = null;
|
||||
$wallmessage_link = null;
|
||||
|
||||
// Who is the logged-in user to this profile?
|
||||
$visitor_contact = [];
|
||||
if (!empty($profile['uid']) && self::getMyURL()) {
|
||||
$visitor_contact = Contact::selectFirst(['rel'], ['uid' => $profile['uid'], 'nurl' => Strings::normaliseLink(self::getMyURL())]);
|
||||
}
|
||||
|
||||
$profile_contact = [];
|
||||
if (!empty($profile['cid']) && self::getMyURL()) {
|
||||
$profile_contact = Contact::selectFirst(['rel'], ['id' => $profile['cid']]);
|
||||
}
|
||||
|
||||
$profile_is_dfrn = $profile['network'] == Protocol::DFRN;
|
||||
$profile_is_native = in_array($profile['network'], Protocol::NATIVE_SUPPORT);
|
||||
$local_user_is_self = self::getMyURL() && ($profile['url'] == self::getMyURL());
|
||||
|
|
@ -332,17 +392,19 @@ class Profile
|
|||
$subscribe_feed_link = 'dfrn_poll/' . $profile['nickname'];
|
||||
}
|
||||
|
||||
if (Contact::canReceivePrivateMessages($profile)) {
|
||||
if (Contact::canReceivePrivateMessages($profile_contact)) {
|
||||
if ($visitor_is_followed || $visitor_is_following) {
|
||||
$wallmessage_link = $visitor_base_path . '/message/new/' . base64_encode($profile['addr'] ?? '');
|
||||
$wallmessage_link = $visitor_base_path . '/message/new/' . $profile_contact['id'];
|
||||
} elseif ($visitor_is_authenticated && !empty($profile['unkmail'])) {
|
||||
$wallmessage_link = 'wallmessage/' . $profile['nickname'];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// show edit profile to yourself
|
||||
if (!$is_contact && $local_user_is_self) {
|
||||
// show edit profile to yourself, but only if this is not meant to be
|
||||
// rendered as a "contact". i.e., if 'self' (a "contact" table column) isn't
|
||||
// set in $profile.
|
||||
if (!isset($profile['self']) && $local_user_is_self) {
|
||||
$profile['edit'] = [DI::baseUrl() . '/settings/profile', DI::l10n()->t('Edit profile'), '', DI::l10n()->t('Edit profile')];
|
||||
$profile['menu'] = [
|
||||
'chg_photo' => DI::l10n()->t('Change profile photo'),
|
||||
|
|
@ -431,11 +493,9 @@ class Profile
|
|||
$p['address'] = BBCode::convert($p['address']);
|
||||
}
|
||||
|
||||
if (isset($p['photo'])) {
|
||||
$p['photo'] = ProxyUtils::proxifyUrl($p['photo'], false, ProxyUtils::SIZE_SMALL);
|
||||
}
|
||||
$p['photo'] = Contact::getAvatarUrlForId($cid, ProxyUtils::SIZE_SMALL);
|
||||
|
||||
$p['url'] = Contact::magicLink(($p['url'] ?? '') ?: $profile_url);
|
||||
$p['url'] = Contact::magicLinkById($cid);
|
||||
|
||||
$tpl = Renderer::getMarkupTemplate('profile/vcard.tpl');
|
||||
$o .= Renderer::replaceMacros($tpl, [
|
||||
|
|
@ -754,11 +814,11 @@ class Profile
|
|||
// Try to find the public contact entry of the visitor.
|
||||
$cid = Contact::getIdForURL($handle);
|
||||
if (!$cid) {
|
||||
Logger::log('unable to finger ' . $handle, Logger::DEBUG);
|
||||
Logger::info('Handle not found', ['handle' => $handle]);
|
||||
return [];
|
||||
}
|
||||
|
||||
$visitor = DBA::selectFirst('contact', [], ['id' => $cid]);
|
||||
$visitor = Contact::getById($cid);
|
||||
|
||||
// Authenticate the visitor.
|
||||
$_SESSION['authenticated'] = 1;
|
||||
|
|
@ -777,6 +837,19 @@ class Profile
|
|||
return $visitor;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the visitor cookies (see remote_user()) for signed HTTP requests
|
||||
* @return array Visitor contact array
|
||||
*/
|
||||
public static function addVisitorCookieForHTTPSigner()
|
||||
{
|
||||
$requester = HTTPSignature::getSigner('', $_SERVER);
|
||||
if (empty($requester)) {
|
||||
return [];
|
||||
}
|
||||
return Profile::addVisitorCookieForHandle($requester);
|
||||
}
|
||||
|
||||
/**
|
||||
* OpenWebAuth authentication.
|
||||
*
|
||||
|
|
|
|||
113
src/Model/Storage/ExternalResource.php
Normal file
113
src/Model/Storage/ExternalResource.php
Normal file
|
|
@ -0,0 +1,113 @@
|
|||
<?php
|
||||
/**
|
||||
* @copyright Copyright (C) 2010-2021, the Friendica project
|
||||
*
|
||||
* @license GNU AGPL version 3 or any later version
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
namespace Friendica\Model\Storage;
|
||||
|
||||
use BadMethodCallException;
|
||||
use Friendica\Util\HTTPSignature;
|
||||
use Friendica\Network\IHTTPRequest;
|
||||
|
||||
/**
|
||||
* External resource storage class
|
||||
*
|
||||
* This class is used to load external resources, like images.
|
||||
* Is not intended to be selectable by admins as default storage class.
|
||||
*/
|
||||
class ExternalResource implements IStorage
|
||||
{
|
||||
const NAME = 'ExternalResource';
|
||||
|
||||
/** @var IHTTPRequest */
|
||||
private $httpRequest;
|
||||
|
||||
public function __construct(IHTTPRequest $httpRequest)
|
||||
{
|
||||
$this->httpRequest = $httpRequest;
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function get(string $reference)
|
||||
{
|
||||
$data = json_decode($reference);
|
||||
if (empty($data->url)) {
|
||||
return "";
|
||||
}
|
||||
|
||||
$parts = parse_url($data->url);
|
||||
if (empty($parts['scheme']) || empty($parts['host'])) {
|
||||
return "";
|
||||
}
|
||||
|
||||
$fetchResult = HTTPSignature::fetchRaw($data->url, $data->uid);
|
||||
if ($fetchResult->isSuccess()) {
|
||||
return $fetchResult->getBody();
|
||||
} else {
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function put(string $data, string $reference = '')
|
||||
{
|
||||
throw new BadMethodCallException();
|
||||
}
|
||||
|
||||
public function delete(string $reference)
|
||||
{
|
||||
throw new BadMethodCallException();
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function getOptions()
|
||||
{
|
||||
return [];
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function saveOptions(array $data)
|
||||
{
|
||||
return [];
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function __toString()
|
||||
{
|
||||
return self::NAME;
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public static function getName()
|
||||
{
|
||||
return self::NAME;
|
||||
}
|
||||
}
|
||||
|
|
@ -23,6 +23,8 @@ namespace Friendica\Model\Storage;
|
|||
|
||||
/**
|
||||
* Interface for storage backends
|
||||
*
|
||||
* @todo Split this interface into "IStorage" for get() operations (including Resource fetching) and "IUserStorage" for real user backends including put/delete/options
|
||||
*/
|
||||
interface IStorage
|
||||
{
|
||||
|
|
|
|||
|
|
@ -312,8 +312,8 @@ class User
|
|||
*/
|
||||
public static function getIdForURL(string $url)
|
||||
{
|
||||
// Avoid any database requests when the hostname isn't even part of the url.
|
||||
if (!strpos($url, DI::baseUrl()->getHostname())) {
|
||||
// Avoid database queries when the local node hostname isn't even part of the url.
|
||||
if (!Contact::isLocal($url)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -391,7 +391,12 @@ class User
|
|||
if (!DBA::exists('user', ['uid' => $uid]) || !$repairMissing) {
|
||||
return false;
|
||||
}
|
||||
Contact::createSelfFromUserId($uid);
|
||||
if (!DBA::exists('profile', ['uid' => $uid])) {
|
||||
DBA::insert('profile', ['uid' => $uid]);
|
||||
}
|
||||
if (!DBA::exists('contact', ['uid' => $uid, 'self' => true])) {
|
||||
Contact::createSelfFromUserId($uid);
|
||||
}
|
||||
$owner = self::getOwnerDataById($uid, false);
|
||||
}
|
||||
|
||||
|
|
@ -407,7 +412,7 @@ class User
|
|||
|
||||
// Check for correct url and normalised nurl
|
||||
$url = DI::baseUrl() . '/profile/' . $owner['nickname'];
|
||||
$repair = ($owner['url'] != $url) || ($owner['nurl'] != Strings::normaliseLink($owner['url']));
|
||||
$repair = empty($owner['network']) || ($owner['url'] != $url) || ($owner['nurl'] != Strings::normaliseLink($owner['url']));
|
||||
|
||||
if (!$repair) {
|
||||
// Check if "addr" is present and correct
|
||||
|
|
@ -1123,6 +1128,8 @@ class User
|
|||
Photo::update(['profile' => 1], ['resource-id' => $resource_id]);
|
||||
}
|
||||
}
|
||||
|
||||
Contact::updateSelfFromUserID($uid, true);
|
||||
}
|
||||
|
||||
Hook::callAll('register_account', $uid);
|
||||
|
|
@ -1131,6 +1138,42 @@ class User
|
|||
return $return;
|
||||
}
|
||||
|
||||
/**
|
||||
* Update a user entry and distribute the changes if needed
|
||||
*
|
||||
* @param array $fields
|
||||
* @param integer $uid
|
||||
* @return boolean
|
||||
*/
|
||||
public static function update(array $fields, int $uid): bool
|
||||
{
|
||||
$old_owner = self::getOwnerDataById($uid);
|
||||
if (empty($old_owner)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!DBA::update('user', $fields, ['uid' => $uid])) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$update = Contact::updateSelfFromUserID($uid);
|
||||
|
||||
$owner = self::getOwnerDataById($uid);
|
||||
if (empty($owner)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ($old_owner['name'] != $owner['name']) {
|
||||
Profile::update(['name' => $owner['name']], $uid);
|
||||
}
|
||||
|
||||
if ($update) {
|
||||
Profile::publishUpdate($uid);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets block state for a given user
|
||||
*
|
||||
|
|
@ -1462,6 +1505,10 @@ class User
|
|||
*/
|
||||
public static function identities($uid)
|
||||
{
|
||||
if (empty($uid)) {
|
||||
return [];
|
||||
}
|
||||
|
||||
$identities = [];
|
||||
|
||||
$user = DBA::selectFirst('user', ['uid', 'nickname', 'username', 'parent-uid'], ['uid' => $uid]);
|
||||
|
|
|
|||
|
|
@ -51,6 +51,8 @@ class Federation extends BaseAdmin
|
|||
'socialhome' => ['name' => 'SocialHome', 'color' => '#52056b'], // lilac from the Django Image used at the Socialhome homepage
|
||||
'wordpress' => ['name' => 'WordPress', 'color' => '#016087'], // Background color of the homepage
|
||||
'writefreely' => ['name' => 'WriteFreely', 'color' => '#292929'], // Font color of the homepage
|
||||
'mistpark' => ['name' => 'Nomad projects (Mistpark, Osada, Roadhouse, Zap)', 'color' => '#348a4a'], // Green like the Mistpark green
|
||||
'relay' => ['name' => 'ActivityPub Relay', 'color' => '#888888'], // Grey like the second color of the ActivityPub logo
|
||||
'other' => ['name' => DI::l10n()->t('Other'), 'color' => '#F1007E'], // ActivityPub main color
|
||||
];
|
||||
|
||||
|
|
@ -80,6 +82,10 @@ class Federation extends BaseAdmin
|
|||
|
||||
if (in_array($gserver['platform'], ['Red Matrix', 'redmatrix', 'red'])) {
|
||||
$version['version'] = 'Red ' . $version['version'];
|
||||
} elseif (in_array($gserver['platform'], ['osada', 'mistpark', 'roadhouse', 'zap'])) {
|
||||
$version['version'] = $gserver['platform'] . ' ' . $version['version'];
|
||||
} elseif (in_array($gserver['platform'], ['activityrelay', 'pub-relay', 'selective-relay', 'aoderelay'])) {
|
||||
$version['version'] = $gserver['platform'] . '-' . $version['version'];
|
||||
}
|
||||
|
||||
$versionCounts[] = $version;
|
||||
|
|
@ -92,12 +98,16 @@ class Federation extends BaseAdmin
|
|||
$platform = 'friendica';
|
||||
} elseif (in_array($platform, ['red matrix', 'redmatrix', 'red'])) {
|
||||
$platform = 'hubzilla';
|
||||
} elseif (in_array($platform, ['mistpark', 'osada', 'roadhouse', 'zap'])) {
|
||||
$platform = 'mistpark';
|
||||
} elseif(stristr($platform, 'pleroma')) {
|
||||
$platform = 'pleroma';
|
||||
} elseif(stristr($platform, 'statusnet')) {
|
||||
$platform = 'gnusocial';
|
||||
} elseif(stristr($platform, 'wordpress')) {
|
||||
$platform = 'wordpress';
|
||||
} elseif (in_array($platform, ['activityrelay', 'pub-relay', 'selective-relay', 'aoderelay'])) {
|
||||
$platform = 'relay';
|
||||
} elseif (!in_array($platform, $platforms)) {
|
||||
$platform = 'other';
|
||||
}
|
||||
|
|
@ -122,9 +132,17 @@ class Federation extends BaseAdmin
|
|||
$versionCounts = self::reformaPleromaVersions($versionCounts);
|
||||
} elseif ($platform == 'diaspora') {
|
||||
$versionCounts = self::reformaDiasporaVersions($versionCounts);
|
||||
} elseif ($platform == 'relay') {
|
||||
$versionCounts = self::reformatRelayVersions($versionCounts);
|
||||
} elseif (in_array($platform, ['funkwhale', 'mastodon', 'mobilizon', 'misskey'])) {
|
||||
$versionCounts = self::removeVersionSuffixes($versionCounts);
|
||||
}
|
||||
|
||||
$versionCounts = self::sortVersion($versionCounts);
|
||||
if (!in_array($platform, ['other', 'relay', 'mistpark'])) {
|
||||
$versionCounts = self::sortVersion($versionCounts);
|
||||
} else {
|
||||
ksort($versionCounts);
|
||||
}
|
||||
|
||||
$gserver['platform'] = $systems[$platform]['name'];
|
||||
|
||||
|
|
@ -250,6 +268,68 @@ class Federation extends BaseAdmin
|
|||
return $versionCounts;
|
||||
}
|
||||
|
||||
/**
|
||||
* Clean up version numbers
|
||||
*
|
||||
* @param array $versionCounts list of version numbers
|
||||
* @return array with cleaned version numbers
|
||||
*/
|
||||
private static function removeVersionSuffixes(array $versionCounts)
|
||||
{
|
||||
$compacted = [];
|
||||
foreach ($versionCounts as $key => $value) {
|
||||
$version = $versionCounts[$key]['version'];
|
||||
|
||||
foreach ([' ', '+', '-', '#', '_', '~'] as $delimiter) {
|
||||
$parts = explode($delimiter, trim($version));
|
||||
$version = array_shift($parts);
|
||||
}
|
||||
|
||||
if (empty($compacted[$version])) {
|
||||
$compacted[$version] = $versionCounts[$key]['total'];
|
||||
} else {
|
||||
$compacted[$version] += $versionCounts[$key]['total'];
|
||||
}
|
||||
}
|
||||
|
||||
$versionCounts = [];
|
||||
foreach ($compacted as $version => $pl_total) {
|
||||
$versionCounts[] = ['version' => $version, 'total' => $pl_total];
|
||||
}
|
||||
|
||||
return $versionCounts;
|
||||
}
|
||||
|
||||
/**
|
||||
* Clean up relay version numbers
|
||||
*
|
||||
* @param array $versionCounts list of version numbers
|
||||
* @return array with cleaned version numbers
|
||||
*/
|
||||
private static function reformatRelayVersions(array $versionCounts)
|
||||
{
|
||||
$compacted = [];
|
||||
foreach ($versionCounts as $key => $value) {
|
||||
$version = $versionCounts[$key]['version'];
|
||||
|
||||
$parts = explode(' ', trim($version));
|
||||
$version = array_shift($parts);
|
||||
|
||||
if (empty($compacted[$version])) {
|
||||
$compacted[$version] = $versionCounts[$key]['total'];
|
||||
} else {
|
||||
$compacted[$version] += $versionCounts[$key]['total'];
|
||||
}
|
||||
}
|
||||
|
||||
$versionCounts = [];
|
||||
foreach ($compacted as $version => $pl_total) {
|
||||
$versionCounts[] = ['version' => $version, 'total' => $pl_total];
|
||||
}
|
||||
|
||||
return $versionCounts;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reformat, sort and compact version numbers
|
||||
*
|
||||
|
|
|
|||
|
|
@ -32,6 +32,7 @@ use Friendica\Model\Contact;
|
|||
use Friendica\Model\User;
|
||||
use Friendica\Module\BaseAdmin;
|
||||
use Friendica\Module\Register;
|
||||
use Friendica\Protocol\Relay;
|
||||
use Friendica\Util\BasePath;
|
||||
use Friendica\Util\EMailer\MailBuilder;
|
||||
use Friendica\Util\Strings;
|
||||
|
|
@ -208,8 +209,6 @@ class Site extends BaseAdmin
|
|||
$worker_fastlane = !empty($_POST['worker_fastlane']);
|
||||
|
||||
$relay_directly = !empty($_POST['relay_directly']);
|
||||
$relay_server = (!empty($_POST['relay_server']) ? Strings::escapeTags(trim($_POST['relay_server'])) : '');
|
||||
$relay_subscribe = !empty($_POST['relay_subscribe']);
|
||||
$relay_scope = (!empty($_POST['relay_scope']) ? Strings::escapeTags(trim($_POST['relay_scope'])) : '');
|
||||
$relay_server_tags = (!empty($_POST['relay_server_tags']) ? Strings::escapeTags(trim($_POST['relay_server_tags'])) : '');
|
||||
$relay_deny_tags = (!empty($_POST['relay_deny_tags']) ? Strings::escapeTags(trim($_POST['relay_deny_tags'])) : '');
|
||||
|
|
@ -418,8 +417,6 @@ class Site extends BaseAdmin
|
|||
DI::config()->set('system', 'worker_fastlane' , $worker_fastlane);
|
||||
|
||||
DI::config()->set('system', 'relay_directly' , $relay_directly);
|
||||
DI::config()->set('system', 'relay_server' , $relay_server);
|
||||
DI::config()->set('system', 'relay_subscribe' , $relay_subscribe);
|
||||
DI::config()->set('system', 'relay_scope' , $relay_scope);
|
||||
DI::config()->set('system', 'relay_server_tags', $relay_server_tags);
|
||||
DI::config()->set('system', 'relay_deny_tags' , $relay_deny_tags);
|
||||
|
|
@ -589,6 +586,10 @@ class Site extends BaseAdmin
|
|||
'$performance' => DI::l10n()->t('Performance'),
|
||||
'$worker_title' => DI::l10n()->t('Worker'),
|
||||
'$relay_title' => DI::l10n()->t('Message Relay'),
|
||||
'$relay_description' => DI::l10n()->t('Use the command "console relay" in the command line to add or remove relays.'),
|
||||
'$no_relay_list' => DI::l10n()->t('The system is not subscribed to any relays at the moment.'),
|
||||
'$relay_list_title' => DI::l10n()->t('The system is currently subscribed to the following relays:'),
|
||||
'$relay_list' => Relay::getList(['url']),
|
||||
'$relocate' => DI::l10n()->t('Relocate Instance'),
|
||||
'$relocate_warning' => DI::l10n()->t('<strong>Warning!</strong> Advanced function. Could make this server unreachable.'),
|
||||
'$baseurl' => DI::baseUrl()->get(true),
|
||||
|
|
@ -688,10 +689,8 @@ class Site extends BaseAdmin
|
|||
'$worker_queues' => ['worker_queues', DI::l10n()->t('Maximum number of parallel workers'), DI::config()->get('system', 'worker_queues'), DI::l10n()->t('On shared hosters set this to %d. On larger systems, values of %d are great. Default value is %d.', 5, 20, 10)],
|
||||
'$worker_fastlane' => ['worker_fastlane', DI::l10n()->t('Enable fastlane'), DI::config()->get('system', 'worker_fastlane'), DI::l10n()->t('When enabed, the fastlane mechanism starts an additional worker if processes with higher priority are blocked by processes of lower priority.')],
|
||||
|
||||
'$relay_subscribe' => ['relay_subscribe', DI::l10n()->t('Use relay servers'), DI::config()->get('system', 'relay_subscribe'), DI::l10n()->t('Enables the receiving of public posts from relay servers. They will be included in the search, subscribed tags and on the global community page.')],
|
||||
'$relay_server' => ['relay_server', DI::l10n()->t('"Social Relay" server'), DI::config()->get('system', 'relay_server'), DI::l10n()->t('Address of the "Social Relay" server where public posts should be send to. For example %s. ActivityRelay servers are administrated via the "console relay" command line command.', 'https://social-relay.isurf.ca')],
|
||||
'$relay_directly' => ['relay_directly', DI::l10n()->t('Direct relay transfer'), DI::config()->get('system', 'relay_directly'), DI::l10n()->t('Enables the direct transfer to other servers without using the relay servers')],
|
||||
'$relay_scope' => ['relay_scope', DI::l10n()->t('Relay scope'), DI::config()->get('system', 'relay_scope'), DI::l10n()->t('Can be "all" or "tags". "all" means that every public post should be received. "tags" means that only posts with selected tags should be received.'), ['' => DI::l10n()->t('Disabled'), 'all' => DI::l10n()->t('all'), 'tags' => DI::l10n()->t('tags')]],
|
||||
'$relay_scope' => ['relay_scope', DI::l10n()->t('Relay scope'), DI::config()->get('system', 'relay_scope'), DI::l10n()->t('Can be "all" or "tags". "all" means that every public post should be received. "tags" means that only posts with selected tags should be received.'), [SR_SCOPE_NONE => DI::l10n()->t('Disabled'), SR_SCOPE_ALL => DI::l10n()->t('all'), SR_SCOPE_TAGS => DI::l10n()->t('tags')]],
|
||||
'$relay_server_tags' => ['relay_server_tags', DI::l10n()->t('Server tags'), DI::config()->get('system', 'relay_server_tags'), DI::l10n()->t('Comma separated list of tags for the "tags" subscription.')],
|
||||
'$relay_deny_tags' => ['relay_deny_tags', DI::l10n()->t('Deny Server tags'), DI::config()->get('system', 'relay_deny_tags'), DI::l10n()->t('Comma separated list of tags that are rejected.')],
|
||||
'$relay_user_tags' => ['relay_user_tags', DI::l10n()->t('Allow user tags'), DI::config()->get('system', 'relay_user_tags'), DI::l10n()->t('If enabled, the tags from the saved searches will used for the "tags" subscription in addition to the "relay_server_tags".')],
|
||||
|
|
|
|||
|
|
@ -194,7 +194,7 @@ class Summary extends BaseAdmin
|
|||
];
|
||||
|
||||
$users = 0;
|
||||
$pageFlagsCountStmt = DBA::p('SELECT `page-flags`, COUNT(`uid`) AS `count` FROM `user` GROUP BY `page-flags`');
|
||||
$pageFlagsCountStmt = DBA::p('SELECT `page-flags`, COUNT(`uid`) AS `count` FROM `user` WHERE `uid` != ? GROUP BY `page-flags`', 0);
|
||||
while ($pageFlagsCount = DBA::fetch($pageFlagsCountStmt)) {
|
||||
$accounts[$pageFlagsCount['page-flags']][1] = $pageFlagsCount['count'];
|
||||
$users += $pageFlagsCount['count'];
|
||||
|
|
|
|||
|
|
@ -35,16 +35,15 @@ class Index extends BaseApi
|
|||
{
|
||||
public static function rawContent(array $parameters = [])
|
||||
{
|
||||
if (self::login(self::SCOPE_READ) === false) {
|
||||
throw new HTTPException\ForbiddenException();
|
||||
}
|
||||
self::checkAllowedScope(self::SCOPE_READ);
|
||||
$uid = self::getCurrentUserID();
|
||||
|
||||
$request = self::getRequest([
|
||||
'since_id' => 0,
|
||||
'count' => 0,
|
||||
]);
|
||||
|
||||
$condition = ["`id` > ? AND `uid` = ?", $request['since_id'], self::$current_user_id];
|
||||
$condition = ["`id` > ? AND `uid` = ?", $request['since_id'], $uid];
|
||||
$params = ['limit' => $request['count']];
|
||||
$events = DBA::selectToArray('event', [], $condition, $params);
|
||||
|
||||
|
|
|
|||
|
|
@ -37,16 +37,15 @@ class Show extends BaseApi
|
|||
{
|
||||
public static function rawContent(array $parameters = [])
|
||||
{
|
||||
if (self::login(self::SCOPE_READ) === false) {
|
||||
throw new HTTPException\ForbiddenException();
|
||||
}
|
||||
self::checkAllowedScope(self::SCOPE_READ);
|
||||
$uid = self::getCurrentUserID();
|
||||
|
||||
// retrieve general information about profiles for user
|
||||
$directory = DI::config()->get('system', 'directory');
|
||||
|
||||
$profile = Profile::getByUID(self::$current_user_id);
|
||||
$profile = Profile::getByUID($uid);
|
||||
|
||||
$profileFields = DI::profileField()->select(['uid' => self::$current_user_id, 'psid' => PermissionSet::PUBLIC]);
|
||||
$profileFields = DI::profileField()->select(['uid' => $uid, 'psid' => PermissionSet::PUBLIC]);
|
||||
|
||||
$profile = self::formatProfile($profile, $profileFields);
|
||||
|
||||
|
|
@ -58,7 +57,7 @@ class Show extends BaseApi
|
|||
}
|
||||
|
||||
// return settings, authenticated user and profiles data
|
||||
$self = Contact::selectFirst(['nurl'], ['uid' => self::$current_user_id, 'self' => true]);
|
||||
$self = Contact::selectFirst(['nurl'], ['uid' => $uid, 'self' => true]);
|
||||
|
||||
$result = [
|
||||
'multi_profiles' => false,
|
||||
|
|
|
|||
|
|
@ -24,6 +24,7 @@ namespace Friendica\Module\Api\Mastodon;
|
|||
use Friendica\Core\System;
|
||||
use Friendica\Database\DBA;
|
||||
use Friendica\DI;
|
||||
use Friendica\Model\Contact;
|
||||
use Friendica\Module\BaseApi;
|
||||
|
||||
/**
|
||||
|
|
@ -37,16 +38,27 @@ class Accounts extends BaseApi
|
|||
*/
|
||||
public static function rawContent(array $parameters = [])
|
||||
{
|
||||
if (empty($parameters['id'])) {
|
||||
$uid = self::getCurrentUserID();
|
||||
|
||||
if (empty($parameters['id']) && empty($parameters['name'])) {
|
||||
DI::mstdnError()->UnprocessableEntity();
|
||||
}
|
||||
|
||||
$id = $parameters['id'];
|
||||
if (!DBA::exists('contact', ['id' => $id, 'uid' => 0])) {
|
||||
DI::mstdnError()->RecordNotFound();
|
||||
if (!empty($parameters['id'])) {
|
||||
$id = $parameters['id'];
|
||||
if (!DBA::exists('contact', ['id' => $id, 'uid' => 0])) {
|
||||
DI::mstdnError()->RecordNotFound();
|
||||
}
|
||||
} else {
|
||||
$contact = Contact::selectFirst(['id'], ['nick' => $parameters['name'], 'uid' => 0]);
|
||||
if (!empty($contact['id'])) {
|
||||
$id = $contact['id'];
|
||||
} elseif (!($id = Contact::getIdForURL($parameters['name'], 0, false))) {
|
||||
DI::mstdnError()->RecordNotFound();
|
||||
}
|
||||
}
|
||||
|
||||
$account = DI::mstdnAccount()->createFromContactId($id, self::getCurrentUserID());
|
||||
$account = DI::mstdnAccount()->createFromContactId($id, $uid);
|
||||
System::jsonExit($account);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -33,7 +33,7 @@ class Block extends BaseApi
|
|||
{
|
||||
public static function post(array $parameters = [])
|
||||
{
|
||||
self::login(self::SCOPE_FOLLOW);
|
||||
self::checkAllowedScope(self::SCOPE_FOLLOW);
|
||||
$uid = self::getCurrentUserID();
|
||||
|
||||
if (empty($parameters['id'])) {
|
||||
|
|
|
|||
|
|
@ -33,14 +33,14 @@ class Follow extends BaseApi
|
|||
{
|
||||
public static function post(array $parameters = [])
|
||||
{
|
||||
self::login(self::SCOPE_FOLLOW);
|
||||
self::checkAllowedScope(self::SCOPE_FOLLOW);
|
||||
$uid = self::getCurrentUserID();
|
||||
|
||||
if (empty($parameters['id'])) {
|
||||
DI::mstdnError()->UnprocessableEntity();
|
||||
}
|
||||
|
||||
$cid = Contact::follow($parameters['id'], self::getCurrentUserID());
|
||||
$cid = Contact::follow($parameters['id'], $uid);
|
||||
|
||||
System::jsonExit(DI::mstdnRelationship()->createFromContactId($cid, $uid)->toArray());
|
||||
}
|
||||
|
|
|
|||
|
|
@ -37,7 +37,7 @@ class Followers extends BaseApi
|
|||
*/
|
||||
public static function rawContent(array $parameters = [])
|
||||
{
|
||||
self::login(self::SCOPE_READ);
|
||||
self::checkAllowedScope(self::SCOPE_READ);
|
||||
$uid = self::getCurrentUserID();
|
||||
|
||||
if (empty($parameters['id'])) {
|
||||
|
|
@ -54,30 +54,31 @@ class Followers extends BaseApi
|
|||
$request = self::getRequest([
|
||||
'max_id' => 0, // Return results older than this id
|
||||
'since_id' => 0, // Return results newer than this id
|
||||
'limit' => 20, // Maximum number of results to return. Defaults to 20.
|
||||
'limit' => 40, // Maximum number of results to return. Defaults to 40.
|
||||
]);
|
||||
|
||||
$params = ['order' => ['cid' => true], 'limit' => $request['limit']];
|
||||
$params = ['order' => ['relation-cid' => true], 'limit' => $request['limit']];
|
||||
|
||||
$condition = ['relation-cid' => $id, 'follows' => true];
|
||||
$condition = ['cid' => $id, 'follows' => true];
|
||||
|
||||
if (!empty($request['max_id'])) {
|
||||
$condition = DBA::mergeConditions($condition, ["`cid` < ?", $request['max_id']]);
|
||||
$condition = DBA::mergeConditions($condition, ["`relation-cid` < ?", $request['max_id']]);
|
||||
}
|
||||
|
||||
if (!empty($request['since_id'])) {
|
||||
$condition = DBA::mergeConditions($condition, ["`cid` > ?", $request['since_id']]);
|
||||
$condition = DBA::mergeConditions($condition, ["`relation-cid` > ?", $request['since_id']]);
|
||||
}
|
||||
|
||||
if (!empty($min_id)) {
|
||||
$condition = DBA::mergeConditions($condition, ["`cid` > ?", $min_id]);
|
||||
$condition = DBA::mergeConditions($condition, ["`relation-cid` > ?", $min_id]);
|
||||
|
||||
$params['order'] = ['cid'];
|
||||
}
|
||||
|
||||
$followers = DBA::select('contact-relation', ['cid'], $condition, $parameters);
|
||||
$followers = DBA::select('contact-relation', ['relation-cid'], $condition, $parameters);
|
||||
while ($follower = DBA::fetch($followers)) {
|
||||
$accounts[] = DI::mstdnAccount()->createFromContactId($follower['cid'], $uid);
|
||||
self::setBoundaries($follower['relation-cid']);
|
||||
$accounts[] = DI::mstdnAccount()->createFromContactId($follower['relation-cid'], $uid);
|
||||
}
|
||||
DBA::close($followers);
|
||||
|
||||
|
|
@ -85,6 +86,7 @@ class Followers extends BaseApi
|
|||
array_reverse($accounts);
|
||||
}
|
||||
|
||||
self::setLinkHeader();
|
||||
System::jsonExit($accounts);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -37,7 +37,7 @@ class Following extends BaseApi
|
|||
*/
|
||||
public static function rawContent(array $parameters = [])
|
||||
{
|
||||
self::login(self::SCOPE_READ);
|
||||
self::checkAllowedScope(self::SCOPE_READ);
|
||||
$uid = self::getCurrentUserID();
|
||||
|
||||
if (empty($parameters['id'])) {
|
||||
|
|
@ -57,27 +57,28 @@ class Following extends BaseApi
|
|||
'limit' => 40, // Maximum number of results to return. Defaults to 40.
|
||||
]);
|
||||
|
||||
$params = ['order' => ['relation-cid' => true], 'limit' => $request['limit']];
|
||||
$params = ['order' => ['cid' => true], 'limit' => $request['limit']];
|
||||
|
||||
$condition = ['cid' => $id, 'follows' => true];
|
||||
$condition = ['relation-cid' => $id, 'follows' => true];
|
||||
|
||||
if (!empty($request['max_id'])) {
|
||||
$condition = DBA::mergeConditions($condition, ["`relation-cid` < ?", $request['max_id']]);
|
||||
$condition = DBA::mergeConditions($condition, ["`cid` < ?", $request['max_id']]);
|
||||
}
|
||||
|
||||
if (!empty($request['since_id'])) {
|
||||
$condition = DBA::mergeConditions($condition, ["`relation-cid` > ?", $request['since_id']]);
|
||||
$condition = DBA::mergeConditions($condition, ["`cid` > ?", $request['since_id']]);
|
||||
}
|
||||
|
||||
if (!empty($min_id)) {
|
||||
$condition = DBA::mergeConditions($condition, ["`relation-cid` > ?", $min_id]);
|
||||
$condition = DBA::mergeConditions($condition, ["`cid` > ?", $min_id]);
|
||||
|
||||
$params['order'] = ['cid'];
|
||||
}
|
||||
|
||||
$followers = DBA::select('contact-relation', ['relation-cid'], $condition, $parameters);
|
||||
$followers = DBA::select('contact-relation', ['cid'], $condition, $parameters);
|
||||
while ($follower = DBA::fetch($followers)) {
|
||||
$accounts[] = DI::mstdnAccount()->createFromContactId($follower['relation-cid'], $uid);
|
||||
self::setBoundaries($follower['cid']);
|
||||
$accounts[] = DI::mstdnAccount()->createFromContactId($follower['cid'], $uid);
|
||||
}
|
||||
DBA::close($followers);
|
||||
|
||||
|
|
@ -85,6 +86,7 @@ class Following extends BaseApi
|
|||
array_reverse($accounts);
|
||||
}
|
||||
|
||||
self::setLinkHeader();
|
||||
System::jsonExit($accounts);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -35,7 +35,7 @@ class IdentityProofs extends BaseApi
|
|||
*/
|
||||
public static function rawContent(array $parameters = [])
|
||||
{
|
||||
self::login(self::SCOPE_READ);
|
||||
self::checkAllowedScope(self::SCOPE_READ);
|
||||
|
||||
System::jsonExit([]);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -38,7 +38,7 @@ class Lists extends BaseApi
|
|||
*/
|
||||
public static function rawContent(array $parameters = [])
|
||||
{
|
||||
self::login(self::SCOPE_READ);
|
||||
self::checkAllowedScope(self::SCOPE_READ);
|
||||
$uid = self::getCurrentUserID();
|
||||
|
||||
if (empty($parameters['id'])) {
|
||||
|
|
|
|||
|
|
@ -33,7 +33,7 @@ class Mute extends BaseApi
|
|||
{
|
||||
public static function post(array $parameters = [])
|
||||
{
|
||||
self::login(self::SCOPE_FOLLOW);
|
||||
self::checkAllowedScope(self::SCOPE_FOLLOW);
|
||||
$uid = self::getCurrentUserID();
|
||||
|
||||
if (empty($parameters['id'])) {
|
||||
|
|
|
|||
|
|
@ -34,7 +34,7 @@ class Note extends BaseApi
|
|||
{
|
||||
public static function post(array $parameters = [])
|
||||
{
|
||||
self::login(self::SCOPE_WRITE);
|
||||
self::checkAllowedScope(self::SCOPE_WRITE);
|
||||
$uid = self::getCurrentUserID();
|
||||
|
||||
if (empty($parameters['id'])) {
|
||||
|
|
|
|||
|
|
@ -37,17 +37,21 @@ class Relationships extends BaseApi
|
|||
*/
|
||||
public static function rawContent(array $parameters = [])
|
||||
{
|
||||
self::login(self::SCOPE_READ);
|
||||
self::checkAllowedScope(self::SCOPE_READ);
|
||||
$uid = self::getCurrentUserID();
|
||||
|
||||
$request = self::getRequest([
|
||||
'id' => [],
|
||||
]);
|
||||
|
||||
if (empty($request['id']) || !is_array($request['id'])) {
|
||||
if (empty($request['id'])) {
|
||||
DI::mstdnError()->UnprocessableEntity();
|
||||
}
|
||||
|
||||
if (!is_array($request['id'])) {
|
||||
$request['id'] = [$request['id']];
|
||||
}
|
||||
|
||||
$relationsships = [];
|
||||
|
||||
foreach ($request['id'] as $id) {
|
||||
|
|
|
|||
|
|
@ -40,7 +40,7 @@ class Search extends BaseApi
|
|||
*/
|
||||
public static function rawContent(array $parameters = [])
|
||||
{
|
||||
self::login(self::SCOPE_READ);
|
||||
self::checkAllowedScope(self::SCOPE_READ);
|
||||
$uid = self::getCurrentUserID();
|
||||
|
||||
$request = self::getRequest([
|
||||
|
|
|
|||
|
|
@ -42,6 +42,8 @@ class Statuses extends BaseApi
|
|||
*/
|
||||
public static function rawContent(array $parameters = [])
|
||||
{
|
||||
$uid = self::getCurrentUserID();
|
||||
|
||||
if (empty($parameters['id'])) {
|
||||
DI::mstdnError()->UnprocessableEntity();
|
||||
}
|
||||
|
|
@ -66,8 +68,6 @@ class Statuses extends BaseApi
|
|||
|
||||
$params = ['order' => ['uri-id' => true], 'limit' => $request['limit']];
|
||||
|
||||
$uid = self::getCurrentUserID();
|
||||
|
||||
if (!$uid) {
|
||||
$condition = ['author-id' => $id, 'private' => [Item::PUBLIC, Item::UNLISTED],
|
||||
'uid' => 0, 'network' => Protocol::FEDERATED];
|
||||
|
|
@ -108,6 +108,7 @@ class Statuses extends BaseApi
|
|||
|
||||
$statuses = [];
|
||||
while ($item = Post::fetch($items)) {
|
||||
self::setBoundaries($item['uri-id']);
|
||||
$statuses[] = DI::mstdnStatus()->createFromUriId($item['uri-id'], $uid);
|
||||
}
|
||||
DBA::close($items);
|
||||
|
|
@ -116,6 +117,7 @@ class Statuses extends BaseApi
|
|||
array_reverse($statuses);
|
||||
}
|
||||
|
||||
self::setLinkHeader();
|
||||
System::jsonExit($statuses);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -33,7 +33,7 @@ class Unblock extends BaseApi
|
|||
{
|
||||
public static function post(array $parameters = [])
|
||||
{
|
||||
self::login(self::SCOPE_FOLLOW);
|
||||
self::checkAllowedScope(self::SCOPE_FOLLOW);
|
||||
$uid = self::getCurrentUserID();
|
||||
|
||||
if (empty($parameters['id'])) {
|
||||
|
|
|
|||
|
|
@ -33,7 +33,7 @@ class Unfollow extends BaseApi
|
|||
{
|
||||
public static function post(array $parameters = [])
|
||||
{
|
||||
self::login(self::SCOPE_FOLLOW);
|
||||
self::checkAllowedScope(self::SCOPE_FOLLOW);
|
||||
$uid = self::getCurrentUserID();
|
||||
|
||||
if (empty($parameters['id'])) {
|
||||
|
|
|
|||
|
|
@ -33,7 +33,7 @@ class Unmute extends BaseApi
|
|||
{
|
||||
public static function post(array $parameters = [])
|
||||
{
|
||||
self::login(self::SCOPE_FOLLOW);
|
||||
self::checkAllowedScope(self::SCOPE_FOLLOW);
|
||||
$uid = self::getCurrentUserID();
|
||||
|
||||
if (empty($parameters['id'])) {
|
||||
|
|
|
|||
|
|
@ -21,8 +21,9 @@
|
|||
|
||||
namespace Friendica\Module\Api\Mastodon\Accounts;
|
||||
|
||||
use Friendica\Core\Logger;
|
||||
use Friendica\Module\BaseApi;
|
||||
use Friendica\Util\Network;
|
||||
use Friendica\Util\HTTPInputData;
|
||||
|
||||
/**
|
||||
* @see https://docs.joinmastodon.org/methods/accounts/
|
||||
|
|
@ -31,12 +32,13 @@ class UpdateCredentials extends BaseApi
|
|||
{
|
||||
public static function patch(array $parameters = [])
|
||||
{
|
||||
self::login(self::SCOPE_WRITE);
|
||||
self::checkAllowedScope(self::SCOPE_WRITE);
|
||||
$uid = self::getCurrentUserID();
|
||||
|
||||
$data = Network::postdata();
|
||||
$data = HTTPInputData::process();
|
||||
|
||||
Logger::info('Patch data', ['data' => $data]);
|
||||
|
||||
// @todo Parse the raw data that is in the "multipart/form-data" format
|
||||
self::unsupported('patch');
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -38,7 +38,7 @@ class VerifyCredentials extends BaseApi
|
|||
*/
|
||||
public static function rawContent(array $parameters = [])
|
||||
{
|
||||
self::login(self::SCOPE_READ);
|
||||
self::checkAllowedScope(self::SCOPE_READ);
|
||||
$uid = self::getCurrentUserID();
|
||||
|
||||
$self = User::getOwnerDataById($uid);
|
||||
|
|
|
|||
|
|
@ -35,7 +35,7 @@ class Announcements extends BaseApi
|
|||
*/
|
||||
public static function rawContent(array $parameters = [])
|
||||
{
|
||||
self::login(self::SCOPE_READ);
|
||||
self::checkAllowedScope(self::SCOPE_READ);
|
||||
|
||||
// @todo Possibly use the message from the pageheader addon for this
|
||||
System::jsonExit([]);
|
||||
|
|
|
|||
|
|
@ -50,7 +50,7 @@ class Apps extends BaseApi
|
|||
if (!empty($postdata)) {
|
||||
$postrequest = json_decode($postdata, true);
|
||||
if (!empty($postrequest) && is_array($postrequest)) {
|
||||
$request = array_merge($request, $$postrequest);
|
||||
$request = array_merge($request, $postrequest);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -80,6 +80,6 @@ class Apps extends BaseApi
|
|||
DI::mstdnError()->InternalError();
|
||||
}
|
||||
|
||||
System::jsonExit(DI::mstdnApplication()->createFromApplicationId(DBA::lastInsertId()));
|
||||
System::jsonExit(DI::mstdnApplication()->createFromApplicationId(DBA::lastInsertId())->toArray());
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -32,13 +32,13 @@ class VerifyCredentials extends BaseApi
|
|||
{
|
||||
public static function rawContent(array $parameters = [])
|
||||
{
|
||||
self::login(self::SCOPE_READ);
|
||||
self::checkAllowedScope(self::SCOPE_READ);
|
||||
$application = self::getCurrentApplication();
|
||||
|
||||
if (empty($application['id'])) {
|
||||
DI::mstdnError()->Unauthorized();
|
||||
}
|
||||
|
||||
System::jsonExit($application['id']);
|
||||
System::jsonExit(DI::mstdnApplication()->createFromApplicationId($application['id']));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -37,7 +37,7 @@ class Blocks extends BaseApi
|
|||
*/
|
||||
public static function rawContent(array $parameters = [])
|
||||
{
|
||||
self::login(self::SCOPE_READ);
|
||||
self::checkAllowedScope(self::SCOPE_READ);
|
||||
$uid = self::getCurrentUserID();
|
||||
|
||||
if (empty($parameters['id'])) {
|
||||
|
|
@ -77,6 +77,7 @@ class Blocks extends BaseApi
|
|||
|
||||
$followers = DBA::select('user-contact', ['cid'], $condition, $parameters);
|
||||
while ($follower = DBA::fetch($followers)) {
|
||||
self::setBoundaries($follower['cid']);
|
||||
$accounts[] = DI::mstdnAccount()->createFromContactId($follower['cid'], $uid);
|
||||
}
|
||||
DBA::close($followers);
|
||||
|
|
@ -85,6 +86,7 @@ class Blocks extends BaseApi
|
|||
array_reverse($accounts);
|
||||
}
|
||||
|
||||
self::setLinkHeader();
|
||||
System::jsonExit($accounts);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -39,7 +39,7 @@ class Bookmarks extends BaseApi
|
|||
*/
|
||||
public static function rawContent(array $parameters = [])
|
||||
{
|
||||
self::login(self::SCOPE_READ);
|
||||
self::checkAllowedScope(self::SCOPE_READ);
|
||||
$uid = self::getCurrentUserID();
|
||||
|
||||
$request = self::getRequest([
|
||||
|
|
@ -52,7 +52,7 @@ class Bookmarks extends BaseApi
|
|||
|
||||
$params = ['order' => ['uri-id' => true], 'limit' => $request['limit']];
|
||||
|
||||
$condition = ['pinned' => true, 'uid' => $uid];
|
||||
$condition = ['starred' => true, 'uid' => $uid];
|
||||
|
||||
if (!empty($request['max_id'])) {
|
||||
$condition = DBA::mergeConditions($condition, ["`uri-id` < ?", $request['max_id']]);
|
||||
|
|
@ -72,6 +72,7 @@ class Bookmarks extends BaseApi
|
|||
|
||||
$statuses = [];
|
||||
while ($item = Post::fetch($items)) {
|
||||
self::setBoundaries($item['uri-id']);
|
||||
$statuses[] = DI::mstdnStatus()->createFromUriId($item['uri-id'], $uid);
|
||||
}
|
||||
DBA::close($items);
|
||||
|
|
@ -80,6 +81,7 @@ class Bookmarks extends BaseApi
|
|||
array_reverse($statuses);
|
||||
}
|
||||
|
||||
self::setLinkHeader();
|
||||
System::jsonExit($statuses);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -29,11 +29,11 @@ use Friendica\Module\BaseApi;
|
|||
/**
|
||||
* @see https://docs.joinmastodon.org/methods/timelines/conversations/
|
||||
*/
|
||||
class Conversation extends BaseApi
|
||||
class Conversations extends BaseApi
|
||||
{
|
||||
public static function delete(array $parameters = [])
|
||||
{
|
||||
self::login(self::SCOPE_WRITE);
|
||||
self::checkAllowedScope(self::SCOPE_WRITE);
|
||||
$uid = self::getCurrentUserID();
|
||||
|
||||
if (!empty($parameters['id'])) {
|
||||
|
|
@ -52,7 +52,7 @@ class Conversation extends BaseApi
|
|||
*/
|
||||
public static function rawContent(array $parameters = [])
|
||||
{
|
||||
self::login(self::SCOPE_READ);
|
||||
self::checkAllowedScope(self::SCOPE_READ);
|
||||
$uid = self::getCurrentUserID();
|
||||
|
||||
$request = self::getRequest([
|
||||
|
|
@ -85,6 +85,7 @@ class Conversation extends BaseApi
|
|||
$conversations = [];
|
||||
|
||||
while ($conv = DBA::fetch($convs)) {
|
||||
self::setBoundaries($conv['id']);
|
||||
$conversations[] = DI::mstdnConversation()->CreateFromConvId($conv['id']);
|
||||
}
|
||||
|
||||
|
|
@ -94,6 +95,7 @@ class Conversation extends BaseApi
|
|||
array_reverse($conversations);
|
||||
}
|
||||
|
||||
self::setLinkHeader();
|
||||
System::jsonExit($conversations);
|
||||
}
|
||||
}
|
||||
|
|
@ -19,7 +19,7 @@
|
|||
*
|
||||
*/
|
||||
|
||||
namespace Friendica\Module\Api\Mastodon\Conversation;
|
||||
namespace Friendica\Module\Api\Mastodon\Conversations;
|
||||
|
||||
use Friendica\Core\System;
|
||||
use Friendica\Database\DBA;
|
||||
|
|
@ -33,7 +33,7 @@ class Read extends BaseApi
|
|||
{
|
||||
public static function post(array $parameters = [])
|
||||
{
|
||||
self::login(self::SCOPE_WRITE);
|
||||
self::checkAllowedScope(self::SCOPE_WRITE);
|
||||
$uid = self::getCurrentUserID();
|
||||
|
||||
if (!empty($parameters['id'])) {
|
||||
|
|
|
|||
|
|
@ -40,7 +40,7 @@ class Favourited extends BaseApi
|
|||
*/
|
||||
public static function rawContent(array $parameters = [])
|
||||
{
|
||||
self::login(self::SCOPE_READ);
|
||||
self::checkAllowedScope(self::SCOPE_READ);
|
||||
$uid = self::getCurrentUserID();
|
||||
|
||||
// @todo provide HTTP link header
|
||||
|
|
@ -70,6 +70,7 @@ class Favourited extends BaseApi
|
|||
|
||||
$statuses = [];
|
||||
while ($item = Post::fetch($items)) {
|
||||
self::setBoundaries($item['thr-parent-id']);
|
||||
$statuses[] = DI::mstdnStatus()->createFromUriId($item['thr-parent-id'], $uid);
|
||||
}
|
||||
DBA::close($items);
|
||||
|
|
@ -78,6 +79,7 @@ class Favourited extends BaseApi
|
|||
array_reverse($statuses);
|
||||
}
|
||||
|
||||
self::setLinkHeader();
|
||||
System::jsonExit($statuses);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -29,12 +29,21 @@ use Friendica\Module\BaseApi;
|
|||
*/
|
||||
class Filters extends BaseApi
|
||||
{
|
||||
public static function post(array $parameters = [])
|
||||
{
|
||||
self::checkAllowedScope(self::SCOPE_WRITE);
|
||||
|
||||
self::unsupported('post');
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $parameters
|
||||
* @throws \Friendica\Network\HTTPException\InternalServerErrorException
|
||||
*/
|
||||
public static function rawContent(array $parameters = [])
|
||||
{
|
||||
System::jsonError(404, ['error' => 'Record not found']);
|
||||
self::checkAllowedScope(self::SCOPE_READ);
|
||||
|
||||
System::jsonExit([]);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -45,7 +45,7 @@ class FollowRequests extends BaseApi
|
|||
*/
|
||||
public static function post(array $parameters = [])
|
||||
{
|
||||
self::login(self::SCOPE_FOLLOW);
|
||||
self::checkAllowedScope(self::SCOPE_FOLLOW);
|
||||
$uid = self::getCurrentUserID();
|
||||
|
||||
$introduction = DI::intro()->selectFirst(['id' => $parameters['id'], 'uid' => $uid]);
|
||||
|
|
@ -83,7 +83,7 @@ class FollowRequests extends BaseApi
|
|||
*/
|
||||
public static function rawContent(array $parameters = [])
|
||||
{
|
||||
self::login(self::SCOPE_READ);
|
||||
self::checkAllowedScope(self::SCOPE_READ);
|
||||
$uid = self::getCurrentUserID();
|
||||
|
||||
$request = self::getRequest([
|
||||
|
|
@ -92,8 +92,6 @@ class FollowRequests extends BaseApi
|
|||
'limit' => 40, // Maximum number of results to return. Defaults to 40. Paginate using the HTTP Link header.
|
||||
]);
|
||||
|
||||
$baseUrl = DI::baseUrl();
|
||||
|
||||
$introductions = DI::intro()->selectByBoundaries(
|
||||
['`uid` = ? AND NOT `ignore`', $uid],
|
||||
['order' => ['id' => 'DESC']],
|
||||
|
|
@ -106,6 +104,7 @@ class FollowRequests extends BaseApi
|
|||
|
||||
foreach ($introductions as $key => $introduction) {
|
||||
try {
|
||||
self::setBoundaries($introduction->id);
|
||||
$return[] = DI::mstdnFollowRequest()->createFromIntroduction($introduction);
|
||||
} catch (HTTPException\InternalServerErrorException $exception) {
|
||||
DI::intro()->delete($introduction);
|
||||
|
|
@ -113,22 +112,7 @@ class FollowRequests extends BaseApi
|
|||
}
|
||||
}
|
||||
|
||||
$base_query = [];
|
||||
if (isset($_GET['limit'])) {
|
||||
$base_query['limit'] = $request['limit'];
|
||||
}
|
||||
|
||||
$links = [];
|
||||
if ($introductions->getTotalCount() > $request['limit']) {
|
||||
$links[] = '<' . $baseUrl->get() . '/api/v1/follow_requests?' . http_build_query($base_query + ['max_id' => $introductions[count($introductions) - 1]->id]) . '>; rel="next"';
|
||||
}
|
||||
|
||||
if (count($introductions)) {
|
||||
$links[] = '<' . $baseUrl->get() . '/api/v1/follow_requests?' . http_build_query($base_query + ['min_id' => $introductions[0]->id]) . '>; rel="prev"';
|
||||
}
|
||||
|
||||
header('Link: ' . implode(', ', $links));
|
||||
|
||||
self::setLinkHeader();
|
||||
System::jsonExit($return);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
59
src/Module/Api/Mastodon/Instance/Rules.php
Normal file
59
src/Module/Api/Mastodon/Instance/Rules.php
Normal file
|
|
@ -0,0 +1,59 @@
|
|||
<?php
|
||||
/**
|
||||
* @copyright Copyright (C) 2010-2021, the Friendica project
|
||||
*
|
||||
* @license GNU AGPL version 3 or any later version
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
namespace Friendica\Module\Api\Mastodon\Instance;
|
||||
|
||||
use Friendica\Content\Text\BBCode;
|
||||
use Friendica\Content\Text\HTML;
|
||||
use Friendica\Core\System;
|
||||
use Friendica\DI;
|
||||
use Friendica\Module\BaseApi;
|
||||
use Friendica\Network\HTTPException;
|
||||
|
||||
/**
|
||||
* Undocumented API endpoint
|
||||
*/
|
||||
class Rules extends BaseApi
|
||||
{
|
||||
/**
|
||||
* @param array $parameters
|
||||
* @throws HTTPException\InternalServerErrorException
|
||||
*/
|
||||
public static function rawContent(array $parameters = [])
|
||||
{
|
||||
$rules = [];
|
||||
$id = 0;
|
||||
|
||||
if (DI::config()->get('system', 'tosdisplay')) {
|
||||
$html = BBCode::convert(DI::config()->get('system', 'tostext'), false, BBCode::EXTERNAL);
|
||||
|
||||
$msg = HTML::toPlaintext($html, 0, true);
|
||||
foreach (explode("\n", $msg) as $line) {
|
||||
$line = trim($line);
|
||||
if ($line) {
|
||||
$rules[] = ['id' => (string)++$id, 'text' => $line];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
System::jsonExit($rules);
|
||||
}
|
||||
}
|
||||
|
|
@ -33,8 +33,7 @@ class Lists extends BaseApi
|
|||
{
|
||||
public static function delete(array $parameters = [])
|
||||
{
|
||||
self::login(self::SCOPE_WRITE);
|
||||
|
||||
self::checkAllowedScope(self::SCOPE_WRITE);
|
||||
$uid = self::getCurrentUserID();
|
||||
|
||||
if (empty($parameters['id'])) {
|
||||
|
|
@ -54,9 +53,8 @@ class Lists extends BaseApi
|
|||
|
||||
public static function post(array $parameters = [])
|
||||
{
|
||||
self::login(self::SCOPE_WRITE);
|
||||
|
||||
$uid = self::getCurrentUserID();
|
||||
self::checkAllowedScope(self::SCOPE_WRITE);
|
||||
$uid = self::getCurrentUserID();
|
||||
|
||||
$request = self::getRequest([
|
||||
'title' => '',
|
||||
|
|
@ -78,13 +76,16 @@ class Lists extends BaseApi
|
|||
|
||||
public static function put(array $parameters = [])
|
||||
{
|
||||
$data = self::getPutData();
|
||||
$request = self::getRequest([
|
||||
'title' => '', // The title of the list to be updated.
|
||||
'replies_policy' => '', // One of: "followed", "list", or "none".
|
||||
]);
|
||||
|
||||
if (empty($data['title']) || empty($parameters['id'])) {
|
||||
if (empty($request['title']) || empty($parameters['id'])) {
|
||||
DI::mstdnError()->UnprocessableEntity();
|
||||
}
|
||||
|
||||
Group::update($parameters['id'], $data['title']);
|
||||
Group::update($parameters['id'], $request['title']);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -93,7 +94,7 @@ class Lists extends BaseApi
|
|||
*/
|
||||
public static function rawContent(array $parameters = [])
|
||||
{
|
||||
self::login(self::SCOPE_READ);
|
||||
self::checkAllowedScope(self::SCOPE_READ);
|
||||
$uid = self::getCurrentUserID();
|
||||
|
||||
if (empty($parameters['id'])) {
|
||||
|
|
|
|||
|
|
@ -49,7 +49,7 @@ class Accounts extends BaseApi
|
|||
*/
|
||||
public static function rawContent(array $parameters = [])
|
||||
{
|
||||
self::login(self::SCOPE_READ);
|
||||
self::checkAllowedScope(self::SCOPE_READ);
|
||||
$uid = self::getCurrentUserID();
|
||||
|
||||
if (empty($parameters['id'])) {
|
||||
|
|
@ -95,6 +95,7 @@ class Accounts extends BaseApi
|
|||
|
||||
$members = DBA::select('group_member', ['contact-id'], $condition, $params);
|
||||
while ($member = DBA::fetch($members)) {
|
||||
self::setBoundaries($member['contact-id']);
|
||||
$accounts[] = DI::mstdnAccount()->createFromContactId($member['contact-id'], $uid);
|
||||
}
|
||||
DBA::close($members);
|
||||
|
|
@ -103,6 +104,7 @@ class Accounts extends BaseApi
|
|||
array_reverse($accounts);
|
||||
}
|
||||
|
||||
self::setLinkHeader();
|
||||
System::jsonExit($accounts);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue