Merge remote-tracking branch 'upstream/develop' into http-417
This commit is contained in:
commit
36ba7fa79c
14
.codecov.yml
14
.codecov.yml
|
@ -1,10 +1,14 @@
|
|||
codecov:
|
||||
branch: develop
|
||||
ci:
|
||||
- drone.friendi.ca
|
||||
|
||||
coverage:
|
||||
precision: 2
|
||||
round: down
|
||||
range: "70...100"
|
||||
status:
|
||||
project:
|
||||
default:
|
||||
target: auto
|
||||
threshold: null
|
||||
base: auto
|
||||
project: off
|
||||
patch: off
|
||||
|
||||
comment: off
|
||||
|
|
439
.drone.yml
Normal file
439
.drone.yml
Normal file
|
@ -0,0 +1,439 @@
|
|||
kind: pipeline
|
||||
name: mysql8.0-php7.1
|
||||
|
||||
steps:
|
||||
- name: mysql8.0-php7.1
|
||||
image: friendicaci/php7.1:php7.1.32
|
||||
commands:
|
||||
- NOCOVERAGE=true ./autotest.sh mysql
|
||||
environment:
|
||||
MYSQL_USERNAME: friendica
|
||||
MYSQL_PASSWORD: friendica
|
||||
MYSQL_DATABASE: friendica
|
||||
MYSQL_HOST: mysql
|
||||
|
||||
services:
|
||||
- name: mysql
|
||||
image: mysql:8.0
|
||||
command: [ "--default-authentication-plugin=mysql_native_password" ]
|
||||
environment:
|
||||
MYSQL_ROOT_PASSWORD: friendica
|
||||
MYSQL_USER: friendica
|
||||
MYSQL_PASSWORD: friendica
|
||||
MYSQL_DATABASE: friendica
|
||||
volumes:
|
||||
- name: cache
|
||||
path: /var/lib/mysql
|
||||
|
||||
volumes:
|
||||
- name: cache
|
||||
temp: {}
|
||||
|
||||
trigger:
|
||||
branch:
|
||||
- master
|
||||
- develop
|
||||
- "*-rc"
|
||||
event:
|
||||
- pull_request
|
||||
- push
|
||||
---
|
||||
kind: pipeline
|
||||
name: mysql8.0-php7.2
|
||||
|
||||
steps:
|
||||
- name: mysql8.0-php7.2
|
||||
image: friendicaci/php7.2:php7.2.22
|
||||
commands:
|
||||
- NOCOVERAGE=true ./autotest.sh mysql
|
||||
environment:
|
||||
MYSQL_USERNAME: friendica
|
||||
MYSQL_PASSWORD: friendica
|
||||
MYSQL_DATABASE: friendica
|
||||
MYSQL_HOST: mysql
|
||||
|
||||
services:
|
||||
- name: mysql
|
||||
image: mysql:8.0
|
||||
command: [ "--default-authentication-plugin=mysql_native_password" ]
|
||||
environment:
|
||||
MYSQL_ROOT_PASSWORD: friendica
|
||||
MYSQL_USER: friendica
|
||||
MYSQL_PASSWORD: friendica
|
||||
MYSQL_DATABASE: friendica
|
||||
volumes:
|
||||
- name: cache
|
||||
path: /var/lib/mysql
|
||||
|
||||
volumes:
|
||||
- name: cache
|
||||
temp: {}
|
||||
|
||||
trigger:
|
||||
branch:
|
||||
- master
|
||||
- develop
|
||||
- "*-rc"
|
||||
event:
|
||||
- pull_request
|
||||
- push
|
||||
---
|
||||
kind: pipeline
|
||||
name: mysql8.0-php7.3
|
||||
|
||||
steps:
|
||||
- name: mysql8.0-php7.3
|
||||
image: friendicaci/php7.3:php7.3.9
|
||||
commands:
|
||||
- NOCOVERAGE=true ./autotest.sh mysql
|
||||
environment:
|
||||
MYSQL_USERNAME: friendica
|
||||
MYSQL_PASSWORD: friendica
|
||||
MYSQL_DATABASE: friendica
|
||||
MYSQL_HOST: mysql
|
||||
|
||||
services:
|
||||
- name: mysql
|
||||
image: mysql:8.0
|
||||
command: [ "--default-authentication-plugin=mysql_native_password" ]
|
||||
environment:
|
||||
MYSQL_ROOT_PASSWORD: friendica
|
||||
MYSQL_USER: friendica
|
||||
MYSQL_PASSWORD: friendica
|
||||
MYSQL_DATABASE: friendica
|
||||
volumes:
|
||||
- name: cache
|
||||
path: /var/lib/mysql
|
||||
|
||||
volumes:
|
||||
- name: cache
|
||||
temp: {}
|
||||
|
||||
trigger:
|
||||
branch:
|
||||
- master
|
||||
- develop
|
||||
- "*-rc"
|
||||
event:
|
||||
- pull_request
|
||||
- push
|
||||
---
|
||||
kind: pipeline
|
||||
name: mariadb10.1-php7.1
|
||||
|
||||
steps:
|
||||
- name: mariadb10.1-php7.1
|
||||
image: friendicaci/php7.1:php7.1.32
|
||||
commands:
|
||||
- phpenmod xdebug
|
||||
- sleep 20
|
||||
- ./autotest.sh mariadb
|
||||
- wget https://codecov.io/bash -O codecov.sh
|
||||
- sh -c "if [ '$DRONE_BUILD_EVENT' = 'pull_request' ]; then bash codecov.sh -B $DRONE_BRANCH -C $DRONE_COMMIT -P $DRONE_PULL_REQUEST -t 5ce7d64e-07b4-4adf-8700-e2eae27e14ec -f tests/autotest-clover.xml; fi"
|
||||
- sh -c "if [ '$DRONE_BUILD_EVENT' != 'pull_request' ]; then bash codecov.sh -B $DRONE_BRANCH -C $DRONE_COMMIT -t 5ce7d64e-07b4-4adf-8700-e2eae27e14ec -f tests/autotest-clover.xml; fi"
|
||||
environment:
|
||||
MYSQL_USER: friendica
|
||||
MYSQL_PASSWORD: friendica
|
||||
MYSQL_DATABASE: friendica
|
||||
MYSQL_HOST: mariadb
|
||||
|
||||
services:
|
||||
- name: mariadb
|
||||
image: mariadb:10.1
|
||||
environment:
|
||||
MYSQL_ROOT_PASSWORD: friendica
|
||||
MYSQL_USER: friendica
|
||||
MYSQL_PASSWORD: friendica
|
||||
MYSQL_DATABASE: friendica
|
||||
volumes:
|
||||
- name: cache
|
||||
path: /var/lib/mysql
|
||||
|
||||
volumes:
|
||||
- name: cache
|
||||
temp: {}
|
||||
|
||||
trigger:
|
||||
branch:
|
||||
- master
|
||||
- develop
|
||||
- "*-rc"
|
||||
event:
|
||||
- pull_request
|
||||
- push
|
||||
---
|
||||
kind: pipeline
|
||||
name: mariadb10.1-php7.2
|
||||
|
||||
steps:
|
||||
- name: mariadb10.1-php7.2
|
||||
image: friendicaci/php7.2:php7.2.22
|
||||
commands:
|
||||
- NOCOVERAGE=true ./autotest.sh mariadb
|
||||
environment:
|
||||
MYSQL_USER: friendica
|
||||
MYSQL_PASSWORD: friendica
|
||||
MYSQL_DATABASE: friendica
|
||||
MYSQL_HOST: mariadb
|
||||
|
||||
services:
|
||||
- name: mariadb
|
||||
image: mariadb:10.1
|
||||
environment:
|
||||
MYSQL_ROOT_PASSWORD: friendica
|
||||
MYSQL_USER: friendica
|
||||
MYSQL_PASSWORD: friendica
|
||||
MYSQL_DATABASE: friendica
|
||||
volumes:
|
||||
- name: cache
|
||||
path: /var/lib/mysql
|
||||
|
||||
volumes:
|
||||
- name: cache
|
||||
temp: {}
|
||||
|
||||
trigger:
|
||||
branch:
|
||||
- master
|
||||
- develop
|
||||
- "*-rc"
|
||||
event:
|
||||
- pull_request
|
||||
- push
|
||||
---
|
||||
kind: pipeline
|
||||
name: mariadb10.1-php7.3
|
||||
|
||||
steps:
|
||||
- name: mariadb10.1-php7.3
|
||||
image: friendicaci/php7.3:php7.3.9
|
||||
commands:
|
||||
- NOCOVERAGE=true ./autotest.sh mariadb
|
||||
environment:
|
||||
MYSQL_USER: friendica
|
||||
MYSQL_PASSWORD: friendica
|
||||
MYSQL_DATABASE: friendica
|
||||
MYSQL_HOST: mariadb
|
||||
|
||||
services:
|
||||
- name: mariadb
|
||||
image: mariadb:10.1
|
||||
environment:
|
||||
MYSQL_ROOT_PASSWORD: friendica
|
||||
MYSQL_USER: friendica
|
||||
MYSQL_PASSWORD: friendica
|
||||
MYSQL_DATABASE: friendica
|
||||
volumes:
|
||||
- name: cache
|
||||
path: /var/lib/mysql
|
||||
|
||||
volumes:
|
||||
- name: cache
|
||||
temp: {}
|
||||
|
||||
---
|
||||
kind: pipeline
|
||||
name: redis-php7.1
|
||||
|
||||
steps:
|
||||
- name: redis-php7.1
|
||||
image: friendicaci/php7.1:php7.1.32
|
||||
commands:
|
||||
- phpenmod xdebug
|
||||
- sleep 20
|
||||
- NOINSTALL=true TEST_SELECTION=REDIS ./autotest.sh mysql
|
||||
- wget https://codecov.io/bash -O codecov.sh
|
||||
- sh -c "if [ '$DRONE_BUILD_EVENT' = 'pull_request' ]; then bash codecov.sh -B $DRONE_BRANCH -C $DRONE_COMMIT -P $DRONE_PULL_REQUEST -t 5ce7d64e-07b4-4adf-8700-e2eae27e14ec -f tests/autotest-clover.xml; fi"
|
||||
- sh -c "if [ '$DRONE_BUILD_EVENT' != 'pull_request' ]; then bash codecov.sh -B $DRONE_BRANCH -C $DRONE_COMMIT -t 5ce7d64e-07b4-4adf-8700-e2eae27e14ec -f tests/autotest-clover.xml; fi"
|
||||
environment:
|
||||
REDIS_HOST: redis
|
||||
|
||||
services:
|
||||
- name: redis
|
||||
image: redis
|
||||
|
||||
trigger:
|
||||
branch:
|
||||
- master
|
||||
- develop
|
||||
- "*-rc"
|
||||
event:
|
||||
- pull_request
|
||||
- push
|
||||
---
|
||||
kind: pipeline
|
||||
name: redis-php7.2
|
||||
|
||||
steps:
|
||||
- name: redis-php7.2
|
||||
image: friendicaci/php7.2:php7.2.22
|
||||
commands:
|
||||
- NOCOVERAGE=true NOINSTALL=true TEST_SELECTION=REDIS ./autotest.sh mysql
|
||||
environment:
|
||||
REDIS_HOST: redis
|
||||
|
||||
services:
|
||||
- name: redis
|
||||
image: redis
|
||||
|
||||
trigger:
|
||||
branch:
|
||||
- master
|
||||
- develop
|
||||
- "*-rc"
|
||||
event:
|
||||
- pull_request
|
||||
- push
|
||||
---
|
||||
kind: pipeline
|
||||
name: redis-php7.3
|
||||
|
||||
steps:
|
||||
- name: redis-php7.3
|
||||
image: friendicaci/php7.3:php7.3.9
|
||||
commands:
|
||||
- NOCOVERAGE=true NOINSTALL=true TEST_SELECTION=REDIS ./autotest.sh mysql
|
||||
environment:
|
||||
REDIS_HOST: redis
|
||||
|
||||
services:
|
||||
- name: redis
|
||||
image: redis
|
||||
|
||||
---
|
||||
kind: pipeline
|
||||
name: memcache-php7.1
|
||||
|
||||
steps:
|
||||
- name: memcache-php7.1
|
||||
image: friendicaci/php7.1:php7.1.32
|
||||
commands:
|
||||
- phpenmod xdebug
|
||||
- sleep 20
|
||||
- NOINSTALL=true TEST_SELECTION=MEMCACHE ./autotest.sh mysql
|
||||
- wget https://codecov.io/bash -O codecov.sh
|
||||
- sh -c "if [ '$DRONE_BUILD_EVENT' = 'pull_request' ]; then bash codecov.sh -B $DRONE_BRANCH -C $DRONE_COMMIT -P $DRONE_PULL_REQUEST -t 5ce7d64e-07b4-4adf-8700-e2eae27e14ec -f tests/autotest-clover.xml; fi"
|
||||
- sh -c "if [ '$DRONE_BUILD_EVENT' != 'pull_request' ]; then bash codecov.sh -B $DRONE_BRANCH -C $DRONE_COMMIT -t 5ce7d64e-07b4-4adf-8700-e2eae27e14ec -f tests/autotest-clover.xml; fi"
|
||||
environment:
|
||||
MEMCACHE_HOST: memcached
|
||||
|
||||
services:
|
||||
- name: memcached
|
||||
image: memcached
|
||||
|
||||
trigger:
|
||||
branch:
|
||||
- master
|
||||
- develop
|
||||
- "*-rc"
|
||||
event:
|
||||
- pull_request
|
||||
- push
|
||||
---
|
||||
kind: pipeline
|
||||
name: memcache-php7.2
|
||||
|
||||
steps:
|
||||
- name: memcache-php7.2
|
||||
image: friendicaci/php7.2:php7.2.22
|
||||
commands:
|
||||
- NOCOVERAGE=true NOINSTALL=true TEST_SELECTION=MEMCACHE ./autotest.sh mysql
|
||||
environment:
|
||||
MEMCACHE_HOST: memcached
|
||||
|
||||
services:
|
||||
- name: memcached
|
||||
image: memcached
|
||||
|
||||
trigger:
|
||||
branch:
|
||||
- master
|
||||
- develop
|
||||
- "*-rc"
|
||||
event:
|
||||
- pull_request
|
||||
- push
|
||||
---
|
||||
kind: pipeline
|
||||
name: memcache-php7.3
|
||||
|
||||
steps:
|
||||
- name: memcache-php7.3
|
||||
image: friendicaci/php7.3:php7.3.9
|
||||
commands:
|
||||
- NOCOVERAGE=true NOINSTALL=true TEST_SELECTION=MEMCACHE ./autotest.sh mysql
|
||||
environment:
|
||||
MEMCACHE_HOST: memcached
|
||||
|
||||
services:
|
||||
- name: memcached
|
||||
image: memcached
|
||||
|
||||
---
|
||||
kind: pipeline
|
||||
name: memcached-php7.1
|
||||
|
||||
steps:
|
||||
- name: memcached-php7.1
|
||||
image: friendicaci/php7.1:php7.1.32
|
||||
commands:
|
||||
- phpenmod xdebug
|
||||
- sleep 20
|
||||
- NOINSTALL=true TEST_SELECTION=MEMCACHED ./autotest.sh mysql
|
||||
- wget https://codecov.io/bash -O codecov.sh
|
||||
- sh -c "if [ '$DRONE_BUILD_EVENT' = 'pull_request' ]; then bash codecov.sh -B $DRONE_BRANCH -C $DRONE_COMMIT -P $DRONE_PULL_REQUEST -t 5ce7d64e-07b4-4adf-8700-e2eae27e14ec -f tests/autotest-clover.xml; fi"
|
||||
- sh -c "if [ '$DRONE_BUILD_EVENT' != 'pull_request' ]; then bash codecov.sh -B $DRONE_BRANCH -C $DRONE_COMMIT -t 5ce7d64e-07b4-4adf-8700-e2eae27e14ec -f tests/autotest-clover.xml; fi"
|
||||
environment:
|
||||
MEMCACHED_HOST: memcached
|
||||
|
||||
services:
|
||||
- name: memcached
|
||||
image: memcached
|
||||
|
||||
trigger:
|
||||
branch:
|
||||
- master
|
||||
- develop
|
||||
- "*-rc"
|
||||
event:
|
||||
- pull_request
|
||||
- push
|
||||
---
|
||||
kind: pipeline
|
||||
name: memcached-php7.2
|
||||
|
||||
steps:
|
||||
- name: memcached-php7.2
|
||||
image: friendicaci/php7.2:php7.2.22
|
||||
commands:
|
||||
- NOCOVERAGE=true NOINSTALL=true TEST_SELECTION=MEMCACHED ./autotest.sh mysql
|
||||
environment:
|
||||
MEMCACHED_HOST: memcached
|
||||
|
||||
services:
|
||||
- name: memcached
|
||||
image: memcached
|
||||
|
||||
trigger:
|
||||
branch:
|
||||
- master
|
||||
- develop
|
||||
- "*-rc"
|
||||
event:
|
||||
- pull_request
|
||||
- push
|
||||
---
|
||||
kind: pipeline
|
||||
name: memcached-php7.3
|
||||
|
||||
steps:
|
||||
- name: memcached-php7.3
|
||||
image: friendicaci/php7.3:php7.3.9
|
||||
commands:
|
||||
- NOCOVERAGE=true NOINSTALL=true TEST_SELECTION=MEMCACHED ./autotest.sh mysql
|
||||
environment:
|
||||
MEMCACHED_HOST: memcached
|
||||
|
||||
services:
|
||||
- name: memcached
|
||||
image: memcached
|
|
@ -26,4 +26,4 @@ before_script:
|
|||
- phpenv config-add .travis/redis.ini
|
||||
- phpenv config-add .travis/memcached.ini
|
||||
|
||||
after_success: bash <(curl -s https://codecov.io/bash)
|
||||
script: vendor/bin/phpunit --configuration tests/phpunit.xml
|
||||
|
|
66
CHANGELOG
66
CHANGELOG
|
@ -1,24 +1,44 @@
|
|||
Version 2019.09-dev (UNRELEASED)
|
||||
Version 2019.12-dev (unreleased)
|
||||
Friendica Core:
|
||||
Update to the translations (CS, DE, FR, JA, NL) [translation teams]
|
||||
Enhanced the manage functionality [annando]
|
||||
Fixed some problems with the remote auth functionality [annando]
|
||||
Added router configuration file [nupplaphil]
|
||||
Added drone.io as CI service [nupplaphil]
|
||||
|
||||
Friendica Addons:
|
||||
mailstream:
|
||||
Support for new img format was added [mexon]
|
||||
BB Code is now included as plaintext [mexon]
|
||||
Logging format is enhanced [mexon]
|
||||
ActivityPub "announce" notifications are not included [mexon]
|
||||
|
||||
Closed Issues:
|
||||
1071, 7548, 7657, 7681
|
||||
|
||||
Version 2019.09 (2019-09-29)
|
||||
Friendica Core:
|
||||
Update to the translations (CS, DE, EN GB, EN US, FR, JA, NL, PL) [translation teams]
|
||||
Update to the themes (frio, vier) [JeroenED, MrPetovan, tobiasd, vinzv]
|
||||
Update to the documentation [guzzisti, vinzv]
|
||||
Update to the documentation [annando, tobiasd, guzzisti, vinzv]
|
||||
Enhanced the log output of the background process [annando]
|
||||
Enhanced the vcard translation in the profile (JeroenED)
|
||||
Enhanced the vcard translation in the profile [JeroenED]
|
||||
Enhanced the delivery count [annando]
|
||||
Enhanced ActivityPub envelopes [MrPetovan]
|
||||
Enhanced communication about deleted accounts via AP [annando]
|
||||
Enhanced the following process [annando]
|
||||
Enhanced the tests [nupplaphil]
|
||||
Enhanced the frontend worker [annando]
|
||||
Enhanced the front-end worker [annando]
|
||||
Enhanced the img format to allow alternative texts [annando]
|
||||
Enhanced the detection of supported protocols for contacts [annando]
|
||||
Enhanced the reshare of items [annando]
|
||||
Enhanced the re-share of items [annando]
|
||||
Enhanced 2FA process [MrPetovan]
|
||||
Enhanced server wide theme settings [MrPetovan]
|
||||
Enhanced config loading process [MrPetovan, nupplaphil]
|
||||
Enhanced handling of emoticons [MrPetovan]
|
||||
Fixed a bug in the admin panel leading to orphand options [tobiasd]
|
||||
Enhanced performance [annando]
|
||||
Fixed a bug in the admin panel leading to orphaned options [tobiasd]
|
||||
Fixed a problem that could lead to duplicated Pleroma contacts [annando]
|
||||
Fixed a problem with the hide profile setting [annando]
|
||||
Fixed the problem sending out the post when hitting the enter key in the ACL dialog [MrPetovan]
|
||||
Fixed a bug in HTML special character escaping of event titles [MrPetovan]
|
||||
Fixed a bug in HTML special character conversion in item titles [MrPetovan]
|
||||
|
@ -26,7 +46,19 @@ Version 2019.09-dev (UNRELEASED)
|
|||
Fixed a bug that prevented the display of images in some postings from diaspora* [MrPetovan]
|
||||
Fixed a bug in setting the permissions on uploaded images [annando]
|
||||
Fixed a bug that lead to potentially unwanted importing threads started by contacts of contacts [annando]
|
||||
Fixed implicit self mentions [MrPetovan]
|
||||
Fixed display of register links on closed nodes landing pages [MrPetovan]
|
||||
Fixed the display of [spoiler] tags [MrPetovan]
|
||||
Fixed an issue with photo permissions in private mails [annando]
|
||||
Fixed a bug in the process of following Pleroma accounts [annando]
|
||||
Fixed a bug that caused notifications about locally deleted items [annando]
|
||||
Fixed the link to the source of an event [MrPetovan]
|
||||
Fixed a problem that caused authors from twitter postings having no profile pic [annando]
|
||||
Fixed a bug in BBCode -> Markdown conversation for font size [annando]
|
||||
Fixed a BBCode parser problem with the audio tag [MrPetovan]
|
||||
Fixed a session problem [annando]
|
||||
Fixed a problem with the auto-installer [nupplaphil]
|
||||
Fixed a bug with magic links redirection for non profiles [annando]
|
||||
General code cleaning [annando, MrPetovan, nupplaphil]
|
||||
Removed contacts auto completion (in /contacts [MrPetovan]
|
||||
Replaced FontAwesome by ForkAwesome in frio theme [vinzv]
|
||||
|
@ -37,19 +69,29 @@ Version 2019.09-dev (UNRELEASED)
|
|||
Added support of wildcards to server block lists [MrPetovan]
|
||||
Added app specific passwords when using 2FA [MrPetovan]
|
||||
Added fetching of postings via URL to interact with public postings [annando]
|
||||
Added opt-out flag for federated search engines and associated header information for profiles [annando]
|
||||
|
||||
Friendica Addons:
|
||||
Update to the translation (CS, DE, FR, JA, NL SV) [translation teams]
|
||||
Update to the translation (CS, DE, EN GB, EN US, ES, FR, JA, NL SV) [translation teams]
|
||||
General code cleanup [nupplaphil, Quix0r]
|
||||
blockbot:
|
||||
Added translations
|
||||
Added more bots [annando]
|
||||
Added admin panel settings [annando]
|
||||
tumblr:
|
||||
Changed used URLs to https adopting tumblrs change [annando]
|
||||
twitter:
|
||||
Enhanced handling of multi image postings [annando]
|
||||
Enhanced display of quoted tweets [MrPetovan]
|
||||
Added alternative text support for images [annando]
|
||||
|
||||
Closed Issues:
|
||||
3816, 4815, 6384, 6675, 7235, 7293, 7314, 7317, 7337, 7338, 7346,
|
||||
7350, 7367, 7383, 7396, 7397, 7401, 7406, 7408, 7426, 7428, 7456,
|
||||
7442, 7457, 7468, 7471, 7473, 7488, 7497, 7498, 7501, 7507, 7522,
|
||||
7527, 7536, 7542, 7545
|
||||
870, 1605, 2199, 3239, 3816, 4117, 4815, 5721, 6384, 6521, 6553,
|
||||
6675, 7212, 7235, 7285, 7293, 7314, 7317, 7337, 7338, 7346, 7350,
|
||||
7367, 7383, 7396, 7397, 7401, 7406, 7408, 7426, 7428, 7456, 7442,
|
||||
7457, 7468, 7471, 7473, 7488, 7497, 7498, 7501, 7507, 7521, 7526,
|
||||
7527, 7536, 7542, 7545, 7576, 7586, 7594, 7597, 7603, 7610, 7618,
|
||||
7629, 7635, 7638, 7663, 7665, 7672
|
||||
|
||||
Version 2019.06 (2019-06-23)
|
||||
Friendica Core:
|
||||
|
|
4
Vagrantfile
vendored
4
Vagrantfile
vendored
|
@ -6,8 +6,8 @@ server_timezone = "UTC"
|
|||
public_folder = "/vagrant"
|
||||
|
||||
Vagrant.configure(2) do |config|
|
||||
# Set server to Ubuntu 16.04
|
||||
config.vm.box = "ubuntu/xenial64"
|
||||
# Set server to Debian 10 / Buster 64bit
|
||||
config.vm.box = "debian/buster64"
|
||||
|
||||
# Disable automatic box update checking. If you disable this, then
|
||||
# boxes will only be checked for updates when the user runs
|
||||
|
|
279
autotest.sh
Executable file
279
autotest.sh
Executable file
|
@ -0,0 +1,279 @@
|
|||
#!/usr/bin/env bash
|
||||
#
|
||||
# This script is used for autotesting the Friendica codebase with different
|
||||
# types of tests and environments.
|
||||
#
|
||||
# Currently, there are three types of autotesting possibilities:
|
||||
# - "USEDOCKER=true ./autotest.sh" will start a database docker container for testing
|
||||
# - "./autotest.sh" on the Drone CI environment will use the database container of the drone CI pipeline
|
||||
# - "./autotest.sh" on a local environment will try to use the local database instance for testing
|
||||
#
|
||||
# You can specify a database (mysql, mariadb currently) for the db backend of Friendica ("./autotest.sh mysql")
|
||||
# And you can specify some parameters for the test, like:
|
||||
# - NOCOVERAGE=true ... Don't create a coverage XML (this is only useful if you will send coverage to codecov.io)
|
||||
# - NOINSTALL=true ... Skip the whole Friendica installation process (e.g. you just test Caching drivers)
|
||||
# - TEST_SELECTION= ... Specify which tests are used to run (based on the test-labeling)
|
||||
# - XDEBUG_CONFIG= ... Set some XDEBUG specific environment settings for development
|
||||
|
||||
DATABASENAME=${MYSQL_DATABASE:-test}
|
||||
DATABASEUSER=${MYSQL_USERNAME:-friendica}
|
||||
DATABASEHOST=${MYSQL_HOST:-localhost}
|
||||
BASEDIR=$PWD
|
||||
|
||||
DBCONFIGS="mysql mariadb"
|
||||
TESTS="REDIS MEMCACHE MEMCACHED APCU NODB"
|
||||
|
||||
export MYSQL_DATABASE="$DATABASENAME"
|
||||
export MYSQL_USERNAME="$DATABASEUSER"
|
||||
export MYSQL_PASSWORD="friendica"
|
||||
|
||||
if [ -z "$PHP_EXE" ]; then
|
||||
PHP_EXE=php
|
||||
fi
|
||||
PHP=$(which "$PHP_EXE")
|
||||
# Use the Friendica internal composer
|
||||
COMPOSER="$BASEDIR/bin/composer.phar"
|
||||
|
||||
set -e
|
||||
|
||||
_XDEBUG_CONFIG=$XDEBUG_CONFIG
|
||||
unset XDEBUG_CONFIG
|
||||
|
||||
function show_syntax() {
|
||||
echo -e "Syntax: ./autotest.sh [dbconfigname] [testfile]\n" >&2
|
||||
echo -e "\t\"dbconfigname\" can be one of: $DBCONFIGS" >&2
|
||||
echo -e "\t\"testfile\" is the name of a test file, for example lib/template.php" >&2
|
||||
echo -e "\nDatabase environment variables:\n" >&2
|
||||
echo -e "\t\"MYSQL_HOST\" Mysql Hostname (Default: localhost)" >&2
|
||||
echo -e "\t\"MYSQL_USDRNAME\" Mysql Username (Default: friendica)" >&2
|
||||
echo -e "\t\"MYSQL_DATABASE\" Mysql Database (Default: test)" >&2
|
||||
echo -e "\nOther environment variables:\n" >&2
|
||||
echo -e "\t\"TEST_SELECTION\" test a specific group of tests, can be one of: $TESTS" >&2
|
||||
echo -e "\t\"NOINSTALL\" If set to true, skip the db and install process" >&2
|
||||
echo -e "\t\"NOCOVERAGE\" If set to true, don't create a coverage output" >&2
|
||||
echo -e "\t\"USEDOCKER\" If set to true, the DB server will be executed inside a docker container" >&2
|
||||
echo -e "\nExample: NOCOVERAGE=true ./autotest.sh mysql src/Core/Cache/MemcacheTest.php" >&2
|
||||
echo "will run the test suite from \"tests/src/Core/Cache/MemcacheTest.php\" without a Coverage" >&2
|
||||
echo -e "\nIf no arguments are specified, all tests will be run with all database configs" >&2
|
||||
}
|
||||
|
||||
if [ -x "$PHP" ]; then
|
||||
echo "Using PHP executable $PHP"
|
||||
else
|
||||
echo "Could not find PHP executable $PHP_EXE" >&2
|
||||
exit 3
|
||||
fi
|
||||
|
||||
echo "Installing depdendencies"
|
||||
$PHP "$COMPOSER" install
|
||||
|
||||
PHPUNIT="$BASEDIR/vendor/bin/phpunit"
|
||||
|
||||
if [ -x "$PHPUNIT" ]; then
|
||||
echo "Using PHPUnit executable $PHPUNIT"
|
||||
else
|
||||
echo "Could not find PHPUnit executable after composer $PHPUNIT" >&2
|
||||
exit 3
|
||||
fi
|
||||
|
||||
if ! [ \( -w config -a ! -f config/local.config.php \) -o \( -f config/local.config.php -a -w config/local.config.php \) ]; then
|
||||
echo "Please enable write permissions on config and config/config.php" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ "$1" ]; then
|
||||
FOUND=0
|
||||
for DBCONFIG in $DBCONFIGS; do
|
||||
if [ "$1" = "$DBCONFIG" ]; then
|
||||
FOUND=1
|
||||
break
|
||||
fi
|
||||
done
|
||||
if [ $FOUND = 0 ]; then
|
||||
echo -e "Unknown database config name \"$1\"\n" >&2
|
||||
show_syntax
|
||||
exit 2
|
||||
fi
|
||||
fi
|
||||
|
||||
# Back up existing (dev) config if one exists and backup not already there
|
||||
if [ -f config/local.config.php ] && [ ! -f config/local.config-autotest-backup.php ]; then
|
||||
mv config/local.config.php config/local.config-autotest-backup.php
|
||||
fi
|
||||
|
||||
function cleanup_config() {
|
||||
|
||||
if [ -n "$DOCKER_CONTAINER_ID" ]; then
|
||||
echo "Kill the docker $DOCKER_CONTAINER_ID"
|
||||
docker stop "$DOCKER_CONTAINER_ID"
|
||||
docker rm -f "$DOCKER_CONTAINER_ID"
|
||||
fi
|
||||
|
||||
cd "$BASEDIR"
|
||||
|
||||
# Restore existing config
|
||||
if [ -f config/local.config-autotest-backup.php ]; then
|
||||
mv config/local.config-autotest-backup.php config/local.config.php
|
||||
fi
|
||||
}
|
||||
|
||||
# restore config on exit
|
||||
trap cleanup_config EXIT
|
||||
|
||||
function execute_tests() {
|
||||
DB=$1
|
||||
echo "Setup environment for $DB testing ..."
|
||||
# back to root folder
|
||||
cd "$BASEDIR"
|
||||
|
||||
# backup current config
|
||||
if [ -f config/local.config.php ]; then
|
||||
mv config/local.config.php config/local.config-autotest-backup.php
|
||||
fi
|
||||
|
||||
if [ -z "$NOINSTALL" ]; then
|
||||
#drop database
|
||||
if [ "$DB" == "mysql" ]; then
|
||||
if [ -n "$USEDOCKER" ]; then
|
||||
echo "Fire up the mysql docker"
|
||||
DOCKER_CONTAINER_ID=$(docker run \
|
||||
-e MYSQL_ROOT_PASSWORD=friendica \
|
||||
-e MYSQL_USER="$DATABASEUSER" \
|
||||
-e MYSQL_PASSWORD=friendica \
|
||||
-e MYSQL_DATABASE="$DATABASENAME" \
|
||||
-d mysql)
|
||||
DATABASEHOST=$(docker inspect --format="{{.NetworkSettings.IPAddress}}" "$DOCKER_CONTAINER_ID")
|
||||
|
||||
else
|
||||
if [ -z "$DRONE" ]; then # no need to drop the DB when we are on CI
|
||||
if [ "mysql" != "$(mysql --version | grep -o mysql)" ]; then
|
||||
echo "Your mysql binary is not provided by mysql"
|
||||
echo "To use the docker container set the USEDOCKER environment variable"
|
||||
exit 3
|
||||
fi
|
||||
mysql -u "$DATABASEUSER" -pfriendica -e "DROP DATABASE IF EXISTS $DATABASENAME" -h $DATABASEHOST || true
|
||||
mysql -u "$DATABASEUSER" -pfriendica -e "CREATE DATABASE $DATABASENAME DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci" -h $DATABASEHOST
|
||||
else
|
||||
DATABASEHOST=mysql
|
||||
fi
|
||||
fi
|
||||
|
||||
echo "Waiting for MySQL $DATABASEHOST initialization..."
|
||||
if ! bin/wait-for-connection $DATABASEHOST 3306 300; then
|
||||
echo "[ERROR] Waited 300 seconds, no response" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "MySQL is up."
|
||||
fi
|
||||
if [ "$DB" == "mariadb" ]; then
|
||||
if [ -n "$USEDOCKER" ]; then
|
||||
echo "Fire up the mariadb docker"
|
||||
DOCKER_CONTAINER_ID=$(docker run \
|
||||
-e MYSQL_ROOT_PASSWORD=friendica \
|
||||
-e MYSQL_USER="$DATABASEUSER" \
|
||||
-e MYSQL_PASSWORD=friendica \
|
||||
-e MYSQL_DATABASE="$DATABASENAME" \
|
||||
-d mariadb)
|
||||
DATABASEHOST=$(docker inspect --format="{{.NetworkSettings.IPAddress}}" "$DOCKER_CONTAINER_ID")
|
||||
|
||||
else
|
||||
if [ -z "$DRONE" ]; then # no need to drop the DB when we are on CI
|
||||
if [ "MariaDB" != "$(mysql --version | grep -o MariaDB)" ]; then
|
||||
echo "Your mysql binary is not provided by mysql"
|
||||
echo "To use the docker container set the USEDOCKER environment variable"
|
||||
exit 3
|
||||
fi
|
||||
mysql -u "$DATABASEUSER" -pfriendica -e "DROP DATABASE IF EXISTS $DATABASENAME" -h $DATABASEHOST || true
|
||||
mysql -u "$DATABASEUSER" -pfriendica -e "CREATE DATABASE $DATABASENAME DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci" -h $DATABASEHOST
|
||||
else
|
||||
DATABASEHOST=mariadb
|
||||
fi
|
||||
fi
|
||||
|
||||
echo "Waiting for MariaDB $DATABASEHOST initialization..."
|
||||
if ! bin/wait-for-connection $DATABASEHOST 3306 300; then
|
||||
echo "[ERROR] Waited 300 seconds, no response" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "MariaDB is up."
|
||||
fi
|
||||
|
||||
if [ -n "$USEDOCKER" ]; then
|
||||
echo "Initialize database..."
|
||||
docker exec $DOCKER_CONTAINER_ID mysql -u root -pfriendica -e 'CREATE DATABASE IF NOT EXISTS $DATABASENAME;'
|
||||
fi
|
||||
|
||||
export MYSQL_HOST="$DATABASEHOST"
|
||||
|
||||
#call installer
|
||||
echo "Installing Friendica..."
|
||||
"$PHP" ./bin/console.php autoinstall --dbuser="$DATABASEUSER" --dbpass=friendica --dbdata="$DATABASENAME" --dbhost="$DATABASEHOST" --url=https://friendica.local --admin=admin@friendica.local
|
||||
fi
|
||||
|
||||
#test execution
|
||||
echo "Testing..."
|
||||
rm -fr "coverage-html"
|
||||
mkdir "coverage-html"
|
||||
if [[ "$_XDEBUG_CONFIG" ]]; then
|
||||
export XDEBUG_CONFIG=$_XDEBUG_CONFIG
|
||||
fi
|
||||
|
||||
COVER=''
|
||||
if [ -z "$NOCOVERAGE" ]; then
|
||||
COVER="--coverage-clover tests/autotest-clover.xml"
|
||||
else
|
||||
echo "No coverage"
|
||||
fi
|
||||
|
||||
# per default, there is no cache installed
|
||||
GROUP='--exclude-group REDIS,MEMCACHE,MEMCACHED,APCU'
|
||||
if [ "$TEST_SELECTION" == "REDIS" ]; then
|
||||
GROUP="--group REDIS"
|
||||
fi
|
||||
if [ "$TEST_SELECTION" == "MEMCACHE" ]; then
|
||||
GROUP="--group MEMCACHE"
|
||||
fi
|
||||
if [ "$TEST_SELECTION" == "MEMCACHED" ]; then
|
||||
GROUP="--group MEMCACHED"
|
||||
fi
|
||||
if [ "$TEST_SELECTION" == "APCU" ]; then
|
||||
GROUP="--group APCU"
|
||||
fi
|
||||
if [ "$TEST_SELECTION" == "NODB" ]; then
|
||||
GROUP="--exclude-group DB,SLOWDB"
|
||||
fi
|
||||
|
||||
INPUT="$BASEDIR/tests"
|
||||
if [ -n "$2" ]; then
|
||||
INPUT="$INPUT/$2"
|
||||
fi
|
||||
|
||||
echo "${PHPUNIT[@]}" --configuration tests/phpunit.xml $GROUP $COVER --log-junit "autotest-results.xml" "$INPUT" "$3"
|
||||
"${PHPUNIT[@]}" --configuration tests/phpunit.xml $GROUP $COVER --log-junit "autotest-results.xml" "$INPUT" "$3"
|
||||
RESULT=$?
|
||||
|
||||
if [ -n "$DOCKER_CONTAINER_ID" ]; then
|
||||
echo "Kill the docker $DOCKER_CONTAINER_ID"
|
||||
docker stop $DOCKER_CONTAINER_ID
|
||||
docker rm -f $DOCKER_CONTAINER_ID
|
||||
unset $DOCKER_CONTAINER_ID
|
||||
fi
|
||||
}
|
||||
|
||||
#
|
||||
# Start the test execution
|
||||
#
|
||||
if [ -z "$1" ] && [ -n "$TEST_SELECTION" ]; then
|
||||
# run all known database configs
|
||||
for DBCONFIG in $DBCONFIGS; do
|
||||
execute_tests "$DBCONFIG"
|
||||
done
|
||||
else
|
||||
FILENAME="$2"
|
||||
if [ -n "$2" ] && [ ! -f "tests/$FILENAME" ] && [ "${FILENAME:0:2}" != "--" ]; then
|
||||
FILENAME="../$FILENAME"
|
||||
fi
|
||||
execute_tests "$1" "$FILENAME" "$3"
|
||||
fi
|
|
@ -36,6 +36,7 @@ use Dice\Dice;
|
|||
use Friendica\App\Mode;
|
||||
use Friendica\BaseObject;
|
||||
use Friendica\Util\ExAuth;
|
||||
use Psr\Log\LoggerInterface;
|
||||
|
||||
if (sizeof($_SERVER["argv"]) == 0) {
|
||||
die();
|
||||
|
@ -54,6 +55,8 @@ chdir($directory);
|
|||
require dirname(__DIR__) . '/vendor/autoload.php';
|
||||
|
||||
$dice = (new Dice())->addRules(include __DIR__ . '/../static/dependencies.config.php');
|
||||
$dice = $dice->addRule(LoggerInterface::class,['constructParams' => ['auth_ejabberd']]);
|
||||
|
||||
BaseObject::setDependencyInjection($dice);
|
||||
|
||||
$appMode = $dice->create(Mode::class);
|
||||
|
|
|
@ -2,9 +2,11 @@
|
|||
<?php
|
||||
|
||||
use Dice\Dice;
|
||||
use Psr\Log\LoggerInterface;
|
||||
|
||||
require dirname(__DIR__) . '/vendor/autoload.php';
|
||||
|
||||
$dice = (new Dice())->addRules(include __DIR__ . '/../static/dependencies.config.php');
|
||||
$dice = $dice->addRule(LoggerInterface::class,['constructParams' => ['console']]);
|
||||
|
||||
(new Friendica\Core\Console($dice, $argv))->execute();
|
||||
|
|
|
@ -12,6 +12,7 @@ use Friendica\Core\Config;
|
|||
use Friendica\Core\Logger;
|
||||
use Friendica\Core\Worker;
|
||||
use Friendica\Database\DBA;
|
||||
use Psr\Log\LoggerInterface;
|
||||
|
||||
// Get options
|
||||
$shortopts = 'f';
|
||||
|
@ -33,6 +34,7 @@ if (!file_exists("boot.php") && (sizeof($_SERVER["argv"]) != 0)) {
|
|||
require dirname(__DIR__) . '/vendor/autoload.php';
|
||||
|
||||
$dice = (new Dice())->addRules(include __DIR__ . '/../static/dependencies.config.php');
|
||||
$dice = $dice->addRule(LoggerInterface::class,['constructParams' => ['daemon']]);
|
||||
|
||||
\Friendica\BaseObject::setDependencyInjection($dice);
|
||||
$a = \Friendica\BaseObject::getApp();
|
||||
|
|
|
@ -37,9 +37,9 @@ 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
|
||||
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
|
||||
|
||||
#Install php
|
||||
echo ">>> Installing PHP7"
|
||||
|
@ -48,9 +48,9 @@ sudo systemctl restart apache2
|
|||
|
||||
#Install mysql
|
||||
echo ">>> Installing Mysql"
|
||||
sudo debconf-set-selections <<< "mysql-server mysql-server/root_password password root"
|
||||
sudo debconf-set-selections <<< "mysql-server mysql-server/root_password_again password root"
|
||||
sudo apt-get install -qq mysql-server
|
||||
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
|
||||
# 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
|
||||
|
@ -76,6 +76,9 @@ 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
|
||||
|
||||
# Friendica needs git for fetching some dependencies
|
||||
sudo apt-get install -y git
|
||||
|
||||
#make the vagrant directory the docroot
|
||||
sudo rm -rf /var/www/
|
||||
sudo ln -fs /vagrant /var/www
|
||||
|
@ -83,7 +86,7 @@ sudo ln -fs /vagrant /var/www
|
|||
# install deps with composer
|
||||
sudo apt install unzip
|
||||
cd /var/www
|
||||
php bin/composer.phar install
|
||||
sudo -u www-data php bin/composer.phar install
|
||||
|
||||
# initial config file for friendica in vagrant
|
||||
cp /vagrant/mods/local.config.vagrant.php /vagrant/config/local.config.php
|
||||
|
|
45
bin/wait-for-connection
Executable file
45
bin/wait-for-connection
Executable file
|
@ -0,0 +1,45 @@
|
|||
#!/usr/bin/php
|
||||
#
|
||||
# This script tries to connect to a database for a given interval
|
||||
# Useful in case of installation e.g. to wait for the database to not generate unnecessary errors
|
||||
#
|
||||
# Usage: php bin/wait-for-connection {HOST} {PORT} [{TIMEOUT}]
|
||||
|
||||
<?php
|
||||
$timeout = 60;
|
||||
switch ($argc) {
|
||||
case 4:
|
||||
$timeout = (float)$argv[3];
|
||||
case 3:
|
||||
$host = $argv[1];
|
||||
$port = (int)$argv[2];
|
||||
break;
|
||||
default:
|
||||
fwrite(STDERR, 'Usage: '.$argv[0].' host port [timeout]'."\n");
|
||||
exit(2);
|
||||
}
|
||||
if ($timeout < 0) {
|
||||
fwrite(STDERR, 'Timeout must be greater than zero'."\n");
|
||||
exit(2);
|
||||
}
|
||||
if ($port < 1) {
|
||||
fwrite(STDERR, 'Port must be an integer greater than zero'."\n");
|
||||
exit(2);
|
||||
}
|
||||
$socketTimeout = (float)ini_get('default_socket_timeout');
|
||||
if ($socketTimeout > $timeout) {
|
||||
$socketTimeout = $timeout;
|
||||
}
|
||||
$stopTime = time() + $timeout;
|
||||
do {
|
||||
$sock = @fsockopen($host, $port, $errno, $errstr, $socketTimeout);
|
||||
if ($sock !== false) {
|
||||
fclose($sock);
|
||||
fwrite(STDOUT, "\n");
|
||||
exit(0);
|
||||
}
|
||||
sleep(1);
|
||||
fwrite(STDOUT, '.');
|
||||
} while (time() < $stopTime);
|
||||
fwrite(STDOUT, "\n");
|
||||
exit(1);
|
|
@ -11,6 +11,7 @@ use Friendica\BaseObject;
|
|||
use Friendica\Core\Config;
|
||||
use Friendica\Core\Update;
|
||||
use Friendica\Core\Worker;
|
||||
use Psr\Log\LoggerInterface;
|
||||
|
||||
// Get options
|
||||
$shortopts = 'sn';
|
||||
|
@ -32,6 +33,7 @@ if (!file_exists("boot.php") && (sizeof($_SERVER["argv"]) != 0)) {
|
|||
require dirname(__DIR__) . '/vendor/autoload.php';
|
||||
|
||||
$dice = (new Dice())->addRules(include __DIR__ . '/../static/dependencies.config.php');
|
||||
$dice = $dice->addRule(LoggerInterface::class,['constructParams' => ['worker']]);
|
||||
|
||||
BaseObject::setDependencyInjection($dice);
|
||||
$a = BaseObject::getApp();
|
||||
|
|
58
boot.php
58
boot.php
|
@ -23,6 +23,7 @@ use Friendica\Core\Config;
|
|||
use Friendica\Core\PConfig;
|
||||
use Friendica\Core\Protocol;
|
||||
use Friendica\Core\System;
|
||||
use Friendica\Core\Session;
|
||||
use Friendica\Database\DBA;
|
||||
use Friendica\Model\Contact;
|
||||
use Friendica\Model\Term;
|
||||
|
@ -31,7 +32,7 @@ use Friendica\Util\DateTimeFormat;
|
|||
|
||||
define('FRIENDICA_PLATFORM', 'Friendica');
|
||||
define('FRIENDICA_CODENAME', 'Dalmatian Bellflower');
|
||||
define('FRIENDICA_VERSION', '2019.09-rc');
|
||||
define('FRIENDICA_VERSION', '2019.12-dev');
|
||||
define('DFRN_PROTOCOL_VERSION', '2.23');
|
||||
define('NEW_UPDATE_ROUTINE_VERSION', 1170);
|
||||
|
||||
|
@ -321,47 +322,6 @@ function get_app()
|
|||
return BaseObject::getApp();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the provided variable value if it exists and is truthy or the provided
|
||||
* default value instead.
|
||||
*
|
||||
* Works with initialized variables and potentially uninitialized array keys
|
||||
*
|
||||
* Usages:
|
||||
* - defaults($var, $default)
|
||||
* - defaults($array, 'key', $default)
|
||||
*
|
||||
* @param array $args
|
||||
* @brief Returns a defaut value if the provided variable or array key is falsy
|
||||
* @return mixed
|
||||
* @deprecated since version 2019.06, use native coalesce operator (??) instead
|
||||
*/
|
||||
function defaults(...$args)
|
||||
{
|
||||
if (count($args) < 2) {
|
||||
throw new BadFunctionCallException('defaults() requires at least 2 parameters');
|
||||
}
|
||||
if (count($args) > 3) {
|
||||
throw new BadFunctionCallException('defaults() cannot use more than 3 parameters');
|
||||
}
|
||||
if (count($args) === 3 && is_null($args[1])) {
|
||||
throw new BadFunctionCallException('defaults($arr, $key, $def) $key is null');
|
||||
}
|
||||
|
||||
// The default value always is the last argument
|
||||
$return = array_pop($args);
|
||||
|
||||
if (count($args) == 2 && is_array($args[0]) && !empty($args[0][$args[1]])) {
|
||||
$return = $args[0][$args[1]];
|
||||
}
|
||||
|
||||
if (count($args) == 1 && !empty($args[0])) {
|
||||
$return = $args[0];
|
||||
}
|
||||
|
||||
return $return;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Used to end the current process, after saving session state.
|
||||
* @deprecated
|
||||
|
@ -415,20 +375,14 @@ function public_contact()
|
|||
*/
|
||||
function remote_user()
|
||||
{
|
||||
// You cannot be both local and remote.
|
||||
// Unncommented by rabuzarus because remote authentication to local
|
||||
// profiles wasn't possible anymore (2018-04-12).
|
||||
// if (local_user()) {
|
||||
// return false;
|
||||
// }
|
||||
|
||||
if (empty($_SESSION)) {
|
||||
if (empty($_SESSION['authenticated'])) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!empty($_SESSION['authenticated']) && !empty($_SESSION['visitor_id'])) {
|
||||
if (!empty($_SESSION['visitor_id'])) {
|
||||
return intval($_SESSION['visitor_id']);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -532,7 +486,7 @@ function is_site_admin()
|
|||
|
||||
$adminlist = explode(',', str_replace(' ', '', $admin_email));
|
||||
|
||||
return local_user() && $admin_email && in_array(defaults($a->user, 'email', ''), $adminlist);
|
||||
return local_user() && $admin_email && in_array($a->user['email'] ?? '', $adminlist);
|
||||
}
|
||||
|
||||
function explode_querystring($query)
|
||||
|
|
564
composer.lock
generated
564
composer.lock
generated
File diff suppressed because it is too large
Load diff
|
@ -533,7 +533,7 @@ Here is a complete list of all hook callbacks with file locations (as of 24-Sep-
|
|||
|
||||
Hook::callAll("parse_link", $arr);
|
||||
|
||||
### mod/manage.php
|
||||
### src/Module/Delegation.php
|
||||
|
||||
Hook::callAll('home_init', $ret);
|
||||
|
||||
|
|
|
@ -602,6 +602,9 @@ While taking pictures in the woods I had a really strange encounter...</td>
|
|||
The [abstract] element is not working with connectors where we post HTML directly, like Tumblr, Wordpress or Pump.io.
|
||||
For the native connections--that is to e.g. Friendica, Hubzilla, Diaspora or GNU Social--the full posting is used and the contacts instance will display the posting as desired.
|
||||
|
||||
For postings that are delivered via ActivityPub, the text from the abstract is placed in the summary field.
|
||||
On Mastodon this field is used for the content warning.
|
||||
|
||||
## Special
|
||||
|
||||
<table class="bbcodes">
|
||||
|
|
|
@ -81,6 +81,7 @@ Here's a few primers if you are new to Friendica or to the PSR-2 coding standard
|
|||
* No closing PHP tag
|
||||
* No trailing spaces
|
||||
* Array declarations use the new square brackets syntax
|
||||
* Quoting style is single quotes by default, except for needed string interpolation, SQL query strings by convention and comments that should stay in natural language.
|
||||
|
||||
Don't worry, you don't have to know by heart the PSR-2 coding standards to start contributing to Friendica.
|
||||
There are a few tools you can use to check or fix your files before you commit.
|
||||
|
|
|
@ -40,7 +40,7 @@ You are not required to do this, but the alternative is to log out and log back
|
|||
This could get cumbersome if you manage several different forums/identities.
|
||||
|
||||
You may also appoint a delegate to manage your forum.
|
||||
Do this by visiting the [Delegation Setup Page](delegate).
|
||||
Do this by visiting the [Delegation Setup Page](settings/delegation).
|
||||
This will provide you with a list of contacts on this system under "Potential Delegates".
|
||||
Selecting one or more persons will give them access to manage your forum.
|
||||
They will be able to edit contacts, profiles, and all content for this account/page.
|
||||
|
|
|
@ -11,13 +11,13 @@ with your web browser.
|
|||
You will need to be logged in at the time.
|
||||
|
||||
You will be asked for your password to confirm the request.
|
||||
If this matches your stored password, your account will immediately be blocked to all probing.
|
||||
Unlike some social networks we do **not** hold onto it for a grace period in case you change your mind.
|
||||
All your content and user data, etc is instantly removed.
|
||||
For all intents and purposes, the account is gone in moments.
|
||||
If this matches your stored password, your account will immediately be marked as deleted.
|
||||
There is no grace period, this action cannot be reverted.
|
||||
Most of your content and user data will be deleted shortly in the background.
|
||||
|
||||
We then send out an "unfriend" signal to all of your contacts.
|
||||
This signal deletes all content on those networks.
|
||||
Unfortunately, due to limitations of the other networks, this only works well with Friendica contacts.
|
||||
We allow four days for this, in case some servers were down and the unfriend signal was queued.
|
||||
After this, we finish off deleting the account.
|
||||
We then send out a notification about the account removal to all of your contacts so that they can do the same with their copy of your data.
|
||||
|
||||
For technical reasons some of your user data is still needed to transmit this removal message.
|
||||
This remaining data will be deleted after a period of around seven days.
|
||||
|
||||
To disallow impersonation we have to save your used nickname, so that it can't be used again to register on this node.
|
||||
|
|
|
@ -256,7 +256,7 @@ Eine komplette Liste aller Hook-Callbacks mit den zugehörigen Dateien (am 01-Ap
|
|||
|
||||
Hook::callAll("parse_link", $arr);
|
||||
|
||||
### mod/manage.php
|
||||
### src/Module/Delegation.php
|
||||
|
||||
Hook::callAll('home_init', $ret);
|
||||
|
||||
|
|
|
@ -580,6 +580,9 @@ Für Verbindungen zu Netzwerken, zu denen Friendica den HTML Code postet, wi
|
|||
Bei nativen Verbindungen; das heißt zu z.B. Friendica, Hubzilla, Diaspora oder GNU Social Kontakten; wird der ungekürzte Beitrag übertragen.
|
||||
Die Instanz des Kontakts kümmert sich um die Darstellung.
|
||||
|
||||
Wird ein Beitrag über das ActivityPub Protokoll übermittelt, wird der Text des Abstracts für das "summary" (Zusammenfassung) Feld verwendet.
|
||||
Dieses Feld wird von Mastodon für die Inhaltswarnung (content warning) verwendet.
|
||||
|
||||
## Special
|
||||
|
||||
<table class="bbcodes">
|
||||
|
|
|
@ -38,7 +38,7 @@ Du musst das nicht machen, die Alternative ist allerdings, Dich immer wieder aus
|
|||
Und das kann umständlich sein, wenn Du mehrere verschiedene Foren/Identitäten verwaltest.
|
||||
|
||||
Du kannst ebenso jemanden wählen, der Dein Forum verwaltet.
|
||||
Mach das, indem Du die [Delegations-Setup-Seite](/delegate) besuchst.
|
||||
Mach das, indem Du die [Delegations-Setup-Seite](/settings/delegation) besuchst.
|
||||
Dort wird Dir eine Liste an "Potentiellen Bevollmächtigen" angezeigt.
|
||||
Die Auswahl einer oder mehrerer Personen gibt diesen die Möglichkeit, Dein Forum zu verwalten.
|
||||
Sie können Kontakte, Profile und alle Inhalte Deines Accounts/deiner Seite bearbeiten.
|
||||
|
|
|
@ -10,24 +10,14 @@ Wir freuen uns nicht, wenn Leute Friendica verlassen, aber wenn du deinen Accoun
|
|||
in deinem Webbrowser. Du musst dabei eingeloggt sein.
|
||||
|
||||
Du wirst nach deinem Passwort gefragt, um die Anfrage zu bestätigen.
|
||||
Wenn dieses mit deinem gespeichertem Passwort übereinstimmt, dann wird dein Account sofort gelöscht.
|
||||
Anders als andere Netzwerke, behalten wir die Daten **nicht** für eine gewisse Zeit, falls du deine Meinung noch änderst.
|
||||
Deine Nutzerdetails, deine Unterhaltungen, deine Photos, deine Freunde - alles; wird sofort gelöscht und du wirst ausgeloggt.
|
||||
Wenn dieses mit deinem gespeichertem Passwort übereinstimmt, dann wird dein Account als "gelöscht" markiert.
|
||||
Dies passiert sofort und kann nicht rückgängig gemacht werden.
|
||||
Die meisten Deiner Inhalte und Benutzerdaten werden kurzfristig danach durch Hintergrundprozesse gelöscht.
|
||||
|
||||
Wenn Beiträge ablaufen, schicken wir Mitteilungen an Friendica, um diese zu löschen.
|
||||
Diaspora hat keine automatische Löschfunktion, so dass diese Funktion in dem Netzwerk deaktiviert ist.
|
||||
Und hoffentlich ist klar, dass das Löschen auch in anderen Netzwerken nicht funktioniert.
|
||||
Wenn du manuell einen Beitrag bzw. eine Reihe von Beiträgen löschst, dann senden wir individuelle Mitteilungen zu Friendica und Diaspora für jeden gelöschten Post.
|
||||
Parallel dazu senden wir eine Mitteilung an die Server deiner Kontakte, damit sie deine dort vorliegenden Daten ebenfalls löschen.
|
||||
Wir haben keinen Einfluss darauf, wie sorgfältig und ob überhaupt diese Systeme der Löschaufforderung nachgehen.
|
||||
|
||||
Diaspora versäumt dieses oft.
|
||||
Aus technischen Gründen benötigen wir für die Übetragung dieser Mitteilung ein paar Benutzerdaten.
|
||||
Diese Daten werden dann nach einer Frist von etwa sieben Tagen ebenfalls gelöscht.
|
||||
|
||||
Wenn du einen Beitrag löscht, aber jemand diesem Beitrag folgt, wird es trotzdem gelöscht.
|
||||
Dein Wunsch hat Priorität.
|
||||
|
||||
Wenn du deinen Account löscht, dann löschen wir alle Beiträge, dein Profil, die Nutzerdaten etc. sofort.
|
||||
|
||||
Um einen Gesamtlöschauftrag zu versenden, bräuchten wir zunächst noch deinen Account; auch, um deinen Freunden zu zeigen, wer diese Anfrage stellt.
|
||||
Das können wir nicht tun, wenn du keinen Account mehr hast.
|
||||
|
||||
Deine Freunde können möglicherweise noch deine Beiträge sehen, wenn dein Account gelöscht wurde, aber es gibt keinen öffentlichen Ort in Friendica mehr, wo diese angeschaut werden können.
|
||||
Wenn du Freunde bei Diaspora hast, kann es sein, dass deine Beiträge weiterhin vorhanden und für andere aus diesem Netzwerk sichtbar sind.
|
||||
Wir speichern deinen Benutzernamen dauerhaft, damit sich niemand einen Account unter deinem Spitznamen anlegen kann.
|
||||
|
|
|
@ -177,6 +177,7 @@ Field parameter:
|
|||
1. Label for the input box,
|
||||
2. Current text for the box,
|
||||
3. Help text for the input box.
|
||||
4. if set to "required" modern browser will check that this input box is filled when submitting the form,
|
||||
|
||||
### field_yesno.tpl
|
||||
|
||||
|
|
303
include/api.php
303
include/api.php
|
@ -48,9 +48,9 @@ use Friendica\Util\Proxy as ProxyUtils;
|
|||
use Friendica\Util\Strings;
|
||||
use Friendica\Util\XML;
|
||||
|
||||
require_once 'mod/share.php';
|
||||
require_once 'mod/item.php';
|
||||
require_once 'mod/wall_upload.php';
|
||||
require_once __DIR__ . '/../mod/share.php';
|
||||
require_once __DIR__ . '/../mod/item.php';
|
||||
require_once __DIR__ . '/../mod/wall_upload.php';
|
||||
|
||||
define('API_METHOD_ANY', '*');
|
||||
define('API_METHOD_GET', 'GET');
|
||||
|
@ -162,6 +162,7 @@ function api_register_func($path, $func, $auth = false, $method = API_METHOD_ANY
|
|||
* @brief Login API user
|
||||
*
|
||||
* @param App $a App
|
||||
* @throws ForbiddenException
|
||||
* @throws InternalServerErrorException
|
||||
* @throws UnauthorizedException
|
||||
* @hook 'authenticate'
|
||||
|
@ -170,8 +171,6 @@ function api_register_func($path, $func, $auth = false, $method = API_METHOD_ANY
|
|||
* 'password' => password from login form
|
||||
* 'authenticated' => return status,
|
||||
* 'user_record' => return authenticated user record
|
||||
* @hook 'logged_in'
|
||||
* array $user logged user record
|
||||
*/
|
||||
function api_login(App $a)
|
||||
{
|
||||
|
@ -182,7 +181,7 @@ function api_login(App $a)
|
|||
list($consumer, $token) = $oauth1->verify_request($request);
|
||||
if (!is_null($token)) {
|
||||
$oauth1->loginUser($token->uid);
|
||||
Hook::callAll('logged_in', $a->user);
|
||||
Session::set('allow_api', true);
|
||||
return;
|
||||
}
|
||||
echo __FILE__.__LINE__.__FUNCTION__ . "<pre>";
|
||||
|
@ -208,8 +207,8 @@ function api_login(App $a)
|
|||
throw new UnauthorizedException("This API requires login");
|
||||
}
|
||||
|
||||
$user = defaults($_SERVER, 'PHP_AUTH_USER', '');
|
||||
$password = defaults($_SERVER, 'PHP_AUTH_PW', '');
|
||||
$user = $_SERVER['PHP_AUTH_USER'] ?? '';
|
||||
$password = $_SERVER['PHP_AUTH_PW'] ?? '';
|
||||
|
||||
// allow "user@server" login (but ignore 'server' part)
|
||||
$at = strstr($user, "@", true);
|
||||
|
@ -273,7 +272,7 @@ function api_check_method($method)
|
|||
if ($method == "*") {
|
||||
return true;
|
||||
}
|
||||
return (stripos($method, defaults($_SERVER, 'REQUEST_METHOD', 'GET')) !== false);
|
||||
return (stripos($method, $_SERVER['REQUEST_METHOD'] ?? 'GET') !== false);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -323,7 +322,7 @@ function api_call(App $a)
|
|||
|
||||
$stamp = microtime(true);
|
||||
$return = call_user_func($info['func'], $type);
|
||||
$duration = (float) (microtime(true) - $stamp);
|
||||
$duration = floatval(microtime(true) - $stamp);
|
||||
|
||||
Logger::info(API_LOG_PREFIX . 'username {username}', ['module' => 'api', 'action' => 'call', 'username' => $a->user['username'], 'duration' => round($duration, 2)]);
|
||||
|
||||
|
@ -776,14 +775,14 @@ function api_get_user(App $a, $contact_id = null)
|
|||
*/
|
||||
function api_item_get_user(App $a, $item)
|
||||
{
|
||||
$status_user = api_get_user($a, defaults($item, 'author-id', null));
|
||||
$status_user = api_get_user($a, $item['author-id'] ?? null);
|
||||
|
||||
$author_user = $status_user;
|
||||
|
||||
$status_user["protected"] = defaults($item, 'private', 0);
|
||||
$status_user["protected"] = $item['private'] ?? 0;
|
||||
|
||||
if (defaults($item, 'thr-parent', '') == defaults($item, 'uri', '')) {
|
||||
$owner_user = api_get_user($a, defaults($item, 'owner-id', null));
|
||||
if (($item['thr-parent'] ?? '') == ($item['uri'] ?? '')) {
|
||||
$owner_user = api_get_user($a, $item['owner-id'] ?? null);
|
||||
} else {
|
||||
$owner_user = $author_user;
|
||||
}
|
||||
|
@ -947,7 +946,7 @@ function api_account_verify_credentials($type)
|
|||
unset($_REQUEST["screen_name"]);
|
||||
unset($_GET["screen_name"]);
|
||||
|
||||
$skip_status = defaults($_REQUEST, 'skip_status', false);
|
||||
$skip_status = $_REQUEST['skip_status'] ?? false;
|
||||
|
||||
$user_info = api_get_user($a);
|
||||
|
||||
|
@ -1518,10 +1517,12 @@ function api_search($type)
|
|||
$count = $_REQUEST['count'];
|
||||
}
|
||||
|
||||
$since_id = defaults($_REQUEST, 'since_id', 0);
|
||||
$max_id = defaults($_REQUEST, 'max_id', 0);
|
||||
$page = (!empty($_REQUEST['page']) ? $_REQUEST['page'] - 1 : 0);
|
||||
$start = $page * $count;
|
||||
$since_id = $_REQUEST['since_id'] ?? 0;
|
||||
$max_id = $_REQUEST['max_id'] ?? 0;
|
||||
$page = $_REQUEST['page'] ?? 1;
|
||||
|
||||
$start = max(0, ($page - 1) * $count);
|
||||
|
||||
$params = ['order' => ['id' => true], 'limit' => [$start, $count]];
|
||||
if (preg_match('/^#(\w+)$/', $searchTerm, $matches) === 1 && isset($matches[1])) {
|
||||
$searchTerm = $matches[1];
|
||||
|
@ -1609,17 +1610,14 @@ function api_statuses_home_timeline($type)
|
|||
// get last network messages
|
||||
|
||||
// params
|
||||
$count = defaults($_REQUEST, 'count', 20);
|
||||
$page = (!empty($_REQUEST['page']) ? $_REQUEST['page'] - 1 : 0);
|
||||
if ($page < 0) {
|
||||
$page = 0;
|
||||
}
|
||||
$since_id = defaults($_REQUEST, 'since_id', 0);
|
||||
$max_id = defaults($_REQUEST, 'max_id', 0);
|
||||
$count = $_REQUEST['count'] ?? 20;
|
||||
$page = $_REQUEST['page']?? 0;
|
||||
$since_id = $_REQUEST['since_id'] ?? 0;
|
||||
$max_id = $_REQUEST['max_id'] ?? 0;
|
||||
$exclude_replies = !empty($_REQUEST['exclude_replies']);
|
||||
$conversation_id = defaults($_REQUEST, 'conversation_id', 0);
|
||||
$conversation_id = $_REQUEST['conversation_id'] ?? 0;
|
||||
|
||||
$start = $page * $count;
|
||||
$start = max(0, ($page - 1) * $count);
|
||||
|
||||
$condition = ["`uid` = ? AND `gravity` IN (?, ?) AND `item`.`id` > ?",
|
||||
api_user(), GRAVITY_PARENT, GRAVITY_COMMENT, $since_id];
|
||||
|
@ -1699,17 +1697,14 @@ function api_statuses_public_timeline($type)
|
|||
// get last network messages
|
||||
|
||||
// params
|
||||
$count = defaults($_REQUEST, 'count', 20);
|
||||
$page = (!empty($_REQUEST['page']) ? $_REQUEST['page'] -1 : 0);
|
||||
if ($page < 0) {
|
||||
$page = 0;
|
||||
}
|
||||
$since_id = defaults($_REQUEST, 'since_id', 0);
|
||||
$max_id = defaults($_REQUEST, 'max_id', 0);
|
||||
$count = $_REQUEST['count'] ?? 20;
|
||||
$page = $_REQUEST['page'] ?? 1;
|
||||
$since_id = $_REQUEST['since_id'] ?? 0;
|
||||
$max_id = $_REQUEST['max_id'] ?? 0;
|
||||
$exclude_replies = (!empty($_REQUEST['exclude_replies']) ? 1 : 0);
|
||||
$conversation_id = defaults($_REQUEST, 'conversation_id', 0);
|
||||
$conversation_id = $_REQUEST['conversation_id'] ?? 0;
|
||||
|
||||
$start = $page * $count;
|
||||
$start = max(0, ($page - 1) * $count);
|
||||
|
||||
if ($exclude_replies && !$conversation_id) {
|
||||
$condition = ["`gravity` IN (?, ?) AND `iid` > ? AND NOT `private` AND `wall` AND NOT `user`.`hidewall` AND NOT `author`.`hidden`",
|
||||
|
@ -1784,16 +1779,14 @@ function api_statuses_networkpublic_timeline($type)
|
|||
throw new ForbiddenException();
|
||||
}
|
||||
|
||||
$since_id = defaults($_REQUEST, 'since_id', 0);
|
||||
$max_id = defaults($_REQUEST, 'max_id', 0);
|
||||
$since_id = $_REQUEST['since_id'] ?? 0;
|
||||
$max_id = $_REQUEST['max_id'] ?? 0;
|
||||
|
||||
// pagination
|
||||
$count = defaults($_REQUEST, 'count', 20);
|
||||
$page = defaults($_REQUEST, 'page', 1);
|
||||
if ($page < 1) {
|
||||
$page = 1;
|
||||
}
|
||||
$start = ($page - 1) * $count;
|
||||
$count = $_REQUEST['count'] ?? 20;
|
||||
$page = $_REQUEST['page'] ?? 1;
|
||||
|
||||
$start = max(0, ($page - 1) * $count);
|
||||
|
||||
$condition = ["`uid` = 0 AND `gravity` IN (?, ?) AND `thread`.`iid` > ? AND NOT `private`",
|
||||
GRAVITY_PARENT, GRAVITY_COMMENT, $since_id];
|
||||
|
@ -1848,15 +1841,15 @@ function api_statuses_show($type)
|
|||
}
|
||||
|
||||
// params
|
||||
$id = intval(defaults($a->argv, 3, 0));
|
||||
$id = intval($a->argv[3] ?? 0);
|
||||
|
||||
if ($id == 0) {
|
||||
$id = intval(defaults($_REQUEST, 'id', 0));
|
||||
$id = intval($_REQUEST['id'] ?? 0);
|
||||
}
|
||||
|
||||
// Hotot workaround
|
||||
if ($id == 0) {
|
||||
$id = intval(defaults($a->argv, 4, 0));
|
||||
$id = intval($a->argv[4] ?? 0);
|
||||
}
|
||||
|
||||
Logger::log('API: api_statuses_show: ' . $id);
|
||||
|
@ -1927,24 +1920,21 @@ function api_conversation_show($type)
|
|||
}
|
||||
|
||||
// params
|
||||
$id = intval(defaults($a->argv , 3 , 0));
|
||||
$since_id = intval(defaults($_REQUEST, 'since_id', 0));
|
||||
$max_id = intval(defaults($_REQUEST, 'max_id' , 0));
|
||||
$count = intval(defaults($_REQUEST, 'count' , 20));
|
||||
$page = intval(defaults($_REQUEST, 'page' , 1)) - 1;
|
||||
if ($page < 0) {
|
||||
$page = 0;
|
||||
}
|
||||
$id = intval($a->argv[3] ?? 0);
|
||||
$since_id = intval($_REQUEST['since_id'] ?? 0);
|
||||
$max_id = intval($_REQUEST['max_id'] ?? 0);
|
||||
$count = intval($_REQUEST['count'] ?? 20);
|
||||
$page = intval($_REQUEST['page'] ?? 1);
|
||||
|
||||
$start = $page * $count;
|
||||
$start = max(0, ($page - 1) * $count);
|
||||
|
||||
if ($id == 0) {
|
||||
$id = intval(defaults($_REQUEST, 'id', 0));
|
||||
$id = intval($_REQUEST['id'] ?? 0);
|
||||
}
|
||||
|
||||
// Hotot workaround
|
||||
if ($id == 0) {
|
||||
$id = intval(defaults($a->argv, 4, 0));
|
||||
$id = intval($a->argv[4] ?? 0);
|
||||
}
|
||||
|
||||
Logger::info(API_LOG_PREFIX . '{subaction}', ['module' => 'api', 'action' => 'conversation', 'subaction' => 'show', 'id' => $id]);
|
||||
|
@ -2013,15 +2003,15 @@ function api_statuses_repeat($type)
|
|||
api_get_user($a);
|
||||
|
||||
// params
|
||||
$id = intval(defaults($a->argv, 3, 0));
|
||||
$id = intval($a->argv[3] ?? 0);
|
||||
|
||||
if ($id == 0) {
|
||||
$id = intval(defaults($_REQUEST, 'id', 0));
|
||||
$id = intval($_REQUEST['id'] ?? 0);
|
||||
}
|
||||
|
||||
// Hotot workaround
|
||||
if ($id == 0) {
|
||||
$id = intval(defaults($a->argv, 4, 0));
|
||||
$id = intval($a->argv[4] ?? 0);
|
||||
}
|
||||
|
||||
Logger::log('API: api_statuses_repeat: '.$id);
|
||||
|
@ -2084,15 +2074,15 @@ function api_statuses_destroy($type)
|
|||
api_get_user($a);
|
||||
|
||||
// params
|
||||
$id = intval(defaults($a->argv, 3, 0));
|
||||
$id = intval($a->argv[3] ?? 0);
|
||||
|
||||
if ($id == 0) {
|
||||
$id = intval(defaults($_REQUEST, 'id', 0));
|
||||
$id = intval($_REQUEST['id'] ?? 0);
|
||||
}
|
||||
|
||||
// Hotot workaround
|
||||
if ($id == 0) {
|
||||
$id = intval(defaults($a->argv, 4, 0));
|
||||
$id = intval($a->argv[4] ?? 0);
|
||||
}
|
||||
|
||||
Logger::log('API: api_statuses_destroy: '.$id);
|
||||
|
@ -2138,15 +2128,12 @@ function api_statuses_mentions($type)
|
|||
// get last network messages
|
||||
|
||||
// params
|
||||
$since_id = defaults($_REQUEST, 'since_id', 0);
|
||||
$max_id = defaults($_REQUEST, 'max_id' , 0);
|
||||
$count = defaults($_REQUEST, 'count' , 20);
|
||||
$page = defaults($_REQUEST, 'page' , 1);
|
||||
if ($page < 1) {
|
||||
$page = 1;
|
||||
}
|
||||
$since_id = $_REQUEST['since_id'] ?? 0;
|
||||
$max_id = $_REQUEST['max_id'] ?? 0;
|
||||
$count = $_REQUEST['count'] ?? 20;
|
||||
$page = $_REQUEST['page'] ?? 1;
|
||||
|
||||
$start = ($page - 1) * $count;
|
||||
$start = max(0, ($page - 1) * $count);
|
||||
|
||||
$condition = ["`uid` = ? AND `gravity` IN (?, ?) AND `item`.`id` > ? AND `author-id` != ?
|
||||
AND `item`.`parent` IN (SELECT `iid` FROM `thread` WHERE `thread`.`uid` = ? AND `thread`.`mention` AND NOT `thread`.`ignored`)",
|
||||
|
@ -2208,18 +2195,16 @@ function api_statuses_user_timeline($type)
|
|||
Logger::DEBUG
|
||||
);
|
||||
|
||||
$since_id = defaults($_REQUEST, 'since_id', 0);
|
||||
$max_id = defaults($_REQUEST, 'max_id', 0);
|
||||
$since_id = $_REQUEST['since_id'] ?? 0;
|
||||
$max_id = $_REQUEST['max_id'] ?? 0;
|
||||
$exclude_replies = !empty($_REQUEST['exclude_replies']);
|
||||
$conversation_id = defaults($_REQUEST, 'conversation_id', 0);
|
||||
$conversation_id = $_REQUEST['conversation_id'] ?? 0;
|
||||
|
||||
// pagination
|
||||
$count = defaults($_REQUEST, 'count', 20);
|
||||
$page = defaults($_REQUEST, 'page', 1);
|
||||
if ($page < 1) {
|
||||
$page = 1;
|
||||
}
|
||||
$start = ($page - 1) * $count;
|
||||
$count = $_REQUEST['count'] ?? 20;
|
||||
$page = $_REQUEST['page'] ?? 1;
|
||||
|
||||
$start = max(0, ($page - 1) * $count);
|
||||
|
||||
$condition = ["`uid` = ? AND `gravity` IN (?, ?) AND `item`.`id` > ? AND `item`.`contact-id` = ?",
|
||||
api_user(), GRAVITY_PARENT, GRAVITY_COMMENT, $since_id, $user_info['cid']];
|
||||
|
@ -2298,9 +2283,9 @@ function api_favorites_create_destroy($type)
|
|||
}
|
||||
$action = str_replace("." . $type, "", $a->argv[$action_argv_id]);
|
||||
if ($a->argc == $action_argv_id + 2) {
|
||||
$itemid = intval(defaults($a->argv, $action_argv_id + 1, 0));
|
||||
$itemid = intval($a->argv[$action_argv_id + 1] ?? 0);
|
||||
} else {
|
||||
$itemid = intval(defaults($_REQUEST, 'id', 0));
|
||||
$itemid = intval($_REQUEST['id'] ?? 0);
|
||||
}
|
||||
|
||||
$item = Item::selectFirstForUser(api_user(), [], ['id' => $itemid, 'uid' => api_user()]);
|
||||
|
@ -2380,15 +2365,12 @@ function api_favorites($type)
|
|||
$ret = [];
|
||||
} else {
|
||||
// params
|
||||
$since_id = defaults($_REQUEST, 'since_id', 0);
|
||||
$max_id = defaults($_REQUEST, 'max_id', 0);
|
||||
$count = defaults($_GET, 'count', 20);
|
||||
$page = (!empty($_REQUEST['page']) ? $_REQUEST['page'] -1 : 0);
|
||||
if ($page < 0) {
|
||||
$page = 0;
|
||||
}
|
||||
$since_id = $_REQUEST['since_id'] ?? 0;
|
||||
$max_id = $_REQUEST['max_id'] ?? 0;
|
||||
$count = $_GET['count'] ?? 20;
|
||||
$page = $_REQUEST['page'] ?? 1;
|
||||
|
||||
$start = $page*$count;
|
||||
$start = max(0, ($page - 1) * $count);
|
||||
|
||||
$condition = ["`uid` = ? AND `gravity` IN (?, ?) AND `id` > ? AND `starred`",
|
||||
api_user(), GRAVITY_PARENT, GRAVITY_COMMENT, $since_id];
|
||||
|
@ -2439,14 +2421,14 @@ function api_format_messages($item, $recipient, $sender)
|
|||
'sender_id' => $sender['id'],
|
||||
'text' => "",
|
||||
'recipient_id' => $recipient['id'],
|
||||
'created_at' => api_date(defaults($item, 'created', DateTimeFormat::utcNow())),
|
||||
'created_at' => api_date($item['created'] ?? DateTimeFormat::utcNow()),
|
||||
'sender_screen_name' => $sender['screen_name'],
|
||||
'recipient_screen_name' => $recipient['screen_name'],
|
||||
'sender' => $sender,
|
||||
'recipient' => $recipient,
|
||||
'title' => "",
|
||||
'friendica_seen' => defaults($item, 'seen', 0),
|
||||
'friendica_parent_uri' => defaults($item, 'parent-uri', ''),
|
||||
'friendica_seen' => $item['seen'] ?? 0,
|
||||
'friendica_parent_uri' => $item['parent-uri'] ?? '',
|
||||
];
|
||||
|
||||
// "uid" and "self" are only needed for some internal stuff, so remove it from here
|
||||
|
@ -2509,8 +2491,8 @@ function api_convert_item($item)
|
|||
$statustext = trim($statustitle."\n\n".$statusbody);
|
||||
}
|
||||
|
||||
if ((defaults($item, 'network', Protocol::PHANTOM) == Protocol::FEED) && (mb_strlen($statustext)> 1000)) {
|
||||
$statustext = mb_substr($statustext, 0, 1000) . "... \n" . defaults($item, 'plink', '');
|
||||
if ((($item['network'] ?? Protocol::PHANTOM) == Protocol::FEED) && (mb_strlen($statustext)> 1000)) {
|
||||
$statustext = mb_substr($statustext, 0, 1000) . "... \n" . ($item['plink'] ?? '');
|
||||
}
|
||||
|
||||
$statushtml = BBCode::convert(api_clean_attachments($body), false);
|
||||
|
@ -2544,7 +2526,7 @@ function api_convert_item($item)
|
|||
}
|
||||
|
||||
// feeds without body should contain the link
|
||||
if ((defaults($item, 'network', Protocol::PHANTOM) == Protocol::FEED) && (strlen($item['body']) == 0)) {
|
||||
if ((($item['network'] ?? Protocol::PHANTOM) == Protocol::FEED) && (strlen($item['body']) == 0)) {
|
||||
$statushtml .= BBCode::convert($item['plink']);
|
||||
}
|
||||
|
||||
|
@ -2587,7 +2569,7 @@ function api_get_attachments(&$body)
|
|||
}
|
||||
}
|
||||
|
||||
if (strstr(defaults($_SERVER, 'HTTP_USER_AGENT', ''), "AndStatus")) {
|
||||
if (strstr($_SERVER['HTTP_USER_AGENT'] ?? '', 'AndStatus')) {
|
||||
foreach ($images[0] as $orig) {
|
||||
$body = str_replace($orig, "", $body);
|
||||
}
|
||||
|
@ -2607,7 +2589,7 @@ function api_get_attachments(&$body)
|
|||
*/
|
||||
function api_get_entitities(&$text, $bbcode)
|
||||
{
|
||||
$include_entities = strtolower(defaults($_REQUEST, 'include_entities', "false"));
|
||||
$include_entities = strtolower($_REQUEST['include_entities'] ?? 'false');
|
||||
|
||||
if ($include_entities != "true") {
|
||||
preg_match_all("/\[img](.*?)\[\/img\]/ism", $bbcode, $images);
|
||||
|
@ -3040,6 +3022,8 @@ function api_format_item($item, $type = "json", $status_user = null, $author_use
|
|||
'statusnet_conversation_id' => $item['parent'],
|
||||
'external_url' => System::baseUrl() . "/display/" . $item['guid'],
|
||||
'friendica_activities' => api_format_items_activities($item, $type),
|
||||
'friendica_title' => $item['title'],
|
||||
'friendica_html' => BBCode::convert($item['body'], false)
|
||||
];
|
||||
|
||||
if (count($converted["attachments"]) > 0) {
|
||||
|
@ -3310,17 +3294,14 @@ function api_lists_statuses($type)
|
|||
}
|
||||
|
||||
// params
|
||||
$count = defaults($_REQUEST, 'count', 20);
|
||||
$page = (!empty($_REQUEST['page']) ? $_REQUEST['page'] - 1 : 0);
|
||||
if ($page < 0) {
|
||||
$page = 0;
|
||||
}
|
||||
$since_id = defaults($_REQUEST, 'since_id', 0);
|
||||
$max_id = defaults($_REQUEST, 'max_id', 0);
|
||||
$count = $_REQUEST['count'] ?? 20;
|
||||
$page = $_REQUEST['page'] ?? 1;
|
||||
$since_id = $_REQUEST['since_id'] ?? 0;
|
||||
$max_id = $_REQUEST['max_id'] ?? 0;
|
||||
$exclude_replies = (!empty($_REQUEST['exclude_replies']) ? 1 : 0);
|
||||
$conversation_id = defaults($_REQUEST, 'conversation_id', 0);
|
||||
$conversation_id = $_REQUEST['conversation_id'] ?? 0;
|
||||
|
||||
$start = $page * $count;
|
||||
$start = max(0, ($page - 1) * $count);
|
||||
|
||||
$condition = ["`uid` = ? AND `gravity` IN (?, ?) AND `id` > ? AND `group_member`.`gid` = ?",
|
||||
api_user(), GRAVITY_PARENT, GRAVITY_COMMENT, $since_id, $_REQUEST['list_id']];
|
||||
|
@ -3380,12 +3361,10 @@ function api_statuses_f($qtype)
|
|||
}
|
||||
|
||||
// pagination
|
||||
$count = defaults($_GET, 'count', 20);
|
||||
$page = defaults($_GET, 'page', 1);
|
||||
if ($page < 1) {
|
||||
$page = 1;
|
||||
}
|
||||
$start = ($page - 1) * $count;
|
||||
$count = $_GET['count'] ?? 20;
|
||||
$page = $_GET['page'] ?? 1;
|
||||
|
||||
$start = max(0, ($page - 1) * $count);
|
||||
|
||||
$user_info = api_get_user($a);
|
||||
|
||||
|
@ -3632,7 +3611,7 @@ function api_ff_ids($type)
|
|||
|
||||
api_get_user($a);
|
||||
|
||||
$stringify_ids = defaults($_REQUEST, 'stringify_ids', false);
|
||||
$stringify_ids = $_REQUEST['stringify_ids'] ?? false;
|
||||
|
||||
$r = q(
|
||||
"SELECT `pcontact`.`id` FROM `contact`
|
||||
|
@ -3807,9 +3786,9 @@ function api_direct_messages_destroy($type)
|
|||
// params
|
||||
$user_info = api_get_user($a);
|
||||
//required
|
||||
$id = defaults($_REQUEST, 'id', 0);
|
||||
$id = $_REQUEST['id'] ?? 0;
|
||||
// optional
|
||||
$parenturi = defaults($_REQUEST, 'friendica_parenturi', "");
|
||||
$parenturi = $_REQUEST['friendica_parenturi'] ?? '';
|
||||
$verbose = (!empty($_GET['friendica_verbose']) ? strtolower($_GET['friendica_verbose']) : "false");
|
||||
/// @todo optional parameter 'include_entities' from Twitter API not yet implemented
|
||||
|
||||
|
@ -3890,7 +3869,7 @@ function api_friendships_destroy($type)
|
|||
throw new ForbiddenException();
|
||||
}
|
||||
|
||||
$contact_id = defaults($_REQUEST, 'user_id');
|
||||
$contact_id = $_REQUEST['user_id'] ?? 0;
|
||||
|
||||
if (empty($contact_id)) {
|
||||
Logger::notice(API_LOG_PREFIX . 'No user_id specified', ['module' => 'api', 'action' => 'friendships_destroy']);
|
||||
|
@ -3971,17 +3950,14 @@ function api_direct_messages_box($type, $box, $verbose)
|
|||
throw new ForbiddenException();
|
||||
}
|
||||
// params
|
||||
$count = defaults($_GET, 'count', 20);
|
||||
$page = defaults($_REQUEST, 'page', 1) - 1;
|
||||
if ($page < 0) {
|
||||
$page = 0;
|
||||
}
|
||||
$count = $_GET['count'] ?? 20;
|
||||
$page = $_REQUEST['page'] ?? 1;
|
||||
|
||||
$since_id = defaults($_REQUEST, 'since_id', 0);
|
||||
$max_id = defaults($_REQUEST, 'max_id', 0);
|
||||
$since_id = $_REQUEST['since_id'] ?? 0;
|
||||
$max_id = $_REQUEST['max_id'] ?? 0;
|
||||
|
||||
$user_id = defaults($_REQUEST, 'user_id', '');
|
||||
$screen_name = defaults($_REQUEST, 'screen_name', '');
|
||||
$user_id = $_REQUEST['user_id'] ?? '';
|
||||
$screen_name = $_REQUEST['screen_name'] ?? '';
|
||||
|
||||
// caller user info
|
||||
unset($_REQUEST["user_id"]);
|
||||
|
@ -3997,7 +3973,7 @@ function api_direct_messages_box($type, $box, $verbose)
|
|||
$profile_url = $user_info["url"];
|
||||
|
||||
// pagination
|
||||
$start = $page * $count;
|
||||
$start = max(0, ($page - 1) * $count);
|
||||
|
||||
$sql_extra = "";
|
||||
|
||||
|
@ -4005,7 +3981,7 @@ function api_direct_messages_box($type, $box, $verbose)
|
|||
if ($box=="sentbox") {
|
||||
$sql_extra = "`mail`.`from-url`='" . DBA::escape($profile_url) . "'";
|
||||
} elseif ($box == "conversation") {
|
||||
$sql_extra = "`mail`.`parent-uri`='" . DBA::escape(defaults($_GET, 'uri', '')) . "'";
|
||||
$sql_extra = "`mail`.`parent-uri`='" . DBA::escape($_GET['uri'] ?? '') . "'";
|
||||
} elseif ($box == "all") {
|
||||
$sql_extra = "true";
|
||||
} elseif ($box == "inbox") {
|
||||
|
@ -4185,7 +4161,7 @@ function api_fr_photoalbum_delete($type)
|
|||
throw new ForbiddenException();
|
||||
}
|
||||
// input params
|
||||
$album = defaults($_REQUEST, 'album', "");
|
||||
$album = $_REQUEST['album'] ?? '';
|
||||
|
||||
// we do not allow calls without album string
|
||||
if ($album == "") {
|
||||
|
@ -4240,8 +4216,8 @@ function api_fr_photoalbum_update($type)
|
|||
throw new ForbiddenException();
|
||||
}
|
||||
// input params
|
||||
$album = defaults($_REQUEST, 'album', "");
|
||||
$album_new = defaults($_REQUEST, 'album_new', "");
|
||||
$album = $_REQUEST['album'] ?? '';
|
||||
$album_new = $_REQUEST['album_new'] ?? '';
|
||||
|
||||
// we do not allow calls without album string
|
||||
if ($album == "") {
|
||||
|
@ -4332,14 +4308,14 @@ function api_fr_photo_create_update($type)
|
|||
throw new ForbiddenException();
|
||||
}
|
||||
// input params
|
||||
$photo_id = defaults($_REQUEST, 'photo_id', null);
|
||||
$desc = defaults($_REQUEST, 'desc', (array_key_exists('desc', $_REQUEST) ? "" : null)) ; // extra check necessary to distinguish between 'not provided' and 'empty string'
|
||||
$album = defaults($_REQUEST, 'album', null);
|
||||
$album_new = defaults($_REQUEST, 'album_new', null);
|
||||
$allow_cid = defaults($_REQUEST, 'allow_cid', (array_key_exists('allow_cid', $_REQUEST) ? " " : null));
|
||||
$deny_cid = defaults($_REQUEST, 'deny_cid' , (array_key_exists('deny_cid' , $_REQUEST) ? " " : null));
|
||||
$allow_gid = defaults($_REQUEST, 'allow_gid', (array_key_exists('allow_gid', $_REQUEST) ? " " : null));
|
||||
$deny_gid = defaults($_REQUEST, 'deny_gid' , (array_key_exists('deny_gid' , $_REQUEST) ? " " : null));
|
||||
$photo_id = $_REQUEST['photo_id'] ?? null;
|
||||
$desc = $_REQUEST['desc'] ?? null;
|
||||
$album = $_REQUEST['album'] ?? null;
|
||||
$album_new = $_REQUEST['album_new'] ?? null;
|
||||
$allow_cid = $_REQUEST['allow_cid'] ?? null;
|
||||
$deny_cid = $_REQUEST['deny_cid' ] ?? null;
|
||||
$allow_gid = $_REQUEST['allow_gid'] ?? null;
|
||||
$deny_gid = $_REQUEST['deny_gid' ] ?? null;
|
||||
$visibility = !empty($_REQUEST['visibility']) && $_REQUEST['visibility'] !== "false";
|
||||
|
||||
// do several checks on input parameters
|
||||
|
@ -4470,7 +4446,7 @@ function api_fr_photo_delete($type)
|
|||
}
|
||||
|
||||
// input params
|
||||
$photo_id = defaults($_REQUEST, 'photo_id', null);
|
||||
$photo_id = $_REQUEST['photo_id'] ?? null;
|
||||
|
||||
// do several checks on input parameters
|
||||
// we do not allow calls without photo id
|
||||
|
@ -4557,7 +4533,7 @@ function api_account_update_profile_image($type)
|
|||
throw new ForbiddenException();
|
||||
}
|
||||
// input params
|
||||
$profile_id = defaults($_REQUEST, 'profile_id', 0);
|
||||
$profile_id = $_REQUEST['profile_id'] ?? 0;
|
||||
|
||||
// error if image data is missing
|
||||
if (empty($_FILES['image'])) {
|
||||
|
@ -4689,9 +4665,10 @@ api_register_func('api/account/update_profile', 'api_account_update_profile', tr
|
|||
*/
|
||||
function check_acl_input($acl_string)
|
||||
{
|
||||
if ($acl_string == null || $acl_string == " ") {
|
||||
if (empty($acl_string)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$contact_not_found = false;
|
||||
|
||||
// split <x><y><z> into array of cid's
|
||||
|
@ -4709,7 +4686,6 @@ function check_acl_input($acl_string)
|
|||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param string $mediatype
|
||||
* @param array $media
|
||||
* @param string $type
|
||||
|
@ -4728,6 +4704,7 @@ function check_acl_input($acl_string)
|
|||
* @throws ImagickException
|
||||
* @throws InternalServerErrorException
|
||||
* @throws NotFoundException
|
||||
* @throws UnauthorizedException
|
||||
*/
|
||||
function save_media_to_database($mediatype, $media, $type, $album, $allow_cid, $deny_cid, $allow_gid, $deny_gid, $desc, $profile = 0, $visibility = false, $photo_id = null)
|
||||
{
|
||||
|
@ -5062,8 +5039,8 @@ function prepare_photo_data($type, $scale, $photo_id)
|
|||
*/
|
||||
function api_friendica_remoteauth()
|
||||
{
|
||||
$url = defaults($_GET, 'url', '');
|
||||
$c_url = defaults($_GET, 'c_url', '');
|
||||
$url = $_GET['url'] ?? '';
|
||||
$c_url = $_GET['c_url'] ?? '';
|
||||
|
||||
if ($url === '' || $c_url === '') {
|
||||
throw new BadRequestException("Wrong parameters.");
|
||||
|
@ -5081,7 +5058,7 @@ function api_friendica_remoteauth()
|
|||
|
||||
$cid = $contact['id'];
|
||||
|
||||
$dfrn_id = defaults($contact, 'issued-id', $contact['dfrn-id']);
|
||||
$dfrn_id = $contact['issued-id'] ?? $contact['dfrn-id'];
|
||||
|
||||
if ($contact['duplex'] && $contact['issued-id']) {
|
||||
$orig_id = $contact['issued-id'];
|
||||
|
@ -5416,7 +5393,7 @@ function api_in_reply_to($item)
|
|||
*/
|
||||
function api_clean_plain_items($text)
|
||||
{
|
||||
$include_entities = strtolower(defaults($_REQUEST, 'include_entities', "false"));
|
||||
$include_entities = strtolower($_REQUEST['include_entities'] ?? 'false');
|
||||
|
||||
$text = BBCode::cleanPictureLinks($text);
|
||||
$URLSearchString = "^\[\]";
|
||||
|
@ -5554,7 +5531,7 @@ function api_friendica_group_show($type)
|
|||
|
||||
// params
|
||||
$user_info = api_get_user($a);
|
||||
$gid = defaults($_REQUEST, 'gid', 0);
|
||||
$gid = $_REQUEST['gid'] ?? 0;
|
||||
$uid = $user_info['uid'];
|
||||
|
||||
// get data of the specified group id or all groups if not specified
|
||||
|
@ -5624,8 +5601,8 @@ function api_friendica_group_delete($type)
|
|||
|
||||
// params
|
||||
$user_info = api_get_user($a);
|
||||
$gid = defaults($_REQUEST, 'gid', 0);
|
||||
$name = defaults($_REQUEST, 'name', "");
|
||||
$gid = $_REQUEST['gid'] ?? 0;
|
||||
$name = $_REQUEST['name'] ?? '';
|
||||
$uid = $user_info['uid'];
|
||||
|
||||
// error if no gid specified
|
||||
|
@ -5691,7 +5668,7 @@ function api_lists_destroy($type)
|
|||
|
||||
// params
|
||||
$user_info = api_get_user($a);
|
||||
$gid = defaults($_REQUEST, 'list_id', 0);
|
||||
$gid = $_REQUEST['list_id'] ?? 0;
|
||||
$uid = $user_info['uid'];
|
||||
|
||||
// error if no gid specified
|
||||
|
@ -5813,7 +5790,7 @@ function api_friendica_group_create($type)
|
|||
|
||||
// params
|
||||
$user_info = api_get_user($a);
|
||||
$name = defaults($_REQUEST, 'name', "");
|
||||
$name = $_REQUEST['name'] ?? '';
|
||||
$uid = $user_info['uid'];
|
||||
$json = json_decode($_POST['json'], true);
|
||||
$users = $json['user'];
|
||||
|
@ -5847,7 +5824,7 @@ function api_lists_create($type)
|
|||
|
||||
// params
|
||||
$user_info = api_get_user($a);
|
||||
$name = defaults($_REQUEST, 'name', "");
|
||||
$name = $_REQUEST['name'] ?? '';
|
||||
$uid = $user_info['uid'];
|
||||
|
||||
$success = group_create($name, $uid);
|
||||
|
@ -5887,8 +5864,8 @@ function api_friendica_group_update($type)
|
|||
// params
|
||||
$user_info = api_get_user($a);
|
||||
$uid = $user_info['uid'];
|
||||
$gid = defaults($_REQUEST, 'gid', 0);
|
||||
$name = defaults($_REQUEST, 'name', "");
|
||||
$gid = $_REQUEST['gid'] ?? 0;
|
||||
$name = $_REQUEST['name'] ?? '';
|
||||
$json = json_decode($_POST['json'], true);
|
||||
$users = $json['user'];
|
||||
|
||||
|
@ -5965,8 +5942,8 @@ function api_lists_update($type)
|
|||
|
||||
// params
|
||||
$user_info = api_get_user($a);
|
||||
$gid = defaults($_REQUEST, 'list_id', 0);
|
||||
$name = defaults($_REQUEST, 'name', "");
|
||||
$gid = $_REQUEST['list_id'] ?? 0;
|
||||
$name = $_REQUEST['name'] ?? '';
|
||||
$uid = $user_info['uid'];
|
||||
|
||||
// error if no gid specified
|
||||
|
@ -6015,7 +5992,7 @@ function api_friendica_activity($type)
|
|||
$verb = strtolower($a->argv[3]);
|
||||
$verb = preg_replace("|\..*$|", "", $verb);
|
||||
|
||||
$id = defaults($_REQUEST, 'id', 0);
|
||||
$id = $_REQUEST['id'] ?? 0;
|
||||
|
||||
$res = Item::performLike($id, $verb);
|
||||
|
||||
|
@ -6152,7 +6129,7 @@ function api_friendica_direct_messages_setseen($type)
|
|||
// params
|
||||
$user_info = api_get_user($a);
|
||||
$uid = $user_info['uid'];
|
||||
$id = defaults($_REQUEST, 'id', 0);
|
||||
$id = $_REQUEST['id'] ?? 0;
|
||||
|
||||
// return error if id is zero
|
||||
if ($id == "") {
|
||||
|
@ -6206,7 +6183,7 @@ function api_friendica_direct_messages_search($type, $box = "")
|
|||
|
||||
// params
|
||||
$user_info = api_get_user($a);
|
||||
$searchstring = defaults($_REQUEST, 'searchstring', "");
|
||||
$searchstring = $_REQUEST['searchstring'] ?? '';
|
||||
$uid = $user_info['uid'];
|
||||
|
||||
// error if no searchstring specified
|
||||
|
@ -6273,7 +6250,7 @@ function api_friendica_profile_show($type)
|
|||
}
|
||||
|
||||
// input params
|
||||
$profile_id = defaults($_REQUEST, 'profile_id', 0);
|
||||
$profile_id = $_REQUEST['profile_id'] ?? 0;
|
||||
|
||||
// retrieve general information about profiles for user
|
||||
$multi_profiles = Feature::isEnabled(api_user(), 'multi_profiles');
|
||||
|
|
|
@ -365,7 +365,7 @@ function localize_item(&$item)
|
|||
'network' => $item['author-network'], 'url' => $item['author-link']];
|
||||
|
||||
// Only create a redirection to a magic link when logged in
|
||||
if (!empty($item['plink']) && (local_user() || remote_user())) {
|
||||
if (!empty($item['plink']) && Session::isAuthenticated()) {
|
||||
$item['plink'] = Contact::magicLinkByContact($author, $item['plink']);
|
||||
}
|
||||
}
|
||||
|
@ -1208,7 +1208,7 @@ function status_editor(App $a, $x, $notes_cid = 0, $popup = false)
|
|||
'$new_post' => L10n::t('New Post'),
|
||||
'$return_path' => $query_str,
|
||||
'$action' => 'item',
|
||||
'$share' => defaults($x, 'button', L10n::t('Share')),
|
||||
'$share' => ($x['button'] ?? '') ?: L10n::t('Share'),
|
||||
'$upload' => L10n::t('Upload photo'),
|
||||
'$shortupload' => L10n::t('upload photo'),
|
||||
'$attach' => L10n::t('Attach file'),
|
||||
|
@ -1225,17 +1225,17 @@ function status_editor(App $a, $x, $notes_cid = 0, $popup = false)
|
|||
'$shortsetloc' => L10n::t('set location'),
|
||||
'$noloc' => L10n::t('Clear browser location'),
|
||||
'$shortnoloc' => L10n::t('clear location'),
|
||||
'$title' => defaults($x, 'title', ''),
|
||||
'$title' => $x['title'] ?? '',
|
||||
'$placeholdertitle' => L10n::t('Set title'),
|
||||
'$category' => defaults($x, 'category', ''),
|
||||
'$category' => $x['category'] ?? '',
|
||||
'$placeholdercategory' => Feature::isEnabled(local_user(), 'categories') ? L10n::t("Categories \x28comma-separated list\x29") : '',
|
||||
'$wait' => L10n::t('Please wait'),
|
||||
'$permset' => L10n::t('Permission settings'),
|
||||
'$shortpermset' => L10n::t('permissions'),
|
||||
'$wall' => $notes_cid ? 0 : 1,
|
||||
'$posttype' => $notes_cid ? Item::PT_PERSONAL_NOTE : Item::PT_ARTICLE,
|
||||
'$content' => defaults($x, 'content', ''),
|
||||
'$post_id' => defaults($x, 'post_id', ''),
|
||||
'$content' => $x['content'] ?? '',
|
||||
'$post_id' => $x['post_id'] ?? '',
|
||||
'$baseurl' => System::baseUrl(true),
|
||||
'$defloc' => $x['default_location'],
|
||||
'$visitor' => $x['visitor'],
|
||||
|
@ -1527,9 +1527,9 @@ function get_responses(array $conv_responses, array $response_verbs, array $item
|
|||
$ret = [];
|
||||
foreach ($response_verbs as $v) {
|
||||
$ret[$v] = [];
|
||||
$ret[$v]['count'] = defaults($conv_responses[$v], $item['uri'], 0);
|
||||
$ret[$v]['list'] = defaults($conv_responses[$v], $item['uri'] . '-l', []);
|
||||
$ret[$v]['self'] = defaults($conv_responses[$v], $item['uri'] . '-self', '0');
|
||||
$ret[$v]['count'] = $conv_responses[$v][$item['uri']] ?? 0;
|
||||
$ret[$v]['list'] = $conv_responses[$v][$item['uri'] . '-l'] ?? [];
|
||||
$ret[$v]['self'] = $conv_responses[$v][$item['uri'] . '-self'] ?? '0';
|
||||
if (count($ret[$v]['list']) > MAX_LIKERS) {
|
||||
$ret[$v]['list_part'] = array_slice($ret[$v]['list'], 0, MAX_LIKERS);
|
||||
array_push($ret[$v]['list_part'], '<a href="#" data-toggle="modal" data-target="#' . $v . 'Modal-'
|
||||
|
|
|
@ -46,10 +46,10 @@ function notification($params)
|
|||
return false;
|
||||
}
|
||||
|
||||
$params['notify_flags'] = defaults($params, 'notify_flags', $user['notify-flags']);
|
||||
$params['language'] = defaults($params, 'language' , $user['language']);
|
||||
$params['to_name'] = defaults($params, 'to_name' , $user['username']);
|
||||
$params['to_email'] = defaults($params, 'to_email' , $user['email']);
|
||||
$params['notify_flags'] = ($params['notify_flags'] ?? '') ?: $user['notify-flags'];
|
||||
$params['language'] = ($params['language'] ?? '') ?: $user['language'];
|
||||
$params['to_name'] = ($params['to_name'] ?? '') ?: $user['username'];
|
||||
$params['to_email'] = ($params['to_email'] ?? '') ?: $user['email'];
|
||||
|
||||
// from here on everything is in the recipients language
|
||||
L10n::pushLang($params['language']);
|
||||
|
@ -142,7 +142,7 @@ function notification($params)
|
|||
}
|
||||
|
||||
if ($params['type'] == NOTIFY_COMMENT || $params['type'] == NOTIFY_TAGSELF) {
|
||||
$thread = Item::selectFirstThreadForUser($params['uid'], ['ignored'], ['iid' => $parent_id]);
|
||||
$thread = Item::selectFirstThreadForUser($params['uid'], ['ignored'], ['iid' => $parent_id, 'deleted' => false]);
|
||||
if (DBA::isResult($thread) && $thread['ignored']) {
|
||||
Logger::log('Thread ' . $parent_id . ' will be ignored', Logger::DEBUG);
|
||||
L10n::popLang();
|
||||
|
@ -161,7 +161,7 @@ function notification($params)
|
|||
// if it's a post figure out who's post it is.
|
||||
$item = null;
|
||||
if ($params['otype'] === 'item' && $parent_id) {
|
||||
$item = Item::selectFirstForUser($params['uid'], Item::ITEM_FIELDLIST, ['id' => $parent_id]);
|
||||
$item = Item::selectFirstForUser($params['uid'], Item::ITEM_FIELDLIST, ['id' => $parent_id, 'deleted' => false]);
|
||||
}
|
||||
|
||||
$item_post_type = Item::postType($item);
|
||||
|
@ -456,17 +456,17 @@ function notification($params)
|
|||
if (!isset($params['subject'])) {
|
||||
Logger::warning('subject isn\'t set.', ['type' => $params['type']]);
|
||||
}
|
||||
$subject = defaults($params, 'subject', '');
|
||||
$subject = $params['subject'] ?? '';
|
||||
|
||||
if (!isset($params['preamble'])) {
|
||||
Logger::warning('preamble isn\'t set.', ['type' => $params['type'], 'subject' => $subject]);
|
||||
}
|
||||
$preamble = defaults($params, 'preamble', '');
|
||||
$preamble = $params['preamble'] ?? '';
|
||||
|
||||
if (!isset($params['body'])) {
|
||||
Logger::warning('body isn\'t set.', ['type' => $params['type'], 'subject' => $subject, 'preamble' => $preamble]);
|
||||
}
|
||||
$body = defaults($params, 'body', '');
|
||||
$body = $params['body'] ?? '';
|
||||
|
||||
$show_in_notification_page = false;
|
||||
}
|
||||
|
@ -613,11 +613,11 @@ function notification($params)
|
|||
$datarray['siteurl'] = $siteurl;
|
||||
$datarray['type'] = $params['type'];
|
||||
$datarray['parent'] = $parent_id;
|
||||
$datarray['source_name'] = defaults($params, 'source_name', '');
|
||||
$datarray['source_link'] = defaults($params, 'source_link', '');
|
||||
$datarray['source_photo'] = defaults($params, 'source_photo', '');
|
||||
$datarray['source_name'] = $params['source_name'] ?? '';
|
||||
$datarray['source_link'] = $params['source_link'] ?? '';
|
||||
$datarray['source_photo'] = $params['source_photo'] ?? '';
|
||||
$datarray['uid'] = $params['uid'];
|
||||
$datarray['username'] = defaults($params, 'to_name', '');
|
||||
$datarray['username'] = $params['to_name'] ?? '';
|
||||
$datarray['hsitelink'] = $hsitelink;
|
||||
$datarray['tsitelink'] = $tsitelink;
|
||||
$datarray['hitemlink'] = '<a href="'.$itemlink.'">'.$itemlink.'</a>';
|
||||
|
@ -783,7 +783,7 @@ function check_item_notification($itemid, $uid, $defaulttype = "") {
|
|||
$fields = ['id', 'mention', 'tag', 'parent', 'title', 'body',
|
||||
'author-link', 'author-name', 'author-avatar', 'author-id',
|
||||
'guid', 'parent-uri', 'uri', 'contact-id', 'network'];
|
||||
$condition = ['id' => $itemid, 'gravity' => [GRAVITY_PARENT, GRAVITY_COMMENT]];
|
||||
$condition = ['id' => $itemid, 'gravity' => [GRAVITY_PARENT, GRAVITY_COMMENT], 'deleted' => false];
|
||||
$item = Item::selectFirstForUser($uid, $fields, $condition);
|
||||
if (!DBA::isResult($item) || in_array($item['author-id'], $contacts)) {
|
||||
return false;
|
||||
|
@ -840,7 +840,7 @@ function check_item_notification($itemid, $uid, $defaulttype = "") {
|
|||
|
||||
// Is it a post that the user had started?
|
||||
$fields = ['ignored', 'mention'];
|
||||
$thread = Item::selectFirstThreadForUser($params['uid'], $fields, ['iid' => $item["parent"]]);
|
||||
$thread = Item::selectFirstThreadForUser($params['uid'], $fields, ['iid' => $item["parent"], 'deleted' => false]);
|
||||
|
||||
if ($thread['mention'] && !$thread['ignored'] && !isset($params["type"])) {
|
||||
$params["type"] = NOTIFY_COMMENT;
|
||||
|
@ -848,7 +848,7 @@ function check_item_notification($itemid, $uid, $defaulttype = "") {
|
|||
}
|
||||
|
||||
// And now we check for participation of one of our contacts in the thread
|
||||
$condition = ['parent' => $item["parent"], 'author-id' => $contacts];
|
||||
$condition = ['parent' => $item["parent"], 'author-id' => $contacts, 'deleted' => false];
|
||||
|
||||
if (!$thread['ignored'] && !isset($params["type"]) && Item::exists($condition)) {
|
||||
$params["type"] = NOTIFY_COMMENT;
|
||||
|
|
|
@ -13,6 +13,7 @@ use Friendica\Core\PConfig;
|
|||
use Friendica\Core\Protocol;
|
||||
use Friendica\Core\Renderer;
|
||||
use Friendica\Core\System;
|
||||
use Friendica\Core\Session;
|
||||
use Friendica\Database\DBA;
|
||||
use Friendica\Model\Item;
|
||||
use Friendica\Protocol\DFRN;
|
||||
|
@ -41,7 +42,7 @@ function add_page_info_data(array $data, $no_photos = false)
|
|||
$data["type"] = "link";
|
||||
}
|
||||
|
||||
$data["title"] = defaults($data, "title", "");
|
||||
$data["title"] = $data["title"] ?? '';
|
||||
|
||||
if ((($data["type"] != "link") && ($data["type"] != "video") && ($data["type"] != "photo")) || ($data["title"] == $data["url"])) {
|
||||
return "";
|
||||
|
@ -326,7 +327,7 @@ function drop_items(array $items)
|
|||
{
|
||||
$uid = 0;
|
||||
|
||||
if (!local_user() && !remote_user()) {
|
||||
if (!Session::isAuthenticated()) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -362,14 +363,8 @@ function drop_item($id, $return = '')
|
|||
$contact_id = 0;
|
||||
|
||||
// check if logged in user is either the author or owner of this item
|
||||
|
||||
if (!empty($_SESSION['remote'])) {
|
||||
foreach ($_SESSION['remote'] as $visitor) {
|
||||
if ($visitor['uid'] == $item['uid'] && $visitor['cid'] == $item['contact-id']) {
|
||||
$contact_id = $visitor['cid'];
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (Session::getRemoteContactID($item['uid']) == $item['contact-id']) {
|
||||
$contact_id = $item['contact-id'];
|
||||
}
|
||||
|
||||
if ((local_user() == $item['uid']) || $contact_id) {
|
||||
|
|
|
@ -122,7 +122,7 @@ function redir_private_images($a, &$item)
|
|||
}
|
||||
|
||||
if ((local_user() == $item['uid']) && ($item['private'] == 1) && ($item['contact-id'] != $a->contact['id']) && ($item['network'] == Protocol::DFRN)) {
|
||||
$img_url = 'redir?f=1&quiet=1&url=' . urlencode($mtch[1]) . '&conurl=' . urlencode($item['author-link']);
|
||||
$img_url = 'redir/' . $item['contact-id'] . '?url=' . urlencode($mtch[1]);
|
||||
$item['body'] = str_replace($mtch[0], '[img]' . $img_url . '[/img]', $item['body']);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -13,6 +13,7 @@ if (!file_exists(__DIR__ . '/vendor/autoload.php')) {
|
|||
require __DIR__ . '/vendor/autoload.php';
|
||||
|
||||
$dice = (new Dice())->addRules(include __DIR__ . '/static/dependencies.config.php');
|
||||
$dice = $dice->addRule(Friendica\App\Mode::class, ['call' => [['determineRunMode', [false, $_SERVER], Dice::CHAIN_CALL]]]);
|
||||
|
||||
\Friendica\BaseObject::setDependencyInjection($dice);
|
||||
|
||||
|
|
|
@ -4,27 +4,30 @@
|
|||
/* Generic exception class
|
||||
*/
|
||||
if (!class_exists('OAuthException', false)) {
|
||||
class OAuthException extends Exception {
|
||||
// pass
|
||||
}
|
||||
class OAuthException extends Exception
|
||||
{ }
|
||||
}
|
||||
|
||||
class OAuthConsumer {
|
||||
class OAuthConsumer
|
||||
{
|
||||
public $key;
|
||||
public $secret;
|
||||
|
||||
function __construct($key, $secret, $callback_url=NULL) {
|
||||
function __construct($key, $secret, $callback_url = NULL)
|
||||
{
|
||||
$this->key = $key;
|
||||
$this->secret = $secret;
|
||||
$this->callback_url = $callback_url;
|
||||
}
|
||||
|
||||
function __toString() {
|
||||
function __toString()
|
||||
{
|
||||
return "OAuthConsumer[key=$this->key,secret=$this->secret]";
|
||||
}
|
||||
}
|
||||
|
||||
class OAuthToken {
|
||||
class OAuthToken
|
||||
{
|
||||
// access tokens and request tokens
|
||||
public $key;
|
||||
public $secret;
|
||||
|
@ -37,7 +40,8 @@ class OAuthToken {
|
|||
* key = the token
|
||||
* secret = the token secret
|
||||
*/
|
||||
function __construct($key, $secret) {
|
||||
function __construct($key, $secret)
|
||||
{
|
||||
$this->key = $key;
|
||||
$this->secret = $secret;
|
||||
}
|
||||
|
@ -46,14 +50,16 @@ class OAuthToken {
|
|||
* generates the basic string serialization of a token that a server
|
||||
* would respond to request_token and access_token calls with
|
||||
*/
|
||||
function to_string() {
|
||||
function to_string()
|
||||
{
|
||||
return "oauth_token=" .
|
||||
OAuthUtil::urlencode_rfc3986($this->key) .
|
||||
"&oauth_token_secret=" .
|
||||
OAuthUtil::urlencode_rfc3986($this->secret);
|
||||
OAuthUtil::urlencode_rfc3986($this->key) .
|
||||
"&oauth_token_secret=" .
|
||||
OAuthUtil::urlencode_rfc3986($this->secret);
|
||||
}
|
||||
|
||||
function __toString() {
|
||||
function __toString()
|
||||
{
|
||||
return $this->to_string();
|
||||
}
|
||||
}
|
||||
|
@ -62,7 +68,8 @@ class OAuthToken {
|
|||
* A class for implementing a Signature Method
|
||||
* See section 9 ("Signing Requests") in the spec
|
||||
*/
|
||||
abstract class OAuthSignatureMethod {
|
||||
abstract class OAuthSignatureMethod
|
||||
{
|
||||
/**
|
||||
* Needs to return the name of the Signature Method (ie HMAC-SHA1)
|
||||
* @return string
|
||||
|
@ -89,25 +96,29 @@ abstract class OAuthSignatureMethod {
|
|||
* @param string $signature
|
||||
* @return bool
|
||||
*/
|
||||
public function check_signature($request, $consumer, $token, $signature) {
|
||||
public function check_signature($request, $consumer, $token, $signature)
|
||||
{
|
||||
$built = $this->build_signature($request, $consumer, $token);
|
||||
return ($built == $signature);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The HMAC-SHA1 signature method uses the HMAC-SHA1 signature algorithm as defined in [RFC2104]
|
||||
* where the Signature Base String is the text and the key is the concatenated values (each first
|
||||
* encoded per Parameter Encoding) of the Consumer Secret and Token Secret, separated by an '&'
|
||||
* The HMAC-SHA1 signature method uses the HMAC-SHA1 signature algorithm as defined in [RFC2104]
|
||||
* where the Signature Base String is the text and the key is the concatenated values (each first
|
||||
* encoded per Parameter Encoding) of the Consumer Secret and Token Secret, separated by an '&'
|
||||
* character (ASCII code 38) even if empty.
|
||||
* - Chapter 9.2 ("HMAC-SHA1")
|
||||
*/
|
||||
class OAuthSignatureMethod_HMAC_SHA1 extends OAuthSignatureMethod {
|
||||
function get_name() {
|
||||
class OAuthSignatureMethod_HMAC_SHA1 extends OAuthSignatureMethod
|
||||
{
|
||||
function get_name()
|
||||
{
|
||||
return "HMAC-SHA1";
|
||||
}
|
||||
|
||||
public function build_signature($request, $consumer, $token) {
|
||||
public function build_signature($request, $consumer, $token)
|
||||
{
|
||||
$base_string = $request->get_signature_base_string();
|
||||
$request->base_string = $base_string;
|
||||
|
||||
|
@ -126,25 +137,28 @@ class OAuthSignatureMethod_HMAC_SHA1 extends OAuthSignatureMethod {
|
|||
}
|
||||
|
||||
/**
|
||||
* The PLAINTEXT method does not provide any security protection and SHOULD only be used
|
||||
* The PLAINTEXT method does not provide any security protection and SHOULD only be used
|
||||
* over a secure channel such as HTTPS. It does not use the Signature Base String.
|
||||
* - Chapter 9.4 ("PLAINTEXT")
|
||||
*/
|
||||
class OAuthSignatureMethod_PLAINTEXT extends OAuthSignatureMethod {
|
||||
public function get_name() {
|
||||
class OAuthSignatureMethod_PLAINTEXT extends OAuthSignatureMethod
|
||||
{
|
||||
public function get_name()
|
||||
{
|
||||
return "PLAINTEXT";
|
||||
}
|
||||
|
||||
/**
|
||||
* oauth_signature is set to the concatenated encoded values of the Consumer Secret and
|
||||
* Token Secret, separated by a '&' character (ASCII code 38), even if either secret is
|
||||
* oauth_signature is set to the concatenated encoded values of the Consumer Secret and
|
||||
* Token Secret, separated by a '&' character (ASCII code 38), even if either secret is
|
||||
* empty. The result MUST be encoded again.
|
||||
* - Chapter 9.4.1 ("Generating Signatures")
|
||||
*
|
||||
* Please note that the second encoding MUST NOT happen in the SignatureMethod, as
|
||||
* OAuthRequest handles this!
|
||||
*/
|
||||
public function build_signature($request, $consumer, $token) {
|
||||
public function build_signature($request, $consumer, $token)
|
||||
{
|
||||
$key_parts = array(
|
||||
$consumer->secret,
|
||||
($token) ? $token->secret : ""
|
||||
|
@ -159,15 +173,17 @@ class OAuthSignatureMethod_PLAINTEXT extends OAuthSignatureMethod {
|
|||
}
|
||||
|
||||
/**
|
||||
* The RSA-SHA1 signature method uses the RSASSA-PKCS1-v1_5 signature algorithm as defined in
|
||||
* [RFC3447] section 8.2 (more simply known as PKCS#1), using SHA-1 as the hash function for
|
||||
* EMSA-PKCS1-v1_5. It is assumed that the Consumer has provided its RSA public key in a
|
||||
* verified way to the Service Provider, in a manner which is beyond the scope of this
|
||||
* The RSA-SHA1 signature method uses the RSASSA-PKCS1-v1_5 signature algorithm as defined in
|
||||
* [RFC3447] section 8.2 (more simply known as PKCS#1), using SHA-1 as the hash function for
|
||||
* EMSA-PKCS1-v1_5. It is assumed that the Consumer has provided its RSA public key in a
|
||||
* verified way to the Service Provider, in a manner which is beyond the scope of this
|
||||
* specification.
|
||||
* - Chapter 9.3 ("RSA-SHA1")
|
||||
*/
|
||||
abstract class OAuthSignatureMethod_RSA_SHA1 extends OAuthSignatureMethod {
|
||||
public function get_name() {
|
||||
abstract class OAuthSignatureMethod_RSA_SHA1 extends OAuthSignatureMethod
|
||||
{
|
||||
public function get_name()
|
||||
{
|
||||
return "RSA-SHA1";
|
||||
}
|
||||
|
||||
|
@ -185,7 +201,8 @@ abstract class OAuthSignatureMethod_RSA_SHA1 extends OAuthSignatureMethod {
|
|||
// Either way should return a string representation of the certificate
|
||||
protected abstract function fetch_private_cert(&$request);
|
||||
|
||||
public function build_signature($request, $consumer, $token) {
|
||||
public function build_signature($request, $consumer, $token)
|
||||
{
|
||||
$base_string = $request->get_signature_base_string();
|
||||
$request->base_string = $base_string;
|
||||
|
||||
|
@ -204,7 +221,8 @@ abstract class OAuthSignatureMethod_RSA_SHA1 extends OAuthSignatureMethod {
|
|||
return base64_encode($signature);
|
||||
}
|
||||
|
||||
public function check_signature($request, $consumer, $token, $signature) {
|
||||
public function check_signature($request, $consumer, $token, $signature)
|
||||
{
|
||||
$decoded_sig = base64_decode($signature);
|
||||
|
||||
$base_string = $request->get_signature_base_string();
|
||||
|
@ -225,7 +243,8 @@ abstract class OAuthSignatureMethod_RSA_SHA1 extends OAuthSignatureMethod {
|
|||
}
|
||||
}
|
||||
|
||||
class OAuthRequest {
|
||||
class OAuthRequest
|
||||
{
|
||||
private $parameters;
|
||||
private $http_method;
|
||||
private $http_url;
|
||||
|
@ -234,9 +253,10 @@ class OAuthRequest {
|
|||
public static $version = '1.0';
|
||||
public static $POST_INPUT = 'php://input';
|
||||
|
||||
function __construct($http_method, $http_url, $parameters=NULL) {
|
||||
function __construct($http_method, $http_url, $parameters = NULL)
|
||||
{
|
||||
@$parameters or $parameters = array();
|
||||
$parameters = array_merge( OAuthUtil::parse_parameters(parse_url($http_url, PHP_URL_QUERY)), $parameters);
|
||||
$parameters = array_merge(OAuthUtil::parse_parameters(parse_url($http_url, PHP_URL_QUERY)), $parameters);
|
||||
$this->parameters = $parameters;
|
||||
$this->http_method = $http_method;
|
||||
$this->http_url = $http_url;
|
||||
|
@ -246,15 +266,16 @@ class OAuthRequest {
|
|||
/**
|
||||
* attempt to build up a request from what was passed to the server
|
||||
*/
|
||||
public static function from_request($http_method=NULL, $http_url=NULL, $parameters=NULL) {
|
||||
public static function from_request($http_method = NULL, $http_url = NULL, $parameters = NULL)
|
||||
{
|
||||
$scheme = (!isset($_SERVER['HTTPS']) || $_SERVER['HTTPS'] != "on")
|
||||
? 'http'
|
||||
: 'https';
|
||||
? 'http'
|
||||
: 'https';
|
||||
@$http_url or $http_url = $scheme .
|
||||
'://' . $_SERVER['HTTP_HOST'] .
|
||||
':' .
|
||||
$_SERVER['SERVER_PORT'] .
|
||||
$_SERVER['REQUEST_URI'];
|
||||
'://' . $_SERVER['HTTP_HOST'] .
|
||||
':' .
|
||||
$_SERVER['SERVER_PORT'] .
|
||||
$_SERVER['REQUEST_URI'];
|
||||
@$http_method or $http_method = $_SERVER['REQUEST_METHOD'];
|
||||
|
||||
// We weren't handed any parameters, so let's find the ones relevant to
|
||||
|
@ -270,10 +291,13 @@ class OAuthRequest {
|
|||
|
||||
// It's a POST request of the proper content-type, so parse POST
|
||||
// parameters and add those overriding any duplicates from GET
|
||||
if ($http_method == "POST"
|
||||
&& @strstr($request_headers["Content-Type"],
|
||||
"application/x-www-form-urlencoded")
|
||||
) {
|
||||
if (
|
||||
$http_method == "POST"
|
||||
&& @strstr(
|
||||
$request_headers["Content-Type"],
|
||||
"application/x-www-form-urlencoded"
|
||||
)
|
||||
) {
|
||||
$post_data = OAuthUtil::parse_parameters(
|
||||
file_get_contents(self::$POST_INPUT)
|
||||
);
|
||||
|
@ -288,25 +312,27 @@ class OAuthRequest {
|
|||
);
|
||||
$parameters = array_merge($parameters, $header_parameters);
|
||||
}
|
||||
|
||||
}
|
||||
// fix for friendica redirect system
|
||||
|
||||
$http_url = substr($http_url, 0, strpos($http_url,$parameters['pagename'])+strlen($parameters['pagename']));
|
||||
unset( $parameters['pagename'] );
|
||||
|
||||
|
||||
$http_url = substr($http_url, 0, strpos($http_url, $parameters['pagename']) + strlen($parameters['pagename']));
|
||||
unset($parameters['pagename']);
|
||||
|
||||
return new OAuthRequest($http_method, $http_url, $parameters);
|
||||
}
|
||||
|
||||
/**
|
||||
* pretty much a helper function to set up the request
|
||||
*/
|
||||
public static function from_consumer_and_token($consumer, $token, $http_method, $http_url, $parameters=NULL) {
|
||||
public static function from_consumer_and_token($consumer, $token, $http_method, $http_url, $parameters = NULL)
|
||||
{
|
||||
@$parameters or $parameters = array();
|
||||
$defaults = array("oauth_version" => OAuthRequest::$version,
|
||||
"oauth_nonce" => OAuthRequest::generate_nonce(),
|
||||
"oauth_timestamp" => OAuthRequest::generate_timestamp(),
|
||||
"oauth_consumer_key" => $consumer->key);
|
||||
$defaults = array(
|
||||
"oauth_version" => OAuthRequest::$version,
|
||||
"oauth_nonce" => OAuthRequest::generate_nonce(),
|
||||
"oauth_timestamp" => OAuthRequest::generate_timestamp(),
|
||||
"oauth_consumer_key" => $consumer->key
|
||||
);
|
||||
if ($token)
|
||||
$defaults['oauth_token'] = $token->key;
|
||||
|
||||
|
@ -315,7 +341,8 @@ class OAuthRequest {
|
|||
return new OAuthRequest($http_method, $http_url, $parameters);
|
||||
}
|
||||
|
||||
public function set_parameter($name, $value, $allow_duplicates = true) {
|
||||
public function set_parameter($name, $value, $allow_duplicates = true)
|
||||
{
|
||||
if ($allow_duplicates && isset($this->parameters[$name])) {
|
||||
// We have already added parameter(s) with this name, so add to the list
|
||||
if (is_scalar($this->parameters[$name])) {
|
||||
|
@ -330,15 +357,18 @@ class OAuthRequest {
|
|||
}
|
||||
}
|
||||
|
||||
public function get_parameter($name) {
|
||||
public function get_parameter($name)
|
||||
{
|
||||
return isset($this->parameters[$name]) ? $this->parameters[$name] : null;
|
||||
}
|
||||
|
||||
public function get_parameters() {
|
||||
public function get_parameters()
|
||||
{
|
||||
return $this->parameters;
|
||||
}
|
||||
|
||||
public function unset_parameter($name) {
|
||||
public function unset_parameter($name)
|
||||
{
|
||||
unset($this->parameters[$name]);
|
||||
}
|
||||
|
||||
|
@ -346,7 +376,8 @@ class OAuthRequest {
|
|||
* The request parameters, sorted and concatenated into a normalized string.
|
||||
* @return string
|
||||
*/
|
||||
public function get_signable_parameters() {
|
||||
public function get_signable_parameters()
|
||||
{
|
||||
// Grab all parameters
|
||||
$params = $this->parameters;
|
||||
|
||||
|
@ -366,7 +397,8 @@ class OAuthRequest {
|
|||
* and the parameters (normalized), each urlencoded
|
||||
* and the concated with &.
|
||||
*/
|
||||
public function get_signature_base_string() {
|
||||
public function get_signature_base_string()
|
||||
{
|
||||
$parts = array(
|
||||
$this->get_normalized_http_method(),
|
||||
$this->get_normalized_http_url(),
|
||||
|
@ -381,7 +413,8 @@ class OAuthRequest {
|
|||
/**
|
||||
* just uppercases the http method
|
||||
*/
|
||||
public function get_normalized_http_method() {
|
||||
public function get_normalized_http_method()
|
||||
{
|
||||
return strtoupper($this->http_method);
|
||||
}
|
||||
|
||||
|
@ -389,7 +422,8 @@ class OAuthRequest {
|
|||
* parses the url and rebuilds it to be
|
||||
* scheme://host/path
|
||||
*/
|
||||
public function get_normalized_http_url() {
|
||||
public function get_normalized_http_url()
|
||||
{
|
||||
$parts = parse_url($this->http_url);
|
||||
|
||||
$port = @$parts['port'];
|
||||
|
@ -400,7 +434,8 @@ class OAuthRequest {
|
|||
$port or $port = ($scheme == 'https') ? '443' : '80';
|
||||
|
||||
if (($scheme == 'https' && $port != '443')
|
||||
|| ($scheme == 'http' && $port != '80')) {
|
||||
|| ($scheme == 'http' && $port != '80')
|
||||
) {
|
||||
$host = "$host:$port";
|
||||
}
|
||||
return "$scheme://$host$path";
|
||||
|
@ -409,11 +444,12 @@ class OAuthRequest {
|
|||
/**
|
||||
* builds a url usable for a GET request
|
||||
*/
|
||||
public function to_url() {
|
||||
public function to_url()
|
||||
{
|
||||
$post_data = $this->to_postdata();
|
||||
$out = $this->get_normalized_http_url();
|
||||
if ($post_data) {
|
||||
$out .= '?'.$post_data;
|
||||
$out .= '?' . $post_data;
|
||||
}
|
||||
return $out;
|
||||
}
|
||||
|
@ -421,9 +457,10 @@ class OAuthRequest {
|
|||
/**
|
||||
* builds the data one would send in a POST request
|
||||
*/
|
||||
public function to_postdata($raw = false) {
|
||||
public function to_postdata($raw = false)
|
||||
{
|
||||
if ($raw)
|
||||
return($this->parameters);
|
||||
return $this->parameters;
|
||||
else
|
||||
return OAuthUtil::build_http_query($this->parameters);
|
||||
}
|
||||
|
@ -431,15 +468,15 @@ class OAuthRequest {
|
|||
/**
|
||||
* builds the Authorization: header
|
||||
*/
|
||||
public function to_header($realm=null) {
|
||||
public function to_header($realm = null)
|
||||
{
|
||||
$first = true;
|
||||
if($realm) {
|
||||
if ($realm) {
|
||||
$out = 'Authorization: OAuth realm="' . OAuthUtil::urlencode_rfc3986($realm) . '"';
|
||||
$first = false;
|
||||
} else
|
||||
$out = 'Authorization: OAuth';
|
||||
|
||||
$total = array();
|
||||
foreach ($this->parameters as $k => $v) {
|
||||
if (substr($k, 0, 5) != "oauth") continue;
|
||||
if (is_array($v)) {
|
||||
|
@ -447,20 +484,22 @@ class OAuthRequest {
|
|||
}
|
||||
$out .= ($first) ? ' ' : ',';
|
||||
$out .= OAuthUtil::urlencode_rfc3986($k) .
|
||||
'="' .
|
||||
OAuthUtil::urlencode_rfc3986($v) .
|
||||
'"';
|
||||
'="' .
|
||||
OAuthUtil::urlencode_rfc3986($v) .
|
||||
'"';
|
||||
$first = false;
|
||||
}
|
||||
return $out;
|
||||
}
|
||||
|
||||
public function __toString() {
|
||||
public function __toString()
|
||||
{
|
||||
return $this->to_url();
|
||||
}
|
||||
|
||||
|
||||
public function sign_request($signature_method, $consumer, $token) {
|
||||
public function sign_request($signature_method, $consumer, $token)
|
||||
{
|
||||
$this->set_parameter(
|
||||
"oauth_signature_method",
|
||||
$signature_method->get_name(),
|
||||
|
@ -470,7 +509,8 @@ class OAuthRequest {
|
|||
$this->set_parameter("oauth_signature", $signature, false);
|
||||
}
|
||||
|
||||
public function build_signature($signature_method, $consumer, $token) {
|
||||
public function build_signature($signature_method, $consumer, $token)
|
||||
{
|
||||
$signature = $signature_method->build_signature($this, $consumer, $token);
|
||||
return $signature;
|
||||
}
|
||||
|
@ -478,33 +518,35 @@ class OAuthRequest {
|
|||
/**
|
||||
* util function: current timestamp
|
||||
*/
|
||||
private static function generate_timestamp() {
|
||||
private static function generate_timestamp()
|
||||
{
|
||||
return time();
|
||||
}
|
||||
|
||||
/**
|
||||
* util function: current nonce
|
||||
*/
|
||||
private static function generate_nonce() {
|
||||
$mt = microtime();
|
||||
$rand = mt_rand();
|
||||
|
||||
return md5($mt . $rand); // md5s look nicer than numbers
|
||||
private static function generate_nonce()
|
||||
{
|
||||
return Friendica\Util\Strings::getRandomHex(32);
|
||||
}
|
||||
}
|
||||
|
||||
class OAuthServer {
|
||||
class OAuthServer
|
||||
{
|
||||
protected $timestamp_threshold = 300; // in seconds, five minutes
|
||||
protected $version = '1.0'; // hi blaine
|
||||
protected $signature_methods = array();
|
||||
|
||||
protected $data_store;
|
||||
|
||||
function __construct($data_store) {
|
||||
function __construct($data_store)
|
||||
{
|
||||
$this->data_store = $data_store;
|
||||
}
|
||||
|
||||
public function add_signature_method($signature_method) {
|
||||
public function add_signature_method($signature_method)
|
||||
{
|
||||
$this->signature_methods[$signature_method->get_name()] =
|
||||
$signature_method;
|
||||
}
|
||||
|
@ -515,7 +557,8 @@ class OAuthServer {
|
|||
* process a request_token request
|
||||
* returns the request token on success
|
||||
*/
|
||||
public function fetch_request_token(&$request) {
|
||||
public function fetch_request_token(&$request)
|
||||
{
|
||||
$this->get_version($request);
|
||||
|
||||
$consumer = $this->get_consumer($request);
|
||||
|
@ -536,7 +579,8 @@ class OAuthServer {
|
|||
* process an access_token request
|
||||
* returns the access token on success
|
||||
*/
|
||||
public function fetch_access_token(&$request) {
|
||||
public function fetch_access_token(&$request)
|
||||
{
|
||||
$this->get_version($request);
|
||||
|
||||
$consumer = $this->get_consumer($request);
|
||||
|
@ -556,22 +600,24 @@ class OAuthServer {
|
|||
/**
|
||||
* verify an api call, checks all the parameters
|
||||
*/
|
||||
public function verify_request(&$request) {
|
||||
public function verify_request(&$request)
|
||||
{
|
||||
$this->get_version($request);
|
||||
$consumer = $this->get_consumer($request);
|
||||
$token = $this->get_token($request, $consumer, "access");
|
||||
$this->check_signature($request, $consumer, $token);
|
||||
return array($consumer, $token);
|
||||
return [$consumer, $token];
|
||||
}
|
||||
|
||||
// Internals from here
|
||||
/**
|
||||
* version 1
|
||||
*/
|
||||
private function get_version(&$request) {
|
||||
private function get_version(&$request)
|
||||
{
|
||||
$version = $request->get_parameter("oauth_version");
|
||||
if (!$version) {
|
||||
// Service Providers MUST assume the protocol version to be 1.0 if this parameter is not present.
|
||||
// Service Providers MUST assume the protocol version to be 1.0 if this parameter is not present.
|
||||
// Chapter 7.0 ("Accessing Protected Ressources")
|
||||
$version = '1.0';
|
||||
}
|
||||
|
@ -584,9 +630,10 @@ class OAuthServer {
|
|||
/**
|
||||
* figure out the signature with some defaults
|
||||
*/
|
||||
private function get_signature_method(&$request) {
|
||||
private function get_signature_method(&$request)
|
||||
{
|
||||
$signature_method =
|
||||
@$request->get_parameter("oauth_signature_method");
|
||||
@$request->get_parameter("oauth_signature_method");
|
||||
|
||||
if (!$signature_method) {
|
||||
// According to chapter 7 ("Accessing Protected Ressources") the signature-method
|
||||
|
@ -594,12 +641,14 @@ class OAuthServer {
|
|||
throw new OAuthException('No signature method parameter. This parameter is required');
|
||||
}
|
||||
|
||||
if (!in_array($signature_method,
|
||||
array_keys($this->signature_methods))) {
|
||||
if (!in_array(
|
||||
$signature_method,
|
||||
array_keys($this->signature_methods)
|
||||
)) {
|
||||
throw new OAuthException(
|
||||
"Signature method '$signature_method' not supported " .
|
||||
"try one of the following: " .
|
||||
implode(", ", array_keys($this->signature_methods))
|
||||
"try one of the following: " .
|
||||
implode(", ", array_keys($this->signature_methods))
|
||||
);
|
||||
}
|
||||
return $this->signature_methods[$signature_method];
|
||||
|
@ -608,7 +657,8 @@ class OAuthServer {
|
|||
/**
|
||||
* try to find the consumer for the provided request's consumer key
|
||||
*/
|
||||
private function get_consumer(&$request) {
|
||||
private function get_consumer(&$request)
|
||||
{
|
||||
$consumer_key = @$request->get_parameter("oauth_consumer_key");
|
||||
if (!$consumer_key) {
|
||||
throw new OAuthException("Invalid consumer key");
|
||||
|
@ -625,10 +675,13 @@ class OAuthServer {
|
|||
/**
|
||||
* try to find the token for the provided request's token key
|
||||
*/
|
||||
private function get_token(&$request, $consumer, $token_type="access") {
|
||||
private function get_token(&$request, $consumer, $token_type = "access")
|
||||
{
|
||||
$token_field = @$request->get_parameter('oauth_token');
|
||||
$token = $this->data_store->lookup_token(
|
||||
$consumer, $token_type, $token_field
|
||||
$consumer,
|
||||
$token_type,
|
||||
$token_field
|
||||
);
|
||||
if (!$token) {
|
||||
throw new OAuthException("Invalid $token_type token: $token_field");
|
||||
|
@ -640,7 +693,8 @@ class OAuthServer {
|
|||
* all-in-one function to check the signature on a request
|
||||
* should guess the signature method appropriately
|
||||
*/
|
||||
private function check_signature(&$request, $consumer, $token) {
|
||||
private function check_signature(&$request, $consumer, $token)
|
||||
{
|
||||
// this should probably be in a different method
|
||||
$timestamp = @$request->get_parameter('oauth_timestamp');
|
||||
$nonce = @$request->get_parameter('oauth_nonce');
|
||||
|
@ -657,7 +711,7 @@ class OAuthServer {
|
|||
$token,
|
||||
$signature
|
||||
);
|
||||
|
||||
|
||||
|
||||
if (!$valid_sig) {
|
||||
throw new OAuthException("Invalid signature");
|
||||
|
@ -667,12 +721,13 @@ class OAuthServer {
|
|||
/**
|
||||
* check that the timestamp is new enough
|
||||
*/
|
||||
private function check_timestamp($timestamp) {
|
||||
if( ! $timestamp )
|
||||
private function check_timestamp($timestamp)
|
||||
{
|
||||
if (!$timestamp)
|
||||
throw new OAuthException(
|
||||
'Missing timestamp parameter. The parameter is required'
|
||||
);
|
||||
|
||||
|
||||
// verify that timestamp is recentish
|
||||
$now = time();
|
||||
if (abs($now - $timestamp) > $this->timestamp_threshold) {
|
||||
|
@ -685,8 +740,9 @@ class OAuthServer {
|
|||
/**
|
||||
* check that the nonce is not repeated
|
||||
*/
|
||||
private function check_nonce($consumer, $token, $nonce, $timestamp) {
|
||||
if( ! $nonce )
|
||||
private function check_nonce($consumer, $token, $nonce, $timestamp)
|
||||
{
|
||||
if (!$nonce)
|
||||
throw new OAuthException(
|
||||
'Missing nonce parameter. The parameter is required'
|
||||
);
|
||||
|
@ -702,65 +758,73 @@ class OAuthServer {
|
|||
throw new OAuthException("Nonce already used: $nonce");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class OAuthDataStore {
|
||||
function lookup_consumer($consumer_key) {
|
||||
class OAuthDataStore
|
||||
{
|
||||
function lookup_consumer($consumer_key)
|
||||
{
|
||||
// implement me
|
||||
}
|
||||
|
||||
function lookup_token($consumer, $token_type, $token) {
|
||||
function lookup_token($consumer, $token_type, $token)
|
||||
{
|
||||
// implement me
|
||||
}
|
||||
|
||||
function lookup_nonce($consumer, $token, $nonce, $timestamp) {
|
||||
function lookup_nonce($consumer, $token, $nonce, $timestamp)
|
||||
{
|
||||
// implement me
|
||||
}
|
||||
|
||||
function new_request_token($consumer, $callback = null) {
|
||||
function new_request_token($consumer, $callback = null)
|
||||
{
|
||||
// return a new token attached to this consumer
|
||||
}
|
||||
|
||||
function new_access_token($token, $consumer, $verifier = null) {
|
||||
function new_access_token($token, $consumer, $verifier = null)
|
||||
{
|
||||
// return a new access token attached to this consumer
|
||||
// for the user associated with this token if the request token
|
||||
// is authorized
|
||||
// should also invalidate the request token
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class OAuthUtil {
|
||||
public static function urlencode_rfc3986($input) {
|
||||
if (is_array($input)) {
|
||||
return array_map(array('OAuthUtil', 'urlencode_rfc3986'), $input);
|
||||
} else if (is_scalar($input)) {
|
||||
return str_replace(
|
||||
'+',
|
||||
' ',
|
||||
str_replace('%7E', '~', rawurlencode($input))
|
||||
);
|
||||
} else {
|
||||
return '';
|
||||
class OAuthUtil
|
||||
{
|
||||
public static function urlencode_rfc3986($input)
|
||||
{
|
||||
if (is_array($input)) {
|
||||
return array_map(['OAuthUtil', 'urlencode_rfc3986'], $input);
|
||||
} else if (is_scalar($input)) {
|
||||
return str_replace(
|
||||
'+',
|
||||
' ',
|
||||
str_replace('%7E', '~', rawurlencode($input))
|
||||
);
|
||||
} else {
|
||||
return '';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// This decode function isn't taking into consideration the above
|
||||
// modifications to the encoding process. However, this method doesn't
|
||||
// seem to be used anywhere so leaving it as is.
|
||||
public static function urldecode_rfc3986($string) {
|
||||
public static function urldecode_rfc3986($string)
|
||||
{
|
||||
return urldecode($string);
|
||||
}
|
||||
|
||||
// Utility function for turning the Authorization: header into
|
||||
// parameters, has to do some unescaping
|
||||
// Can filter out any non-oauth parameters if needed (default behaviour)
|
||||
public static function split_header($header, $only_allow_oauth_parameters = true) {
|
||||
public static function split_header($header, $only_allow_oauth_parameters = true)
|
||||
{
|
||||
$pattern = '/(([-_a-z]*)=("([^"]*)"|([^,]*)),?)/';
|
||||
$offset = 0;
|
||||
$params = array();
|
||||
$params = [];
|
||||
while (preg_match($pattern, $header, $matches, PREG_OFFSET_CAPTURE, $offset) > 0) {
|
||||
$match = $matches[0];
|
||||
$header_name = $matches[2][0];
|
||||
|
@ -779,7 +843,8 @@ class OAuthUtil {
|
|||
}
|
||||
|
||||
// helper to try to sort out headers for people who aren't running apache
|
||||
public static function get_headers() {
|
||||
public static function get_headers()
|
||||
{
|
||||
if (function_exists('apache_request_headers')) {
|
||||
// we need this to get the actual Authorization: header
|
||||
// because apache tends to tell us it doesn't exist
|
||||
|
@ -789,22 +854,22 @@ class OAuthUtil {
|
|||
// we always want the keys to be Cased-Like-This and arh()
|
||||
// returns the headers in the same case as they are in the
|
||||
// request
|
||||
$out = array();
|
||||
foreach( $headers AS $key => $value ) {
|
||||
$out = [];
|
||||
foreach ($headers as $key => $value) {
|
||||
$key = str_replace(
|
||||
" ",
|
||||
"-",
|
||||
ucwords(strtolower(str_replace("-", " ", $key)))
|
||||
);
|
||||
" ",
|
||||
"-",
|
||||
ucwords(strtolower(str_replace("-", " ", $key)))
|
||||
);
|
||||
$out[$key] = $value;
|
||||
}
|
||||
} else {
|
||||
// otherwise we don't have apache and are just going to have to hope
|
||||
// that $_SERVER actually contains what we need
|
||||
$out = array();
|
||||
if( isset($_SERVER['CONTENT_TYPE']) )
|
||||
$out = [];
|
||||
if (isset($_SERVER['CONTENT_TYPE']))
|
||||
$out['Content-Type'] = $_SERVER['CONTENT_TYPE'];
|
||||
if( isset($_ENV['CONTENT_TYPE']) )
|
||||
if (isset($_ENV['CONTENT_TYPE']))
|
||||
$out['Content-Type'] = $_ENV['CONTENT_TYPE'];
|
||||
|
||||
foreach ($_SERVER as $key => $value) {
|
||||
|
@ -827,12 +892,13 @@ class OAuthUtil {
|
|||
// This function takes a input like a=b&a=c&d=e and returns the parsed
|
||||
// parameters like this
|
||||
// array('a' => array('b','c'), 'd' => 'e')
|
||||
public static function parse_parameters( $input ) {
|
||||
public static function parse_parameters($input)
|
||||
{
|
||||
if (!isset($input) || !$input) return array();
|
||||
|
||||
$pairs = explode('&', $input);
|
||||
|
||||
$parsed_parameters = array();
|
||||
$parsed_parameters = [];
|
||||
foreach ($pairs as $pair) {
|
||||
$split = explode('=', $pair, 2);
|
||||
$parameter = OAuthUtil::urldecode_rfc3986($split[0]);
|
||||
|
@ -845,7 +911,7 @@ class OAuthUtil {
|
|||
if (is_scalar($parsed_parameters[$parameter])) {
|
||||
// This is the first duplicate, so transform scalar (string) into an array
|
||||
// so we can add the duplicates
|
||||
$parsed_parameters[$parameter] = array($parsed_parameters[$parameter]);
|
||||
$parsed_parameters[$parameter] = [$parsed_parameters[$parameter]];
|
||||
}
|
||||
|
||||
$parsed_parameters[$parameter][] = $value;
|
||||
|
@ -856,7 +922,8 @@ class OAuthUtil {
|
|||
return $parsed_parameters;
|
||||
}
|
||||
|
||||
public static function build_http_query($params) {
|
||||
public static function build_http_query($params)
|
||||
{
|
||||
if (!$params) return '';
|
||||
|
||||
// Urlencode both keys and values
|
||||
|
@ -868,7 +935,7 @@ class OAuthUtil {
|
|||
// Ref: Spec: 9.1.1 (1)
|
||||
uksort($params, 'strcmp');
|
||||
|
||||
$pairs = array();
|
||||
$pairs = [];
|
||||
foreach ($params as $parameter => $value) {
|
||||
if (is_array($value)) {
|
||||
// If two or more parameters share the same name, they are sorted by their value
|
||||
|
@ -886,5 +953,3 @@ class OAuthUtil {
|
|||
return implode('&', $pairs);
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
|
|
316
mod/acl.php
316
mod/acl.php
|
@ -1,316 +0,0 @@
|
|||
<?php
|
||||
|
||||
/* ACL selector json backend */
|
||||
|
||||
use Friendica\App;
|
||||
use Friendica\Content\Widget;
|
||||
use Friendica\Core\ACL;
|
||||
use Friendica\Core\Hook;
|
||||
use Friendica\Core\Logger;
|
||||
use Friendica\Core\Protocol;
|
||||
use Friendica\Database\DBA;
|
||||
use Friendica\Model\Contact;
|
||||
use Friendica\Model\Item;
|
||||
use Friendica\Util\Proxy as ProxyUtils;
|
||||
use Friendica\Util\Strings;
|
||||
|
||||
function acl_content(App $a)
|
||||
{
|
||||
if (!local_user()) {
|
||||
return '';
|
||||
}
|
||||
|
||||
$start = defaults($_REQUEST, 'start' , 0);
|
||||
$count = defaults($_REQUEST, 'count' , 100);
|
||||
$search = defaults($_REQUEST, 'search' , '');
|
||||
$type = defaults($_REQUEST, 'type' , '');
|
||||
$conv_id = defaults($_REQUEST, 'conversation', null);
|
||||
|
||||
// For use with jquery.textcomplete for private mail completion
|
||||
if (!empty($_REQUEST['query'])) {
|
||||
if (!$type) {
|
||||
$type = 'm';
|
||||
}
|
||||
$search = $_REQUEST['query'];
|
||||
}
|
||||
|
||||
Logger::info('ACL {action} - {subaction}', ['module' => 'acl', 'action' => 'content', 'subaction' => 'search', 'search' => $search, 'type' => $type, 'conversation' => $conv_id]);
|
||||
|
||||
if ($search != '') {
|
||||
$sql_extra = "AND `name` LIKE '%%" . DBA::escape($search) . "%%'";
|
||||
$sql_extra2 = "AND (`attag` LIKE '%%" . DBA::escape($search) . "%%' OR `name` LIKE '%%" . DBA::escape($search) . "%%' OR `nick` LIKE '%%" . DBA::escape($search) . "%%')";
|
||||
} else {
|
||||
/// @TODO Avoid these needless else blocks by putting variable-initialization atop of if()
|
||||
$sql_extra = $sql_extra2 = '';
|
||||
}
|
||||
|
||||
// count groups and contacts
|
||||
$group_count = 0;
|
||||
if ($type == '' || $type == 'g') {
|
||||
$r = q("SELECT COUNT(*) AS g FROM `group` WHERE NOT `deleted` AND `uid` = %d $sql_extra",
|
||||
intval(local_user())
|
||||
);
|
||||
$group_count = (int) $r[0]['g'];
|
||||
}
|
||||
|
||||
$sql_extra2 .= ' ' . Widget::unavailableNetworks();
|
||||
|
||||
$contact_count = 0;
|
||||
if ($type == '' || $type == 'c') {
|
||||
// autocomplete for editor mentions
|
||||
$r = q("SELECT COUNT(*) AS c FROM `contact`
|
||||
WHERE `uid` = %d AND NOT `self` AND NOT `deleted`
|
||||
AND NOT `blocked` AND NOT `pending` AND NOT `archive`
|
||||
AND `notify` != '' $sql_extra2",
|
||||
intval(local_user())
|
||||
);
|
||||
$contact_count = (int) $r[0]['c'];
|
||||
} elseif ($type == 'f') {
|
||||
// autocomplete for editor mentions of forums
|
||||
$r = q("SELECT COUNT(*) AS c FROM `contact`
|
||||
WHERE `uid` = %d AND NOT `self` AND NOT `deleted`
|
||||
AND NOT `blocked` AND NOT `pending` AND NOT `archive`
|
||||
AND (`forum` OR `prv`)
|
||||
AND `notify` != '' $sql_extra2",
|
||||
intval(local_user())
|
||||
);
|
||||
$contact_count = (int) $r[0]['c'];
|
||||
} elseif ($type == 'm') {
|
||||
// autocomplete for Private Messages
|
||||
$r = q("SELECT COUNT(*) AS c FROM `contact`
|
||||
WHERE `uid` = %d AND NOT `self` AND NOT `deleted`
|
||||
AND NOT `blocked` AND NOT `pending` AND NOT `archive`
|
||||
AND `network` IN ('%s', '%s', '%s') $sql_extra2",
|
||||
intval(local_user()),
|
||||
DBA::escape(Protocol::ACTIVITYPUB),
|
||||
DBA::escape(Protocol::DFRN),
|
||||
DBA::escape(Protocol::DIASPORA)
|
||||
);
|
||||
$contact_count = (int) $r[0]['c'];
|
||||
} elseif ($type == 'a') {
|
||||
// autocomplete for Contacts
|
||||
$r = q("SELECT COUNT(*) AS c FROM `contact`
|
||||
WHERE `uid` = %d AND NOT `self`
|
||||
AND NOT `pending` AND NOT `deleted` $sql_extra2",
|
||||
intval(local_user())
|
||||
);
|
||||
$contact_count = (int) $r[0]['c'];
|
||||
}
|
||||
|
||||
$tot = $group_count + $contact_count;
|
||||
|
||||
$groups = [];
|
||||
$contacts = [];
|
||||
|
||||
if ($type == '' || $type == 'g') {
|
||||
/// @todo We should cache this query.
|
||||
// This can be done when we can delete cache entries via wildcard
|
||||
$r = q("SELECT `group`.`id`, `group`.`name`, GROUP_CONCAT(DISTINCT `group_member`.`contact-id` SEPARATOR ',') AS uids
|
||||
FROM `group`
|
||||
INNER JOIN `group_member` ON `group_member`.`gid`=`group`.`id`
|
||||
WHERE NOT `group`.`deleted` AND `group`.`uid` = %d
|
||||
$sql_extra
|
||||
GROUP BY `group`.`name`, `group`.`id`
|
||||
ORDER BY `group`.`name`
|
||||
LIMIT %d,%d",
|
||||
intval(local_user()),
|
||||
intval($start),
|
||||
intval($count)
|
||||
);
|
||||
|
||||
foreach ($r as $g) {
|
||||
$groups[] = [
|
||||
'type' => 'g',
|
||||
'photo' => 'images/twopeople.png',
|
||||
'name' => htmlspecialchars($g['name']),
|
||||
'id' => intval($g['id']),
|
||||
'uids' => array_map('intval', explode(',', $g['uids'])),
|
||||
'link' => '',
|
||||
'forum' => '0'
|
||||
];
|
||||
}
|
||||
if ((count($groups) > 0) && ($search == '')) {
|
||||
$groups[] = ['separator' => true];
|
||||
}
|
||||
}
|
||||
|
||||
$r = [];
|
||||
if ($type == '') {
|
||||
$r = q("SELECT `id`, `name`, `nick`, `micro`, `network`, `url`, `attag`, `addr`, `forum`, `prv`, (`prv` OR `forum`) AS `frm` FROM `contact`
|
||||
WHERE `uid` = %d AND NOT `self` AND NOT `deleted` AND NOT `blocked` AND NOT `pending` AND NOT `archive` AND `notify` != ''
|
||||
AND NOT (`network` IN ('%s', '%s'))
|
||||
$sql_extra2
|
||||
ORDER BY `name` ASC ",
|
||||
intval(local_user()),
|
||||
DBA::escape(Protocol::OSTATUS),
|
||||
DBA::escape(Protocol::STATUSNET)
|
||||
);
|
||||
} elseif ($type == 'c') {
|
||||
$r = q("SELECT `id`, `name`, `nick`, `micro`, `network`, `url`, `attag`, `addr`, `forum`, `prv` FROM `contact`
|
||||
WHERE `uid` = %d AND NOT `self` AND NOT `deleted` AND NOT `blocked` AND NOT `pending` AND NOT `archive` AND `notify` != ''
|
||||
AND NOT (`network` IN ('%s'))
|
||||
$sql_extra2
|
||||
ORDER BY `name` ASC ",
|
||||
intval(local_user()),
|
||||
DBA::escape(Protocol::STATUSNET)
|
||||
);
|
||||
} elseif ($type == 'f') {
|
||||
$r = q("SELECT `id`, `name`, `nick`, `micro`, `network`, `url`, `attag`, `addr`, `forum`, `prv` FROM `contact`
|
||||
WHERE `uid` = %d AND NOT `self` AND NOT `deleted` AND NOT `blocked` AND NOT `pending` AND NOT `archive` AND `notify` != ''
|
||||
AND NOT (`network` IN ('%s'))
|
||||
AND (`forum` OR `prv`)
|
||||
$sql_extra2
|
||||
ORDER BY `name` ASC ",
|
||||
intval(local_user()),
|
||||
DBA::escape(Protocol::STATUSNET)
|
||||
);
|
||||
} elseif ($type == 'm') {
|
||||
$r = q("SELECT `id`, `name`, `nick`, `micro`, `network`, `url`, `attag`, `addr` FROM `contact`
|
||||
WHERE `uid` = %d AND NOT `self` AND NOT `deleted` AND NOT `blocked` AND NOT `pending` AND NOT `archive`
|
||||
AND `network` IN ('%s', '%s', '%s')
|
||||
$sql_extra2
|
||||
ORDER BY `name` ASC ",
|
||||
intval(local_user()),
|
||||
DBA::escape(Protocol::ACTIVITYPUB),
|
||||
DBA::escape(Protocol::DFRN),
|
||||
DBA::escape(Protocol::DIASPORA)
|
||||
);
|
||||
} elseif ($type == 'a') {
|
||||
$r = q("SELECT `id`, `name`, `nick`, `micro`, `network`, `url`, `attag`, `addr`, `forum`, `prv` FROM `contact`
|
||||
WHERE `uid` = %d AND NOT `deleted` AND NOT `pending` AND NOT `archive`
|
||||
$sql_extra2
|
||||
ORDER BY `name` ASC ",
|
||||
intval(local_user())
|
||||
);
|
||||
} elseif ($type == 'x') {
|
||||
// autocomplete for global contact search (e.g. navbar search)
|
||||
$search = Strings::escapeTags(trim($_REQUEST['search']));
|
||||
$mode = $_REQUEST['smode'];
|
||||
|
||||
$r = ACL::contactAutocomplete($search, $mode);
|
||||
|
||||
$contacts = [];
|
||||
foreach ($r as $g) {
|
||||
$contacts[] = [
|
||||
'photo' => ProxyUtils::proxifyUrl($g['photo'], false, ProxyUtils::SIZE_MICRO),
|
||||
'name' => htmlspecialchars($g['name']),
|
||||
'nick' => defaults($g, 'addr', $g['url']),
|
||||
'network' => $g['network'],
|
||||
'link' => $g['url'],
|
||||
'forum' => !empty($g['community']) ? 1 : 0,
|
||||
];
|
||||
}
|
||||
$o = [
|
||||
'start' => $start,
|
||||
'count' => $count,
|
||||
'items' => $contacts,
|
||||
];
|
||||
echo json_encode($o);
|
||||
exit;
|
||||
}
|
||||
|
||||
if (DBA::isResult($r)) {
|
||||
$forums = [];
|
||||
foreach ($r as $g) {
|
||||
$entry = [
|
||||
'type' => 'c',
|
||||
'photo' => ProxyUtils::proxifyUrl($g['micro'], false, ProxyUtils::SIZE_MICRO),
|
||||
'name' => htmlspecialchars($g['name']),
|
||||
'id' => intval($g['id']),
|
||||
'network' => $g['network'],
|
||||
'link' => $g['url'],
|
||||
'nick' => htmlentities(defaults($g, 'attag', $g['nick'])),
|
||||
'addr' => htmlentities(defaults($g, 'addr', $g['url'])),
|
||||
'forum' => !empty($g['forum']) || !empty($g['prv']) ? 1 : 0,
|
||||
];
|
||||
if ($entry['forum']) {
|
||||
$forums[] = $entry;
|
||||
} else {
|
||||
$contacts[] = $entry;
|
||||
}
|
||||
}
|
||||
if (count($forums) > 0) {
|
||||
if ($search == '') {
|
||||
$forums[] = ['separator' => true];
|
||||
}
|
||||
$contacts = array_merge($forums, $contacts);
|
||||
}
|
||||
}
|
||||
|
||||
$items = array_merge($groups, $contacts);
|
||||
|
||||
if ($conv_id) {
|
||||
// In multi threaded posts the conv_id is not the parent of the whole thread
|
||||
$parent_item = Item::selectFirst(['parent'], ['id' => $conv_id]);
|
||||
if (DBA::isResult($parent_item)) {
|
||||
$conv_id = $parent_item['parent'];
|
||||
}
|
||||
|
||||
/*
|
||||
* if $conv_id is set, get unknown contacts in thread
|
||||
* but first get known contacts url to filter them out
|
||||
*/
|
||||
$known_contacts = array_map(function ($i) {
|
||||
return $i['link'];
|
||||
}, $contacts);
|
||||
|
||||
$unknown_contacts = [];
|
||||
|
||||
$condition = ["`parent` = ?", $conv_id];
|
||||
$params = ['order' => ['author-name' => true]];
|
||||
$authors = Item::selectForUser(local_user(), ['author-link'], $condition, $params);
|
||||
$item_authors = [];
|
||||
while ($author = Item::fetch($authors)) {
|
||||
$item_authors[$author['author-link']] = $author['author-link'];
|
||||
}
|
||||
DBA::close($authors);
|
||||
|
||||
foreach ($item_authors as $author) {
|
||||
if (in_array($author, $known_contacts)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$contact = Contact::getDetailsByURL($author);
|
||||
|
||||
if (count($contact) > 0) {
|
||||
$unknown_contacts[] = [
|
||||
'type' => 'c',
|
||||
'photo' => ProxyUtils::proxifyUrl($contact['micro'], false, ProxyUtils::SIZE_MICRO),
|
||||
'name' => htmlspecialchars($contact['name']),
|
||||
'id' => intval($contact['cid']),
|
||||
'network' => $contact['network'],
|
||||
'link' => $contact['url'],
|
||||
'nick' => htmlentities(defaults($contact, 'nick', $contact['addr'])),
|
||||
'addr' => htmlentities(defaults($contact, 'addr', $contact['url'])),
|
||||
'forum' => $contact['forum']
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
$items = array_merge($items, $unknown_contacts);
|
||||
$tot += count($unknown_contacts);
|
||||
}
|
||||
|
||||
$results = [
|
||||
'tot' => $tot,
|
||||
'start' => $start,
|
||||
'count' => $count,
|
||||
'groups' => $groups,
|
||||
'contacts' => $contacts,
|
||||
'items' => $items,
|
||||
'type' => $type,
|
||||
'search' => $search,
|
||||
];
|
||||
|
||||
Hook::callAll('acl_lookup_end', $results);
|
||||
|
||||
$o = [
|
||||
'tot' => $results['tot'],
|
||||
'start' => $results['start'],
|
||||
'count' => $results['count'],
|
||||
'items' => $results['items'],
|
||||
];
|
||||
|
||||
echo json_encode($o);
|
||||
exit;
|
||||
}
|
|
@ -2,6 +2,7 @@
|
|||
/**
|
||||
* @file mod/api.php
|
||||
*/
|
||||
|
||||
use Friendica\App;
|
||||
use Friendica\Core\Config;
|
||||
use Friendica\Core\L10n;
|
||||
|
@ -9,7 +10,7 @@ use Friendica\Core\Renderer;
|
|||
use Friendica\Database\DBA;
|
||||
use Friendica\Module\Login;
|
||||
|
||||
require_once 'include/api.php';
|
||||
require_once __DIR__ . '/../include/api.php';
|
||||
|
||||
function oauth_get_client(OAuthRequest $request)
|
||||
{
|
||||
|
|
22
mod/cal.php
22
mod/cal.php
|
@ -14,6 +14,7 @@ use Friendica\Core\Config;
|
|||
use Friendica\Core\L10n;
|
||||
use Friendica\Core\Renderer;
|
||||
use Friendica\Core\System;
|
||||
use Friendica\Core\Session;
|
||||
use Friendica\Database\DBA;
|
||||
use Friendica\Model\Contact;
|
||||
use Friendica\Model\Event;
|
||||
|
@ -26,11 +27,7 @@ use Friendica\Util\Temporal;
|
|||
|
||||
function cal_init(App $a)
|
||||
{
|
||||
if ($a->argc > 1) {
|
||||
DFRN::autoRedir($a, $a->argv[1]);
|
||||
}
|
||||
|
||||
if (Config::get('system', 'block_public') && !local_user() && !remote_user()) {
|
||||
if (Config::get('system', 'block_public') && !Session::isAuthenticated()) {
|
||||
throw new \Friendica\Network\HTTPException\ForbiddenException(L10n::t('Access denied.'));
|
||||
}
|
||||
|
||||
|
@ -113,18 +110,11 @@ function cal_content(App $a)
|
|||
$owner_uid = intval($a->data['user']['uid']);
|
||||
$nick = $a->data['user']['nickname'];
|
||||
|
||||
if (!empty($_SESSION['remote']) && is_array($_SESSION['remote'])) {
|
||||
foreach ($_SESSION['remote'] as $v) {
|
||||
if ($v['uid'] == $a->profile['profile_uid']) {
|
||||
$contact_id = $v['cid'];
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!empty(Session::getRemoteContactID($a->profile['profile_uid']))) {
|
||||
$contact_id = Session::getRemoteContactID($a->profile['profile_uid']);
|
||||
}
|
||||
|
||||
$groups = [];
|
||||
if ($contact_id) {
|
||||
$groups = Group::getIdsByContactId($contact_id);
|
||||
$r = q("SELECT * FROM `contact` WHERE `id` = %d AND `uid` = %d LIMIT 1",
|
||||
intval($contact_id),
|
||||
intval($a->profile['profile_uid'])
|
||||
|
@ -142,7 +132,7 @@ function cal_content(App $a)
|
|||
}
|
||||
|
||||
// get the permissions
|
||||
$sql_perms = Item::getPermissionsSQLByUserId($owner_uid, $remote_contact, $groups);
|
||||
$sql_perms = Item::getPermissionsSQLByUserId($owner_uid);
|
||||
// we only want to have the events of the profile owner
|
||||
$sql_extra = " AND `event`.`cid` = 0 " . $sql_perms;
|
||||
|
||||
|
@ -210,7 +200,7 @@ function cal_content(App $a)
|
|||
|
||||
// put the event parametes in an array so we can better transmit them
|
||||
$event_params = [
|
||||
'event_id' => intval(defaults($_GET, 'id', 0)),
|
||||
'event_id' => intval($_GET['id'] ?? 0),
|
||||
'start' => $start,
|
||||
'finish' => $finish,
|
||||
'adjust_start' => $adjust_start,
|
||||
|
|
|
@ -118,7 +118,7 @@ function common_content(App $a)
|
|||
|
||||
$entry = [
|
||||
'url' => Model\Contact::magicLink($common_friend['url']),
|
||||
'itemurl' => defaults($contact_details, 'addr', $common_friend['url']),
|
||||
'itemurl' => ($contact_details['addr'] ?? '') ?: $common_friend['url'],
|
||||
'name' => $contact_details['name'],
|
||||
'thumb' => ProxyUtils::proxifyUrl($contact_details['thumb'], false, ProxyUtils::SIZE_THUMB),
|
||||
'img_hover' => $contact_details['name'],
|
||||
|
|
|
@ -17,19 +17,11 @@ use Friendica\Database\DBA;
|
|||
use Friendica\Model\Item;
|
||||
use Friendica\Model\User;
|
||||
|
||||
function community_init(App $a)
|
||||
{
|
||||
if (!local_user()) {
|
||||
unset($_SESSION['theme']);
|
||||
unset($_SESSION['mobile-theme']);
|
||||
}
|
||||
}
|
||||
|
||||
function community_content(App $a, $update = 0)
|
||||
{
|
||||
$o = '';
|
||||
|
||||
if (Config::get('system', 'block_public') && !local_user() && !remote_user()) {
|
||||
if (Config::get('system', 'block_public') && !Session::isAuthenticated()) {
|
||||
notice(L10n::t('Public access denied.') . EOL);
|
||||
return;
|
||||
}
|
||||
|
@ -227,6 +219,7 @@ function community_getitems($start, $itemspage, $content, $accounttype)
|
|||
$values = [$start, $itemspage];
|
||||
}
|
||||
|
||||
/// @todo Use "unsearchable" here as well (instead of "hidewall")
|
||||
$r = DBA::p("SELECT `item`.`uri`, `author`.`url` AS `author-link` FROM `thread`
|
||||
STRAIGHT_JOIN `user` ON `user`.`uid` = `thread`.`uid` AND NOT `user`.`hidewall`
|
||||
STRAIGHT_JOIN `item` ON `item`.`id` = `thread`.`iid`
|
||||
|
@ -237,9 +230,9 @@ function community_getitems($start, $itemspage, $content, $accounttype)
|
|||
return DBA::toArray($r);
|
||||
} elseif ($content == 'global') {
|
||||
if (!is_null($accounttype)) {
|
||||
$condition = ["`uid` = ? AND `owner`.`contact-type` = ?", 0, $accounttype];
|
||||
$condition = ["`uid` = ? AND NOT `author`.`unsearchable` AND NOT `owner`.`unsearchable` AND `owner`.`contact-type` = ?", 0, $accounttype];
|
||||
} else {
|
||||
$condition = ['uid' => 0];
|
||||
$condition = ["`uid` = ? AND NOT `author`.`unsearchable` AND NOT `owner`.`unsearchable`", 0];
|
||||
}
|
||||
|
||||
$r = Item::selectThreadForUser(0, ['uri'], $condition, ['order' => ['commented' => true], 'limit' => [$start, $itemspage]]);
|
||||
|
|
|
@ -38,17 +38,17 @@ function crepair_post(App $a)
|
|||
return;
|
||||
}
|
||||
|
||||
$name = defaults($_POST, 'name' , $contact['name']);
|
||||
$nick = defaults($_POST, 'nick' , '');
|
||||
$url = defaults($_POST, 'url' , '');
|
||||
$alias = defaults($_POST, 'alias' , '');
|
||||
$request = defaults($_POST, 'request' , '');
|
||||
$confirm = defaults($_POST, 'confirm' , '');
|
||||
$notify = defaults($_POST, 'notify' , '');
|
||||
$poll = defaults($_POST, 'poll' , '');
|
||||
$attag = defaults($_POST, 'attag' , '');
|
||||
$photo = defaults($_POST, 'photo' , '');
|
||||
$remote_self = defaults($_POST, 'remote_self', false);
|
||||
$name = ($_POST['name'] ?? '') ?: $contact['name'];
|
||||
$nick = $_POST['nick'] ?? '';
|
||||
$url = $_POST['url'] ?? '';
|
||||
$alias = $_POST['alias'] ?? '';
|
||||
$request = $_POST['request'] ?? '';
|
||||
$confirm = $_POST['confirm'] ?? '';
|
||||
$notify = $_POST['notify'] ?? '';
|
||||
$poll = $_POST['poll'] ?? '';
|
||||
$attag = $_POST['attag'] ?? '';
|
||||
$photo = $_POST['photo'] ?? '';
|
||||
$remote_self = $_POST['remote_self'] ?? false;
|
||||
$nurl = Strings::normaliseLink($url);
|
||||
|
||||
$r = DBA::update(
|
||||
|
|
191
mod/delegate.php
191
mod/delegate.php
|
@ -1,191 +0,0 @@
|
|||
<?php
|
||||
/**
|
||||
* @file mod/delegate.php
|
||||
*/
|
||||
|
||||
use Friendica\App;
|
||||
use Friendica\BaseModule;
|
||||
use Friendica\Core\L10n;
|
||||
use Friendica\Core\Protocol;
|
||||
use Friendica\Core\Renderer;
|
||||
use Friendica\Core\System;
|
||||
use Friendica\Database\DBA;
|
||||
use Friendica\Model\User;
|
||||
use Friendica\Util\Strings;
|
||||
|
||||
require_once 'mod/settings.php';
|
||||
|
||||
function delegate_init(App $a)
|
||||
{
|
||||
settings_init($a);
|
||||
}
|
||||
|
||||
function delegate_post(App $a)
|
||||
{
|
||||
if (!local_user()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (count($a->user) && !empty($a->user['uid']) && $a->user['uid'] != local_user()) {
|
||||
notice(L10n::t('Permission denied.') . EOL);
|
||||
return;
|
||||
}
|
||||
|
||||
BaseModule::checkFormSecurityTokenRedirectOnError('/delegate', 'delegate');
|
||||
|
||||
$parent_uid = defaults($_POST, 'parent_user', 0);
|
||||
$parent_password = defaults($_POST, 'parent_password', '');
|
||||
|
||||
if ($parent_uid != 0) {
|
||||
$user = DBA::selectFirst('user', ['nickname'], ['uid' => $parent_uid]);
|
||||
if (!DBA::isResult($user)) {
|
||||
notice(L10n::t('Parent user not found.') . EOL);
|
||||
return;
|
||||
}
|
||||
|
||||
$success = User::authenticate($user['nickname'], trim($parent_password));
|
||||
if (!$success) {
|
||||
notice(L10n::t('Permission denied.') . EOL);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
DBA::update('user', ['parent-uid' => $parent_uid], ['uid' => local_user()]);
|
||||
}
|
||||
|
||||
function delegate_content(App $a)
|
||||
{
|
||||
if (!local_user()) {
|
||||
notice(L10n::t('Permission denied.') . EOL);
|
||||
return;
|
||||
}
|
||||
|
||||
if ($a->argc > 2 && $a->argv[1] === 'add' && intval($a->argv[2])) {
|
||||
// delegated admins can view but not change delegation permissions
|
||||
if (!empty($_SESSION['submanage'])) {
|
||||
$a->internalRedirect('delegate');
|
||||
}
|
||||
|
||||
$user_id = $a->argv[2];
|
||||
|
||||
$user = DBA::selectFirst('user', ['nickname'], ['uid' => $user_id]);
|
||||
if (DBA::isResult($user)) {
|
||||
$condition = [
|
||||
'uid' => local_user(),
|
||||
'nurl' => Strings::normaliseLink(System::baseUrl() . '/profile/' . $user['nickname'])
|
||||
];
|
||||
if (DBA::exists('contact', $condition)) {
|
||||
DBA::insert('manage', ['uid' => $user_id, 'mid' => local_user()]);
|
||||
}
|
||||
}
|
||||
$a->internalRedirect('delegate');
|
||||
}
|
||||
|
||||
if ($a->argc > 2 && $a->argv[1] === 'remove' && intval($a->argv[2])) {
|
||||
// delegated admins can view but not change delegation permissions
|
||||
if (!empty($_SESSION['submanage'])) {
|
||||
$a->internalRedirect('delegate');
|
||||
}
|
||||
|
||||
DBA::delete('manage', ['uid' => $a->argv[2], 'mid' => local_user()]);
|
||||
$a->internalRedirect('delegate');
|
||||
}
|
||||
|
||||
// find everybody that currently has delegated management to this account/page
|
||||
$delegates = [];
|
||||
$r = q("SELECT * FROM `user` WHERE `uid` IN (SELECT `uid` FROM `manage` WHERE `mid` = %d)",
|
||||
intval(local_user())
|
||||
);
|
||||
if (DBA::isResult($r)) {
|
||||
$delegates = $r;
|
||||
}
|
||||
|
||||
$uids = [];
|
||||
foreach ($delegates as $rr) {
|
||||
$uids[] = $rr['uid'];
|
||||
}
|
||||
|
||||
// find every contact who might be a candidate for delegation
|
||||
$potentials = [];
|
||||
|
||||
$r = q("SELECT `nurl`
|
||||
FROM `contact`
|
||||
WHERE `self` = 0
|
||||
AND SUBSTRING_INDEX(`nurl`, '/', 3) = '%s'
|
||||
AND `uid` = %d
|
||||
AND `network` = '%s' ",
|
||||
DBA::escape(Strings::normaliseLink(System::baseUrl())),
|
||||
intval(local_user()),
|
||||
DBA::escape(Protocol::DFRN)
|
||||
);
|
||||
if (DBA::isResult($r)) {
|
||||
$nicknames = [];
|
||||
foreach ($r as $rr) {
|
||||
$nicknames[] = "'" . DBA::escape(basename($rr['nurl'])) . "'";
|
||||
}
|
||||
|
||||
$nicks = implode(',', $nicknames);
|
||||
|
||||
// get user records for all potential page delegates who are not already delegates or managers
|
||||
$r = q("SELECT `uid`, `username`, `nickname` FROM `user` WHERE `nickname` IN ($nicks)");
|
||||
if (DBA::isResult($r)) {
|
||||
foreach ($r as $rr) {
|
||||
if (!in_array($rr['uid'], $uids)) {
|
||||
$potentials[] = $rr;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
settings_init($a);
|
||||
|
||||
$user = DBA::selectFirst('user', ['parent-uid', 'email'], ['uid' => local_user()]);
|
||||
|
||||
$parent_user = null;
|
||||
|
||||
if (DBA::isResult($user)) {
|
||||
if (!DBA::exists('user', ['parent-uid' => local_user()])) {
|
||||
$parent_uid = $user['parent-uid'];
|
||||
$parents = [0 => L10n::t('No parent user')];
|
||||
|
||||
$fields = ['uid', 'username', 'nickname'];
|
||||
$condition = ['email' => $user['email'], 'verified' => true, 'blocked' => false, 'parent-uid' => 0];
|
||||
$parent_users = DBA::select('user', $fields, $condition);
|
||||
while ($parent = DBA::fetch($parent_users)) {
|
||||
if ($parent['uid'] != local_user()) {
|
||||
$parents[$parent['uid']] = sprintf('%s (%s)', $parent['username'], $parent['nickname']);
|
||||
}
|
||||
}
|
||||
$parent_user = ['parent_user', '', $parent_uid, '', $parents];
|
||||
}
|
||||
}
|
||||
|
||||
if (!is_null($parent_user)) {
|
||||
$parent_password = ['parent_password', L10n::t('Parent Password:'), '', L10n::t('Please enter the password of the parent account to legitimize your request.')];
|
||||
} else {
|
||||
$parent_password = '';
|
||||
}
|
||||
|
||||
$o = Renderer::replaceMacros(Renderer::getMarkupTemplate('delegate.tpl'), [
|
||||
'$form_security_token' => BaseModule::getFormSecurityToken('delegate'),
|
||||
'$parent_header' => L10n::t('Parent User'),
|
||||
'$parent_user' => $parent_user,
|
||||
'$parent_password' => $parent_password,
|
||||
'$parent_desc' => L10n::t('Parent users have total control about this account, including the account settings. Please double check whom you give this access.'),
|
||||
'$submit' => L10n::t('Save Settings'),
|
||||
'$header' => L10n::t('Delegate Page Management'),
|
||||
'$delegates_header' => L10n::t('Delegates'),
|
||||
'$base' => System::baseUrl(),
|
||||
'$desc' => L10n::t('Delegates are able to manage all aspects of this account/page except for basic account settings. Please do not delegate your personal account to anybody that you do not trust completely.'),
|
||||
'$head_delegates' => L10n::t('Existing Page Delegates'),
|
||||
'$delegates' => $delegates,
|
||||
'$head_potentials' => L10n::t('Potential Delegates'),
|
||||
'$potentials' => $potentials,
|
||||
'$remove' => L10n::t('Remove'),
|
||||
'$add' => L10n::t('Add'),
|
||||
'$none' => L10n::t('No entries.')
|
||||
]);
|
||||
|
||||
|
||||
return $o;
|
||||
}
|
|
@ -59,7 +59,7 @@ function dfrn_confirm_post(App $a, $handsfree = null)
|
|||
* since we are operating on behalf of our registered user to approve a friendship.
|
||||
*/
|
||||
if (empty($_POST['source_url'])) {
|
||||
$uid = defaults($handsfree, 'uid', local_user());
|
||||
$uid = ($handsfree['uid'] ?? 0) ?: local_user();
|
||||
if (!$uid) {
|
||||
notice(L10n::t('Permission denied.') . EOL);
|
||||
return;
|
||||
|
@ -78,13 +78,13 @@ function dfrn_confirm_post(App $a, $handsfree = null)
|
|||
$intro_id = $handsfree['intro_id'];
|
||||
$duplex = $handsfree['duplex'];
|
||||
$cid = 0;
|
||||
$hidden = intval(defaults($handsfree, 'hidden' , 0));
|
||||
$hidden = intval($handsfree['hidden'] ?? 0);
|
||||
} else {
|
||||
$dfrn_id = Strings::escapeTags(trim(defaults($_POST, 'dfrn_id' , '')));
|
||||
$intro_id = intval(defaults($_POST, 'intro_id' , 0));
|
||||
$duplex = intval(defaults($_POST, 'duplex' , 0));
|
||||
$cid = intval(defaults($_POST, 'contact_id', 0));
|
||||
$hidden = intval(defaults($_POST, 'hidden' , 0));
|
||||
$dfrn_id = Strings::escapeTags(trim($_POST['dfrn_id'] ?? ''));
|
||||
$intro_id = intval($_POST['intro_id'] ?? 0);
|
||||
$duplex = intval($_POST['duplex'] ?? 0);
|
||||
$cid = intval($_POST['contact_id'] ?? 0);
|
||||
$hidden = intval($_POST['hidden'] ?? 0);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -347,12 +347,12 @@ function dfrn_confirm_post(App $a, $handsfree = null)
|
|||
*/
|
||||
if (!empty($_POST['source_url'])) {
|
||||
// We are processing an external confirmation to an introduction created by our user.
|
||||
$public_key = defaults($_POST, 'public_key', '');
|
||||
$dfrn_id = hex2bin(defaults($_POST, 'dfrn_id' , ''));
|
||||
$source_url = hex2bin(defaults($_POST, 'source_url', ''));
|
||||
$aes_key = defaults($_POST, 'aes_key' , '');
|
||||
$duplex = intval(defaults($_POST, 'duplex' , 0));
|
||||
$page = intval(defaults($_POST, 'page' , 0));
|
||||
$public_key = $_POST['public_key'] ?? '';
|
||||
$dfrn_id = hex2bin($_POST['dfrn_id'] ?? '');
|
||||
$source_url = hex2bin($_POST['source_url'] ?? '');
|
||||
$aes_key = $_POST['aes_key'] ?? '';
|
||||
$duplex = intval($_POST['duplex'] ?? 0);
|
||||
$page = intval($_POST['page'] ?? 0);
|
||||
|
||||
$forum = (($page == 1) ? 1 : 0);
|
||||
$prv = (($page == 2) ? 1 : 0);
|
||||
|
|
|
@ -26,7 +26,7 @@ function dfrn_notify_post(App $a) {
|
|||
if (empty($_POST) || !empty($postdata)) {
|
||||
$data = json_decode($postdata);
|
||||
if (is_object($data)) {
|
||||
$nick = defaults($a->argv, 1, '');
|
||||
$nick = $a->argv[1] ?? '';
|
||||
|
||||
$user = DBA::selectFirst('user', [], ['nickname' => $nick, 'account_expired' => false, 'account_removed' => false]);
|
||||
if (!DBA::isResult($user)) {
|
||||
|
@ -42,8 +42,8 @@ function dfrn_notify_post(App $a) {
|
|||
$dfrn_id = (!empty($_POST['dfrn_id']) ? Strings::escapeTags(trim($_POST['dfrn_id'])) : '');
|
||||
$dfrn_version = (!empty($_POST['dfrn_version']) ? (float) $_POST['dfrn_version'] : 2.0);
|
||||
$challenge = (!empty($_POST['challenge']) ? Strings::escapeTags(trim($_POST['challenge'])) : '');
|
||||
$data = defaults($_POST, 'data', '');
|
||||
$key = defaults($_POST, 'key', '');
|
||||
$data = $_POST['data'] ?? '';
|
||||
$key = $_POST['key'] ?? '';
|
||||
$rino_remote = (!empty($_POST['rino']) ? intval($_POST['rino']) : 0);
|
||||
$dissolve = (!empty($_POST['dissolve']) ? intval($_POST['dissolve']) : 0);
|
||||
$perm = (!empty($_POST['perm']) ? Strings::escapeTags(trim($_POST['perm'])) : 'r');
|
||||
|
|
|
@ -9,6 +9,7 @@ use Friendica\Core\Config;
|
|||
use Friendica\Core\L10n;
|
||||
use Friendica\Core\Logger;
|
||||
use Friendica\Core\System;
|
||||
use Friendica\Core\Session;
|
||||
use Friendica\Database\DBA;
|
||||
use Friendica\Module\Login;
|
||||
use Friendica\Protocol\DFRN;
|
||||
|
@ -21,17 +22,17 @@ function dfrn_poll_init(App $a)
|
|||
{
|
||||
Login::sessionAuth();
|
||||
|
||||
$dfrn_id = defaults($_GET, 'dfrn_id' , '');
|
||||
$type = defaults($_GET, 'type' , 'data');
|
||||
$last_update = defaults($_GET, 'last_update' , '');
|
||||
$destination_url = defaults($_GET, 'destination_url', '');
|
||||
$challenge = defaults($_GET, 'challenge' , '');
|
||||
$sec = defaults($_GET, 'sec' , '');
|
||||
$dfrn_version = (float) defaults($_GET, 'dfrn_version' , 2.0);
|
||||
$dfrn_id = $_GET['dfrn_id'] ?? '';
|
||||
$type = ($_GET['type'] ?? '') ?: 'data';
|
||||
$last_update = $_GET['last_update'] ?? '';
|
||||
$destination_url = $_GET['destination_url'] ?? '';
|
||||
$challenge = $_GET['challenge'] ?? '';
|
||||
$sec = $_GET['sec'] ?? '';
|
||||
$dfrn_version = floatval(($_GET['dfrn_version'] ?? 0.0) ?: 2.0);
|
||||
$quiet = !empty($_GET['quiet']);
|
||||
|
||||
// Possibly it is an OStatus compatible server that requests a user feed
|
||||
$user_agent = defaults($_SERVER, 'HTTP_USER_AGENT', '');
|
||||
$user_agent = $_SERVER['HTTP_USER_AGENT'] ?? '';
|
||||
if (($a->argc > 1) && ($dfrn_id == '') && !strstr($user_agent, 'Friendica')) {
|
||||
$nickname = $a->argv[1];
|
||||
header("Content-type: application/atom+xml");
|
||||
|
@ -49,7 +50,7 @@ function dfrn_poll_init(App $a)
|
|||
$hidewall = false;
|
||||
|
||||
if (($dfrn_id === '') && empty($_POST['dfrn_id'])) {
|
||||
if (Config::get('system', 'block_public') && !local_user() && !remote_user()) {
|
||||
if (Config::get('system', 'block_public') && !Session::isAuthenticated()) {
|
||||
throw new \Friendica\Network\HTTPException\ForbiddenException();
|
||||
}
|
||||
|
||||
|
@ -110,17 +111,14 @@ function dfrn_poll_init(App $a)
|
|||
|
||||
if ((int)$xml->status === 1) {
|
||||
$_SESSION['authenticated'] = 1;
|
||||
if (empty($_SESSION['remote'])) {
|
||||
$_SESSION['remote'] = [];
|
||||
}
|
||||
|
||||
$_SESSION['remote'][] = ['cid' => $r[0]['id'], 'uid' => $r[0]['uid'], 'url' => $r[0]['url']];
|
||||
|
||||
$_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::setVisitorsContacts();
|
||||
|
||||
if (!$quiet) {
|
||||
info(L10n::t('%1$s welcomes %2$s', $r[0]['username'], $r[0]['name']) . EOL);
|
||||
}
|
||||
|
@ -227,13 +225,13 @@ function dfrn_poll_init(App $a)
|
|||
|
||||
function dfrn_poll_post(App $a)
|
||||
{
|
||||
$dfrn_id = defaults($_POST, 'dfrn_id' , '');
|
||||
$challenge = defaults($_POST, 'challenge', '');
|
||||
$url = defaults($_POST, 'url' , '');
|
||||
$sec = defaults($_POST, 'sec' , '');
|
||||
$ptype = defaults($_POST, 'type' , '');
|
||||
$perm = defaults($_POST, 'perm' , 'r');
|
||||
$dfrn_version = !empty($_POST['dfrn_version']) ? (float) $_POST['dfrn_version'] : 2.0;
|
||||
$dfrn_id = $_POST['dfrn_id'] ?? '';
|
||||
$challenge = $_POST['challenge'] ?? '';
|
||||
$url = $_POST['url'] ?? '';
|
||||
$sec = $_POST['sec'] ?? '';
|
||||
$ptype = $_POST['type'] ?? '';
|
||||
$perm = ($_POST['perm'] ?? '') ?: 'r';
|
||||
$dfrn_version = floatval(($_GET['dfrn_version'] ?? 0.0) ?: 2.0);
|
||||
|
||||
if ($ptype === 'profile-check') {
|
||||
if (strlen($challenge) && strlen($sec)) {
|
||||
|
@ -393,12 +391,12 @@ function dfrn_poll_post(App $a)
|
|||
|
||||
function dfrn_poll_content(App $a)
|
||||
{
|
||||
$dfrn_id = defaults($_GET, 'dfrn_id' , '');
|
||||
$type = defaults($_GET, 'type' , 'data');
|
||||
$last_update = defaults($_GET, 'last_update' , '');
|
||||
$destination_url = defaults($_GET, 'destination_url', '');
|
||||
$sec = defaults($_GET, 'sec' , '');
|
||||
$dfrn_version = !empty($_GET['dfrn_version']) ? (float) $_GET['dfrn_version'] : 2.0;
|
||||
$dfrn_id = $_GET['dfrn_id'] ?? '';
|
||||
$type = ($_GET['type'] ?? '') ?: 'data';
|
||||
$last_update = $_GET['last_update'] ?? '';
|
||||
$destination_url = $_GET['destination_url'] ?? '';
|
||||
$sec = $_GET['sec'] ?? '';
|
||||
$dfrn_version = floatval(($_GET['dfrn_version'] ?? 0.0) ?: 2.0);
|
||||
$quiet = !empty($_GET['quiet']);
|
||||
|
||||
$direction = -1;
|
||||
|
@ -517,15 +515,13 @@ function dfrn_poll_content(App $a)
|
|||
|
||||
if (((int) $xml->status == 0) && ($xml->challenge == $hash) && ($xml->sec == $sec)) {
|
||||
$_SESSION['authenticated'] = 1;
|
||||
if (empty($_SESSION['remote'])) {
|
||||
$_SESSION['remote'] = [];
|
||||
}
|
||||
|
||||
$_SESSION['remote'][] = ['cid' => $r[0]['id'], 'uid' => $r[0]['uid'], 'url' => $r[0]['url']];
|
||||
$_SESSION['visitor_id'] = $r[0]['id'];
|
||||
$_SESSION['visitor_home'] = $r[0]['url'];
|
||||
$_SESSION['visitor_visiting'] = $r[0]['uid'];
|
||||
$_SESSION['my_url'] = $r[0]['url'];
|
||||
|
||||
Session::setVisitorsContacts();
|
||||
|
||||
if (!$quiet) {
|
||||
info(L10n::t('%1$s welcomes %2$s', $r[0]['username'], $r[0]['name']) . EOL);
|
||||
}
|
||||
|
|
|
@ -19,6 +19,7 @@ use Friendica\Core\Logger;
|
|||
use Friendica\Core\Protocol;
|
||||
use Friendica\Core\Renderer;
|
||||
use Friendica\Core\System;
|
||||
use Friendica\Core\Session;
|
||||
use Friendica\Database\DBA;
|
||||
use Friendica\Model\Contact;
|
||||
use Friendica\Model\Group;
|
||||
|
@ -79,7 +80,7 @@ function dfrn_request_post(App $a)
|
|||
if (local_user() && ($a->user['nickname'] == $a->argv[1]) && !empty($_POST['dfrn_url'])) {
|
||||
$dfrn_url = Strings::escapeTags(trim($_POST['dfrn_url']));
|
||||
$aes_allow = !empty($_POST['aes_allow']);
|
||||
$confirm_key = defaults($_POST, 'confirm_key', "");
|
||||
$confirm_key = $_POST['confirm_key'] ?? '';
|
||||
$hidden = (!empty($_POST['hidden-contact']) ? intval($_POST['hidden-contact']) : 0);
|
||||
$contact_record = null;
|
||||
$blocked = 1;
|
||||
|
@ -168,7 +169,7 @@ function dfrn_request_post(App $a)
|
|||
$r = q("SELECT `id`, `network` FROM `contact` WHERE `uid` = %d AND `url` = '%s' AND `site-pubkey` = '%s' LIMIT 1",
|
||||
intval(local_user()),
|
||||
DBA::escape($dfrn_url),
|
||||
defaults($parms, 'key', '') // Potentially missing
|
||||
$parms['key'] ?? '' // Potentially missing
|
||||
);
|
||||
if (DBA::isResult($r)) {
|
||||
Group::addMember(User::getDefaultGroup(local_user(), $r[0]["network"]), $r[0]['id']);
|
||||
|
@ -422,7 +423,7 @@ function dfrn_request_post(App $a)
|
|||
intval($uid),
|
||||
intval($contact_record['id']),
|
||||
intval(!empty($_POST['knowyou'])),
|
||||
DBA::escape(Strings::escapeTags(trim(defaults($_POST, 'dfrn-request-message', '')))),
|
||||
DBA::escape(Strings::escapeTags(trim($_POST['dfrn-request-message'] ?? ''))),
|
||||
DBA::escape($hash),
|
||||
DBA::escape(DateTimeFormat::utcNow())
|
||||
);
|
||||
|
@ -498,7 +499,7 @@ function dfrn_request_content(App $a)
|
|||
|
||||
$dfrn_url = Strings::escapeTags(trim(hex2bin($_GET['dfrn_url'])));
|
||||
$aes_allow = !empty($_GET['aes_allow']);
|
||||
$confirm_key = defaults($_GET, 'confirm_key', "");
|
||||
$confirm_key = $_GET['confirm_key'] ?? '';
|
||||
|
||||
// Checking fastlane for validity
|
||||
if (!empty($_SESSION['fastlane']) && (Strings::normaliseLink($_SESSION["fastlane"]) == Strings::normaliseLink($dfrn_url))) {
|
||||
|
@ -592,7 +593,7 @@ function dfrn_request_content(App $a)
|
|||
exit();
|
||||
} else {
|
||||
// Normal web request. Display our user's introduction form.
|
||||
if ((Config::get('system', 'block_public')) && (!local_user()) && (!remote_user())) {
|
||||
if (Config::get('system', 'block_public') && !Session::isAuthenticated()) {
|
||||
if (!Config::get('system', 'local_block')) {
|
||||
notice(L10n::t('Public access denied.') . EOL);
|
||||
return;
|
||||
|
|
|
@ -14,6 +14,7 @@ use Friendica\Core\Logger;
|
|||
use Friendica\Core\Protocol;
|
||||
use Friendica\Core\Renderer;
|
||||
use Friendica\Core\System;
|
||||
use Friendica\Core\Session;
|
||||
use Friendica\Database\DBA;
|
||||
use Friendica\Model\Contact;
|
||||
use Friendica\Model\Group;
|
||||
|
@ -31,7 +32,7 @@ function display_init(App $a)
|
|||
Objects::rawContent();
|
||||
}
|
||||
|
||||
if (Config::get('system', 'block_public') && !local_user() && !remote_user()) {
|
||||
if (Config::get('system', 'block_public') && !Session::isAuthenticated()) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -52,9 +53,11 @@ function display_init(App $a)
|
|||
if (DBA::isResult($item)) {
|
||||
$nick = $a->user["nickname"];
|
||||
}
|
||||
}
|
||||
|
||||
// Is this item private but could be visible to the remove visitor?
|
||||
} elseif (remote_user()) {
|
||||
$item = Item::selectFirst($fields, ['guid' => $a->argv[1], 'private' => 1]);
|
||||
if (!DBA::isResult($item) && remote_user()) {
|
||||
$item = Item::selectFirst($fields, ['guid' => $a->argv[1], 'private' => 1, 'origin' => true]);
|
||||
if (DBA::isResult($item)) {
|
||||
if (!Contact::isFollower(remote_user(), $item['uid'])) {
|
||||
$item = null;
|
||||
|
@ -84,10 +87,6 @@ function display_init(App $a)
|
|||
displayShowFeed($item['id'], $a->argc > 3 && $a->argv[3] == 'conversation.atom');
|
||||
}
|
||||
|
||||
if ($a->argc >= 3 && $nick == 'feed-item') {
|
||||
displayShowFeed($item['id'], $a->argc > 3 && $a->argv[3] == 'conversation.atom');
|
||||
}
|
||||
|
||||
if (!empty($_SERVER['HTTP_ACCEPT']) && strstr($_SERVER['HTTP_ACCEPT'], 'application/atom+xml')) {
|
||||
Logger::log('Directly serving XML for id '.$item["id"], Logger::DEBUG);
|
||||
displayShowFeed($item["id"], false);
|
||||
|
@ -102,7 +101,7 @@ function display_init(App $a)
|
|||
if (strstr(Strings::normaliseLink($profiledata["url"]), Strings::normaliseLink(System::baseUrl()))) {
|
||||
$nickname = str_replace(Strings::normaliseLink(System::baseUrl())."/profile/", "", Strings::normaliseLink($profiledata["url"]));
|
||||
|
||||
if (($nickname != $a->user["nickname"])) {
|
||||
if ($nickname != $a->user["nickname"]) {
|
||||
$profile = DBA::fetchFirst("SELECT `profile`.`uid` AS `profile_uid`, `profile`.* , `contact`.`avatar-date` AS picdate, `user`.* FROM `profile`
|
||||
INNER JOIN `contact` on `contact`.`uid` = `profile`.`uid` INNER JOIN `user` ON `profile`.`uid` = `user`.`uid`
|
||||
WHERE `user`.`nickname` = ? AND `profile`.`is-default` AND `contact`.`self` LIMIT 1",
|
||||
|
@ -188,14 +187,16 @@ function display_fetchauthor($a, $item)
|
|||
|
||||
$profiledata = Contact::getDetailsByURL($profiledata["url"], local_user(), $profiledata);
|
||||
|
||||
$profiledata["photo"] = System::removedBaseUrl($profiledata["photo"]);
|
||||
if (!empty($profiledata["photo"])) {
|
||||
$profiledata["photo"] = System::removedBaseUrl($profiledata["photo"]);
|
||||
}
|
||||
|
||||
return $profiledata;
|
||||
}
|
||||
|
||||
function display_content(App $a, $update = false, $update_uid = 0)
|
||||
{
|
||||
if (Config::get('system','block_public') && !local_user() && !remote_user()) {
|
||||
if (Config::get('system','block_public') && !Session::isAuthenticated()) {
|
||||
throw new HTTPException\ForbiddenException(L10n::t('Public access denied.'));
|
||||
}
|
||||
|
||||
|
@ -227,8 +228,10 @@ function display_content(App $a, $update = false, $update_uid = 0)
|
|||
$item_parent = $item["parent"];
|
||||
$item_parent_uri = $item['parent-uri'];
|
||||
}
|
||||
} elseif (remote_user()) {
|
||||
$item = Item::selectFirst($fields, ['guid' => $a->argv[1], 'private' => 1]);
|
||||
}
|
||||
|
||||
if (($item_parent == 0) && remote_user()) {
|
||||
$item = Item::selectFirst($fields, ['guid' => $a->argv[1], 'private' => 1, 'origin' => true]);
|
||||
if (DBA::isResult($item) && Contact::isFollower(remote_user(), $item['uid'])) {
|
||||
$item_id = $item["id"];
|
||||
$item_parent = $item["parent"];
|
||||
|
@ -267,34 +270,26 @@ function display_content(App $a, $update = false, $update_uid = 0)
|
|||
['$alternate' => $alternate,
|
||||
'$conversation' => $conversation]);
|
||||
|
||||
$groups = [];
|
||||
$remote_cid = null;
|
||||
$is_remote_contact = false;
|
||||
$item_uid = local_user();
|
||||
|
||||
if (isset($item_parent_uri)) {
|
||||
$parent = Item::selectFirst(['uid'], ['uri' => $item_parent_uri, 'wall' => true]);
|
||||
if (DBA::isResult($parent)) {
|
||||
$a->profile['uid'] = defaults($a->profile, 'uid', $parent['uid']);
|
||||
$a->profile['profile_uid'] = defaults($a->profile, 'profile_uid', $parent['uid']);
|
||||
$is_remote_contact = Contact::isFollower(remote_user(), $a->profile['profile_uid']);
|
||||
|
||||
$a->profile['uid'] = ($a->profile['uid'] ?? 0) ?: $parent['uid'];
|
||||
$a->profile['profile_uid'] = ($a->profile['profile_uid'] ?? 0) ?: $parent['uid'];
|
||||
$is_remote_contact = Session::getRemoteContactID($a->profile['profile_uid']);
|
||||
if ($is_remote_contact) {
|
||||
$cdata = Contact::getPublicAndUserContacID(remote_user(), $a->profile['profile_uid']);
|
||||
if (!empty($cdata['user'])) {
|
||||
$groups = Group::getIdsByContactId($cdata['user']);
|
||||
$remote_cid = $cdata['user'];
|
||||
$item_uid = $parent['uid'];
|
||||
}
|
||||
$item_uid = $parent['uid'];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
$page_contact = DBA::selectFirst('contact', [], ['self' => true, 'uid' => $a->profile['uid']]);
|
||||
if (DBA::isResult($page_contact)) {
|
||||
$a->page_contact = $page_contact;
|
||||
}
|
||||
|
||||
$is_owner = (local_user() && (in_array($a->profile['profile_uid'], [local_user(), 0])) ? true : false);
|
||||
|
||||
if (!empty($a->profile['hidewall']) && !$is_owner && !$is_remote_contact) {
|
||||
|
@ -316,7 +311,7 @@ function display_content(App $a, $update = false, $update_uid = 0)
|
|||
];
|
||||
$o .= status_editor($a, $x, 0, true);
|
||||
}
|
||||
$sql_extra = Item::getPermissionsSQLByUserId($a->profile['profile_uid'], $is_remote_contact, $groups, $remote_cid);
|
||||
$sql_extra = Item::getPermissionsSQLByUserId($a->profile['profile_uid']);
|
||||
|
||||
if (local_user() && (local_user() == $a->profile['profile_uid'])) {
|
||||
$condition = ['parent-uri' => $item_parent_uri, 'uid' => local_user(), 'unseen' => true];
|
||||
|
@ -330,8 +325,8 @@ function display_content(App $a, $update = false, $update_uid = 0)
|
|||
}
|
||||
|
||||
$condition = ["`id` = ? AND `item`.`uid` IN (0, ?) " . $sql_extra, $item_id, $item_uid];
|
||||
$fields = ['parent-uri', 'body', 'title', 'author-name', 'author-avatar', 'plink'];
|
||||
$item = Item::selectFirstForUser(local_user(), $fields, $condition);
|
||||
$fields = ['parent-uri', 'body', 'title', 'author-name', 'author-avatar', 'plink', 'author-id', 'owner-id', 'contact-id'];
|
||||
$item = Item::selectFirstForUser($a->profile['profile_uid'], $fields, $condition);
|
||||
|
||||
if (!DBA::isResult($item)) {
|
||||
throw new HTTPException\NotFoundException(L10n::t('The requested item doesn\'t exist or has been deleted.'));
|
||||
|
@ -370,7 +365,10 @@ function display_content(App $a, $update = false, $update_uid = 0)
|
|||
$title = htmlspecialchars($title, ENT_COMPAT, 'UTF-8', true); // allow double encoding here
|
||||
$author_name = htmlspecialchars($author_name, ENT_COMPAT, 'UTF-8', true); // allow double encoding here
|
||||
|
||||
//<meta name="keywords" content="">
|
||||
if (DBA::exists('contact', ['unsearchable' => true, 'id' => [$item['contact-id'], $item['author-id'], $item['owner-id']]])) {
|
||||
$a->page['htmlhead'] .= '<meta content="noindex, noarchive" name="robots" />' . "\n";
|
||||
}
|
||||
|
||||
$a->page['htmlhead'] .= '<meta name="author" content="'.$author_name.'" />'."\n";
|
||||
$a->page['htmlhead'] .= '<meta name="title" content="'.$title.'" />'."\n";
|
||||
$a->page['htmlhead'] .= '<meta name="fulltitle" content="'.$title.'" />'."\n";
|
||||
|
|
|
@ -59,11 +59,11 @@ function events_post(App $a)
|
|||
$cid = !empty($_POST['cid']) ? intval($_POST['cid']) : 0;
|
||||
$uid = local_user();
|
||||
|
||||
$start_text = Strings::escapeHtml(defaults($_REQUEST, 'start_text', ''));
|
||||
$finish_text = Strings::escapeHtml(defaults($_REQUEST, 'finish_text', ''));
|
||||
$start_text = Strings::escapeHtml($_REQUEST['start_text'] ?? '');
|
||||
$finish_text = Strings::escapeHtml($_REQUEST['finish_text'] ?? '');
|
||||
|
||||
$adjust = intval(defaults($_POST, 'adjust', 0));
|
||||
$nofinish = intval(defaults($_POST, 'nofinish', 0));
|
||||
$adjust = intval($_POST['adjust'] ?? 0);
|
||||
$nofinish = intval($_POST['nofinish'] ?? 0);
|
||||
|
||||
// The default setting for the `private` field in event_store() is false, so mirror that
|
||||
$private_event = false;
|
||||
|
@ -96,9 +96,9 @@ function events_post(App $a)
|
|||
// and we'll waste a bunch of time responding to it. Time that
|
||||
// could've been spent doing something else.
|
||||
|
||||
$summary = trim(defaults($_POST, 'summary' , ''));
|
||||
$desc = trim(defaults($_POST, 'desc' , ''));
|
||||
$location = trim(defaults($_POST, 'location', ''));
|
||||
$summary = trim($_POST['summary'] ?? '');
|
||||
$desc = trim($_POST['desc'] ?? '');
|
||||
$location = trim($_POST['location'] ?? '');
|
||||
$type = 'event';
|
||||
|
||||
$params = [
|
||||
|
@ -132,7 +132,7 @@ function events_post(App $a)
|
|||
$a->internalRedirect($onerror_path);
|
||||
}
|
||||
|
||||
$share = intval(defaults($_POST, 'share', 0));
|
||||
$share = intval($_POST['share'] ?? 0);
|
||||
|
||||
$c = q("SELECT `id` FROM `contact` WHERE `uid` = %d AND `self` LIMIT 1",
|
||||
intval(local_user())
|
||||
|
@ -146,10 +146,10 @@ function events_post(App $a)
|
|||
|
||||
|
||||
if ($share) {
|
||||
$str_group_allow = perms2str(defaults($_POST, 'group_allow' , ''));
|
||||
$str_contact_allow = perms2str(defaults($_POST, 'contact_allow', ''));
|
||||
$str_group_deny = perms2str(defaults($_POST, 'group_deny' , ''));
|
||||
$str_contact_deny = perms2str(defaults($_POST, 'contact_deny' , ''));
|
||||
$str_group_allow = perms2str($_POST['group_allow'] ?? '');
|
||||
$str_contact_allow = perms2str($_POST['contact_allow'] ?? '');
|
||||
$str_group_deny = perms2str($_POST['group_deny'] ?? '');
|
||||
$str_contact_deny = perms2str($_POST['contact_deny'] ?? '');
|
||||
|
||||
// Undo the pseudo-contact of self, since there are real contacts now
|
||||
if (strpos($str_contact_allow, '<' . $self . '>') !== false) {
|
||||
|
@ -321,7 +321,7 @@ function events_content(App $a)
|
|||
|
||||
// put the event parametes in an array so we can better transmit them
|
||||
$event_params = [
|
||||
'event_id' => intval(defaults($_GET, 'id', 0)),
|
||||
'event_id' => intval($_GET['id'] ?? 0),
|
||||
'start' => $start,
|
||||
'finish' => $finish,
|
||||
'adjust_start' => $adjust_start,
|
||||
|
|
|
@ -29,7 +29,7 @@ function fbrowser_content(App $a)
|
|||
}
|
||||
|
||||
// Needed to match the correct template in a module that uses a different theme than the user/site/default
|
||||
$theme = Strings::sanitizeFilePathItem(defaults($_GET, 'theme', null));
|
||||
$theme = Strings::sanitizeFilePathItem($_GET['theme'] ?? null);
|
||||
if ($theme && is_file("view/theme/$theme/config.php")) {
|
||||
$a->setCurrentTheme($theme);
|
||||
}
|
||||
|
|
|
@ -62,7 +62,7 @@ function follow_content(App $a)
|
|||
$uid = local_user();
|
||||
|
||||
// Issue 4815: Silently removing a prefixing @
|
||||
$url = ltrim(Strings::escapeTags(trim(defaults($_REQUEST, 'url', ''))), '@!');
|
||||
$url = ltrim(Strings::escapeTags(trim($_REQUEST['url'] ?? '')), '@!');
|
||||
|
||||
// Issue 6874: Allow remote following from Peertube
|
||||
if (strpos($url, 'acct:') === 0) {
|
||||
|
|
|
@ -45,7 +45,7 @@ function fsuggest_post(App $a)
|
|||
return;
|
||||
}
|
||||
|
||||
$note = Strings::escapeHtml(trim(defaults($_POST, 'note', '')));
|
||||
$note = Strings::escapeHtml(trim($_POST['note'] ?? ''));
|
||||
|
||||
$fields = ['uid' => local_user(),'cid' => $contact_id, 'name' => $contact['name'],
|
||||
'url' => $contact['url'], 'request' => $contact['request'],
|
||||
|
|
|
@ -6,13 +6,14 @@ use Friendica\App;
|
|||
use Friendica\Core\Config;
|
||||
use Friendica\Core\L10n;
|
||||
use Friendica\Core\System;
|
||||
use Friendica\Core\Session;
|
||||
use Friendica\Model\Contact;
|
||||
use Friendica\Model\Profile;
|
||||
use Friendica\Model\User;
|
||||
|
||||
function hcard_init(App $a)
|
||||
{
|
||||
$blocked = Config::get('system', 'block_public') && !local_user() && !remote_user();
|
||||
$blocked = Config::get('system', 'block_public') && !Session::isAuthenticated();
|
||||
|
||||
if ($a->argc > 1) {
|
||||
$which = $a->argv[1];
|
||||
|
@ -40,7 +41,7 @@ function hcard_init(App $a)
|
|||
}
|
||||
|
||||
if (!$blocked) {
|
||||
$keywords = defaults($a->profile, 'pub_keywords', '');
|
||||
$keywords = $a->profile['pub_keywords'] ?? '';
|
||||
$keywords = str_replace([',',' ',',,'], [' ',',',','], $keywords);
|
||||
if (strlen($keywords)) {
|
||||
$a->page['htmlhead'] .= '<meta name="keywords" content="' . $keywords . '" />' . "\r\n";
|
||||
|
|
|
@ -26,8 +26,8 @@ function hovercard_init(App $a)
|
|||
|
||||
function hovercard_content()
|
||||
{
|
||||
$profileurl = defaults($_REQUEST, 'profileurl', '');
|
||||
$datatype = defaults($_REQUEST, 'datatype' , 'json');
|
||||
$profileurl = $_REQUEST['profileurl'] ?? '';
|
||||
$datatype = ($_REQUEST['datatype'] ?? '') ?: 'json';
|
||||
|
||||
// Get out if the system doesn't have public access allowed
|
||||
if (intval(Config::get('system', 'block_public'))) {
|
||||
|
@ -50,7 +50,7 @@ function hovercard_content()
|
|||
if (strpos($profileurl, 'redir/') === 0) {
|
||||
$cid = intval(substr($profileurl, 6));
|
||||
$remote_contact = DBA::selectFirst('contact', ['nurl'], ['id' => $cid]);
|
||||
$profileurl = defaults($remote_contact, 'nurl', '');
|
||||
$profileurl = $remote_contact['nurl'] ?? '';
|
||||
}
|
||||
|
||||
$contact = [];
|
||||
|
@ -97,7 +97,7 @@ function hovercard_content()
|
|||
$profile = [
|
||||
'name' => $contact['name'],
|
||||
'nick' => $contact['nick'],
|
||||
'addr' => defaults($contact, 'addr', $contact['url']),
|
||||
'addr' => ($contact['addr'] ?? '') ?: $contact['url'],
|
||||
'thumb' => ProxyUtils::proxifyUrl($contact['thumb'], false, ProxyUtils::SIZE_THUMB),
|
||||
'url' => Contact::magicLink($contact['url']),
|
||||
'nurl' => $contact['nurl'], // We additionally store the nurl as identifier
|
||||
|
|
|
@ -33,7 +33,7 @@ function ignored_init(App $a)
|
|||
}
|
||||
|
||||
// See if we've been passed a return path to redirect to
|
||||
$return_path = defaults($_REQUEST, 'return', '');
|
||||
$return_path = $_REQUEST['return'] ?? '';
|
||||
if ($return_path) {
|
||||
$rand = '_=' . time();
|
||||
if (strpos($return_path, '?')) {
|
||||
|
|
96
mod/item.php
96
mod/item.php
|
@ -25,6 +25,7 @@ use Friendica\Core\L10n;
|
|||
use Friendica\Core\Logger;
|
||||
use Friendica\Core\Protocol;
|
||||
use Friendica\Core\System;
|
||||
use Friendica\Core\Session;
|
||||
use Friendica\Core\Worker;
|
||||
use Friendica\Database\DBA;
|
||||
use Friendica\Model\Attach;
|
||||
|
@ -42,10 +43,10 @@ use Friendica\Util\Security;
|
|||
use Friendica\Util\Strings;
|
||||
use Friendica\Worker\Delivery;
|
||||
|
||||
require_once 'include/items.php';
|
||||
require_once __DIR__ . '/../include/items.php';
|
||||
|
||||
function item_post(App $a) {
|
||||
if (!local_user() && !remote_user()) {
|
||||
if (!Session::isAuthenticated()) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -63,12 +64,12 @@ function item_post(App $a) {
|
|||
|
||||
Logger::log('postvars ' . print_r($_REQUEST, true), Logger::DATA);
|
||||
|
||||
$api_source = defaults($_REQUEST, 'api_source', false);
|
||||
$api_source = $_REQUEST['api_source'] ?? false;
|
||||
|
||||
$message_id = ((!empty($_REQUEST['message_id']) && $api_source) ? strip_tags($_REQUEST['message_id']) : '');
|
||||
|
||||
$return_path = defaults($_REQUEST, 'return', '');
|
||||
$preview = intval(defaults($_REQUEST, 'preview', 0));
|
||||
$return_path = $_REQUEST['return'] ?? '';
|
||||
$preview = intval($_REQUEST['preview'] ?? 0);
|
||||
|
||||
/*
|
||||
* Check for doubly-submitted posts, and reject duplicates
|
||||
|
@ -85,8 +86,8 @@ function item_post(App $a) {
|
|||
}
|
||||
|
||||
// Is this a reply to something?
|
||||
$toplevel_item_id = intval(defaults($_REQUEST, 'parent', 0));
|
||||
$thr_parent_uri = trim(defaults($_REQUEST, 'parent_uri', ''));
|
||||
$toplevel_item_id = intval($_REQUEST['parent'] ?? 0);
|
||||
$thr_parent_uri = trim($_REQUEST['parent_uri'] ?? '');
|
||||
|
||||
$thread_parent_id = 0;
|
||||
$thread_parent_contact = null;
|
||||
|
@ -97,8 +98,8 @@ function item_post(App $a) {
|
|||
$parent_contact = null;
|
||||
|
||||
$objecttype = null;
|
||||
$profile_uid = defaults($_REQUEST, 'profile_uid', local_user());
|
||||
$posttype = defaults($_REQUEST, 'post_type', Item::PT_ARTICLE);
|
||||
$profile_uid = ($_REQUEST['profile_uid'] ?? 0) ?: local_user();
|
||||
$posttype = ($_REQUEST['post_type'] ?? '') ?: Item::PT_ARTICLE;
|
||||
|
||||
if ($toplevel_item_id || $thr_parent_uri) {
|
||||
if ($toplevel_item_id) {
|
||||
|
@ -137,10 +138,10 @@ function item_post(App $a) {
|
|||
Logger::info('mod_item: item_post parent=' . $toplevel_item_id);
|
||||
}
|
||||
|
||||
$post_id = intval(defaults($_REQUEST, 'post_id', 0));
|
||||
$app = strip_tags(defaults($_REQUEST, 'source', ''));
|
||||
$extid = strip_tags(defaults($_REQUEST, 'extid', ''));
|
||||
$object = defaults($_REQUEST, 'object', '');
|
||||
$post_id = intval($_REQUEST['post_id'] ?? 0);
|
||||
$app = strip_tags($_REQUEST['source'] ?? '');
|
||||
$extid = strip_tags($_REQUEST['extid'] ?? '');
|
||||
$object = $_REQUEST['object'] ?? '';
|
||||
|
||||
// Don't use "defaults" here. It would turn 0 to 1
|
||||
if (!isset($_REQUEST['wall'])) {
|
||||
|
@ -193,20 +194,20 @@ function item_post(App $a) {
|
|||
$categories = '';
|
||||
$postopts = '';
|
||||
$emailcc = '';
|
||||
$body = defaults($_REQUEST, 'body', '');
|
||||
$has_attachment = defaults($_REQUEST, 'has_attachment', 0);
|
||||
$body = $_REQUEST['body'] ?? '';
|
||||
$has_attachment = $_REQUEST['has_attachment'] ?? 0;
|
||||
|
||||
// If we have a speparate attachment, we need to add it to the body.
|
||||
if (!empty($has_attachment)) {
|
||||
$attachment_type = defaults($_REQUEST, 'attachment_type', '');
|
||||
$attachment_title = defaults($_REQUEST, 'attachment_title', '');
|
||||
$attachment_text = defaults($_REQUEST, 'attachment_text', '');
|
||||
$attachment_type = $_REQUEST['attachment_type'] ?? '';
|
||||
$attachment_title = $_REQUEST['attachment_title'] ?? '';
|
||||
$attachment_text = $_REQUEST['attachment_text'] ?? '';
|
||||
|
||||
$attachment_url = hex2bin(defaults($_REQUEST, 'attachment_url', ''));
|
||||
$attachment_img_src = hex2bin(defaults($_REQUEST, 'attachment_img_src', ''));
|
||||
$attachment_url = hex2bin($_REQUEST['attachment_url'] ?? '');
|
||||
$attachment_img_src = hex2bin($_REQUEST['attachment_img_src'] ?? '');
|
||||
|
||||
$attachment_img_width = defaults($_REQUEST, 'attachment_img_width', 0);
|
||||
$attachment_img_height = defaults($_REQUEST, 'attachment_img_height', 0);
|
||||
$attachment_img_width = $_REQUEST['attachment_img_width'] ?? 0;
|
||||
$attachment_img_height = $_REQUEST['attachment_img_height'] ?? 0;
|
||||
$attachment = [
|
||||
'type' => $attachment_type,
|
||||
'title' => $attachment_title,
|
||||
|
@ -228,6 +229,9 @@ function item_post(App $a) {
|
|||
$body .= $att_bbcode;
|
||||
}
|
||||
|
||||
// Convert links with empty descriptions to links without an explicit description
|
||||
$body = preg_replace('#\[url=([^\]]*?)\]\[/url\]#ism', '[url]$1[/url]', $body);
|
||||
|
||||
if (!empty($orig_post)) {
|
||||
$str_group_allow = $orig_post['allow_gid'];
|
||||
$str_contact_allow = $orig_post['allow_cid'];
|
||||
|
@ -265,29 +269,25 @@ function item_post(App $a) {
|
|||
$str_contact_deny = $user['deny_cid'];
|
||||
} else {
|
||||
// use the posted permissions
|
||||
$str_group_allow = perms2str(defaults($_REQUEST, 'group_allow', ''));
|
||||
$str_contact_allow = perms2str(defaults($_REQUEST, 'contact_allow', ''));
|
||||
$str_group_deny = perms2str(defaults($_REQUEST, 'group_deny', ''));
|
||||
$str_contact_deny = perms2str(defaults($_REQUEST, 'contact_deny', ''));
|
||||
$str_group_allow = perms2str($_REQUEST['group_allow'] ?? '');
|
||||
$str_contact_allow = perms2str($_REQUEST['contact_allow'] ?? '');
|
||||
$str_group_deny = perms2str($_REQUEST['group_deny'] ?? '');
|
||||
$str_contact_deny = perms2str($_REQUEST['contact_deny'] ?? '');
|
||||
}
|
||||
|
||||
$title = Strings::escapeTags(trim(defaults($_REQUEST, 'title' , '')));
|
||||
$location = Strings::escapeTags(trim(defaults($_REQUEST, 'location', '')));
|
||||
$coord = Strings::escapeTags(trim(defaults($_REQUEST, 'coord' , '')));
|
||||
$verb = Strings::escapeTags(trim(defaults($_REQUEST, 'verb' , '')));
|
||||
$emailcc = Strings::escapeTags(trim(defaults($_REQUEST, 'emailcc' , '')));
|
||||
$title = Strings::escapeTags(trim($_REQUEST['title'] ?? ''));
|
||||
$location = Strings::escapeTags(trim($_REQUEST['location'] ?? ''));
|
||||
$coord = Strings::escapeTags(trim($_REQUEST['coord'] ?? ''));
|
||||
$verb = Strings::escapeTags(trim($_REQUEST['verb'] ?? ''));
|
||||
$emailcc = Strings::escapeTags(trim($_REQUEST['emailcc'] ?? ''));
|
||||
$body = Strings::escapeHtml(trim($body));
|
||||
$network = Strings::escapeTags(trim(defaults($_REQUEST, 'network' , Protocol::DFRN)));
|
||||
$network = Strings::escapeTags(trim(($_REQUEST['network'] ?? '') ?: Protocol::DFRN));
|
||||
$guid = System::createUUID();
|
||||
|
||||
$postopts = defaults($_REQUEST, 'postopts', '');
|
||||
$postopts = $_REQUEST['postopts'] ?? '';
|
||||
|
||||
$private = ((strlen($str_group_allow) || strlen($str_contact_allow) || strlen($str_group_deny) || strlen($str_contact_deny)) ? 1 : 0);
|
||||
|
||||
if ($user['hidewall']) {
|
||||
$private = 2;
|
||||
}
|
||||
|
||||
// If this is a comment, set the permissions from the parent.
|
||||
|
||||
if ($toplevel_item) {
|
||||
|
@ -307,7 +307,7 @@ function item_post(App $a) {
|
|||
$wall = $toplevel_item['wall'];
|
||||
}
|
||||
|
||||
$pubmail_enabled = defaults($_REQUEST, 'pubmail_enable', false) && !$private;
|
||||
$pubmail_enabled = ($_REQUEST['pubmail_enable'] ?? false) && !$private;
|
||||
|
||||
// if using the API, we won't see pubmail_enable - figure out if it should be set
|
||||
if ($api_source && $profile_uid && $profile_uid == local_user() && !$private) {
|
||||
|
@ -335,7 +335,7 @@ function item_post(App $a) {
|
|||
|
||||
// save old and new categories, so we can determine what needs to be deleted from pconfig
|
||||
$categories_old = $categories;
|
||||
$categories = FileTag::listToFile(trim(defaults($_REQUEST, 'category', '')), 'category');
|
||||
$categories = FileTag::listToFile(trim($_REQUEST['category'] ?? ''), 'category');
|
||||
$categories_new = $categories;
|
||||
|
||||
if (!empty($filedas) && is_array($filedas)) {
|
||||
|
@ -352,18 +352,8 @@ function item_post(App $a) {
|
|||
if (local_user() && ((local_user() == $profile_uid) || $allow_comment)) {
|
||||
$self = true;
|
||||
$author = DBA::selectFirst('contact', [], ['uid' => local_user(), 'self' => true]);
|
||||
} elseif (remote_user()) {
|
||||
if (!empty($_SESSION['remote']) && is_array($_SESSION['remote'])) {
|
||||
foreach ($_SESSION['remote'] as $v) {
|
||||
if ($v['uid'] == $profile_uid) {
|
||||
$contact_id = $v['cid'];
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if ($contact_id) {
|
||||
$author = DBA::selectFirst('contact', [], ['id' => $contact_id]);
|
||||
}
|
||||
} elseif (!empty(Session::getRemoteContactID($profile_uid))) {
|
||||
$author = DBA::selectFirst('contact', [], ['id' => Session::getRemoteContactID($profile_uid)]);
|
||||
}
|
||||
|
||||
if (DBA::isResult($author)) {
|
||||
|
@ -874,7 +864,7 @@ function item_post_return($baseurl, $api_source, $return_path)
|
|||
|
||||
function item_content(App $a)
|
||||
{
|
||||
if (!local_user() && !remote_user()) {
|
||||
if (!Session::isAuthenticated()) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -1025,7 +1015,7 @@ function handle_tag(&$body, &$inform, &$str_tags, $profile_uid, $tag, $network =
|
|||
|
||||
$profile = $contact["url"];
|
||||
$alias = $contact["alias"];
|
||||
$newname = defaults($contact, "name", $contact["nick"]);
|
||||
$newname = ($contact["name"] ?? '') ?: $contact["nick"];
|
||||
}
|
||||
|
||||
//if there is an url for this persons profile
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* @file mod/lostpass.php
|
||||
*/
|
||||
|
@ -27,7 +28,7 @@ function lostpass_post(App $a)
|
|||
$a->internalRedirect();
|
||||
}
|
||||
|
||||
$pwdreset_token = Strings::getRandomName(12) . mt_rand(1000, 9999);
|
||||
$pwdreset_token = Strings::getRandomName(12) . random_int(1000, 9999);
|
||||
|
||||
$fields = [
|
||||
'pwdreset' => $pwdreset_token,
|
||||
|
|
188
mod/manage.php
188
mod/manage.php
|
@ -1,188 +0,0 @@
|
|||
<?php
|
||||
/**
|
||||
* @file mod/manage.php
|
||||
*/
|
||||
|
||||
use Friendica\App;
|
||||
use Friendica\Core\Hook;
|
||||
use Friendica\Core\L10n;
|
||||
use Friendica\Core\Renderer;
|
||||
use Friendica\Core\Session;
|
||||
use Friendica\Database\DBA;
|
||||
|
||||
function manage_post(App $a) {
|
||||
|
||||
if (! local_user()) {
|
||||
return;
|
||||
}
|
||||
|
||||
$uid = local_user();
|
||||
$orig_record = $a->user;
|
||||
|
||||
if(!empty($_SESSION['submanage'])) {
|
||||
$r = q("select * from user where uid = %d limit 1",
|
||||
intval($_SESSION['submanage'])
|
||||
);
|
||||
if (DBA::isResult($r)) {
|
||||
$uid = intval($r[0]['uid']);
|
||||
$orig_record = $r[0];
|
||||
}
|
||||
}
|
||||
|
||||
$r = q("SELECT * FROM `manage` WHERE `uid` = %d",
|
||||
intval($uid)
|
||||
);
|
||||
|
||||
$submanage = $r;
|
||||
|
||||
$identity = (!empty($_POST['identity']) ? intval($_POST['identity']) : 0);
|
||||
if (!$identity) {
|
||||
return;
|
||||
}
|
||||
|
||||
$limited_id = 0;
|
||||
$original_id = $uid;
|
||||
|
||||
if (DBA::isResult($submanage)) {
|
||||
foreach ($submanage as $m) {
|
||||
if ($identity == $m['mid']) {
|
||||
$limited_id = $m['mid'];
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ($limited_id) {
|
||||
$r = q("SELECT * FROM `user` WHERE `uid` = %d LIMIT 1",
|
||||
intval($limited_id)
|
||||
);
|
||||
} else {
|
||||
// Check if the target user is one of our children
|
||||
$r = q("SELECT * FROM `user` WHERE `uid` = %d AND `parent-uid` = %d LIMIT 1",
|
||||
intval($identity),
|
||||
DBA::escape($orig_record['uid'])
|
||||
);
|
||||
|
||||
// Check if the target user is one of our siblings
|
||||
if (!DBA::isResult($r) && ($orig_record['parent-uid'] != 0)) {
|
||||
$r = q("SELECT * FROM `user` WHERE `uid` = %d AND `parent-uid` = %d LIMIT 1",
|
||||
intval($identity),
|
||||
DBA::escape($orig_record['parent-uid'])
|
||||
);
|
||||
}
|
||||
|
||||
// Check if it's our parent
|
||||
if (!DBA::isResult($r) && ($orig_record['parent-uid'] != 0) && ($orig_record['parent-uid'] == $identity)) {
|
||||
$r = q("SELECT * FROM `user` WHERE `uid` = %d LIMIT 1",
|
||||
intval($identity)
|
||||
);
|
||||
}
|
||||
|
||||
// Finally check if it's out own user
|
||||
if (!DBA::isResult($r) && ($orig_record['uid'] != 0) && ($orig_record['uid'] == $identity)) {
|
||||
$r = q("SELECT * FROM `user` WHERE `uid` = %d LIMIT 1",
|
||||
intval($identity)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
if (!DBA::isResult($r)) {
|
||||
return;
|
||||
}
|
||||
|
||||
unset($_SESSION['authenticated']);
|
||||
unset($_SESSION['uid']);
|
||||
unset($_SESSION['visitor_id']);
|
||||
unset($_SESSION['administrator']);
|
||||
unset($_SESSION['cid']);
|
||||
unset($_SESSION['theme']);
|
||||
unset($_SESSION['mobile-theme']);
|
||||
unset($_SESSION['page_flags']);
|
||||
unset($_SESSION['return_path']);
|
||||
if (!empty($_SESSION['submanage'])) {
|
||||
unset($_SESSION['submanage']);
|
||||
}
|
||||
if (!empty($_SESSION['sysmsg'])) {
|
||||
unset($_SESSION['sysmsg']);
|
||||
}
|
||||
if (!empty($_SESSION['sysmsg_info'])) {
|
||||
unset($_SESSION['sysmsg_info']);
|
||||
}
|
||||
|
||||
Session::setAuthenticatedForUser($a, $r[0], true, true);
|
||||
|
||||
if ($limited_id) {
|
||||
$_SESSION['submanage'] = $original_id;
|
||||
}
|
||||
|
||||
$ret = [];
|
||||
Hook::callAll('home_init',$ret);
|
||||
|
||||
$a->internalRedirect('profile/' . $a->user['nickname'] );
|
||||
// NOTREACHED
|
||||
}
|
||||
|
||||
|
||||
|
||||
function manage_content(App $a) {
|
||||
|
||||
if (! local_user()) {
|
||||
notice(L10n::t('Permission denied.') . EOL);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!empty($_GET['identity'])) {
|
||||
$_POST['identity'] = $_GET['identity'];
|
||||
manage_post($a);
|
||||
return;
|
||||
}
|
||||
|
||||
$identities = $a->identities;
|
||||
|
||||
//getting additinal information for each identity
|
||||
foreach ($identities as $key=>$id) {
|
||||
$thumb = q("SELECT `thumb` FROM `contact` WHERE `uid` = '%s' AND `self` = 1",
|
||||
DBA::escape($id['uid'])
|
||||
);
|
||||
|
||||
$identities[$key]['thumb'] = $thumb[0]['thumb'];
|
||||
|
||||
$identities[$key]['selected'] = ($id['nickname'] === $a->user['nickname']);
|
||||
|
||||
$notifications = 0;
|
||||
|
||||
$r = q("SELECT DISTINCT(`parent`) FROM `notify` WHERE `uid` = %d AND NOT `seen` AND NOT (`type` IN (%d, %d))",
|
||||
intval($id['uid']), intval(NOTIFY_INTRO), intval(NOTIFY_MAIL));
|
||||
|
||||
if (DBA::isResult($r)) {
|
||||
$notifications = sizeof($r);
|
||||
}
|
||||
|
||||
$r = q("SELECT DISTINCT(`convid`) FROM `mail` WHERE `uid` = %d AND NOT `seen`",
|
||||
intval($id['uid']));
|
||||
|
||||
if (DBA::isResult($r)) {
|
||||
$notifications = $notifications + sizeof($r);
|
||||
}
|
||||
|
||||
$r = q("SELECT COUNT(*) AS `introductions` FROM `intro` WHERE NOT `blocked` AND NOT `ignore` AND `uid` = %d",
|
||||
intval($id['uid']));
|
||||
|
||||
if (DBA::isResult($r)) {
|
||||
$notifications = $notifications + $r[0]["introductions"];
|
||||
}
|
||||
|
||||
$identities[$key]['notifications'] = $notifications;
|
||||
}
|
||||
|
||||
$o = Renderer::replaceMacros(Renderer::getMarkupTemplate('manage.tpl'), [
|
||||
'$title' => L10n::t('Manage Identities and/or Pages'),
|
||||
'$desc' => L10n::t('Toggle between different identities or community/group pages which share your account details or which you have been granted "manage" permissions'),
|
||||
'$choose' => L10n::t('Select an identity to manage: '),
|
||||
'$identities' => $identities,
|
||||
'$submit' => L10n::t('Submit'),
|
||||
]);
|
||||
|
||||
return $o;
|
||||
|
||||
}
|
|
@ -66,7 +66,7 @@ function match_content(App $a)
|
|||
|
||||
$msearch = json_decode($msearch_json);
|
||||
|
||||
$start = defaults($_GET, 'start', 0);
|
||||
$start = $_GET['start'] ?? 0;
|
||||
$entries = [];
|
||||
$paginate = '';
|
||||
|
||||
|
@ -92,11 +92,11 @@ function match_content(App $a)
|
|||
|
||||
$entry = [
|
||||
'url' => Contact::magicLink($profile->url),
|
||||
'itemurl' => defaults($contact_details, 'addr', $profile->url),
|
||||
'itemurl' => $contact_details['addr'] ?? $profile->url,
|
||||
'name' => $profile->name,
|
||||
'details' => defaults($contact_details, 'location', ''),
|
||||
'tags' => defaults($contact_details, 'keywords', ''),
|
||||
'about' => defaults($contact_details, 'about', ''),
|
||||
'details' => $contact_details['location'] ?? '',
|
||||
'tags' => $contact_details['keywords'] ?? '',
|
||||
'about' => $contact_details['about'] ?? '',
|
||||
'account_type' => Contact::getAccountType($contact_details),
|
||||
'thumb' => ProxyUtils::proxifyUrl($profile->photo, false, ProxyUtils::SIZE_THUMB),
|
||||
'conntxt' => L10n::t('Connect'),
|
||||
|
|
|
@ -249,8 +249,8 @@ function message_content(App $a)
|
|||
'$prefill' => $prefill,
|
||||
'$preid' => $preid,
|
||||
'$subject' => L10n::t('Subject:'),
|
||||
'$subjtxt' => defaults($_REQUEST, 'subject', ''),
|
||||
'$text' => defaults($_REQUEST, 'body', ''),
|
||||
'$subjtxt' => $_REQUEST['subject'] ?? '',
|
||||
'$text' => $_REQUEST['body'] ?? '',
|
||||
'$readonly' => '',
|
||||
'$yourmessage'=> L10n::t('Your message:'),
|
||||
'$select' => $select,
|
||||
|
@ -530,7 +530,7 @@ function render_messages(array $msg, $t)
|
|||
'$id' => $rr['id'],
|
||||
'$from_name' => $participants,
|
||||
'$from_url' => Contact::magicLink($rr['url']),
|
||||
'$from_addr' => defaults($contact, 'addr', ''),
|
||||
'$from_addr' => $contact['addr'] ?? '',
|
||||
'$sparkle' => ' sparkle',
|
||||
'$from_photo' => ProxyUtils::proxifyUrl($from_photo, false, ProxyUtils::SIZE_THUMB),
|
||||
'$subject' => $rr['title'],
|
||||
|
|
|
@ -6,9 +6,9 @@ use Friendica\Database\DBA;
|
|||
|
||||
function msearch_post(App $a)
|
||||
{
|
||||
$search = defaults($_POST, 's', '');
|
||||
$perpage = intval(defaults($_POST, 'n', 80));
|
||||
$page = intval(defaults($_POST, 'p', 1));
|
||||
$search = $_POST['s'] ?? '';
|
||||
$perpage = intval(($_POST['n'] ?? 0) ?: 80);
|
||||
$page = intval(($_POST['p'] ?? 0) ?: 1);
|
||||
$startrec = ($page - 1) * $perpage;
|
||||
|
||||
$total = 0;
|
||||
|
|
|
@ -40,22 +40,6 @@ function network_init(App $a)
|
|||
|
||||
Hook::add('head', __FILE__, 'network_infinite_scroll_head');
|
||||
|
||||
$search = (!empty($_GET['search']) ? Strings::escapeHtml($_GET['search']) : '');
|
||||
|
||||
if (($search != '') && !empty($_GET['submit'])) {
|
||||
$a->internalRedirect('search?search=' . urlencode($search));
|
||||
}
|
||||
|
||||
if (!empty($_GET['save'])) {
|
||||
$exists = DBA::exists('search', ['uid' => local_user(), 'term' => $search]);
|
||||
if (!$exists) {
|
||||
DBA::insert('search', ['uid' => local_user(), 'term' => $search]);
|
||||
}
|
||||
}
|
||||
if (!empty($_GET['remove'])) {
|
||||
DBA::delete('search', ['uid' => local_user(), 'term' => $search]);
|
||||
}
|
||||
|
||||
$is_a_date_query = false;
|
||||
|
||||
$group_id = (($a->argc > 1 && is_numeric($a->argv[1])) ? intval($a->argv[1]) : 0);
|
||||
|
@ -82,7 +66,7 @@ function network_init(App $a)
|
|||
|
||||
// fetch last used network view and redirect if needed
|
||||
if (!$is_a_date_query) {
|
||||
$sel_nets = defaults($_GET, 'nets', '');
|
||||
$sel_nets = $_GET['nets'] ?? '';
|
||||
$sel_tabs = network_query_get_sel_tab($a);
|
||||
$sel_groups = network_query_get_sel_group($a);
|
||||
$last_sel_tabs = PConfig::get(local_user(), 'network.view', 'tab.selected');
|
||||
|
@ -154,46 +138,9 @@ function network_init(App $a)
|
|||
$a->page['aside'] .= Group::sidebarWidget('network/0', 'network', 'standard', $group_id);
|
||||
$a->page['aside'] .= ForumManager::widget(local_user(), $cid);
|
||||
$a->page['aside'] .= Widget::postedByYear('network', local_user(), false);
|
||||
$a->page['aside'] .= Widget::networks('network', defaults($_GET, 'nets', '') );
|
||||
$a->page['aside'] .= saved_searches($search);
|
||||
$a->page['aside'] .= Widget::fileAs('network', defaults($_GET, 'file', '') );
|
||||
}
|
||||
|
||||
function saved_searches($search)
|
||||
{
|
||||
$srchurl = '/network?f='
|
||||
. (!empty($_GET['cid']) ? '&cid=' . rawurlencode($_GET['cid']) : '')
|
||||
. (!empty($_GET['star']) ? '&star=' . rawurlencode($_GET['star']) : '')
|
||||
. (!empty($_GET['bmark']) ? '&bmark=' . rawurlencode($_GET['bmark']) : '')
|
||||
. (!empty($_GET['conv']) ? '&conv=' . rawurlencode($_GET['conv']) : '')
|
||||
. (!empty($_GET['nets']) ? '&nets=' . rawurlencode($_GET['nets']) : '')
|
||||
. (!empty($_GET['cmin']) ? '&cmin=' . rawurlencode($_GET['cmin']) : '')
|
||||
. (!empty($_GET['cmax']) ? '&cmax=' . rawurlencode($_GET['cmax']) : '')
|
||||
. (!empty($_GET['file']) ? '&file=' . rawurlencode($_GET['file']) : '');
|
||||
;
|
||||
|
||||
$terms = DBA::select('search', ['id', 'term'], ['uid' => local_user()]);
|
||||
$saved = [];
|
||||
|
||||
while ($rr = DBA::fetch($terms)) {
|
||||
$saved[] = [
|
||||
'id' => $rr['id'],
|
||||
'term' => $rr['term'],
|
||||
'encodedterm' => urlencode($rr['term']),
|
||||
'delete' => L10n::t('Remove term'),
|
||||
'selected' => ($search == $rr['term']),
|
||||
];
|
||||
}
|
||||
|
||||
$tpl = Renderer::getMarkupTemplate('saved_searches_aside.tpl');
|
||||
$o = Renderer::replaceMacros($tpl, [
|
||||
'$title' => L10n::t('Saved Searches'),
|
||||
'$add' => L10n::t('add'),
|
||||
'$searchbox' => HTML::search($search, 'netsearch-box', $srchurl),
|
||||
'$saved' => $saved,
|
||||
]);
|
||||
|
||||
return $o;
|
||||
$a->page['aside'] .= Widget::networks('network', $_GET['nets'] ?? '');
|
||||
$a->page['aside'] .= Widget\SavedSearches::getHTML($a->query_string);
|
||||
$a->page['aside'] .= Widget::fileAs('network', $_GET['file'] ?? '');
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -409,7 +356,7 @@ function networkFlatView(App $a, $update = 0)
|
|||
|
||||
$o = '';
|
||||
|
||||
$file = defaults($_GET, 'file', '');
|
||||
$file = $_GET['file'] ?? '';
|
||||
|
||||
if (!$update && !$rawmode) {
|
||||
$tabs = network_tabs($a);
|
||||
|
@ -532,12 +479,12 @@ function networkThreadedView(App $a, $update, $parent)
|
|||
|
||||
$o = '';
|
||||
|
||||
$cid = intval(defaults($_GET, 'cid' , 0));
|
||||
$star = intval(defaults($_GET, 'star' , 0));
|
||||
$bmark = intval(defaults($_GET, 'bmark', 0));
|
||||
$conv = intval(defaults($_GET, 'conv' , 0));
|
||||
$order = Strings::escapeTags(defaults($_GET, 'order', 'comment'));
|
||||
$nets = defaults($_GET, 'nets' , '');
|
||||
$cid = intval($_GET['cid'] ?? 0);
|
||||
$star = intval($_GET['star'] ?? 0);
|
||||
$bmark = intval($_GET['bmark'] ?? 0);
|
||||
$conv = intval($_GET['conv'] ?? 0);
|
||||
$order = Strings::escapeTags(($_GET['order'] ?? '') ?: 'comment');
|
||||
$nets = $_GET['nets'] ?? '';
|
||||
|
||||
$allowedCids = [];
|
||||
if ($cid) {
|
||||
|
@ -676,7 +623,7 @@ function networkThreadedView(App $a, $update, $parent)
|
|||
$entries[0] = [
|
||||
'id' => 'network',
|
||||
'name' => $contact['name'],
|
||||
'itemurl' => defaults($contact, 'addr', $contact['nurl']),
|
||||
'itemurl' => ($contact['addr'] ?? '') ?: $contact['nurl'],
|
||||
'thumb' => ProxyUtils::proxifyUrl($contact['thumb'], false, ProxyUtils::SIZE_THUMB),
|
||||
'details' => $contact['location'],
|
||||
];
|
||||
|
@ -1066,7 +1013,7 @@ function network_infinite_scroll_head(App $a, &$htmlhead)
|
|||
global $pager;
|
||||
|
||||
if (PConfig::get(local_user(), 'system', 'infinite_scroll')
|
||||
&& defaults($_GET, 'mode', '') != 'minimal'
|
||||
&& ($_GET['mode'] ?? '') != 'minimal'
|
||||
) {
|
||||
$tpl = Renderer::getMarkupTemplate('infinite_scroll_head.tpl');
|
||||
$htmlhead .= Renderer::replaceMacros($tpl, [
|
||||
|
|
|
@ -49,7 +49,7 @@ function noscrape_init(App $a)
|
|||
exit;
|
||||
}
|
||||
|
||||
$keywords = defaults($a->profile, 'pub_keywords', '');
|
||||
$keywords = $a->profile['pub_keywords'] ?? '';
|
||||
$keywords = str_replace(['#',',',' ',',,'], ['',' ',',',','], $keywords);
|
||||
$keywords = explode(',', $keywords);
|
||||
|
||||
|
|
|
@ -12,9 +12,11 @@ use Friendica\Core\L10n;
|
|||
use Friendica\Core\NotificationsManager;
|
||||
use Friendica\Core\Protocol;
|
||||
use Friendica\Core\Renderer;
|
||||
use Friendica\Core\Logger;
|
||||
use Friendica\Core\System;
|
||||
use Friendica\Database\DBA;
|
||||
use Friendica\Module\Login;
|
||||
use Friendica\Model\Contact;
|
||||
|
||||
function notifications_post(App $a)
|
||||
{
|
||||
|
@ -46,13 +48,18 @@ function notifications_post(App $a)
|
|||
|
||||
if ($_POST['submit'] == L10n::t('Discard')) {
|
||||
DBA::delete('intro', ['id' => $intro_id]);
|
||||
|
||||
if (!$fid) {
|
||||
// The check for blocked and pending is in case the friendship was already approved
|
||||
// and we just want to get rid of the now pointless notification
|
||||
// When the contact entry had been created just for that intro, we want to get rid of it now
|
||||
$condition = ['id' => $contact_id, 'uid' => local_user(),
|
||||
'self' => false, 'blocked' => true, 'pending' => true];
|
||||
DBA::delete('contact', $condition);
|
||||
'self' => false, 'pending' => true, 'rel' => [0, Contact::FOLLOWER]];
|
||||
$contact_pending = DBA::exists('contact', $condition);
|
||||
|
||||
// Remove the "pending" to stop the reappearing in any case
|
||||
DBA::update('contact', ['pending' => false], ['id' => $contact_id]);
|
||||
|
||||
if ($contact_pending) {
|
||||
Contact::remove($contact_id);
|
||||
}
|
||||
}
|
||||
$a->internalRedirect('notifications/intros');
|
||||
}
|
||||
|
@ -71,8 +78,8 @@ function notifications_content(App $a)
|
|||
return Login::form();
|
||||
}
|
||||
|
||||
$page = defaults($_REQUEST, 'page', 1);
|
||||
$show = defaults($_REQUEST, 'show', 0);
|
||||
$page = ($_REQUEST['page'] ?? 0) ?: 1;
|
||||
$show = $_REQUEST['show'] ?? 0;
|
||||
|
||||
Nav::setSelected('notifications');
|
||||
|
||||
|
@ -98,9 +105,14 @@ function notifications_content(App $a)
|
|||
if ((($a->argc > 1) && ($a->argv[1] == 'intros')) || (($a->argc == 1))) {
|
||||
Nav::setSelected('introductions');
|
||||
|
||||
$id = 0;
|
||||
if (!empty($a->argv[2]) && intval($a->argv[2]) != 0) {
|
||||
$id = (int)$a->argv[2];
|
||||
}
|
||||
|
||||
$all = (($a->argc > 2) && ($a->argv[2] == 'all'));
|
||||
|
||||
$notifs = $nm->introNotifs($all, $startrec, $perpage);
|
||||
$notifs = $nm->introNotifs($all, $startrec, $perpage, $id);
|
||||
|
||||
// Get the network notifications
|
||||
} elseif (($a->argc > 1) && ($a->argv[1] == 'network')) {
|
||||
|
@ -146,7 +158,7 @@ function notifications_content(App $a)
|
|||
];
|
||||
|
||||
// Process the data for template creation
|
||||
if (defaults($notifs, 'ident', '') === 'introductions') {
|
||||
if (($notifs['ident'] ?? '') == 'introductions') {
|
||||
$sugg = Renderer::getMarkupTemplate('suggestions.tpl');
|
||||
$tpl = Renderer::getMarkupTemplate('intros.tpl');
|
||||
|
||||
|
|
|
@ -13,21 +13,20 @@ use Friendica\Util\Strings;
|
|||
|
||||
function openid_content(App $a) {
|
||||
|
||||
$noid = Config::get('system','no_openid');
|
||||
if($noid)
|
||||
if (Config::get('system','no_openid')) {
|
||||
$a->internalRedirect();
|
||||
}
|
||||
|
||||
Logger::log('mod_openid ' . print_r($_REQUEST,true), Logger::DATA);
|
||||
|
||||
if(!empty($_GET['openid_mode']) && !empty($_SESSION['openid'])) {
|
||||
if (!empty($_GET['openid_mode']) && !empty($_SESSION['openid'])) {
|
||||
|
||||
$openid = new LightOpenID($a->getHostName());
|
||||
|
||||
if($openid->validate()) {
|
||||
if ($openid->validate()) {
|
||||
$authid = $openid->identity;
|
||||
|
||||
$authid = $_REQUEST['openid_identity'];
|
||||
|
||||
if(! strlen($authid)) {
|
||||
if (empty($authid)) {
|
||||
Logger::log(L10n::t('OpenID protocol error. No ID returned.') . EOL);
|
||||
$a->internalRedirect();
|
||||
}
|
||||
|
@ -37,22 +36,16 @@ function openid_content(App $a) {
|
|||
// mod/settings.php in 8367cad so it might have left mixed
|
||||
// records in the user table
|
||||
//
|
||||
$r = q("SELECT *
|
||||
FROM `user`
|
||||
WHERE ( `openid` = '%s' OR `openid` = '%s' )
|
||||
AND `blocked` = 0 AND `account_expired` = 0
|
||||
AND `account_removed` = 0 AND `verified` = 1
|
||||
LIMIT 1",
|
||||
DBA::escape($authid), DBA::escape(Strings::normaliseOpenID($authid))
|
||||
);
|
||||
|
||||
if (DBA::isResult($r)) {
|
||||
$condition = ['blocked' => false, 'account_expired' => false, 'account_removed' => false, 'verified' => true,
|
||||
'openid' => [$authid, Strings::normaliseOpenID($authid)]];
|
||||
$user = DBA::selectFirst('user', [], $condition);
|
||||
if (DBA::isResult($user)) {
|
||||
|
||||
// successful OpenID login
|
||||
|
||||
unset($_SESSION['openid']);
|
||||
|
||||
Session::setAuthenticatedForUser($a, $r[0],true,true);
|
||||
Session::setAuthenticatedForUser($a, $user, true, true);
|
||||
|
||||
// just in case there was no return url set
|
||||
// and we fell through
|
||||
|
@ -76,10 +69,10 @@ function openid_content(App $a) {
|
|||
if ($k === 'namePerson/friendly') {
|
||||
$nick = Strings::escapeTags(trim($v));
|
||||
}
|
||||
if($k === 'namePerson/first') {
|
||||
if ($k === 'namePerson/first') {
|
||||
$first = Strings::escapeTags(trim($v));
|
||||
}
|
||||
if($k === 'namePerson') {
|
||||
if ($k === 'namePerson') {
|
||||
$args .= '&username=' . urlencode(Strings::escapeTags(trim($v)));
|
||||
}
|
||||
if ($k === 'contact/email') {
|
||||
|
@ -95,15 +88,13 @@ function openid_content(App $a) {
|
|||
}
|
||||
if (!empty($nick)) {
|
||||
$args .= '&nickname=' . urlencode($nick);
|
||||
}
|
||||
elseif (!empty($first)) {
|
||||
} elseif (!empty($first)) {
|
||||
$args .= '&nickname=' . urlencode($first);
|
||||
}
|
||||
|
||||
if (!empty($photosq)) {
|
||||
$args .= '&photo=' . urlencode($photosq);
|
||||
}
|
||||
elseif (!empty($photo)) {
|
||||
} elseif (!empty($photo)) {
|
||||
$args .= '&photo=' . urlencode($photo);
|
||||
}
|
||||
|
||||
|
|
105
mod/photos.php
105
mod/photos.php
|
@ -15,6 +15,7 @@ use Friendica\Core\L10n;
|
|||
use Friendica\Core\Logger;
|
||||
use Friendica\Core\Renderer;
|
||||
use Friendica\Core\System;
|
||||
use Friendica\Core\Session;
|
||||
use Friendica\Database\DBA;
|
||||
use Friendica\Model\Contact;
|
||||
use Friendica\Model\Group;
|
||||
|
@ -35,11 +36,7 @@ use Friendica\Util\XML;
|
|||
|
||||
function photos_init(App $a) {
|
||||
|
||||
if ($a->argc > 1) {
|
||||
DFRN::autoRedir($a, $a->argv[1]);
|
||||
}
|
||||
|
||||
if (Config::get('system', 'block_public') && !local_user() && !remote_user()) {
|
||||
if (Config::get('system', 'block_public') && !Session::isAuthenticated()) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -66,14 +63,14 @@ function photos_init(App $a) {
|
|||
$vcard_widget = Renderer::replaceMacros($tpl, [
|
||||
'$name' => $profile['name'],
|
||||
'$photo' => $profile['photo'],
|
||||
'$addr' => defaults($profile, 'addr', ''),
|
||||
'$addr' => $profile['addr'] ?? '',
|
||||
'$account_type' => $account_type,
|
||||
'$pdesc' => defaults($profile, 'pdesc', ''),
|
||||
'$pdesc' => $profile['pdesc'] ?? '',
|
||||
]);
|
||||
|
||||
$albums = Photo::getAlbums($a->data['user']['uid']);
|
||||
|
||||
$albums_visible = ((intval($a->data['user']['hidewall']) && !local_user() && !remote_user()) ? false : true);
|
||||
$albums_visible = ((intval($a->data['user']['hidewall']) && !Session::isAuthenticated()) ? false : true);
|
||||
|
||||
// add various encodings to the array so we can just loop through and pick them out in a template
|
||||
$ret = ['success' => false];
|
||||
|
@ -88,7 +85,7 @@ function photos_init(App $a) {
|
|||
$ret['albums'] = [];
|
||||
foreach ($albums as $k => $album) {
|
||||
//hide profile photos to others
|
||||
if (!$is_owner && !remote_user() && ($album['album'] == L10n::t('Profile Photos')))
|
||||
if (!$is_owner && !Session::getRemoteContactID($a->profile_uid) && ($album['album'] == L10n::t('Profile Photos')))
|
||||
continue;
|
||||
$entry = [
|
||||
'text' => $album['album'],
|
||||
|
@ -154,24 +151,10 @@ function photos_post(App $a)
|
|||
|
||||
if (local_user() && (local_user() == $page_owner_uid)) {
|
||||
$can_post = true;
|
||||
} elseif ($community_page && remote_user()) {
|
||||
$contact_id = 0;
|
||||
|
||||
if (!empty($_SESSION['remote']) && is_array($_SESSION['remote'])) {
|
||||
foreach ($_SESSION['remote'] as $v) {
|
||||
if ($v['uid'] == $page_owner_uid) {
|
||||
$contact_id = $v['cid'];
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ($contact_id > 0) {
|
||||
if (DBA::exists('contact', ['id' => $contact_id, 'uid' => $page_owner_uid, 'blocked' => false, 'pending' => false])) {
|
||||
$can_post = true;
|
||||
$visitor = $contact_id;
|
||||
}
|
||||
}
|
||||
} elseif ($community_page && !empty(Session::getRemoteContactID($page_owner_uid))) {
|
||||
$contact_id = Session::getRemoteContactID($page_owner_uid);
|
||||
$can_post = true;
|
||||
$visitor = $contact_id;
|
||||
}
|
||||
|
||||
if (!$can_post) {
|
||||
|
@ -647,10 +630,10 @@ function photos_post(App $a)
|
|||
$visible = 0;
|
||||
}
|
||||
|
||||
$group_allow = defaults($_REQUEST, 'group_allow' , []);
|
||||
$contact_allow = defaults($_REQUEST, 'contact_allow', []);
|
||||
$group_deny = defaults($_REQUEST, 'group_deny' , []);
|
||||
$contact_deny = defaults($_REQUEST, 'contact_deny' , []);
|
||||
$group_allow = $_REQUEST['group_allow'] ?? [];
|
||||
$contact_allow = $_REQUEST['contact_allow'] ?? [];
|
||||
$group_deny = $_REQUEST['group_deny'] ?? [];
|
||||
$contact_deny = $_REQUEST['contact_deny'] ?? [];
|
||||
|
||||
$str_group_allow = perms2str(is_array($group_allow) ? $group_allow : explode(',', $group_allow));
|
||||
$str_contact_allow = perms2str(is_array($contact_allow) ? $contact_allow : explode(',', $contact_allow));
|
||||
|
@ -683,7 +666,7 @@ function photos_post(App $a)
|
|||
notice(L10n::t('Image exceeds size limit of %s', ini_get('upload_max_filesize')) . EOL);
|
||||
break;
|
||||
case UPLOAD_ERR_FORM_SIZE:
|
||||
notice(L10n::t('Image exceeds size limit of %s', Strings::formatBytes(defaults($_REQUEST, 'MAX_FILE_SIZE', 0))) . EOL);
|
||||
notice(L10n::t('Image exceeds size limit of %s', Strings::formatBytes($_REQUEST['MAX_FILE_SIZE'] ?? 0)) . EOL);
|
||||
break;
|
||||
case UPLOAD_ERR_PARTIAL:
|
||||
notice(L10n::t('Image upload didn\'t complete, please try again') . EOL);
|
||||
|
@ -846,7 +829,7 @@ function photos_content(App $a)
|
|||
// photos/name/image/xxxxx/edit
|
||||
// photos/name/image/xxxxx/drop
|
||||
|
||||
if (Config::get('system', 'block_public') && !local_user() && !remote_user()) {
|
||||
if (Config::get('system', 'block_public') && !Session::isAuthenticated()) {
|
||||
notice(L10n::t('Public access denied.') . EOL);
|
||||
return;
|
||||
}
|
||||
|
@ -892,50 +875,24 @@ function photos_content(App $a)
|
|||
|
||||
if (local_user() && (local_user() == $owner_uid)) {
|
||||
$can_post = true;
|
||||
} else {
|
||||
if ($community_page && remote_user()) {
|
||||
if (is_array($_SESSION['remote'])) {
|
||||
foreach ($_SESSION['remote'] as $v) {
|
||||
if ($v['uid'] == $owner_uid) {
|
||||
$contact_id = $v['cid'];
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
} elseif ($community_page && !empty(Session::getRemoteContactID($owner_uid))) {
|
||||
$contact_id = Session::getRemoteContactID($owner_uid);
|
||||
$contact = DBA::selectFirst('contact', [], ['id' => $contact_id, 'uid' => $owner_uid, 'blocked' => false, 'pending' => false]);
|
||||
|
||||
if ($contact_id) {
|
||||
$contact = DBA::selectFirst('contact', [], ['id' => $contact_id, 'uid' => $owner_uid, 'blocked' => false, 'pending' => false]);
|
||||
|
||||
if (DBA::isResult($contact)) {
|
||||
$can_post = true;
|
||||
$remote_contact = true;
|
||||
$visitor = $contact_id;
|
||||
}
|
||||
}
|
||||
if (DBA::isResult($contact)) {
|
||||
$can_post = true;
|
||||
$remote_contact = true;
|
||||
$visitor = $contact_id;
|
||||
}
|
||||
}
|
||||
|
||||
$groups = [];
|
||||
|
||||
// perhaps they're visiting - but not a community page, so they wouldn't have write access
|
||||
if (remote_user() && !$visitor) {
|
||||
$contact_id = 0;
|
||||
if (is_array($_SESSION['remote'])) {
|
||||
foreach ($_SESSION['remote'] as $v) {
|
||||
if ($v['uid'] == $owner_uid) {
|
||||
$contact_id = $v['cid'];
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!empty(Session::getRemoteContactID($owner_uid)) && !$visitor) {
|
||||
$contact_id = Session::getRemoteContactID($owner_uid);
|
||||
|
||||
if ($contact_id) {
|
||||
$groups = Group::getIdsByContactId($contact_id);
|
||||
$contact = DBA::selectFirst('contact', [], ['id' => $contact_id, 'uid' => $owner_uid, 'blocked' => false, 'pending' => false]);
|
||||
|
||||
$contact = DBA::selectFirst('contact', [], ['id' => $contact_id, 'uid' => $owner_uid, 'blocked' => false, 'pending' => false]);
|
||||
|
||||
$remote_contact = DBA::isResult($contact);
|
||||
}
|
||||
$remote_contact = DBA::isResult($contact);
|
||||
}
|
||||
|
||||
if (!$remote_contact && local_user()) {
|
||||
|
@ -948,7 +905,7 @@ function photos_content(App $a)
|
|||
return;
|
||||
}
|
||||
|
||||
$sql_extra = Security::getPermissionsSQLByUserId($owner_uid, $remote_contact, $groups);
|
||||
$sql_extra = Security::getPermissionsSQLByUserId($owner_uid);
|
||||
|
||||
$o = "";
|
||||
|
||||
|
@ -1049,7 +1006,7 @@ function photos_content(App $a)
|
|||
$pager = new Pager($a->query_string, 20);
|
||||
|
||||
/// @TODO I have seen this many times, maybe generalize it script-wide and encapsulate it?
|
||||
$order_field = defaults($_GET, 'order', '');
|
||||
$order_field = $_GET['order'] ?? '';
|
||||
if ($order_field === 'posted') {
|
||||
$order = 'ASC';
|
||||
} else {
|
||||
|
@ -1201,7 +1158,7 @@ function photos_content(App $a)
|
|||
* By now we hide it if someone wants to.
|
||||
*/
|
||||
if ($cmd === 'view' && !Config::get('system', 'no_count', false)) {
|
||||
$order_field = defaults($_GET, 'order', '');
|
||||
$order_field = $_GET['order'] ?? '';
|
||||
|
||||
if ($order_field === 'posted') {
|
||||
$order = 'ASC';
|
||||
|
@ -1607,7 +1564,7 @@ function photos_content(App $a)
|
|||
$twist = false;
|
||||
foreach ($r as $rr) {
|
||||
//hide profile photos to others
|
||||
if (!$is_owner && !remote_user() && ($rr['album'] == L10n::t('Profile Photos'))) {
|
||||
if (!$is_owner && !Session::getRemoteContactID($owner_uid) && ($rr['album'] == L10n::t('Profile Photos'))) {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
|
|
@ -36,7 +36,7 @@ function poco_init(App $a) {
|
|||
$system_mode = true;
|
||||
}
|
||||
|
||||
$format = defaults($_GET, 'format', 'json');
|
||||
$format = ($_GET['format'] ?? '') ?: 'json';
|
||||
|
||||
$justme = false;
|
||||
$global = false;
|
||||
|
|
|
@ -594,7 +594,7 @@ function profiles_content(App $a) {
|
|||
'$default' => (($is_default) ? '<p id="profile-edit-default-desc">' . L10n::t('This is your <strong>public</strong> profile.<br />It <strong>may</strong> be visible to anybody using the internet.') . '</p>' : ""),
|
||||
'$name' => ['name', L10n::t('Your Full Name:'), $r[0]['name']],
|
||||
'$pdesc' => ['pdesc', L10n::t('Title/Description:'), $r[0]['pdesc']],
|
||||
'$dob' => Temporal::getDateofBirthField($r[0]['dob']),
|
||||
'$dob' => Temporal::getDateofBirthField($r[0]['dob'], $a->user['timezone']),
|
||||
'$hide_friends' => $hide_friends,
|
||||
'$address' => ['address', L10n::t('Street Address:'), $r[0]['address']],
|
||||
'$locality' => ['locality', L10n::t('Locality/City:'), $r[0]['locality']],
|
||||
|
|
|
@ -33,10 +33,10 @@ function pubsub_init(App $a)
|
|||
$contact_id = (($a->argc > 2) ? intval($a->argv[2]) : 0 );
|
||||
|
||||
if ($_SERVER['REQUEST_METHOD'] === 'GET') {
|
||||
$hub_mode = Strings::escapeTags(trim(defaults($_GET, 'hub_mode', '')));
|
||||
$hub_topic = Strings::escapeTags(trim(defaults($_GET, 'hub_topic', '')));
|
||||
$hub_challenge = Strings::escapeTags(trim(defaults($_GET, 'hub_challenge', '')));
|
||||
$hub_verify = Strings::escapeTags(trim(defaults($_GET, 'hub_verify_token', '')));
|
||||
$hub_mode = Strings::escapeTags(trim($_GET['hub_mode'] ?? ''));
|
||||
$hub_topic = Strings::escapeTags(trim($_GET['hub_topic'] ?? ''));
|
||||
$hub_challenge = Strings::escapeTags(trim($_GET['hub_challenge'] ?? ''));
|
||||
$hub_verify = Strings::escapeTags(trim($_GET['hub_verify_token'] ?? ''));
|
||||
|
||||
Logger::log('Subscription from ' . $_SERVER['REMOTE_ADDR'] . ' Mode: ' . $hub_mode . ' Nick: ' . $nick);
|
||||
Logger::log('Data: ' . print_r($_GET,true), Logger::DATA);
|
||||
|
|
|
@ -13,18 +13,18 @@ use Friendica\Util\Strings;
|
|||
|
||||
function redir_init(App $a) {
|
||||
|
||||
$url = defaults($_GET, 'url', '');
|
||||
$url = $_GET['url'] ?? '';
|
||||
$quiet = !empty($_GET['quiet']) ? '&quiet=1' : '';
|
||||
$con_url = defaults($_GET, 'conurl', '');
|
||||
|
||||
if ($a->argc > 1 && intval($a->argv[1])) {
|
||||
$cid = intval($a->argv[1]);
|
||||
} elseif (local_user() && !empty($con_url)) {
|
||||
$cid = Contact::getIdForURL($con_url, local_user());
|
||||
} else {
|
||||
$cid = 0;
|
||||
}
|
||||
|
||||
// Try magic auth before the legacy stuff
|
||||
redir_magic($a, $cid, $url);
|
||||
|
||||
if (!empty($cid)) {
|
||||
$fields = ['id', 'uid', 'nurl', 'url', 'addr', 'name', 'network', 'poll', 'issued-id', 'dfrn-id', 'duplex', 'pending'];
|
||||
$contact = DBA::selectFirst('contact', $fields, ['id' => $cid, 'uid' => [0, local_user()]]);
|
||||
|
@ -35,10 +35,10 @@ function redir_init(App $a) {
|
|||
|
||||
$contact_url = $contact['url'];
|
||||
|
||||
if ((!local_user() && !remote_user()) // Visitors (not logged in or not remotes) can't authenticate.
|
||||
if (!Session::isAuthenticated() // Visitors (not logged in or not remotes) can't authenticate.
|
||||
|| (!empty($a->contact['id']) && $a->contact['id'] == $cid)) // Local user is already authenticated.
|
||||
{
|
||||
$a->redirect(defaults($url, $contact_url));
|
||||
$a->redirect($url ?: $contact_url);
|
||||
}
|
||||
|
||||
if ($contact['uid'] == 0 && local_user()) {
|
||||
|
@ -52,7 +52,7 @@ function redir_init(App $a) {
|
|||
|
||||
if (!empty($a->contact['id']) && $a->contact['id'] == $cid) {
|
||||
// Local user is already authenticated.
|
||||
$target_url = defaults($url, $contact_url);
|
||||
$target_url = $url ?: $contact_url;
|
||||
Logger::log($contact['name'] . " is already authenticated. Redirecting to " . $target_url, Logger::DEBUG);
|
||||
$a->redirect($target_url);
|
||||
}
|
||||
|
@ -66,34 +66,16 @@ function redir_init(App $a) {
|
|||
// with the local contact. Otherwise the local user would ask the local contact
|
||||
// for authentification everytime he/she is visiting a profile page of the local
|
||||
// contact.
|
||||
if ($host == $remotehost
|
||||
&& !empty($_SESSION['remote'])
|
||||
&& is_array($_SESSION['remote']))
|
||||
{
|
||||
foreach ($_SESSION['remote'] as $v) {
|
||||
if (!empty($v['uid']) && !empty($v['cid']) &&
|
||||
$v['uid'] == Session::get('visitor_visiting') &&
|
||||
$v['cid'] == Session::get('visitor_id')) {
|
||||
// Remote user is already authenticated.
|
||||
$target_url = defaults($url, $contact_url);
|
||||
Logger::log($contact['name'] . " is already authenticated. Redirecting to " . $target_url, Logger::DEBUG);
|
||||
$a->redirect($target_url);
|
||||
}
|
||||
}
|
||||
if (($host == $remotehost) && (Session::getRemoteContactID(Session::get('visitor_visiting')) == Session::get('visitor_id'))) {
|
||||
// Remote user is already authenticated.
|
||||
$target_url = $url ?: $contact_url;
|
||||
Logger::log($contact['name'] . " is already authenticated. Redirecting to " . $target_url, Logger::DEBUG);
|
||||
$a->redirect($target_url);
|
||||
}
|
||||
}
|
||||
|
||||
// When the remote page does support OWA, then we enforce the use of it
|
||||
$basepath = Contact::getBasepath($contact_url);
|
||||
if (Strings::compareLink($basepath, System::baseUrl())) {
|
||||
$use_magic = true;
|
||||
} else {
|
||||
$serverret = Network::curl($basepath . '/magic');
|
||||
$use_magic = $serverret->isSuccess();
|
||||
}
|
||||
|
||||
// Doing remote auth with dfrn.
|
||||
if (local_user() && !$use_magic && (!empty($contact['dfrn-id']) || !empty($contact['issued-id'])) && empty($contact['pending'])) {
|
||||
if (local_user() && (!empty($contact['dfrn-id']) || !empty($contact['issued-id'])) && empty($contact['pending'])) {
|
||||
$dfrn_id = $orig_id = (($contact['issued-id']) ? $contact['issued-id'] : $contact['dfrn-id']);
|
||||
|
||||
if ($contact['duplex'] && $contact['issued-id']) {
|
||||
|
@ -119,7 +101,7 @@ function redir_init(App $a) {
|
|||
. '&dfrn_version=' . DFRN_PROTOCOL_VERSION . '&type=profile&sec=' . $sec . $dest . $quiet);
|
||||
}
|
||||
|
||||
$url = defaults($url, $contact_url);
|
||||
$url = $url ?: $contact_url;
|
||||
}
|
||||
|
||||
// If we don't have a connected contact, redirect with
|
||||
|
@ -140,3 +122,46 @@ function redir_init(App $a) {
|
|||
notice(L10n::t('Contact not found.'));
|
||||
$a->internalRedirect();
|
||||
}
|
||||
|
||||
function redir_magic($a, $cid, $url)
|
||||
{
|
||||
$visitor = Profile::getMyURL();
|
||||
if (!empty($visitor)) {
|
||||
Logger::info('Got my url', ['visitor' => $visitor]);
|
||||
}
|
||||
|
||||
$contact = DBA::selectFirst('contact', ['url'], ['id' => $cid]);
|
||||
if (!DBA::isResult($contact)) {
|
||||
Logger::info('Contact not found', ['id' => $cid]);
|
||||
// Shouldn't happen under normal conditions
|
||||
notice(L10n::t('Contact not found.'));
|
||||
if (!empty($url)) {
|
||||
$a->redirect($url);
|
||||
} else {
|
||||
$a->internalRedirect();
|
||||
}
|
||||
} else {
|
||||
$contact_url = $contact['url'];
|
||||
$target_url = $url ?: $contact_url;
|
||||
}
|
||||
|
||||
$basepath = Contact::getBasepath($contact_url);
|
||||
|
||||
// We don't use magic auth when there is no visitor, we are on the same system or we visit our own stuff
|
||||
if (empty($visitor) || Strings::compareLink($basepath, System::baseUrl()) || Strings::compareLink($contact_url, $visitor)) {
|
||||
Logger::info('Redirecting without magic', ['target' => $target_url, 'visitor' => $visitor, 'contact' => $contact_url]);
|
||||
$a->redirect($target_url);
|
||||
}
|
||||
|
||||
// Test for magic auth on the target system
|
||||
$serverret = Network::curl($basepath . '/magic');
|
||||
if ($serverret->isSuccess()) {
|
||||
$separator = strpos($target_url, '?') ? '&' : '?';
|
||||
$target_url .= $separator . 'zrl=' . urlencode($visitor) . '&addr=' . urlencode($contact_url);
|
||||
|
||||
Logger::info('Redirecting with magic', ['target' => $target_url, 'visitor' => $visitor, 'contact' => $contact_url]);
|
||||
$a->redirect($target_url);
|
||||
} else {
|
||||
Logger::info('No magic for contact', ['contact' => $contact_url]);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -44,7 +44,7 @@ function user_allow($hash)
|
|||
$user,
|
||||
Config::get('config', 'sitename'),
|
||||
$a->getBaseUrl(),
|
||||
defaults($register, 'password', 'Sent in a previous email')
|
||||
($register['password'] ?? '') ?: 'Sent in a previous email'
|
||||
);
|
||||
|
||||
L10n::popLang();
|
||||
|
|
245
mod/search.php
245
mod/search.php
|
@ -1,245 +0,0 @@
|
|||
<?php
|
||||
/**
|
||||
* @file mod/search.php
|
||||
*/
|
||||
|
||||
use Friendica\App;
|
||||
use Friendica\Content\Nav;
|
||||
use Friendica\Content\Pager;
|
||||
use Friendica\Content\Text\HTML;
|
||||
use Friendica\Core\Cache;
|
||||
use Friendica\Core\Config;
|
||||
use Friendica\Core\L10n;
|
||||
use Friendica\Core\Logger;
|
||||
use Friendica\Core\Renderer;
|
||||
use Friendica\Database\DBA;
|
||||
use Friendica\Model\Item;
|
||||
use Friendica\Module\BaseSearchModule;
|
||||
use Friendica\Util\Strings;
|
||||
|
||||
function search_saved_searches() {
|
||||
$o = '';
|
||||
$search = (!empty($_GET['search']) ? Strings::escapeTags(trim(rawurldecode($_GET['search']))) : '');
|
||||
|
||||
$r = q("SELECT `id`,`term` FROM `search` WHERE `uid` = %d",
|
||||
intval(local_user())
|
||||
);
|
||||
|
||||
if (DBA::isResult($r)) {
|
||||
$saved = [];
|
||||
foreach ($r as $rr) {
|
||||
$saved[] = [
|
||||
'id' => $rr['id'],
|
||||
'term' => $rr['term'],
|
||||
'encodedterm' => urlencode($rr['term']),
|
||||
'delete' => L10n::t('Remove term'),
|
||||
'selected' => ($search==$rr['term']),
|
||||
];
|
||||
}
|
||||
|
||||
|
||||
$tpl = Renderer::getMarkupTemplate("saved_searches_aside.tpl");
|
||||
|
||||
$o .= Renderer::replaceMacros($tpl, [
|
||||
'$title' => L10n::t('Saved Searches'),
|
||||
'$add' => '',
|
||||
'$searchbox' => '',
|
||||
'$saved' => $saved,
|
||||
]);
|
||||
}
|
||||
|
||||
return $o;
|
||||
}
|
||||
|
||||
|
||||
function search_init(App $a) {
|
||||
$search = (!empty($_GET['search']) ? Strings::escapeTags(trim(rawurldecode($_GET['search']))) : '');
|
||||
|
||||
if (local_user()) {
|
||||
if (!empty($_GET['save']) && $search) {
|
||||
$r = q("SELECT * FROM `search` WHERE `uid` = %d AND `term` = '%s' LIMIT 1",
|
||||
intval(local_user()),
|
||||
DBA::escape($search)
|
||||
);
|
||||
if (!DBA::isResult($r)) {
|
||||
DBA::insert('search', ['uid' => local_user(), 'term' => $search]);
|
||||
}
|
||||
}
|
||||
if (!empty($_GET['remove']) && $search) {
|
||||
DBA::delete('search', ['uid' => local_user(), 'term' => $search]);
|
||||
}
|
||||
|
||||
/// @todo Check if there is a case at all that "aside" is prefilled here
|
||||
if (!isset($a->page['aside'])) {
|
||||
$a->page['aside'] = '';
|
||||
}
|
||||
|
||||
$a->page['aside'] .= search_saved_searches();
|
||||
|
||||
} else {
|
||||
unset($_SESSION['theme']);
|
||||
unset($_SESSION['mobile-theme']);
|
||||
}
|
||||
}
|
||||
|
||||
function search_content(App $a) {
|
||||
if (Config::get('system','block_public') && !local_user() && !remote_user()) {
|
||||
notice(L10n::t('Public access denied.') . EOL);
|
||||
return;
|
||||
}
|
||||
|
||||
if (Config::get('system','local_search') && !local_user() && !remote_user()) {
|
||||
$e = new \Friendica\Network\HTTPException\ForbiddenException(L10n::t("Only logged in users are permitted to perform a search."));
|
||||
$e->httpdesc = L10n::t("Public access denied.");
|
||||
throw $e;
|
||||
}
|
||||
|
||||
if (Config::get('system','permit_crawling') && !local_user() && !remote_user()) {
|
||||
// Default values:
|
||||
// 10 requests are "free", after the 11th only a call per minute is allowed
|
||||
|
||||
$free_crawls = intval(Config::get('system','free_crawls'));
|
||||
if ($free_crawls == 0)
|
||||
$free_crawls = 10;
|
||||
|
||||
$crawl_permit_period = intval(Config::get('system','crawl_permit_period'));
|
||||
if ($crawl_permit_period == 0)
|
||||
$crawl_permit_period = 10;
|
||||
|
||||
$remote = $_SERVER["REMOTE_ADDR"];
|
||||
$result = Cache::get("remote_search:".$remote);
|
||||
if (!is_null($result)) {
|
||||
$resultdata = json_decode($result);
|
||||
if (($resultdata->time > (time() - $crawl_permit_period)) && ($resultdata->accesses > $free_crawls)) {
|
||||
throw new \Friendica\Network\HTTPException\TooManyRequestsException(L10n::t("Only one search per minute is permitted for not logged in users."));
|
||||
}
|
||||
Cache::set("remote_search:".$remote, json_encode(["time" => time(), "accesses" => $resultdata->accesses + 1]), Cache::HOUR);
|
||||
} else
|
||||
Cache::set("remote_search:".$remote, json_encode(["time" => time(), "accesses" => 1]), Cache::HOUR);
|
||||
}
|
||||
|
||||
Nav::setSelected('search');
|
||||
|
||||
$search = (!empty($_REQUEST['search']) ? Strings::escapeTags(trim(rawurldecode($_REQUEST['search']))) : '');
|
||||
|
||||
$tag = false;
|
||||
if (!empty($_GET['tag'])) {
|
||||
$tag = true;
|
||||
$search = (!empty($_GET['tag']) ? '#' . Strings::escapeTags(trim(rawurldecode($_GET['tag']))) : '');
|
||||
}
|
||||
|
||||
// contruct a wrapper for the search header
|
||||
$o = Renderer::replaceMacros(Renderer::getMarkupTemplate("content_wrapper.tpl"),[
|
||||
'name' => "search-header",
|
||||
'$title' => L10n::t("Search"),
|
||||
'$title_size' => 3,
|
||||
'$content' => HTML::search($search,'search-box','search', false)
|
||||
]);
|
||||
|
||||
if (strpos($search,'#') === 0) {
|
||||
$tag = true;
|
||||
$search = substr($search,1);
|
||||
}
|
||||
if (strpos($search,'@') === 0) {
|
||||
return BaseSearchModule::performSearch();
|
||||
}
|
||||
if (strpos($search,'!') === 0) {
|
||||
return BaseSearchModule::performSearch();
|
||||
}
|
||||
|
||||
if (parse_url($search, PHP_URL_SCHEME) != '') {
|
||||
$id = Item::fetchByLink($search);
|
||||
if (!empty($id)) {
|
||||
$item = Item::selectFirst(['guid'], ['id' => $id]);
|
||||
if (DBA::isResult($item)) {
|
||||
$a->internalRedirect('display/' . $item['guid']);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!empty($_GET['search-option']))
|
||||
switch($_GET['search-option']) {
|
||||
case 'fulltext':
|
||||
break;
|
||||
case 'tags':
|
||||
$tag = true;
|
||||
break;
|
||||
case 'contacts':
|
||||
return BaseSearchModule::performSearch('@');
|
||||
case 'forums':
|
||||
return BaseSearchModule::performSearch('!');
|
||||
}
|
||||
|
||||
if (!$search)
|
||||
return $o;
|
||||
|
||||
if (Config::get('system','only_tag_search'))
|
||||
$tag = true;
|
||||
|
||||
// Here is the way permissions work in the search module...
|
||||
// Only public posts can be shown
|
||||
// OR your own posts if you are a logged in member
|
||||
// No items will be shown if the member has a blocked profile wall.
|
||||
|
||||
$pager = new Pager($a->query_string);
|
||||
|
||||
if ($tag) {
|
||||
Logger::log("Start tag search for '".$search."'", Logger::DEBUG);
|
||||
|
||||
$condition = ["(`uid` = 0 OR (`uid` = ? AND NOT `global`))
|
||||
AND `otype` = ? AND `type` = ? AND `term` = ?",
|
||||
local_user(), TERM_OBJ_POST, TERM_HASHTAG, $search];
|
||||
$params = ['order' => ['received' => true],
|
||||
'limit' => [$pager->getStart(), $pager->getItemsPerPage()]];
|
||||
$terms = DBA::select('term', ['oid'], $condition, $params);
|
||||
|
||||
$itemids = [];
|
||||
while ($term = DBA::fetch($terms)) {
|
||||
$itemids[] = $term['oid'];
|
||||
}
|
||||
DBA::close($terms);
|
||||
|
||||
if (!empty($itemids)) {
|
||||
$params = ['order' => ['id' => true]];
|
||||
$items = Item::selectForUser(local_user(), [], ['id' => $itemids], $params);
|
||||
$r = Item::inArray($items);
|
||||
} else {
|
||||
$r = [];
|
||||
}
|
||||
} else {
|
||||
Logger::log("Start fulltext search for '".$search."'", Logger::DEBUG);
|
||||
|
||||
$condition = ["(`uid` = 0 OR (`uid` = ? AND NOT `global`))
|
||||
AND `body` LIKE CONCAT('%',?,'%')",
|
||||
local_user(), $search];
|
||||
$params = ['order' => ['id' => true],
|
||||
'limit' => [$pager->getStart(), $pager->getItemsPerPage()]];
|
||||
$items = Item::selectForUser(local_user(), [], $condition, $params);
|
||||
$r = Item::inArray($items);
|
||||
}
|
||||
|
||||
if (!DBA::isResult($r)) {
|
||||
info(L10n::t('No results.') . EOL);
|
||||
return $o;
|
||||
}
|
||||
|
||||
|
||||
if ($tag) {
|
||||
$title = L10n::t('Items tagged with: %s', $search);
|
||||
} else {
|
||||
$title = L10n::t('Results for: %s', $search);
|
||||
}
|
||||
|
||||
$o .= Renderer::replaceMacros(Renderer::getMarkupTemplate("section_title.tpl"),[
|
||||
'$title' => $title
|
||||
]);
|
||||
|
||||
Logger::log("Start Conversation for '".$search."'", Logger::DEBUG);
|
||||
$o .= conversation($a, $r, $pager, 'search', false, false, 'commented', local_user());
|
||||
|
||||
$o .= $pager->renderMinimal(count($r));
|
||||
|
||||
Logger::log("Done '".$search."'", Logger::DEBUG);
|
||||
|
||||
return $o;
|
||||
}
|
|
@ -35,7 +35,7 @@ function get_theme_config_file($theme)
|
|||
$theme = Strings::sanitizeFilePathItem($theme);
|
||||
|
||||
$a = \get_app();
|
||||
$base_theme = defaults($a->theme_info, 'extends');
|
||||
$base_theme = $a->theme_info['extends'] ?? '';
|
||||
|
||||
if (file_exists("view/theme/$theme/config.php")) {
|
||||
return "view/theme/$theme/config.php";
|
||||
|
@ -115,8 +115,8 @@ function settings_init(App $a)
|
|||
|
||||
$tabs[] = [
|
||||
'label' => L10n::t('Delegations'),
|
||||
'url' => 'delegate',
|
||||
'selected' => (($a->argc == 1) && ($a->argv[0] === 'delegate')?'active':''),
|
||||
'url' => 'settings/delegation',
|
||||
'selected' => (($a->argc > 1) && ($a->argv[1] === 'delegation')?'active':''),
|
||||
'accesskey' => 'd',
|
||||
];
|
||||
|
||||
|
@ -180,11 +180,11 @@ function settings_post(App $a)
|
|||
if (($a->argc > 2) && ($a->argv[1] === 'oauth') && ($a->argv[2] === 'edit'||($a->argv[2] === 'add')) && !empty($_POST['submit'])) {
|
||||
BaseModule::checkFormSecurityTokenRedirectOnError('/settings/oauth', 'settings_oauth');
|
||||
|
||||
$name = defaults($_POST, 'name' , '');
|
||||
$key = defaults($_POST, 'key' , '');
|
||||
$secret = defaults($_POST, 'secret' , '');
|
||||
$redirect = defaults($_POST, 'redirect', '');
|
||||
$icon = defaults($_POST, 'icon' , '');
|
||||
$name = $_POST['name'] ?? '';
|
||||
$key = $_POST['key'] ?? '';
|
||||
$secret = $_POST['secret'] ?? '';
|
||||
$redirect = $_POST['redirect'] ?? '';
|
||||
$icon = $_POST['icon'] ?? '';
|
||||
|
||||
if ($name == "" || $key == "" || $secret == "") {
|
||||
notice(L10n::t("Missing some important data!"));
|
||||
|
@ -241,24 +241,21 @@ function settings_post(App $a)
|
|||
PConfig::set(local_user(), 'ostatus', 'default_group', $_POST['group-selection']);
|
||||
PConfig::set(local_user(), 'ostatus', 'legacy_contact', $_POST['legacy_contact']);
|
||||
} elseif (!empty($_POST['imap-submit'])) {
|
||||
$mail_server = $_POST['mail_server'] ?? '';
|
||||
$mail_port = $_POST['mail_port'] ?? '';
|
||||
$mail_ssl = strtolower(trim($_POST['mail_ssl'] ?? ''));
|
||||
$mail_user = $_POST['mail_user'] ?? '';
|
||||
$mail_pass = trim($_POST['mail_pass'] ?? '');
|
||||
$mail_action = trim($_POST['mail_action'] ?? '');
|
||||
$mail_movetofolder = trim($_POST['mail_movetofolder'] ?? '');
|
||||
$mail_replyto = $_POST['mail_replyto'] ?? '';
|
||||
$mail_pubmail = $_POST['mail_pubmail'] ?? '';
|
||||
|
||||
$mail_server = defaults($_POST, 'mail_server', '');
|
||||
$mail_port = defaults($_POST, 'mail_port', '');
|
||||
$mail_ssl = (!empty($_POST['mail_ssl']) ? strtolower(trim($_POST['mail_ssl'])) : '');
|
||||
$mail_user = defaults($_POST, 'mail_user', '');
|
||||
$mail_pass = (!empty($_POST['mail_pass']) ? trim($_POST['mail_pass']) : '');
|
||||
$mail_action = (!empty($_POST['mail_action']) ? trim($_POST['mail_action']) : '');
|
||||
$mail_movetofolder = (!empty($_POST['mail_movetofolder']) ? trim($_POST['mail_movetofolder']) : '');
|
||||
$mail_replyto = defaults($_POST, 'mail_replyto', '');
|
||||
$mail_pubmail = defaults($_POST, 'mail_pubmail', '');
|
||||
|
||||
|
||||
$mail_disabled = ((function_exists('imap_open') && (!Config::get('system', 'imap_disabled'))) ? 0 : 1);
|
||||
if (Config::get('system', 'dfrn_only')) {
|
||||
$mail_disabled = 1;
|
||||
}
|
||||
|
||||
if (!$mail_disabled) {
|
||||
if (
|
||||
!Config::get('system', 'dfrn_only')
|
||||
&& function_exists('imap_open')
|
||||
&& !Config::get('system', 'imap_disabled')
|
||||
) {
|
||||
$failed = false;
|
||||
$r = q("SELECT * FROM `mailacct` WHERE `uid` = %d LIMIT 1",
|
||||
intval(local_user())
|
||||
|
@ -1092,7 +1089,7 @@ function settings_content(App $a)
|
|||
|
||||
if (strlen(Config::get('system', 'directory'))) {
|
||||
$profile_in_net_dir = Renderer::replaceMacros($opt_tpl, [
|
||||
'$field' => ['profile_in_netdirectory', L10n::t('Publish your default profile in the global social directory?'), $profile['net-publish'], L10n::t('Your profile will be published in the global friendica directories (e.g. <a href="%s">%s</a>). Your profile will be visible in public.', Config::get('system', 'directory'), Config::get('system', 'directory')), [L10n::t('No'), L10n::t('Yes')]]
|
||||
'$field' => ['profile_in_netdirectory', L10n::t('Publish your default profile in the global social directory?'), $profile['net-publish'], L10n::t('Your profile will be published in the global friendica directories (e.g. <a href="%s">%s</a>). Your profile will be visible in public.', Config::get('system', 'directory'), Config::get('system', 'directory')) . " " . L10n::t("This setting also determines whether Friendica will inform search engines that your profile should be indexed or not. Third-party search engines may or may not respect this setting."), [L10n::t('No'), L10n::t('Yes')]]
|
||||
]);
|
||||
} else {
|
||||
$profile_in_net_dir = '';
|
||||
|
|
|
@ -6,6 +6,7 @@ use Friendica\App;
|
|||
use Friendica\Core\Hook;
|
||||
use Friendica\Core\L10n;
|
||||
use Friendica\Core\Logger;
|
||||
use Friendica\Core\Session;
|
||||
use Friendica\Core\System;
|
||||
use Friendica\Database\DBA;
|
||||
use Friendica\Model\Item;
|
||||
|
@ -15,7 +16,7 @@ use Friendica\Util\XML;
|
|||
|
||||
function subthread_content(App $a) {
|
||||
|
||||
if (!local_user() && !remote_user()) {
|
||||
if (!Session::isAuthenticated()) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -7,6 +7,7 @@ use Friendica\Core\Hook;
|
|||
use Friendica\Core\L10n;
|
||||
use Friendica\Core\Logger;
|
||||
use Friendica\Core\System;
|
||||
use Friendica\Core\Session;
|
||||
use Friendica\Core\Worker;
|
||||
use Friendica\Database\DBA;
|
||||
use Friendica\Model\Item;
|
||||
|
@ -16,7 +17,7 @@ use Friendica\Worker\Delivery;
|
|||
|
||||
function tagger_content(App $a) {
|
||||
|
||||
if (!local_user() && !remote_user()) {
|
||||
if (!Session::isAuthenticated()) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -22,11 +22,11 @@ function tagrm_post(App $a)
|
|||
}
|
||||
|
||||
$tags = [];
|
||||
foreach (defaults($_POST, 'tag', []) as $tag) {
|
||||
foreach ($_POST['tag'] ?? [] as $tag) {
|
||||
$tags[] = hex2bin(Strings::escapeTags(trim($tag)));
|
||||
}
|
||||
|
||||
$item_id = defaults($_POST,'item', 0);
|
||||
$item_id = $_POST['item'] ?? 0;
|
||||
update_tags($item_id, $tags);
|
||||
info(L10n::t('Tag(s) removed') . EOL);
|
||||
|
||||
|
|
|
@ -41,14 +41,6 @@ function uimport_content(App $a)
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
if (!empty($_SESSION['theme'])) {
|
||||
unset($_SESSION['theme']);
|
||||
}
|
||||
if (!empty($_SESSION['mobile-theme'])) {
|
||||
unset($_SESSION['mobile-theme']);
|
||||
}
|
||||
|
||||
$tpl = Renderer::getMarkupTemplate("uimport.tpl");
|
||||
return Renderer::replaceMacros($tpl, [
|
||||
'$regbutt' => L10n::t('Import'),
|
||||
|
|
|
@ -25,7 +25,7 @@ function unfollow_post(App $a)
|
|||
}
|
||||
|
||||
$uid = local_user();
|
||||
$url = Strings::escapeTags(trim(defaults($_REQUEST, 'url', '')));
|
||||
$url = Strings::escapeTags(trim($_REQUEST['url'] ?? ''));
|
||||
|
||||
$condition = ["`uid` = ? AND (`rel` = ? OR `rel` = ?) AND (`nurl` = ? OR `alias` = ? OR `alias` = ?)",
|
||||
$uid, Contact::SHARING, Contact::FRIEND, Strings::normaliseLink($url),
|
||||
|
|
|
@ -10,6 +10,7 @@ use Friendica\Core\Config;
|
|||
use Friendica\Core\L10n;
|
||||
use Friendica\Core\Renderer;
|
||||
use Friendica\Core\System;
|
||||
use Friendica\Core\Session;
|
||||
use Friendica\Database\DBA;
|
||||
use Friendica\Model\Attach;
|
||||
use Friendica\Model\Contact;
|
||||
|
@ -22,11 +23,7 @@ use Friendica\Util\Security;
|
|||
|
||||
function videos_init(App $a)
|
||||
{
|
||||
if ($a->argc > 1) {
|
||||
DFRN::autoRedir($a, $a->argv[1]);
|
||||
}
|
||||
|
||||
if ((Config::get('system', 'block_public')) && (!local_user()) && (!remote_user())) {
|
||||
if (Config::get('system', 'block_public') && !Session::isAuthenticated()) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -54,9 +51,9 @@ function videos_init(App $a)
|
|||
$vcard_widget = Renderer::replaceMacros($tpl, [
|
||||
'$name' => $profile['name'],
|
||||
'$photo' => $profile['photo'],
|
||||
'$addr' => defaults($profile, 'addr', ''),
|
||||
'$addr' => $profile['addr'] ?? '',
|
||||
'$account_type' => $account_type,
|
||||
'$pdesc' => defaults($profile, 'pdesc', ''),
|
||||
'$pdesc' => $profile['pdesc'] ?? '',
|
||||
]);
|
||||
|
||||
// If not there, create 'aside' empty
|
||||
|
@ -114,7 +111,7 @@ function videos_content(App $a)
|
|||
// videos/name/video/xxxxx/edit
|
||||
|
||||
|
||||
if ((Config::get('system', 'block_public')) && (!local_user()) && (!remote_user())) {
|
||||
if (Config::get('system', 'block_public') && !Session::isAuthenticated()) {
|
||||
notice(L10n::t('Public access denied.') . EOL);
|
||||
return;
|
||||
}
|
||||
|
@ -154,64 +151,25 @@ function videos_content(App $a)
|
|||
|
||||
if ((local_user()) && (local_user() == $owner_uid)) {
|
||||
$can_post = true;
|
||||
} elseif ($community_page && remote_user()) {
|
||||
if (!empty($_SESSION['remote'])) {
|
||||
foreach ($_SESSION['remote'] as $v) {
|
||||
if ($v['uid'] == $owner_uid) {
|
||||
$contact_id = $v['cid'];
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ($contact_id > 0) {
|
||||
$r = q("SELECT `uid` FROM `contact` WHERE `blocked` = 0 AND `pending` = 0 AND `id` = %d AND `uid` = %d LIMIT 1",
|
||||
intval($contact_id),
|
||||
intval($owner_uid)
|
||||
);
|
||||
|
||||
if (DBA::isResult($r)) {
|
||||
$can_post = true;
|
||||
$remote_contact = true;
|
||||
$visitor = $contact_id;
|
||||
}
|
||||
}
|
||||
} elseif ($community_page && !empty(Session::getRemoteContactID($owner_uid))) {
|
||||
$contact_id = Session::getRemoteContactID($owner_uid);
|
||||
$can_post = true;
|
||||
$remote_contact = true;
|
||||
$visitor = $contact_id;
|
||||
}
|
||||
|
||||
$groups = [];
|
||||
|
||||
// perhaps they're visiting - but not a community page, so they wouldn't have write access
|
||||
if (remote_user() && (!$visitor)) {
|
||||
$contact_id = 0;
|
||||
|
||||
if (!empty($_SESSION['remote'])) {
|
||||
foreach($_SESSION['remote'] as $v) {
|
||||
if($v['uid'] == $owner_uid) {
|
||||
$contact_id = $v['cid'];
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ($contact_id > 0) {
|
||||
$groups = Group::getIdsByContactId($contact_id);
|
||||
$r = q("SELECT * FROM `contact` WHERE `blocked` = 0 AND `pending` = 0 AND `id` = %d AND `uid` = %d LIMIT 1",
|
||||
intval($contact_id),
|
||||
intval($owner_uid)
|
||||
);
|
||||
|
||||
if (DBA::isResult($r)) {
|
||||
$remote_contact = true;
|
||||
}
|
||||
}
|
||||
if (!empty(Session::getRemoteContactID($owner_uid)) && !$visitor) {
|
||||
$contact_id = Session::getRemoteContactID($owner_uid);
|
||||
$remote_contact = true;
|
||||
}
|
||||
|
||||
if ($a->data['user']['hidewall'] && (local_user() != $owner_uid) && (!$remote_contact)) {
|
||||
if ($a->data['user']['hidewall'] && (local_user() != $owner_uid) && !$remote_contact) {
|
||||
notice(L10n::t('Access to this item is restricted.') . EOL);
|
||||
return;
|
||||
}
|
||||
|
||||
$sql_extra = Security::getPermissionsSQLByUserId($owner_uid, $remote_contact, $groups);
|
||||
$sql_extra = Security::getPermissionsSQLByUserId($owner_uid);
|
||||
|
||||
$o = "";
|
||||
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
use Friendica\App;
|
||||
use Friendica\Core\Config;
|
||||
use Friendica\Core\L10n;
|
||||
use Friendica\Core\Session;
|
||||
use Friendica\Database\DBA;
|
||||
use Friendica\Model\Attach;
|
||||
use Friendica\Model\User;
|
||||
|
@ -43,35 +44,21 @@ function wall_attach_post(App $a) {
|
|||
$page_owner_cid = $r[0]['id'];
|
||||
$community_page = (($r[0]['page-flags'] == User::PAGE_FLAGS_COMMUNITY) ? true : false);
|
||||
|
||||
if ((local_user()) && (local_user() == $page_owner_uid)) {
|
||||
if (local_user() && (local_user() == $page_owner_uid)) {
|
||||
$can_post = true;
|
||||
} else {
|
||||
if ($community_page && remote_user()) {
|
||||
$contact_id = 0;
|
||||
} elseif ($community_page && !empty(Session::getRemoteContactID($page_owner_uid))) {
|
||||
$contact_id = Session::getRemoteContactID($page_owner_uid);
|
||||
$r = q("SELECT `uid` FROM `contact` WHERE `blocked` = 0 AND `pending` = 0 AND `id` = %d AND `uid` = %d LIMIT 1",
|
||||
intval($contact_id),
|
||||
intval($page_owner_uid)
|
||||
);
|
||||
|
||||
if (is_array($_SESSION['remote'])) {
|
||||
foreach ($_SESSION['remote'] as $v) {
|
||||
if ($v['uid'] == $page_owner_uid) {
|
||||
$contact_id = $v['cid'];
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ($contact_id > 0) {
|
||||
$r = q("SELECT `uid` FROM `contact` WHERE `blocked` = 0 AND `pending` = 0 AND `id` = %d AND `uid` = %d LIMIT 1",
|
||||
intval($contact_id),
|
||||
intval($page_owner_uid)
|
||||
);
|
||||
|
||||
if (DBA::isResult($r)) {
|
||||
$can_post = true;
|
||||
}
|
||||
}
|
||||
if (DBA::isResult($r)) {
|
||||
$can_post = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (! $can_post) {
|
||||
if (!$can_post) {
|
||||
if ($r_json) {
|
||||
echo json_encode(['error' => L10n::t('Permission denied.')]);
|
||||
exit();
|
||||
|
|
|
@ -12,6 +12,7 @@ use Friendica\App;
|
|||
use Friendica\Core\L10n;
|
||||
use Friendica\Core\Logger;
|
||||
use Friendica\Core\System;
|
||||
use Friendica\Core\Session;
|
||||
use Friendica\Core\Config;
|
||||
use Friendica\Database\DBA;
|
||||
use Friendica\Model\Contact;
|
||||
|
@ -74,34 +75,21 @@ function wall_upload_post(App $a, $desktopmode = true)
|
|||
|
||||
if ((local_user()) && (local_user() == $page_owner_uid)) {
|
||||
$can_post = true;
|
||||
} else {
|
||||
if ($community_page && remote_user()) {
|
||||
$contact_id = 0;
|
||||
if (is_array($_SESSION['remote'])) {
|
||||
foreach ($_SESSION['remote'] as $v) {
|
||||
if ($v['uid'] == $page_owner_uid) {
|
||||
$contact_id = $v['cid'];
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
} elseif ($community_page && !empty(Session::getRemoteContactID($page_owner_uid))) {
|
||||
$contact_id = Session::getRemoteContactID($page_owner_uid);
|
||||
|
||||
if ($contact_id) {
|
||||
$r = q("SELECT `uid` FROM `contact`
|
||||
WHERE `blocked` = 0 AND `pending` = 0
|
||||
AND `id` = %d AND `uid` = %d LIMIT 1",
|
||||
intval($contact_id),
|
||||
intval($page_owner_uid)
|
||||
);
|
||||
if (DBA::isResult($r)) {
|
||||
$can_post = true;
|
||||
$visitor = $contact_id;
|
||||
}
|
||||
}
|
||||
$r = q("SELECT `uid` FROM `contact`
|
||||
WHERE `blocked` = 0 AND `pending` = 0
|
||||
AND `id` = %d AND `uid` = %d LIMIT 1",
|
||||
intval($contact_id),
|
||||
intval($page_owner_uid)
|
||||
);
|
||||
if (DBA::isResult($r)) {
|
||||
$can_post = true;
|
||||
$visitor = $contact_id;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (!$can_post) {
|
||||
if ($r_json) {
|
||||
echo json_encode(['error' => L10n::t('Permission denied.')]);
|
||||
|
|
|
@ -131,8 +131,8 @@ function wallmessage_content(App $a) {
|
|||
'$subject' => L10n::t('Subject:'),
|
||||
'$recipname' => $user['username'],
|
||||
'$nickname' => $user['nickname'],
|
||||
'$subjtxt' => defaults($_REQUEST, 'subject', ''),
|
||||
'$text' => defaults($_REQUEST, 'body', ''),
|
||||
'$subjtxt' => $_REQUEST['subject'] ?? '',
|
||||
'$text' => $_REQUEST['body'] ?? '',
|
||||
'$readonly' => '',
|
||||
'$yourmessage'=> L10n::t('Your message:'),
|
||||
'$parent' => '',
|
||||
|
|
|
@ -102,8 +102,8 @@ $HTTP["scheme"] == "https" {
|
|||
# Got the following 'Drupal Clean URL'after Mike suggested trying
|
||||
# something along those lines, from http://drupal.org/node/1414950
|
||||
url.rewrite-if-not-file = (
|
||||
"^\/([^\?]*)\?(.*)$" => "/index.php?q=$1&$2",
|
||||
"^\/(.*)$" => "/index.php?q=$1"
|
||||
"^\/([^\?]*)\?(.*)$" => "/index.php?pagename=$1&$2",
|
||||
"^\/(.*)$" => "/index.php?pagename=$1"
|
||||
)
|
||||
}
|
||||
else $HTTP["host"] !~ "(friendica.example.com|wordpress.example.com)" {
|
||||
|
|
115
src/App.php
115
src/App.php
|
@ -92,10 +92,10 @@ class App
|
|||
*/
|
||||
private $baseURL;
|
||||
|
||||
/**
|
||||
* @var string The name of the current theme
|
||||
*/
|
||||
/** @var string The name of the current theme */
|
||||
private $currentTheme;
|
||||
/** @var string The name of the current mobile theme */
|
||||
private $currentMobileTheme;
|
||||
|
||||
/**
|
||||
* @var Configuration The config
|
||||
|
@ -450,10 +450,10 @@ class App
|
|||
}
|
||||
|
||||
/**
|
||||
* Returns the current theme name.
|
||||
* Returns the current theme name. May be overriden by the mobile theme name.
|
||||
*
|
||||
* @return string the name of the current theme
|
||||
* @throws HTTPException\InternalServerErrorException
|
||||
* @return string
|
||||
* @throws Exception
|
||||
*/
|
||||
public function getCurrentTheme()
|
||||
{
|
||||
|
@ -461,6 +461,16 @@ class App
|
|||
return '';
|
||||
}
|
||||
|
||||
// Specific mobile theme override
|
||||
if (($this->mode->isMobile() || $this->mode->isTablet()) && Core\Session::get('show-mobile', true)) {
|
||||
$user_mobile_theme = $this->getCurrentMobileTheme();
|
||||
|
||||
// --- means same mobile theme as desktop
|
||||
if (!empty($user_mobile_theme) && $user_mobile_theme !== '---') {
|
||||
return $user_mobile_theme;
|
||||
}
|
||||
}
|
||||
|
||||
if (!$this->currentTheme) {
|
||||
$this->computeCurrentTheme();
|
||||
}
|
||||
|
@ -468,13 +478,37 @@ class App
|
|||
return $this->currentTheme;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the current mobile theme name.
|
||||
*
|
||||
* @return string
|
||||
* @throws Exception
|
||||
*/
|
||||
public function getCurrentMobileTheme()
|
||||
{
|
||||
if ($this->mode->isInstall()) {
|
||||
return '';
|
||||
}
|
||||
|
||||
if (is_null($this->currentMobileTheme)) {
|
||||
$this->computeCurrentMobileTheme();
|
||||
}
|
||||
|
||||
return $this->currentMobileTheme;
|
||||
}
|
||||
|
||||
public function setCurrentTheme($theme)
|
||||
{
|
||||
$this->currentTheme = $theme;
|
||||
}
|
||||
|
||||
public function setCurrentMobileTheme($theme)
|
||||
{
|
||||
$this->currentMobileTheme = $theme;
|
||||
}
|
||||
|
||||
/**
|
||||
* Computes the current theme name based on the node settings, the user settings and the device type
|
||||
* Computes the current theme name based on the node settings, the page owner settings and the user settings
|
||||
*
|
||||
* @throws Exception
|
||||
*/
|
||||
|
@ -486,7 +520,7 @@ class App
|
|||
}
|
||||
|
||||
// Sane default
|
||||
$this->currentTheme = $system_theme;
|
||||
$this->setCurrentTheme($system_theme);
|
||||
|
||||
$page_theme = null;
|
||||
// Find the theme that belongs to the user whose stuff we are looking at
|
||||
|
@ -499,24 +533,7 @@ class App
|
|||
}
|
||||
}
|
||||
|
||||
$user_theme = Core\Session::get('theme', $system_theme);
|
||||
|
||||
// Specific mobile theme override
|
||||
if (($this->is_mobile || $this->is_tablet) && Core\Session::get('show-mobile', true)) {
|
||||
$system_mobile_theme = $this->config->get('system', 'mobile-theme');
|
||||
$user_mobile_theme = Core\Session::get('mobile-theme', $system_mobile_theme);
|
||||
|
||||
// --- means same mobile theme as desktop
|
||||
if (!empty($user_mobile_theme) && $user_mobile_theme !== '---') {
|
||||
$user_theme = $user_mobile_theme;
|
||||
}
|
||||
}
|
||||
|
||||
if ($page_theme) {
|
||||
$theme_name = $page_theme;
|
||||
} else {
|
||||
$theme_name = $user_theme;
|
||||
}
|
||||
$theme_name = $page_theme ?: Core\Session::get('theme', $system_theme);
|
||||
|
||||
$theme_name = Strings::sanitizeFilePathItem($theme_name);
|
||||
if ($theme_name
|
||||
|
@ -524,7 +541,40 @@ class App
|
|||
&& (file_exists('view/theme/' . $theme_name . '/style.css')
|
||||
|| file_exists('view/theme/' . $theme_name . '/style.php'))
|
||||
) {
|
||||
$this->currentTheme = $theme_name;
|
||||
$this->setCurrentTheme($theme_name);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Computes the current mobile theme name based on the node settings, the page owner settings and the user settings
|
||||
*/
|
||||
private function computeCurrentMobileTheme()
|
||||
{
|
||||
$system_mobile_theme = $this->config->get('system', 'mobile-theme', '');
|
||||
|
||||
// Sane default
|
||||
$this->setCurrentMobileTheme($system_mobile_theme);
|
||||
|
||||
$page_mobile_theme = null;
|
||||
// Find the theme that belongs to the user whose stuff we are looking at
|
||||
if ($this->profile_uid && ($this->profile_uid != local_user())) {
|
||||
// Allow folks to override user themes and always use their own on their own site.
|
||||
// This works only if the user is on the same server
|
||||
if (!Core\PConfig::get(local_user(), 'system', 'always_my_theme')) {
|
||||
$page_mobile_theme = Core\PConfig::get($this->profile_uid, 'system', 'mobile-theme');
|
||||
}
|
||||
}
|
||||
|
||||
$mobile_theme_name = $page_mobile_theme ?: Core\Session::get('mobile-theme', $system_mobile_theme);
|
||||
|
||||
$mobile_theme_name = Strings::sanitizeFilePathItem($mobile_theme_name);
|
||||
if ($mobile_theme_name == '---'
|
||||
||
|
||||
in_array($mobile_theme_name, Theme::getAllowedList())
|
||||
&& (file_exists('view/theme/' . $mobile_theme_name . '/style.css')
|
||||
|| file_exists('view/theme/' . $mobile_theme_name . '/style.php'))
|
||||
) {
|
||||
$this->setCurrentMobileTheme($mobile_theme_name);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -534,7 +584,7 @@ class App
|
|||
* Provide a sane default if nothing is chosen or the specified theme does not exist.
|
||||
*
|
||||
* @return string
|
||||
* @throws HTTPException\InternalServerErrorException
|
||||
* @throws Exception
|
||||
*/
|
||||
public function getCurrentThemeStylesheetPath()
|
||||
{
|
||||
|
@ -587,7 +637,11 @@ class App
|
|||
*
|
||||
* This probably should change to limit the size of this monster method.
|
||||
*
|
||||
* @param App\Module $module The determined module
|
||||
* @param App\Module $module The determined module
|
||||
* @param App\Router $router
|
||||
* @param PConfiguration $pconfig
|
||||
* @throws HTTPException\InternalServerErrorException
|
||||
* @throws \ImagickException
|
||||
*/
|
||||
public function runFrontend(App\Module $module, App\Router $router, PConfiguration $pconfig)
|
||||
{
|
||||
|
@ -733,8 +787,7 @@ class App
|
|||
$module = $module->determineClass($this->args, $router, $this->config);
|
||||
|
||||
// Let the module run it's internal process (init, get, post, ...)
|
||||
$module->run($this->l10n, $this, $this->logger, $this->getCurrentTheme(), $_SERVER, $_POST);
|
||||
|
||||
$module->run($this->l10n, $this, $this->logger, $_SERVER, $_POST);
|
||||
} catch (HTTPException $e) {
|
||||
ModuleHTTPException::rawContent($e);
|
||||
}
|
||||
|
|
|
@ -70,7 +70,7 @@ class Arguments
|
|||
|
||||
/**
|
||||
* Returns the value of a argv key
|
||||
* @todo there are a lot of $a->argv usages in combination with defaults() which can be replaced with this method
|
||||
* @todo there are a lot of $a->argv usages in combination with ?? which can be replaced with this method
|
||||
*
|
||||
* @param int $position the position of the argument
|
||||
* @param mixed $default the default value if not found
|
||||
|
|
|
@ -338,12 +338,12 @@ class BaseURL
|
|||
/* Relative script path to the web server root
|
||||
* Not all of those $_SERVER properties can be present, so we do by inverse priority order
|
||||
*/
|
||||
$relative_script_path = '';
|
||||
$relative_script_path = defaults($this->server, 'REDIRECT_URL', $relative_script_path);
|
||||
$relative_script_path = defaults($this->server, 'REDIRECT_URI', $relative_script_path);
|
||||
$relative_script_path = defaults($this->server, 'REDIRECT_SCRIPT_URL', $relative_script_path);
|
||||
$relative_script_path = defaults($this->server, 'SCRIPT_URL', $relative_script_path);
|
||||
$relative_script_path = defaults($this->server, 'REQUEST_URI', $relative_script_path);
|
||||
$relative_script_path =
|
||||
($this->server['REDIRECT_URL'] ?? '') ?:
|
||||
($this->server['REDIRECT_URI'] ?? '') ?:
|
||||
($this->server['REDIRECT_SCRIPT_URL'] ?? '') ?:
|
||||
($this->server['SCRIPT_URL'] ?? '') ?:
|
||||
$this->server['REQUEST_URI'] ?? '';
|
||||
|
||||
/* $relative_script_path gives /relative/path/to/friendica/module/parameter
|
||||
* QUERY_STRING gives pagename=module/parameter
|
||||
|
|
|
@ -106,15 +106,16 @@ class Mode
|
|||
/**
|
||||
* Checks if the site is called via a backend process
|
||||
*
|
||||
* @param bool $isBackend True, if the call is from a backend script (daemon, worker, ...)
|
||||
* @param Module $module The pre-loaded module (just name, not class!)
|
||||
* @param array $server The $_SERVER variable
|
||||
* @param MobileDetect $mobileDetect The mobile detection library
|
||||
*
|
||||
* @return Mode returns the determined mode
|
||||
*/
|
||||
public function determineRunMode(Module $module, array $server, MobileDetect $mobileDetect)
|
||||
public function determineRunMode(bool $isBackend, Module $module, array $server, MobileDetect $mobileDetect)
|
||||
{
|
||||
$isBackend = basename(($server['PHP_SELF'] ?? ''), '.php') !== 'index' ||
|
||||
$isBackend = $isBackend ||
|
||||
$module->isBackend();
|
||||
$isMobile = $mobileDetect->isMobile();
|
||||
$isTablet = $mobileDetect->isTablet();
|
||||
|
|
|
@ -7,7 +7,10 @@ use Friendica\BaseObject;
|
|||
use Friendica\Core;
|
||||
use Friendica\LegacyModule;
|
||||
use Friendica\Module\Home;
|
||||
use Friendica\Module\PageNotFound;
|
||||
use Friendica\Module\HTTPException\MethodNotAllowed;
|
||||
use Friendica\Module\HTTPException\PageNotFound;
|
||||
use Friendica\Network\HTTPException\MethodNotAllowedException;
|
||||
use Friendica\Network\HTTPException\NotFoundException;
|
||||
use Psr\Log\LoggerInterface;
|
||||
|
||||
/**
|
||||
|
@ -138,51 +141,49 @@ class Module
|
|||
*
|
||||
* @return Module The determined module of this call
|
||||
*
|
||||
* @throws \Friendica\Network\HTTPException\InternalServerErrorException
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function determineClass(Arguments $args, Router $router, Core\Config\Configuration $config)
|
||||
{
|
||||
$printNotAllowedAddon = false;
|
||||
|
||||
$module_class = null;
|
||||
/**
|
||||
* ROUTING
|
||||
*
|
||||
* From the request URL, routing consists of obtaining the name of a BaseModule-extending class of which the
|
||||
* post() and/or content() static methods can be respectively called to produce a data change or an output.
|
||||
**/
|
||||
|
||||
// First we try explicit routes defined in App\Router
|
||||
$router->collectRoutes();
|
||||
|
||||
$data = $router->getRouteCollector();
|
||||
Core\Hook::callAll('route_collection', $data);
|
||||
|
||||
$module_class = $router->getModuleClass($args->getCommand());
|
||||
|
||||
// Then we try addon-provided modules that we wrap in the LegacyModule class
|
||||
if (!$module_class && Core\Addon::isEnabled($this->module) && file_exists("addon/{$this->module}/{$this->module}.php")) {
|
||||
//Check if module is an app and if public access to apps is allowed or not
|
||||
$privateapps = $config->get('config', 'private_addons', false);
|
||||
if ((!local_user()) && Core\Hook::isAddonApp($this->module) && $privateapps) {
|
||||
$printNotAllowedAddon = true;
|
||||
} else {
|
||||
include_once "addon/{$this->module}/{$this->module}.php";
|
||||
if (function_exists($this->module . '_module')) {
|
||||
LegacyModule::setModuleFile("addon/{$this->module}/{$this->module}.php");
|
||||
$module_class = LegacyModule::class;
|
||||
try {
|
||||
$module_class = $router->getModuleClass($args->getCommand());
|
||||
} catch (MethodNotAllowedException $e) {
|
||||
$module_class = MethodNotAllowed::class;
|
||||
} catch (NotFoundException $e) {
|
||||
// Then we try addon-provided modules that we wrap in the LegacyModule class
|
||||
if (Core\Addon::isEnabled($this->module) && file_exists("addon/{$this->module}/{$this->module}.php")) {
|
||||
//Check if module is an app and if public access to apps is allowed or not
|
||||
$privateapps = $config->get('config', 'private_addons', false);
|
||||
if ((!local_user()) && Core\Hook::isAddonApp($this->module) && $privateapps) {
|
||||
$printNotAllowedAddon = true;
|
||||
} else {
|
||||
include_once "addon/{$this->module}/{$this->module}.php";
|
||||
if (function_exists($this->module . '_module')) {
|
||||
LegacyModule::setModuleFile("addon/{$this->module}/{$this->module}.php");
|
||||
$module_class = LegacyModule::class;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Finally, we look for a 'standard' program module in the 'mod' directory
|
||||
* We emulate a Module class through the LegacyModule class
|
||||
*/
|
||||
if (!$module_class && file_exists("mod/{$this->module}.php")) {
|
||||
LegacyModule::setModuleFile("mod/{$this->module}.php");
|
||||
$module_class = LegacyModule::class;
|
||||
}
|
||||
/* Finally, we look for a 'standard' program module in the 'mod' directory
|
||||
* We emulate a Module class through the LegacyModule class
|
||||
*/
|
||||
if (!$module_class && file_exists("mod/{$this->module}.php")) {
|
||||
LegacyModule::setModuleFile("mod/{$this->module}.php");
|
||||
$module_class = LegacyModule::class;
|
||||
}
|
||||
|
||||
$module_class = !isset($module_class) ? PageNotFound::class : $module_class;
|
||||
$module_class = $module_class ?: PageNotFound::class;
|
||||
}
|
||||
|
||||
return new Module($this->module, $module_class, $this->isBackend, $printNotAllowedAddon);
|
||||
}
|
||||
|
@ -193,13 +194,12 @@ class Module
|
|||
* @param Core\L10n\L10n $l10n The L10n instance
|
||||
* @param App $app The whole Friendica app (for method arguments)
|
||||
* @param LoggerInterface $logger The Friendica logger
|
||||
* @param string $currentTheme The chosen theme
|
||||
* @param array $server The $_SERVER variable
|
||||
* @param array $post The $_POST variables
|
||||
*
|
||||
* @throws \Friendica\Network\HTTPException\InternalServerErrorException
|
||||
*/
|
||||
public function run(Core\L10n\L10n $l10n, App $app, LoggerInterface $logger, string $currentTheme, array $server, array $post)
|
||||
public function run(Core\L10n\L10n $l10n, App $app, LoggerInterface $logger, array $server, array $post)
|
||||
{
|
||||
if ($this->printNotAllowedAddon) {
|
||||
info($l10n->t("You must be logged in to use addons. "));
|
||||
|
@ -239,17 +239,6 @@ class Module
|
|||
// This endpoint doesn't need any theme initialization or other comparable stuff.
|
||||
call_user_func([$this->module_class, 'rawContent']);
|
||||
|
||||
// Load current theme info after module has been initialized as theme could have been set in module
|
||||
$theme_info_file = 'view/theme/' . $currentTheme . '/theme.php';
|
||||
if (file_exists($theme_info_file)) {
|
||||
require_once $theme_info_file;
|
||||
}
|
||||
|
||||
if (function_exists(str_replace('-', '_', $currentTheme) . '_init')) {
|
||||
$func = str_replace('-', '_', $currentTheme) . '_init';
|
||||
$func($app);
|
||||
}
|
||||
|
||||
if ($server['REQUEST_METHOD'] === 'POST') {
|
||||
Core\Hook::callAll($this->module . '_mod_post', $post);
|
||||
call_user_func([$this->module_class, 'post']);
|
||||
|
|
|
@ -364,6 +364,18 @@ class Page implements ArrayAccess
|
|||
*/
|
||||
$this->initContent($module, $mode);
|
||||
|
||||
// Load current theme info after module has been initialized as theme could have been set in module
|
||||
$currentTheme = $app->getCurrentTheme();
|
||||
$theme_info_file = 'view/theme/' . $currentTheme . '/theme.php';
|
||||
if (file_exists($theme_info_file)) {
|
||||
require_once $theme_info_file;
|
||||
}
|
||||
|
||||
if (function_exists(str_replace('-', '_', $currentTheme) . '_init')) {
|
||||
$func = str_replace('-', '_', $currentTheme) . '_init';
|
||||
$func($app);
|
||||
}
|
||||
|
||||
/* Create the page head after setting the language
|
||||
* and getting any auth credentials.
|
||||
*
|
||||
|
|
|
@ -7,7 +7,9 @@ use FastRoute\DataGenerator\GroupCountBased;
|
|||
use FastRoute\Dispatcher;
|
||||
use FastRoute\RouteCollector;
|
||||
use FastRoute\RouteParser\Std;
|
||||
use Friendica\Module;
|
||||
use Friendica\Core\Hook;
|
||||
use Friendica\Core\L10n;
|
||||
use Friendica\Network\HTTPException;
|
||||
|
||||
/**
|
||||
* Wrapper for FastRoute\Router
|
||||
|
@ -21,212 +23,129 @@ use Friendica\Module;
|
|||
*/
|
||||
class Router
|
||||
{
|
||||
const POST = 'POST';
|
||||
const GET = 'GET';
|
||||
|
||||
const ALLOWED_METHODS = [
|
||||
self::POST,
|
||||
self::GET,
|
||||
];
|
||||
|
||||
/** @var RouteCollector */
|
||||
protected $routeCollector;
|
||||
|
||||
/**
|
||||
* Static declaration of Friendica routes.
|
||||
*
|
||||
* Supports:
|
||||
* - Route groups
|
||||
* - Variable parts
|
||||
* Disregards:
|
||||
* - HTTP method other than GET
|
||||
* - Named parameters
|
||||
*
|
||||
* Handler must be the name of a class extending Friendica\BaseModule.
|
||||
*
|
||||
* @brief Static declaration of Friendica routes.
|
||||
* @var string The HTTP method
|
||||
*/
|
||||
public function collectRoutes()
|
||||
private $httpMethod;
|
||||
|
||||
/**
|
||||
* @param array $server The $_SERVER variable
|
||||
* @param RouteCollector|null $routeCollector Optional the loaded Route collector
|
||||
*/
|
||||
public function __construct(array $server, RouteCollector $routeCollector = null)
|
||||
{
|
||||
$this->routeCollector->addRoute(['GET'], '[/]', Module\Home::class);
|
||||
$this->routeCollector->addGroup('/.well-known', function (RouteCollector $collector) {
|
||||
$collector->addRoute(['GET'], '/host-meta' , Module\WellKnown\HostMeta::class);
|
||||
$collector->addRoute(['GET'], '/nodeinfo[/1.0]' , Module\NodeInfo::class);
|
||||
$collector->addRoute(['GET'], '/webfinger' , Module\Xrd::class);
|
||||
$collector->addRoute(['GET'], '/x-social-relay' , Module\WellKnown\XSocialRelay::class);
|
||||
});
|
||||
$this->routeCollector->addGroup('/2fa', function (RouteCollector $collector) {
|
||||
$collector->addRoute(['GET', 'POST'], '[/]' , Module\TwoFactor\Verify::class);
|
||||
$collector->addRoute(['GET', 'POST'], '/recovery' , Module\TwoFactor\Recovery::class);
|
||||
});
|
||||
$this->routeCollector->addGroup('/admin', function (RouteCollector $collector) {
|
||||
$collector->addRoute(['GET'] , '[/]' , Module\Admin\Summary::class);
|
||||
$httpMethod = $server['REQUEST_METHOD'] ?? self::GET;
|
||||
$this->httpMethod = in_array($httpMethod, self::ALLOWED_METHODS) ? $httpMethod : self::GET;
|
||||
|
||||
$collector->addRoute(['GET', 'POST'], '/addons' , Module\Admin\Addons\Index::class);
|
||||
$collector->addRoute(['GET', 'POST'], '/addons/{addon}' , Module\Admin\Addons\Details::class);
|
||||
|
||||
$collector->addRoute(['GET', 'POST'], '/blocklist/contact' , Module\Admin\Blocklist\Contact::class);
|
||||
$collector->addRoute(['GET', 'POST'], '/blocklist/server' , Module\Admin\Blocklist\Server::class);
|
||||
|
||||
$collector->addRoute(['GET'] , '/dbsync[/check]' , Module\Admin\DBSync::class);
|
||||
$collector->addRoute(['GET'] , '/dbsync/{update:\d+}' , Module\Admin\DBSync::class);
|
||||
$collector->addRoute(['GET'] , '/dbsync/mark/{update:\d+}', Module\Admin\DBSync::class);
|
||||
|
||||
$collector->addRoute(['GET', 'POST'], '/features' , Module\Admin\Features::class);
|
||||
$collector->addRoute(['GET'] , '/federation' , Module\Admin\Federation::class);
|
||||
|
||||
$collector->addRoute(['GET', 'POST'], '/item/delete' , Module\Admin\Item\Delete::class);
|
||||
$collector->addRoute(['GET', 'POST'], '/item/source[/{guid}]' , Module\Admin\Item\Source::class);
|
||||
|
||||
$collector->addRoute(['GET'] , '/logs/view' , Module\Admin\Logs\View::class);
|
||||
$collector->addRoute(['GET', 'POST'], '/logs' , Module\Admin\Logs\Settings::class);
|
||||
|
||||
$collector->addRoute(['GET'] , '/phpinfo' , Module\Admin\PhpInfo::class);
|
||||
|
||||
$collector->addRoute(['GET'] , '/queue[/deferred]' , Module\Admin\Queue::class);
|
||||
|
||||
$collector->addRoute(['GET', 'POST'], '/site' , Module\Admin\Site::class);
|
||||
|
||||
$collector->addRoute(['GET', 'POST'], '/themes' , Module\Admin\Themes\Index::class);
|
||||
$collector->addRoute(['GET', 'POST'], '/themes/{theme}' , Module\Admin\Themes\Details::class);
|
||||
$collector->addRoute(['GET', 'POST'], '/themes/{theme}/embed' , Module\Admin\Themes\Embed::class);
|
||||
|
||||
$collector->addRoute(['GET', 'POST'], '/tos' , Module\Admin\Tos::class);
|
||||
|
||||
$collector->addRoute(['GET', 'POST'], '/users[/{action}/{uid}]' , Module\Admin\Users::class);
|
||||
});
|
||||
$this->routeCollector->addRoute(['GET'], '/amcd', Module\AccountManagementControlDocument::class);
|
||||
$this->routeCollector->addRoute(['GET'], '/acctlink', Module\Acctlink::class);
|
||||
$this->routeCollector->addRoute(['GET'], '/allfriends/{id:\d+}', Module\AllFriends::class);
|
||||
$this->routeCollector->addRoute(['GET'], '/apps', Module\Apps::class);
|
||||
$this->routeCollector->addRoute(['GET'], '/attach/{item:\d+}', Module\Attach::class);
|
||||
$this->routeCollector->addRoute(['GET'], '/babel', Module\Debug\Babel::class);
|
||||
$this->routeCollector->addRoute(['GET'], '/bookmarklet', Module\Bookmarklet::class);
|
||||
$this->routeCollector->addRoute(['GET', 'POST'], '/compose[/{type}]', Module\Item\Compose::class);
|
||||
$this->routeCollector->addGroup('/contact', function (RouteCollector $collector) {
|
||||
$collector->addRoute(['GET'], '[/]', Module\Contact::class);
|
||||
$collector->addRoute(['GET', 'POST'], '/{id:\d+}[/]', Module\Contact::class);
|
||||
$collector->addRoute(['GET'], '/{id:\d+}/archive', Module\Contact::class);
|
||||
$collector->addRoute(['GET'], '/{id:\d+}/block', Module\Contact::class);
|
||||
$collector->addRoute(['GET'], '/{id:\d+}/conversations', Module\Contact::class);
|
||||
$collector->addRoute(['GET'], '/{id:\d+}/drop', Module\Contact::class);
|
||||
$collector->addRoute(['GET'], '/{id:\d+}/ignore', Module\Contact::class);
|
||||
$collector->addRoute(['GET'], '/{id:\d+}/posts', Module\Contact::class);
|
||||
$collector->addRoute(['GET'], '/{id:\d+}/update', Module\Contact::class);
|
||||
$collector->addRoute(['GET'], '/{id:\d+}/updateprofile', Module\Contact::class);
|
||||
$collector->addRoute(['GET'], '/archived', Module\Contact::class);
|
||||
$collector->addRoute(['GET', 'POST'], '/batch', Module\Contact::class);
|
||||
$collector->addRoute(['GET'], '/blocked', Module\Contact::class);
|
||||
$collector->addRoute(['GET'], '/hidden', Module\Contact::class);
|
||||
$collector->addRoute(['GET'], '/ignored', Module\Contact::class);
|
||||
});
|
||||
$this->routeCollector->addRoute(['GET'], '/credits', Module\Credits::class);
|
||||
$this->routeCollector->addRoute(['GET'], '/dirfind', Module\Search\Directory::class);
|
||||
$this->routeCollector->addRoute(['GET'], '/directory', Module\Directory::class);
|
||||
$this->routeCollector->addGroup('/feed', function (RouteCollector $collector) {
|
||||
$collector->addRoute(['GET'], '/{nickname}', Module\Feed::class);
|
||||
$collector->addRoute(['GET'], '/{nickname}/posts', Module\Feed::class);
|
||||
$collector->addRoute(['GET'], '/{nickname}/comments', Module\Feed::class);
|
||||
$collector->addRoute(['GET'], '/{nickname}/replies', Module\Feed::class);
|
||||
$collector->addRoute(['GET'], '/{nickname}/activity', Module\Feed::class);
|
||||
});
|
||||
$this->routeCollector->addRoute(['GET'], '/feedtest', Module\Debug\Feed::class);
|
||||
$this->routeCollector->addGroup('/fetch', function (RouteCollector $collector) {
|
||||
$collector->addRoute(['GET'], '/post/{guid}', Module\Diaspora\Fetch::class);
|
||||
$collector->addRoute(['GET'], '/status_message/{guid}', Module\Diaspora\Fetch::class);
|
||||
$collector->addRoute(['GET'], '/reshare/{guid}', Module\Diaspora\Fetch::class);
|
||||
});
|
||||
$this->routeCollector->addRoute(['GET'], '/filer[/{id:\d+}]', Module\Filer\SaveTag::class);
|
||||
$this->routeCollector->addRoute(['GET'], '/filerm/{id:\d+}', Module\Filer\RemoveTag::class);
|
||||
$this->routeCollector->addRoute(['GET', 'POST'], '/follow_confirm', Module\FollowConfirm::class);
|
||||
$this->routeCollector->addRoute(['GET'], '/followers/{owner}', Module\Followers::class);
|
||||
$this->routeCollector->addRoute(['GET'], '/following/{owner}', Module\Following::class);
|
||||
$this->routeCollector->addRoute(['GET'], '/friendica[/json]', Module\Friendica::class);
|
||||
$this->routeCollector->addGroup('/group', function (RouteCollector $collector) {
|
||||
$collector->addRoute(['GET', 'POST'], '[/]', Module\Group::class);
|
||||
$collector->addRoute(['GET', 'POST'], '/{group:\d+}', Module\Group::class);
|
||||
$collector->addRoute(['GET', 'POST'], '/none', Module\Group::class);
|
||||
$collector->addRoute(['GET', 'POST'], '/new', Module\Group::class);
|
||||
$collector->addRoute(['GET', 'POST'], '/drop/{group:\d+}', Module\Group::class);
|
||||
$collector->addRoute(['GET', 'POST'], '/{group:\d+}/{contact:\d+}', Module\Group::class);
|
||||
|
||||
$collector->addRoute(['GET', 'POST'], '/{group:\d+}/add/{contact:\d+}', Module\Group::class);
|
||||
$collector->addRoute(['GET', 'POST'], '/{group:\d+}/remove/{contact:\d+}', Module\Group::class);
|
||||
});
|
||||
$this->routeCollector->addRoute(['GET'], '/hashtag', Module\Hashtag::class);
|
||||
$this->routeCollector->addRoute(['GET'], '/home', Module\Home::class);
|
||||
$this->routeCollector->addRoute(['GET'], '/help[/{doc:.+}]', Module\Help::class);
|
||||
$this->routeCollector->addRoute(['GET'], '/inbox[/{nickname}]', Module\Inbox::class);
|
||||
$this->routeCollector->addRoute(['GET', 'POST'], '/invite', Module\Invite::class);
|
||||
$this->routeCollector->addGroup('/install', function (RouteCollector $collector) {
|
||||
$collector->addRoute(['GET', 'POST'], '[/]', Module\Install::class);
|
||||
$collector->addRoute(['GET'], '/testrewrite', Module\Install::class);
|
||||
});
|
||||
$this->routeCollector->addRoute(['GET'], '/like/{item:\d+}', Module\Like::class);
|
||||
$this->routeCollector->addRoute(['GET', 'POST'], '/localtime', Module\Debug\Localtime::class);
|
||||
$this->routeCollector->addRoute(['GET', 'POST'], '/login', Module\Login::class);
|
||||
$this->routeCollector->addRoute(['GET', 'POST'], '/logout', Module\Logout::class);
|
||||
$this->routeCollector->addRoute(['GET'], '/magic', Module\Magic::class);
|
||||
$this->routeCollector->addRoute(['GET'], '/maintenance', Module\Maintenance::class);
|
||||
$this->routeCollector->addRoute(['GET'], '/manifest', Module\Manifest::class);
|
||||
$this->routeCollector->addRoute(['GET'], '/modexp/{nick}', Module\PublicRSAKey::class);
|
||||
$this->routeCollector->addRoute(['GET'], '/newmember', Module\Welcome::class);
|
||||
$this->routeCollector->addRoute(['GET'], '/nodeinfo/1.0', Module\NodeInfo::class);
|
||||
$this->routeCollector->addRoute(['GET'], '/nogroup', Module\Group::class);
|
||||
$this->routeCollector->addGroup('/notify', function (RouteCollector $collector) {
|
||||
$collector->addRoute(['GET'], '[/]', Module\Notifications\Notify::class);
|
||||
$collector->addRoute(['GET'], '/view/{id:\d+}', Module\Notifications\Notify::class);
|
||||
$collector->addRoute(['GET'], '/mark/all', Module\Notifications\Notify::class);
|
||||
});
|
||||
$this->routeCollector->addRoute(['GET'], '/objects/{guid}', Module\Objects::class);
|
||||
$this->routeCollector->addGroup('/oembed', function (RouteCollector $collector) {
|
||||
$collector->addRoute(['GET'], '/b2h', Module\Oembed::class);
|
||||
$collector->addRoute(['GET'], '/h2b', Module\Oembed::class);
|
||||
$collector->addRoute(['GET'], '/{hash}', Module\Oembed::class);
|
||||
});
|
||||
$this->routeCollector->addRoute(['GET'], '/outbox/{owner}', Module\Outbox::class);
|
||||
$this->routeCollector->addRoute(['GET'], '/owa', Module\Owa::class);
|
||||
$this->routeCollector->addRoute(['GET'], '/opensearch', Module\OpenSearch::class);
|
||||
$this->routeCollector->addGroup('/photo', function (RouteCollector $collector) {
|
||||
$collector->addRoute(['GET'], '/{name}', Module\Photo::class);
|
||||
$collector->addRoute(['GET'], '/{type}/{name}', Module\Photo::class);
|
||||
$collector->addRoute(['GET'], '/{type}/{customize}/{name}', Module\Photo::class);
|
||||
});
|
||||
$this->routeCollector->addRoute(['GET'], '/pretheme', Module\ThemeDetails::class);
|
||||
$this->routeCollector->addRoute(['GET'], '/probe', Module\Debug\Probe::class);
|
||||
$this->routeCollector->addGroup('/profile', function (RouteCollector $collector) {
|
||||
$collector->addRoute(['GET'], '/{nickname}', Module\Profile::class);
|
||||
$collector->addRoute(['GET'], '/{nickname}/{to:\d{4}-\d{2}-\d{2}}/{from:\d{4}-\d{2}-\d{2}}', Module\Profile::class);
|
||||
$collector->addRoute(['GET'], '/{nickname}/contacts[/{type}]', Module\Profile\Contacts::class);
|
||||
$collector->addRoute(['GET'], '/{profile:\d+}/view', Module\Profile::class);
|
||||
});
|
||||
$this->routeCollector->addGroup('/proxy', function (RouteCollector $collector) {
|
||||
$collector->addRoute(['GET'], '[/]' , Module\Proxy::class);
|
||||
$collector->addRoute(['GET'], '/{url}' , Module\Proxy::class);
|
||||
$collector->addRoute(['GET'], '/{sub1}/{url}' , Module\Proxy::class);
|
||||
$collector->addRoute(['GET'], '/{sub1}/{sub2}/{url}' , Module\Proxy::class);
|
||||
});
|
||||
|
||||
$this->routeCollector->addGroup('/settings', function (RouteCollector $collector) {
|
||||
$collector->addGroup('/2fa', function (RouteCollector $collector) {
|
||||
$collector->addRoute(['GET', 'POST'], '[/]' , Module\Settings\TwoFactor\Index::class);
|
||||
$collector->addRoute(['GET', 'POST'], '/recovery' , Module\Settings\TwoFactor\Recovery::class);
|
||||
$collector->addRoute(['GET', 'POST'], '/app_specific' , Module\Settings\TwoFactor\AppSpecific::class);
|
||||
$collector->addRoute(['GET', 'POST'], '/verify' , Module\Settings\TwoFactor\Verify::class);
|
||||
});
|
||||
});
|
||||
$this->routeCollector->addRoute(['GET'], '/randprof', Module\RandomProfile::class);
|
||||
$this->routeCollector->addRoute(['GET', 'POST'], '/register', Module\Register::class);
|
||||
$this->routeCollector->addRoute(['GET'], '/robots.txt', Module\RobotsTxt::class);
|
||||
$this->routeCollector->addRoute(['GET'], '/rsd.xml', Module\ReallySimpleDiscovery::class);
|
||||
$this->routeCollector->addRoute(['GET'], '/smilies[/json]', Module\Smilies::class);
|
||||
$this->routeCollector->addRoute(['GET'], '/statistics.json', Module\Statistics::class);
|
||||
$this->routeCollector->addRoute(['GET'], '/starred/{item:\d+}', Module\Starred::class);
|
||||
$this->routeCollector->addRoute(['GET'], '/toggle_mobile', Module\ToggleMobile::class);
|
||||
$this->routeCollector->addRoute(['GET'], '/tos', Module\Tos::class);
|
||||
$this->routeCollector->addRoute(['GET'], '/view/theme/{theme}/style.pcss', Module\Theme::class);
|
||||
$this->routeCollector->addRoute(['GET'], '/viewsrc/{item:\d+}', Module\Debug\ItemBody::class);
|
||||
$this->routeCollector->addRoute(['GET'], '/webfinger', Module\Debug\WebFinger::class);
|
||||
$this->routeCollector->addRoute(['GET'], '/xrd', Module\Xrd::class);
|
||||
$this->routeCollector = isset($routeCollector) ?
|
||||
$routeCollector :
|
||||
new RouteCollector(new Std(), new GroupCountBased());
|
||||
}
|
||||
|
||||
public function __construct()
|
||||
/**
|
||||
* @param array $routes The routes to add to the Router
|
||||
*
|
||||
* @return self The router instance with the loaded routes
|
||||
*
|
||||
* @throws HTTPException\InternalServerErrorException In case of invalid configs
|
||||
*/
|
||||
public function addRoutes(array $routes)
|
||||
{
|
||||
$this->routeCollector = new RouteCollector(new Std(), new GroupCountBased());
|
||||
$routeCollector = (isset($this->routeCollector) ?
|
||||
$this->routeCollector :
|
||||
new RouteCollector(new Std(), new GroupCountBased()));
|
||||
|
||||
foreach ($routes as $route => $config) {
|
||||
if ($this->isGroup($config)) {
|
||||
$this->addGroup($route, $config, $routeCollector);
|
||||
} elseif ($this->isRoute($config)) {
|
||||
$routeCollector->addRoute($config[1], $route, $config[0]);
|
||||
} else {
|
||||
throw new HTTPException\InternalServerErrorException("Wrong route config for route '" . print_r($route, true) . "'");
|
||||
}
|
||||
}
|
||||
|
||||
$this->routeCollector = $routeCollector;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a group of routes to a given group
|
||||
*
|
||||
* @param string $groupRoute The route of the group
|
||||
* @param array $routes The routes of the group
|
||||
* @param RouteCollector $routeCollector The route collector to add this group
|
||||
*/
|
||||
private function addGroup(string $groupRoute, array $routes, RouteCollector $routeCollector)
|
||||
{
|
||||
$routeCollector->addGroup($groupRoute, function (RouteCollector $routeCollector) use ($routes) {
|
||||
foreach ($routes as $route => $config) {
|
||||
if ($this->isGroup($config)) {
|
||||
$this->addGroup($route, $config, $routeCollector);
|
||||
} elseif ($this->isRoute($config)) {
|
||||
$routeCollector->addRoute($config[1], $route, $config[0]);
|
||||
}else {
|
||||
throw new HTTPException\InternalServerErrorException("Wrong route config for route '" . print_r($route, true) . "'");
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true in case the config is a group config
|
||||
*
|
||||
* @param array $config
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
private function isGroup(array $config)
|
||||
{
|
||||
return
|
||||
is_array($config) &&
|
||||
is_string(array_keys($config)[0]) &&
|
||||
// This entry should NOT be a BaseModule
|
||||
(substr(array_keys($config)[0], 0, strlen('Friendica\Module')) !== 'Friendica\Module') &&
|
||||
// The second argument is an array (another routes)
|
||||
is_array(array_values($config)[0]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true in case the config is a route config
|
||||
*
|
||||
* @param array $config
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
private function isRoute(array $config)
|
||||
{
|
||||
return
|
||||
// The config array should at least have one entry
|
||||
!empty($config[0]) &&
|
||||
// This entry should be a BaseModule
|
||||
(substr($config[0], 0, strlen('Friendica\Module')) === 'Friendica\Module') &&
|
||||
// Either there is no other argument
|
||||
(empty($config[1]) ||
|
||||
// Or the second argument is an array (HTTP-Methods)
|
||||
is_array($config[1]));
|
||||
}
|
||||
|
||||
/**
|
||||
* The current route collector
|
||||
*
|
||||
* @return RouteCollector|null
|
||||
*/
|
||||
public function getRouteCollector()
|
||||
{
|
||||
return $this->routeCollector;
|
||||
|
@ -236,21 +155,31 @@ class Router
|
|||
* Returns the relevant module class name for the given page URI or NULL if no route rule matched.
|
||||
*
|
||||
* @param string $cmd The path component of the request URL without the query string
|
||||
* @return string|null A Friendica\BaseModule-extending class name if a route rule matched
|
||||
*
|
||||
* @return string A Friendica\BaseModule-extending class name if a route rule matched
|
||||
*
|
||||
* @throws HTTPException\InternalServerErrorException
|
||||
* @throws HTTPException\MethodNotAllowedException If a rule matched but the method didn't
|
||||
* @throws HTTPException\NotFoundException If no rule matched
|
||||
*/
|
||||
public function getModuleClass($cmd)
|
||||
{
|
||||
// Add routes from addons
|
||||
Hook::callAll('route_collection', $this->routeCollector);
|
||||
|
||||
$cmd = '/' . ltrim($cmd, '/');
|
||||
|
||||
$dispatcher = new \FastRoute\Dispatcher\GroupCountBased($this->routeCollector->getData());
|
||||
|
||||
$moduleClass = null;
|
||||
|
||||
// @TODO: Enable method-specific modules
|
||||
$httpMethod = 'GET';
|
||||
$routeInfo = $dispatcher->dispatch($httpMethod, $cmd);
|
||||
$routeInfo = $dispatcher->dispatch($this->httpMethod, $cmd);
|
||||
if ($routeInfo[0] === Dispatcher::FOUND) {
|
||||
$moduleClass = $routeInfo[1];
|
||||
} elseif ($routeInfo[0] === Dispatcher::METHOD_NOT_ALLOWED) {
|
||||
throw new HTTPException\MethodNotAllowedException(L10n::t('Method not allowed for this module. Allowed method(s): %s', implode(', ', $routeInfo[1])));
|
||||
} else {
|
||||
throw new HTTPException\NotFoundException(L10n::t('Page not found.'));
|
||||
}
|
||||
|
||||
return $moduleClass;
|
||||
|
|
|
@ -4,7 +4,6 @@ namespace Friendica;
|
|||
|
||||
use Friendica\Core\L10n;
|
||||
use Friendica\Core\Logger;
|
||||
use Friendica\Core\System;
|
||||
|
||||
/**
|
||||
* All modules in Friendica should extend BaseModule, although not all modules
|
||||
|
@ -121,7 +120,7 @@ abstract class BaseModule extends BaseObject
|
|||
$a = \get_app();
|
||||
|
||||
$x = explode('.', $hash);
|
||||
if (time() > (IntVal($x[0]) + $max_livetime)) {
|
||||
if (time() > (intval($x[0]) + $max_livetime)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
|
@ -60,7 +60,7 @@ class BaseObject
|
|||
throw new InternalServerErrorException('DICE isn\'t initialized.');
|
||||
}
|
||||
|
||||
if (class_exists($name) || interface_exists($name )) {
|
||||
if (class_exists($name) || interface_exists($name)) {
|
||||
return self::$dice->create($name);
|
||||
} else {
|
||||
throw new InternalServerErrorException('Class \'' . $name . '\' isn\'t valid.');
|
||||
|
|
|
@ -129,16 +129,13 @@ HELP;
|
|||
$config_file = $this->getOption(['f', 'file']);
|
||||
|
||||
if (!empty($config_file)) {
|
||||
if ($config_file != 'config' . DIRECTORY_SEPARATOR . 'local.config.php') {
|
||||
// Copy config file
|
||||
$this->out("Copying config file...\n");
|
||||
if (!copy($basePathConf . DIRECTORY_SEPARATOR . $config_file, $basePathConf . DIRECTORY_SEPARATOR . 'config' . DIRECTORY_SEPARATOR . 'local.config.php')) {
|
||||
throw new RuntimeException("ERROR: Saving config file failed. Please copy '$config_file' to '" . $basePathConf . "'" . DIRECTORY_SEPARATOR . "config" . DIRECTORY_SEPARATOR . "local.config.php' manually.\n");
|
||||
}
|
||||
|
||||
if (!file_exists($config_file)) {
|
||||
throw new RuntimeException("ERROR: Config file does not exist.\n");
|
||||
}
|
||||
|
||||
//reload the config cache
|
||||
$loader = new ConfigFileLoader($basePathConf);
|
||||
$loader = new ConfigFileLoader($config_file);
|
||||
$loader->setupCache($configCache);
|
||||
|
||||
} else {
|
||||
|
@ -195,7 +192,7 @@ HELP;
|
|||
$installer->createConfig($configCache);
|
||||
}
|
||||
|
||||
$this->out(" Complete!\n\n");
|
||||
$this->out("Complete!\n\n");
|
||||
|
||||
// Check database connection
|
||||
$this->out("Checking database...\n");
|
||||
|
@ -219,6 +216,14 @@ HELP;
|
|||
throw new RuntimeException($errorMessage);
|
||||
}
|
||||
|
||||
if (!empty($config_file) && $config_file != 'config' . DIRECTORY_SEPARATOR . 'local.config.php') {
|
||||
// Copy config file
|
||||
$this->out("Copying config file...\n");
|
||||
if (!copy($basePathConf . DIRECTORY_SEPARATOR . $config_file, $basePathConf . DIRECTORY_SEPARATOR . 'config' . DIRECTORY_SEPARATOR . 'local.config.php')) {
|
||||
throw new RuntimeException("ERROR: Saving config file failed. Please copy '$config_file' to '" . $basePathConf . "'" . DIRECTORY_SEPARATOR . "config" . DIRECTORY_SEPARATOR . "local.config.php' manually.\n");
|
||||
}
|
||||
}
|
||||
|
||||
$this->out(" Complete!\n\n");
|
||||
|
||||
// Install theme
|
||||
|
|
|
@ -43,7 +43,7 @@ class ForumManager
|
|||
$params = ['order' => ['name']];
|
||||
}
|
||||
|
||||
$condition_str = "`network` = ? AND `uid` = ? AND NOT `blocked` AND NOT `pending` AND NOT `archive` AND ";
|
||||
$condition_str = "`network` IN (?, ?) AND `uid` = ? AND NOT `blocked` AND NOT `pending` AND NOT `archive` AND ";
|
||||
|
||||
if ($showprivate) {
|
||||
$condition_str .= '(`forum` OR `prv`)';
|
||||
|
@ -58,7 +58,7 @@ class ForumManager
|
|||
$forumlist = [];
|
||||
|
||||
$fields = ['id', 'url', 'name', 'micro', 'thumb'];
|
||||
$condition = [$condition_str, Protocol::DFRN, $uid];
|
||||
$condition = [$condition_str, Protocol::DFRN, Protocol::ACTIVITYPUB, $uid];
|
||||
$contacts = DBA::select('contact', $fields, $condition, $params);
|
||||
if (!$contacts) {
|
||||
return($forumlist);
|
||||
|
|
|
@ -29,7 +29,7 @@ class Nav
|
|||
'directory' => null,
|
||||
'settings' => null,
|
||||
'contacts' => null,
|
||||
'manage' => null,
|
||||
'delegation'=> null,
|
||||
'events' => null,
|
||||
'register' => null
|
||||
];
|
||||
|
@ -149,7 +149,7 @@ class Nav
|
|||
$nav['usermenu'] = [];
|
||||
$userinfo = null;
|
||||
|
||||
if (local_user() || remote_user()) {
|
||||
if (Session::isAuthenticated()) {
|
||||
$nav['logout'] = ['logout', L10n::t('Logout'), '', L10n::t('End this session')];
|
||||
} else {
|
||||
$nav['login'] = ['login', L10n::t('Login'), ($a->module == 'login' ? 'selected' : ''), L10n::t('Sign in')];
|
||||
|
@ -182,7 +182,7 @@ class Nav
|
|||
$nav['home'] = [$homelink, L10n::t('Home'), '', L10n::t('Home Page')];
|
||||
}
|
||||
|
||||
if (intval(Config::get('config', 'register_policy')) === \Friendica\Module\Register::OPEN && !local_user() && !remote_user()) {
|
||||
if (intval(Config::get('config', 'register_policy')) === \Friendica\Module\Register::OPEN && !Session::isAuthenticated()) {
|
||||
$nav['register'] = ['register', L10n::t('Register'), '', L10n::t('Create an account')];
|
||||
}
|
||||
|
||||
|
@ -257,11 +257,9 @@ class Nav
|
|||
$nav['messages']['new'] = ['message/new', L10n::t('New Message'), '', L10n::t('New Message')];
|
||||
|
||||
if (is_array($a->identities) && count($a->identities) > 1) {
|
||||
$nav['manage'] = ['manage', L10n::t('Manage'), '', L10n::t('Manage other pages')];
|
||||
$nav['delegation'] = ['delegation', L10n::t('Delegation'), '', L10n::t('Manage other pages')];
|
||||
}
|
||||
|
||||
$nav['delegations'] = ['delegate', L10n::t('Delegations'), '', L10n::t('Delegate Page Management')];
|
||||
|
||||
$nav['settings'] = ['settings', L10n::t('Settings'), '', L10n::t('Account settings')];
|
||||
|
||||
if (Feature::isEnabled(local_user(), 'multi_profiles')) {
|
||||
|
|
|
@ -39,7 +39,7 @@ class Pager
|
|||
{
|
||||
$this->setQueryString($queryString);
|
||||
$this->setItemsPerPage($itemsPerPage);
|
||||
$this->setPage(defaults($_GET, 'page', 1));
|
||||
$this->setPage(($_GET['page'] ?? 0) ?: 1);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -38,7 +38,7 @@ class BBCode extends BaseObject
|
|||
*
|
||||
* @param string $body Message body
|
||||
* @return array
|
||||
* 'type' -> Message type ("link", "video", "photo")
|
||||
* 'type' -> Message type ('link', 'video', 'photo')
|
||||
* 'text' -> Text before the shared message
|
||||
* 'after' -> Text after the shared message
|
||||
* 'image' -> Preview image of the message
|
||||
|
@ -56,19 +56,19 @@ class BBCode extends BaseObject
|
|||
|
||||
if (preg_match_all("(\[class=(.*?)\](.*?)\[\/class\])ism", $body, $attached, PREG_SET_ORDER)) {
|
||||
foreach ($attached as $data) {
|
||||
if (!in_array($data[1], ["type-link", "type-video", "type-photo"])) {
|
||||
if (!in_array($data[1], ['type-link', 'type-video', 'type-photo'])) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$post["type"] = substr($data[1], 5);
|
||||
$post['type'] = substr($data[1], 5);
|
||||
|
||||
$pos = strpos($body, $data[0]);
|
||||
if ($pos > 0) {
|
||||
$post["text"] = trim(substr($body, 0, $pos));
|
||||
$post["after"] = trim(substr($body, $pos + strlen($data[0])));
|
||||
$post['text'] = trim(substr($body, 0, $pos));
|
||||
$post['after'] = trim(substr($body, $pos + strlen($data[0])));
|
||||
} else {
|
||||
$post["text"] = trim(str_replace($data[0], "", $body));
|
||||
$post["after"] = '';
|
||||
$post['text'] = trim(str_replace($data[0], '', $body));
|
||||
$post['after'] = '';
|
||||
}
|
||||
|
||||
$attacheddata = $data[2];
|
||||
|
@ -79,25 +79,25 @@ class BBCode extends BaseObject
|
|||
|
||||
if ($picturedata) {
|
||||
if (($picturedata[0] >= 500) && ($picturedata[0] >= $picturedata[1])) {
|
||||
$post["image"] = $matches[1];
|
||||
$post['image'] = $matches[1];
|
||||
} else {
|
||||
$post["preview"] = $matches[1];
|
||||
$post['preview'] = $matches[1];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (preg_match("/\[bookmark\=(.*?)\](.*?)\[\/bookmark\]/ism", $attacheddata, $matches)) {
|
||||
$post["url"] = $matches[1];
|
||||
$post["title"] = $matches[2];
|
||||
$post['url'] = $matches[1];
|
||||
$post['title'] = $matches[2];
|
||||
}
|
||||
if (!empty($post["url"]) && (in_array($post["type"], ["link", "video"]))
|
||||
if (!empty($post['url']) && (in_array($post['type'], ['link', 'video']))
|
||||
&& preg_match("/\[url\=(.*?)\](.*?)\[\/url\]/ism", $attacheddata, $matches)) {
|
||||
$post["url"] = $matches[1];
|
||||
$post['url'] = $matches[1];
|
||||
}
|
||||
|
||||
// Search for description
|
||||
if (preg_match("/\[quote\](.*?)\[\/quote\]/ism", $attacheddata, $matches)) {
|
||||
$post["description"] = $matches[1];
|
||||
$post['description'] = $matches[1];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -109,7 +109,7 @@ class BBCode extends BaseObject
|
|||
*
|
||||
* @param string $body Message body
|
||||
* @return array
|
||||
* 'type' -> Message type ("link", "video", "photo")
|
||||
* 'type' -> Message type ('link', 'video', 'photo')
|
||||
* 'text' -> Text before the shared message
|
||||
* 'after' -> Text after the shared message
|
||||
* 'image' -> Preview image of the message
|
||||
|
@ -136,9 +136,9 @@ class BBCode extends BaseObject
|
|||
|
||||
$attributes = $match[2];
|
||||
|
||||
$data["text"] = trim($match[1]);
|
||||
$data['text'] = trim($match[1]);
|
||||
|
||||
$type = "";
|
||||
$type = '';
|
||||
preg_match("/type='(.*?)'/ism", $attributes, $matches);
|
||||
if (!empty($matches[1])) {
|
||||
$type = strtolower($matches[1]);
|
||||
|
@ -149,19 +149,19 @@ class BBCode extends BaseObject
|
|||
$type = strtolower($matches[1]);
|
||||
}
|
||||
|
||||
if ($type == "") {
|
||||
if ($type == '') {
|
||||
return [];
|
||||
}
|
||||
|
||||
if (!in_array($type, ["link", "audio", "photo", "video"])) {
|
||||
if (!in_array($type, ['link', 'audio', 'photo', 'video'])) {
|
||||
return [];
|
||||
}
|
||||
|
||||
if ($type != "") {
|
||||
$data["type"] = $type;
|
||||
if ($type != '') {
|
||||
$data['type'] = $type;
|
||||
}
|
||||
|
||||
$url = "";
|
||||
$url = '';
|
||||
preg_match("/url='(.*?)'/ism", $attributes, $matches);
|
||||
if (!empty($matches[1])) {
|
||||
$url = $matches[1];
|
||||
|
@ -172,11 +172,11 @@ class BBCode extends BaseObject
|
|||
$url = $matches[1];
|
||||
}
|
||||
|
||||
if ($url != "") {
|
||||
$data["url"] = html_entity_decode($url, ENT_QUOTES, 'UTF-8');
|
||||
if ($url != '') {
|
||||
$data['url'] = html_entity_decode($url, ENT_QUOTES, 'UTF-8');
|
||||
}
|
||||
|
||||
$title = "";
|
||||
$title = '';
|
||||
preg_match("/title='(.*?)'/ism", $attributes, $matches);
|
||||
if (!empty($matches[1])) {
|
||||
$title = $matches[1];
|
||||
|
@ -187,14 +187,14 @@ class BBCode extends BaseObject
|
|||
$title = $matches[1];
|
||||
}
|
||||
|
||||
if ($title != "") {
|
||||
if ($title != '') {
|
||||
$title = self::convert(html_entity_decode($title, ENT_QUOTES, 'UTF-8'), false, true);
|
||||
$title = html_entity_decode($title, ENT_QUOTES, 'UTF-8');
|
||||
$title = str_replace(["[", "]"], ["[", "]"], $title);
|
||||
$data["title"] = $title;
|
||||
$title = str_replace(['[', ']'], ['[', ']'], $title);
|
||||
$data['title'] = $title;
|
||||
}
|
||||
|
||||
$image = "";
|
||||
$image = '';
|
||||
preg_match("/image='(.*?)'/ism", $attributes, $matches);
|
||||
if (!empty($matches[1])) {
|
||||
$image = $matches[1];
|
||||
|
@ -205,11 +205,11 @@ class BBCode extends BaseObject
|
|||
$image = $matches[1];
|
||||
}
|
||||
|
||||
if ($image != "") {
|
||||
$data["image"] = html_entity_decode($image, ENT_QUOTES, 'UTF-8');
|
||||
if ($image != '') {
|
||||
$data['image'] = html_entity_decode($image, ENT_QUOTES, 'UTF-8');
|
||||
}
|
||||
|
||||
$preview = "";
|
||||
$preview = '';
|
||||
preg_match("/preview='(.*?)'/ism", $attributes, $matches);
|
||||
if (!empty($matches[1])) {
|
||||
$preview = $matches[1];
|
||||
|
@ -220,13 +220,13 @@ class BBCode extends BaseObject
|
|||
$preview = $matches[1];
|
||||
}
|
||||
|
||||
if ($preview != "") {
|
||||
$data["preview"] = html_entity_decode($preview, ENT_QUOTES, 'UTF-8');
|
||||
if ($preview != '') {
|
||||
$data['preview'] = html_entity_decode($preview, ENT_QUOTES, 'UTF-8');
|
||||
}
|
||||
|
||||
$data["description"] = trim($match[3]);
|
||||
$data['description'] = trim($match[3]);
|
||||
|
||||
$data["after"] = trim($match[4]);
|
||||
$data['after'] = trim($match[4]);
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
@ -244,7 +244,7 @@ class BBCode extends BaseObject
|
|||
*/
|
||||
|
||||
$has_title = !empty($item['title']);
|
||||
$plink = defaults($item, 'plink', '');
|
||||
$plink = $item['plink'] ?? '';
|
||||
$post = self::getAttachmentData($body);
|
||||
|
||||
// Get all linked images with alternative image description
|
||||
|
@ -268,11 +268,11 @@ class BBCode extends BaseObject
|
|||
}
|
||||
|
||||
// if nothing is found, it maybe having an image.
|
||||
if (!isset($post["type"])) {
|
||||
if (!isset($post['type'])) {
|
||||
// Simplify image codes
|
||||
$body = preg_replace("/\[img\=([0-9]*)x([0-9]*)\](.*?)\[\/img\]/ism", '[img]$3[/img]', $body);
|
||||
$body = preg_replace("/\[img\=(.*?)\](.*?)\[\/img\]/ism", '[img]$1[/img]', $body);
|
||||
$post["text"] = $body;
|
||||
$post['text'] = $body;
|
||||
|
||||
if (preg_match_all("(\[url=(.*?)\]\s*\[img\](.*?)\[\/img\]\s*\[\/url\])ism", $body, $pictures, PREG_SET_ORDER)) {
|
||||
if ((count($pictures) == 1) && !$has_title) {
|
||||
|
@ -288,75 +288,75 @@ class BBCode extends BaseObject
|
|||
// Workaround:
|
||||
// Sometimes photo posts to the own album are not detected at the start.
|
||||
// So we seem to cannot use the cache for these cases. That's strange.
|
||||
if (($data["type"] != "photo") && strstr($pictures[0][1], "/photos/")) {
|
||||
if (($data['type'] != 'photo') && strstr($pictures[0][1], "/photos/")) {
|
||||
$data = ParseUrl::getSiteinfo($pictures[0][1], true);
|
||||
}
|
||||
|
||||
if ($data["type"] == "photo") {
|
||||
$post["type"] = "photo";
|
||||
if (isset($data["images"][0])) {
|
||||
$post["image"] = $data["images"][0]["src"];
|
||||
$post["url"] = $data["url"];
|
||||
if ($data['type'] == 'photo') {
|
||||
$post['type'] = 'photo';
|
||||
if (isset($data['images'][0])) {
|
||||
$post['image'] = $data['images'][0]['src'];
|
||||
$post['url'] = $data['url'];
|
||||
} else {
|
||||
$post["image"] = $data["url"];
|
||||
$post['image'] = $data['url'];
|
||||
}
|
||||
|
||||
$post["preview"] = $pictures[0][2];
|
||||
$post["text"] = trim(str_replace($pictures[0][0], "", $body));
|
||||
$post['preview'] = $pictures[0][2];
|
||||
$post['text'] = trim(str_replace($pictures[0][0], '', $body));
|
||||
} else {
|
||||
$imgdata = Image::getInfoFromURL($pictures[0][1]);
|
||||
if ($imgdata && substr($imgdata["mime"], 0, 6) == "image/") {
|
||||
$post["type"] = "photo";
|
||||
$post["image"] = $pictures[0][1];
|
||||
$post["preview"] = $pictures[0][2];
|
||||
$post["text"] = trim(str_replace($pictures[0][0], "", $body));
|
||||
if ($imgdata && substr($imgdata['mime'], 0, 6) == 'image/') {
|
||||
$post['type'] = 'photo';
|
||||
$post['image'] = $pictures[0][1];
|
||||
$post['preview'] = $pictures[0][2];
|
||||
$post['text'] = trim(str_replace($pictures[0][0], '', $body));
|
||||
}
|
||||
}
|
||||
} elseif (count($pictures) > 0) {
|
||||
$post["type"] = "link";
|
||||
$post["url"] = $plink;
|
||||
$post["image"] = $pictures[0][2];
|
||||
$post["text"] = $body;
|
||||
$post['type'] = 'link';
|
||||
$post['url'] = $plink;
|
||||
$post['image'] = $pictures[0][2];
|
||||
$post['text'] = $body;
|
||||
|
||||
foreach ($pictures as $picture) {
|
||||
$post["text"] = trim(str_replace($picture[0], "", $post["text"]));
|
||||
$post['text'] = trim(str_replace($picture[0], '', $post['text']));
|
||||
}
|
||||
}
|
||||
} elseif (preg_match_all("(\[img\](.*?)\[\/img\])ism", $body, $pictures, PREG_SET_ORDER)) {
|
||||
if ((count($pictures) == 1) && !$has_title) {
|
||||
$post["type"] = "photo";
|
||||
$post["image"] = $pictures[0][1];
|
||||
$post["text"] = str_replace($pictures[0][0], "", $body);
|
||||
$post['type'] = 'photo';
|
||||
$post['image'] = $pictures[0][1];
|
||||
$post['text'] = str_replace($pictures[0][0], '', $body);
|
||||
} elseif (count($pictures) > 0) {
|
||||
$post["type"] = "link";
|
||||
$post["url"] = $plink;
|
||||
$post["image"] = $pictures[0][1];
|
||||
$post["text"] = $body;
|
||||
$post['type'] = 'link';
|
||||
$post['url'] = $plink;
|
||||
$post['image'] = $pictures[0][1];
|
||||
$post['text'] = $body;
|
||||
|
||||
foreach ($pictures as $picture) {
|
||||
$post["text"] = trim(str_replace($picture[0], "", $post["text"]));
|
||||
$post['text'] = trim(str_replace($picture[0], '', $post['text']));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Test for the external links
|
||||
preg_match_all("(\[url\](.*?)\[\/url\])ism", $post["text"], $links1, PREG_SET_ORDER);
|
||||
preg_match_all("(\[url\=(.*?)\].*?\[\/url\])ism", $post["text"], $links2, PREG_SET_ORDER);
|
||||
preg_match_all("(\[url\](.*?)\[\/url\])ism", $post['text'], $links1, PREG_SET_ORDER);
|
||||
preg_match_all("(\[url\=(.*?)\].*?\[\/url\])ism", $post['text'], $links2, PREG_SET_ORDER);
|
||||
|
||||
$links = array_merge($links1, $links2);
|
||||
|
||||
// If there is only a single one, then use it.
|
||||
// This should cover link posts via API.
|
||||
if ((count($links) == 1) && !isset($post["preview"]) && !$has_title) {
|
||||
$post["type"] = "link";
|
||||
$post["url"] = $links[0][1];
|
||||
if ((count($links) == 1) && !isset($post['preview']) && !$has_title) {
|
||||
$post['type'] = 'link';
|
||||
$post['url'] = $links[0][1];
|
||||
}
|
||||
|
||||
// Now count the number of external media links
|
||||
preg_match_all("(\[vimeo\](.*?)\[\/vimeo\])ism", $post["text"], $links1, PREG_SET_ORDER);
|
||||
preg_match_all("(\[youtube\\](.*?)\[\/youtube\\])ism", $post["text"], $links2, PREG_SET_ORDER);
|
||||
preg_match_all("(\[video\\](.*?)\[\/video\\])ism", $post["text"], $links3, PREG_SET_ORDER);
|
||||
preg_match_all("(\[audio\\](.*?)\[\/audio\\])ism", $post["text"], $links4, PREG_SET_ORDER);
|
||||
preg_match_all("(\[vimeo\](.*?)\[\/vimeo\])ism", $post['text'], $links1, PREG_SET_ORDER);
|
||||
preg_match_all("(\[youtube\\](.*?)\[\/youtube\\])ism", $post['text'], $links2, PREG_SET_ORDER);
|
||||
preg_match_all("(\[video\\](.*?)\[\/video\\])ism", $post['text'], $links3, PREG_SET_ORDER);
|
||||
preg_match_all("(\[audio\\](.*?)\[\/audio\\])ism", $post['text'], $links4, PREG_SET_ORDER);
|
||||
|
||||
// Add them to the other external links
|
||||
$links = array_merge($links, $links1, $links2, $links3, $links4);
|
||||
|
@ -364,19 +364,19 @@ class BBCode extends BaseObject
|
|||
// Are there more than one?
|
||||
if (count($links) > 1) {
|
||||
// The post will be the type "text", which means a blog post
|
||||
unset($post["type"]);
|
||||
$post["url"] = $plink;
|
||||
unset($post['type']);
|
||||
$post['url'] = $plink;
|
||||
}
|
||||
|
||||
if (!isset($post["type"])) {
|
||||
$post["type"] = "text";
|
||||
$post["text"] = trim($body);
|
||||
if (!isset($post['type'])) {
|
||||
$post['type'] = "text";
|
||||
$post['text'] = trim($body);
|
||||
}
|
||||
} elseif (isset($post["url"]) && ($post["type"] == "video")) {
|
||||
$data = ParseUrl::getSiteinfoCached($post["url"], true);
|
||||
} elseif (isset($post['url']) && ($post['type'] == 'video')) {
|
||||
$data = ParseUrl::getSiteinfoCached($post['url'], true);
|
||||
|
||||
if (isset($data["images"][0])) {
|
||||
$post["image"] = $data["images"][0]["src"];
|
||||
if (isset($data['images'][0])) {
|
||||
$post['image'] = $data['images'][0]['src'];
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -581,27 +581,27 @@ class BBCode extends BaseObject
|
|||
private static function convertAttachment($return, $simplehtml = false, $tryoembed = true)
|
||||
{
|
||||
$data = self::getAttachmentData($return);
|
||||
if (empty($data) || empty($data["url"])) {
|
||||
if (empty($data) || empty($data['url'])) {
|
||||
return $return;
|
||||
}
|
||||
|
||||
if (isset($data["title"])) {
|
||||
$data["title"] = strip_tags($data["title"]);
|
||||
$data["title"] = str_replace(["http://", "https://"], "", $data["title"]);
|
||||
if (isset($data['title'])) {
|
||||
$data['title'] = strip_tags($data['title']);
|
||||
$data['title'] = str_replace(['http://', 'https://'], '', $data['title']);
|
||||
} else {
|
||||
$data["title"] = null;
|
||||
$data['title'] = null;
|
||||
}
|
||||
|
||||
if (((strpos($data["text"], "[img=") !== false) || (strpos($data["text"], "[img]") !== false) || Config::get('system', 'always_show_preview')) && !empty($data["image"])) {
|
||||
$data["preview"] = $data["image"];
|
||||
$data["image"] = "";
|
||||
if (((strpos($data['text'], "[img=") !== false) || (strpos($data['text'], "[img]") !== false) || Config::get('system', 'always_show_preview')) && !empty($data['image'])) {
|
||||
$data['preview'] = $data['image'];
|
||||
$data['image'] = '';
|
||||
}
|
||||
|
||||
$return = '';
|
||||
if (in_array($simplehtml, [7, 9])) {
|
||||
$return = self::convertUrlForOStatus($data["url"]);
|
||||
$return = self::convertUrlForActivityPub($data['url']);
|
||||
} elseif (($simplehtml != 4) && ($simplehtml != 0)) {
|
||||
$return = sprintf('<a href="%s" target="_blank">%s</a><br>', $data["url"], $data["title"]);
|
||||
$return = sprintf('<a href="%s" target="_blank">%s</a><br>', $data['url'], $data['title']);
|
||||
} else {
|
||||
try {
|
||||
if ($tryoembed && OEmbed::isAllowedURL($data['url'])) {
|
||||
|
@ -610,28 +610,28 @@ class BBCode extends BaseObject
|
|||
throw new Exception('OEmbed is disabled for this attachment.');
|
||||
}
|
||||
} catch (Exception $e) {
|
||||
$data["title"] = defaults($data, 'title', $data['url']);
|
||||
$data['title'] = ($data['title'] ?? '') ?: $data['url'];
|
||||
|
||||
if ($simplehtml != 4) {
|
||||
$return = sprintf('<div class="type-%s">', $data["type"]);
|
||||
$return = sprintf('<div class="type-%s">', $data['type']);
|
||||
}
|
||||
|
||||
if (!empty($data['title']) && !empty($data['url'])) {
|
||||
if (!empty($data["image"]) && empty($data["text"]) && ($data["type"] == "photo")) {
|
||||
$return .= sprintf('<a href="%s" target="_blank"><img src="%s" alt="" title="%s" class="attachment-image" /></a>', $data["url"], self::proxyUrl($data["image"], $simplehtml), $data["title"]);
|
||||
if (!empty($data['image']) && empty($data['text']) && ($data['type'] == 'photo')) {
|
||||
$return .= sprintf('<a href="%s" target="_blank"><img src="%s" alt="" title="%s" class="attachment-image" /></a>', $data['url'], self::proxyUrl($data['image'], $simplehtml), $data['title']);
|
||||
} else {
|
||||
if (!empty($data["image"])) {
|
||||
$return .= sprintf('<a href="%s" target="_blank"><img src="%s" alt="" title="%s" class="attachment-image" /></a><br />', $data["url"], self::proxyUrl($data["image"], $simplehtml), $data["title"]);
|
||||
} elseif (!empty($data["preview"])) {
|
||||
$return .= sprintf('<a href="%s" target="_blank"><img src="%s" alt="" title="%s" class="attachment-preview" /></a><br />', $data["url"], self::proxyUrl($data["preview"], $simplehtml), $data["title"]);
|
||||
if (!empty($data['image'])) {
|
||||
$return .= sprintf('<a href="%s" target="_blank"><img src="%s" alt="" title="%s" class="attachment-image" /></a><br />', $data['url'], self::proxyUrl($data['image'], $simplehtml), $data['title']);
|
||||
} elseif (!empty($data['preview'])) {
|
||||
$return .= sprintf('<a href="%s" target="_blank"><img src="%s" alt="" title="%s" class="attachment-preview" /></a><br />', $data['url'], self::proxyUrl($data['preview'], $simplehtml), $data['title']);
|
||||
}
|
||||
$return .= sprintf('<h4><a href="%s">%s</a></h4>', $data['url'], $data['title']);
|
||||
}
|
||||
}
|
||||
|
||||
if (!empty($data["description"]) && $data["description"] != $data["title"]) {
|
||||
if (!empty($data['description']) && $data['description'] != $data['title']) {
|
||||
// Sanitize the HTML by converting it to BBCode
|
||||
$bbcode = HTML::toBBCode($data["description"]);
|
||||
$bbcode = HTML::toBBCode($data['description']);
|
||||
$return .= sprintf('<blockquote>%s</blockquote>', trim(self::convert($bbcode)));
|
||||
}
|
||||
|
||||
|
@ -645,7 +645,7 @@ class BBCode extends BaseObject
|
|||
}
|
||||
}
|
||||
|
||||
return trim(defaults($data, 'text', '') . ' ' . $return . ' ' . defaults($data, 'after', ''));
|
||||
return trim(($data['text'] ?? '') . ' ' . $return . ' ' . ($data['after'] ?? ''));
|
||||
}
|
||||
|
||||
public static function removeShareInformation($Text, $plaintext = false, $nolink = false)
|
||||
|
@ -655,36 +655,36 @@ class BBCode extends BaseObject
|
|||
if (!$data) {
|
||||
return $Text;
|
||||
} elseif ($nolink) {
|
||||
return $data["text"] . defaults($data, 'after', '');
|
||||
return $data['text'] . ($data['after'] ?? '');
|
||||
}
|
||||
|
||||
$title = htmlentities(defaults($data, 'title', ''), ENT_QUOTES, 'UTF-8', false);
|
||||
$text = htmlentities($data["text"], ENT_QUOTES, 'UTF-8', false);
|
||||
if ($plaintext || (($title != "") && strstr($text, $title))) {
|
||||
$data["title"] = $data["url"];
|
||||
} elseif (($text != "") && strstr($title, $text)) {
|
||||
$data["text"] = $data["title"];
|
||||
$data["title"] = $data["url"];
|
||||
$title = htmlentities($data['title'] ?? '', ENT_QUOTES, 'UTF-8', false);
|
||||
$text = htmlentities($data['text'], ENT_QUOTES, 'UTF-8', false);
|
||||
if ($plaintext || (($title != '') && strstr($text, $title))) {
|
||||
$data['title'] = $data['url'];
|
||||
} elseif (($text != '') && strstr($title, $text)) {
|
||||
$data['text'] = $data['title'];
|
||||
$data['title'] = $data['url'];
|
||||
}
|
||||
|
||||
if (empty($data["text"]) && !empty($data["title"]) && empty($data["url"])) {
|
||||
return $data["title"] . $data["after"];
|
||||
if (empty($data['text']) && !empty($data['title']) && empty($data['url'])) {
|
||||
return $data['title'] . $data['after'];
|
||||
}
|
||||
|
||||
// If the link already is included in the post, don't add it again
|
||||
if (!empty($data["url"]) && strpos($data["text"], $data["url"])) {
|
||||
return $data["text"] . $data["after"];
|
||||
if (!empty($data['url']) && strpos($data['text'], $data['url'])) {
|
||||
return $data['text'] . $data['after'];
|
||||
}
|
||||
|
||||
$text = $data["text"];
|
||||
$text = $data['text'];
|
||||
|
||||
if (!empty($data["url"]) && !empty($data["title"])) {
|
||||
$text .= "\n[url=" . $data["url"] . "]" . $data["title"] . "[/url]";
|
||||
} elseif (!empty($data["url"])) {
|
||||
$text .= "\n[url]" . $data["url"] . "[/url]";
|
||||
if (!empty($data['url']) && !empty($data['title'])) {
|
||||
$text .= "\n[url=" . $data['url'] . ']' . $data['title'] . '[/url]';
|
||||
} elseif (!empty($data['url'])) {
|
||||
$text .= "\n[url]" . $data['url'] . '[/url]';
|
||||
}
|
||||
|
||||
return $text . "\n" . $data["after"];
|
||||
return $text . "\n" . $data['after'];
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -694,7 +694,7 @@ class BBCode extends BaseObject
|
|||
* @param array $match Array with the matching values
|
||||
* @return string reformatted link including HTML codes
|
||||
*/
|
||||
private static function convertUrlForOStatusCallback($match)
|
||||
private static function convertUrlForActivityPubCallback($match)
|
||||
{
|
||||
$url = $match[1];
|
||||
|
||||
|
@ -707,15 +707,26 @@ class BBCode extends BaseObject
|
|||
return $match[0];
|
||||
}
|
||||
|
||||
return self::convertUrlForOStatus($url);
|
||||
return self::convertUrlForActivityPub($url);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Converts [url] BBCodes in a format that looks fine on OStatus systems.
|
||||
* @brief Converts [url] BBCodes in a format that looks fine on ActivityPub systems.
|
||||
* @param string $url URL that is about to be reformatted
|
||||
* @return string reformatted link including HTML codes
|
||||
*/
|
||||
private static function convertUrlForOStatus($url)
|
||||
private static function convertUrlForActivityPub($url)
|
||||
{
|
||||
$html = '<a href="%s" target="_blank">%s</a>';
|
||||
return sprintf($html, $url, self::getStyledURL($url));
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts an URL in a nicer format (without the scheme and possibly shortened)
|
||||
* @param string $url URL that is about to be reformatted
|
||||
* @return string reformatted link
|
||||
*/
|
||||
private static function getStyledURL($url)
|
||||
{
|
||||
$parts = parse_url($url);
|
||||
$scheme = $parts['scheme'] . '://';
|
||||
|
@ -725,9 +736,7 @@ class BBCode extends BaseObject
|
|||
$styled_url = substr($styled_url, 0, 30) . "…";
|
||||
}
|
||||
|
||||
$html = '<a href="%s" target="_blank">%s</a>';
|
||||
|
||||
return sprintf($html, $url, $styled_url);
|
||||
return $styled_url;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -932,7 +941,7 @@ class BBCode extends BaseObject
|
|||
$attributes = [];
|
||||
foreach(['author', 'profile', 'avatar', 'link', 'posted'] as $field) {
|
||||
preg_match("/$field=(['\"])(.+?)\\1/ism", $attribute_string, $matches);
|
||||
$attributes[$field] = html_entity_decode(defaults($matches, 2, ''), ENT_QUOTES, 'UTF-8');
|
||||
$attributes[$field] = html_entity_decode($matches[2] ?? '', ENT_QUOTES, 'UTF-8');
|
||||
}
|
||||
|
||||
// We only call this so that a previously unknown contact can be added.
|
||||
|
@ -951,11 +960,11 @@ class BBCode extends BaseObject
|
|||
Contact::getIdForURL($attributes['profile'], 0, true, $default);
|
||||
|
||||
$author_contact = Contact::getDetailsByURL($attributes['profile']);
|
||||
$author_contact['addr'] = defaults($author_contact, 'addr' , Protocol::getAddrFromProfileUrl($attributes['profile']));
|
||||
$author_contact['addr'] = ($author_contact['addr'] ?? '') ?: Protocol::getAddrFromProfileUrl($attributes['profile']);
|
||||
|
||||
$attributes['author'] = defaults($author_contact, 'name' , $attributes['author']);
|
||||
$attributes['avatar'] = defaults($author_contact, 'micro', $attributes['avatar']);
|
||||
$attributes['profile'] = defaults($author_contact, 'url' , $attributes['profile']);
|
||||
$attributes['author'] = ($author_contact['name'] ?? '') ?: $attributes['author'];
|
||||
$attributes['avatar'] = ($author_contact['micro'] ?? '') ?: $attributes['avatar'];
|
||||
$attributes['profile'] = ($author_contact['url'] ?? '') ?: $attributes['profile'];
|
||||
|
||||
if ($attributes['avatar']) {
|
||||
$attributes['avatar'] = ProxyUtils::proxifyUrl($attributes['avatar'], false, ProxyUtils::SIZE_THUMB);
|
||||
|
@ -1056,7 +1065,8 @@ class BBCode extends BaseObject
|
|||
|
||||
private static function removePictureLinksCallback($match)
|
||||
{
|
||||
$text = Cache::get($match[1]);
|
||||
$cache_key = 'remove:' . $match[1];
|
||||
$text = Cache::get($cache_key);
|
||||
|
||||
if (is_null($text)) {
|
||||
$a = self::getApp();
|
||||
|
@ -1072,10 +1082,10 @@ class BBCode extends BaseObject
|
|||
|
||||
$a->getProfiler()->saveTimestamp($stamp1, "network", System::callstack());
|
||||
|
||||
if (substr($curl_info["content_type"], 0, 6) == "image/") {
|
||||
$text = "[url=" . $match[1] . "]" . $match[1] . "[/url]";
|
||||
if (substr($curl_info['content_type'], 0, 6) == 'image/') {
|
||||
$text = "[url=" . $match[1] . ']' . $match[1] . "[/url]";
|
||||
} else {
|
||||
$text = "[url=" . $match[2] . "]" . $match[2] . "[/url]";
|
||||
$text = "[url=" . $match[2] . ']' . $match[2] . "[/url]";
|
||||
|
||||
// if its not a picture then look if its a page that contains a picture link
|
||||
$body = Network::fetchUrl($match[1]);
|
||||
|
@ -1093,12 +1103,12 @@ class BBCode extends BaseObject
|
|||
}
|
||||
}
|
||||
|
||||
if (strtolower($attr["name"]) == "twitter:image") {
|
||||
$text = "[url=" . $attr["content"] . "]" . $attr["content"] . "[/url]";
|
||||
if (strtolower($attr['name']) == 'twitter:image') {
|
||||
$text = '[url=' . $attr['content'] . ']' . $attr['content'] . '[/url]';
|
||||
}
|
||||
}
|
||||
}
|
||||
Cache::set($match[1], $text);
|
||||
Cache::set($cache_key, $text);
|
||||
}
|
||||
|
||||
return $text;
|
||||
|
@ -1106,7 +1116,7 @@ class BBCode extends BaseObject
|
|||
|
||||
private static function expandLinksCallback($match)
|
||||
{
|
||||
if (($match[3] == "") || ($match[2] == $match[3]) || stristr($match[2], $match[3])) {
|
||||
if (($match[3] == '') || ($match[2] == $match[3]) || stristr($match[2], $match[3])) {
|
||||
return ($match[1] . "[url]" . $match[2] . "[/url]");
|
||||
} else {
|
||||
return ($match[1] . $match[3] . " [url]" . $match[2] . "[/url]");
|
||||
|
@ -1115,58 +1125,72 @@ class BBCode extends BaseObject
|
|||
|
||||
private static function cleanPictureLinksCallback($match)
|
||||
{
|
||||
$text = Cache::get($match[1]);
|
||||
$a = self::getApp();
|
||||
|
||||
if (is_null($text)) {
|
||||
$a = self::getApp();
|
||||
|
||||
$stamp1 = microtime(true);
|
||||
|
||||
$ch = @curl_init($match[1]);
|
||||
@curl_setopt($ch, CURLOPT_NOBODY, true);
|
||||
@curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
|
||||
@curl_setopt($ch, CURLOPT_USERAGENT, $a->getUserAgent());
|
||||
@curl_exec($ch);
|
||||
$curl_info = @curl_getinfo($ch);
|
||||
|
||||
$a->getProfiler()->saveTimestamp($stamp1, "network", System::callstack());
|
||||
|
||||
// if its a link to a picture then embed this picture
|
||||
if (substr($curl_info["content_type"], 0, 6) == "image/") {
|
||||
$text = "[img]" . $match[1] . "[/img]";
|
||||
// When the picture link is the own photo path then we can avoid fetching the link
|
||||
$own_photo_url = preg_quote(Strings::normaliseLink($a->getBaseURL()) . '/photos/');
|
||||
if (preg_match('|' . $own_photo_url . '.*?/image/|', Strings::normaliseLink($match[1]))) {
|
||||
if (!empty($match[3])) {
|
||||
$text = '[img=' . str_replace('-1.', '-0.', $match[2]) . ']' . $match[3] . '[/img]';
|
||||
} else {
|
||||
if (!empty($match[3])) {
|
||||
$text = "[img=" . $match[2] . "]" . $match[3] . "[/img]";
|
||||
} else {
|
||||
$text = "[img]" . $match[2] . "[/img]";
|
||||
$text = '[img]' . str_replace('-1.', '-0.', $match[2]) . '[/img]';
|
||||
}
|
||||
return $text;
|
||||
}
|
||||
|
||||
$cache_key = 'clean:' . $match[1];
|
||||
$text = Cache::get($cache_key);
|
||||
if (!is_null($text)) {
|
||||
return $text;
|
||||
}
|
||||
|
||||
// Only fetch the header, not the content
|
||||
$stamp1 = microtime(true);
|
||||
|
||||
$ch = @curl_init($match[1]);
|
||||
@curl_setopt($ch, CURLOPT_NOBODY, true);
|
||||
@curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
|
||||
@curl_setopt($ch, CURLOPT_USERAGENT, $a->getUserAgent());
|
||||
@curl_exec($ch);
|
||||
$curl_info = @curl_getinfo($ch);
|
||||
|
||||
$a->getProfiler()->saveTimestamp($stamp1, "network", System::callstack());
|
||||
|
||||
// if its a link to a picture then embed this picture
|
||||
if (substr($curl_info['content_type'], 0, 6) == 'image/') {
|
||||
$text = '[img]' . $match[1] . '[/img]';
|
||||
} else {
|
||||
if (!empty($match[3])) {
|
||||
$text = '[img=' . $match[2] . ']' . $match[3] . '[/img]';
|
||||
} else {
|
||||
$text = '[img]' . $match[2] . '[/img]';
|
||||
}
|
||||
|
||||
// if its not a picture then look if its a page that contains a picture link
|
||||
$body = Network::fetchUrl($match[1]);
|
||||
|
||||
$doc = new DOMDocument();
|
||||
@$doc->loadHTML($body);
|
||||
$xpath = new DOMXPath($doc);
|
||||
$list = $xpath->query("//meta[@name]");
|
||||
foreach ($list as $node) {
|
||||
$attr = [];
|
||||
if ($node->attributes->length) {
|
||||
foreach ($node->attributes as $attribute) {
|
||||
$attr[$attribute->name] = $attribute->value;
|
||||
}
|
||||
}
|
||||
|
||||
// if its not a picture then look if its a page that contains a picture link
|
||||
$body = Network::fetchUrl($match[1]);
|
||||
|
||||
$doc = new DOMDocument();
|
||||
@$doc->loadHTML($body);
|
||||
$xpath = new DOMXPath($doc);
|
||||
$list = $xpath->query("//meta[@name]");
|
||||
foreach ($list as $node) {
|
||||
$attr = [];
|
||||
if ($node->attributes->length) {
|
||||
foreach ($node->attributes as $attribute) {
|
||||
$attr[$attribute->name] = $attribute->value;
|
||||
}
|
||||
}
|
||||
|
||||
if (strtolower($attr["name"]) == "twitter:image") {
|
||||
if (!empty($match[3])) {
|
||||
$text = "[img=" . $attr["content"] . "]" . $match[3] . "[/img]";
|
||||
} else {
|
||||
$text = "[img]" . $attr["content"] . "[/img]";
|
||||
}
|
||||
if (strtolower($attr['name']) == "twitter:image") {
|
||||
if (!empty($match[3])) {
|
||||
$text = "[img=" . $attr['content'] . "]" . $match[3] . "[/img]";
|
||||
} else {
|
||||
$text = "[img]" . $attr['content'] . "[/img]";
|
||||
}
|
||||
}
|
||||
}
|
||||
Cache::set($match[1], $text);
|
||||
}
|
||||
Cache::set($cache_key, $text);
|
||||
|
||||
return $text;
|
||||
}
|
||||
|
@ -1217,7 +1241,7 @@ class BBCode extends BaseObject
|
|||
$try_oembed_callback = function ($match)
|
||||
{
|
||||
$url = $match[1];
|
||||
$title = defaults($match, 2, null);
|
||||
$title = $match[2] ?? null;
|
||||
|
||||
try {
|
||||
$return = OEmbed::getHTML($url, $title);
|
||||
|
@ -1318,7 +1342,7 @@ class BBCode extends BaseObject
|
|||
$text = str_replace($search, $replace, $text);
|
||||
|
||||
// removing multiplicated newlines
|
||||
if (Config::get("system", "remove_multiplicated_lines")) {
|
||||
if (Config::get('system', 'remove_multiplicated_lines')) {
|
||||
$search = ["\n\n\n", "\n ", " \n", "[/quote]\n\n", "\n[/quote]", "[/li]\n", "\n[li]", "\n[ul]", "[/ul]\n", "\n\n[share ", "[/attachment]\n",
|
||||
"\n[h1]", "[/h1]\n", "\n[h2]", "[/h2]\n", "\n[h3]", "[/h3]\n", "\n[h4]", "[/h4]\n", "\n[h5]", "[/h5]\n", "\n[h6]", "[/h6]\n"];
|
||||
$replace = ["\n\n", "\n", "\n", "[/quote]\n", "[/quote]", "[/li]", "[li]", "[ul]", "[/ul]", "\n[share ", "[/attachment]",
|
||||
|
@ -1389,8 +1413,14 @@ class BBCode extends BaseObject
|
|||
|
||||
// Check for sized text
|
||||
// [size=50] --> font-size: 50px (with the unit).
|
||||
$text = preg_replace("(\[size=(\d*?)\](.*?)\[\/size\])ism", "<span style=\"font-size: $1px; line-height: initial;\">$2</span>", $text);
|
||||
$text = preg_replace("(\[size=(.*?)\](.*?)\[\/size\])ism", "<span style=\"font-size: $1; line-height: initial;\">$2</span>", $text);
|
||||
if ($simple_html != 3) {
|
||||
$text = preg_replace("(\[size=(\d*?)\](.*?)\[\/size\])ism", "<span style=\"font-size: $1px; line-height: initial;\">$2</span>", $text);
|
||||
$text = preg_replace("(\[size=(.*?)\](.*?)\[\/size\])ism", "<span style=\"font-size: $1; line-height: initial;\">$2</span>", $text);
|
||||
} else {
|
||||
// Issue 2199: Diaspora doesn't interpret the construct above, nor the <small> or <big> element
|
||||
$text = preg_replace("(\[size=(.*?)\](.*?)\[\/size\])ism", "$2", $text);
|
||||
}
|
||||
|
||||
|
||||
// Check for centered text
|
||||
$text = preg_replace("(\[center\](.*?)\[\/center\])ism", "<div style=\"text-align:center;\">$1</div>", $text);
|
||||
|
@ -1445,6 +1475,11 @@ class BBCode extends BaseObject
|
|||
|
||||
$text = str_replace('[hr]', '<hr />', $text);
|
||||
|
||||
if (!$for_plaintext) {
|
||||
// Autolinker for isolated URLs
|
||||
$text = preg_replace(Strings::autoLinkRegEx(), '[url]$1[/url]', $text);
|
||||
}
|
||||
|
||||
// This is actually executed in Item::prepareBody()
|
||||
|
||||
$nosmile = strpos($text, '[nosmile]') !== false;
|
||||
|
@ -1454,24 +1489,22 @@ class BBCode extends BaseObject
|
|||
$text = preg_replace("/\[font=(.*?)\](.*?)\[\/font\]/sm", "<span style=\"font-family: $1;\">$2</span>", $text);
|
||||
|
||||
// Declare the format for [spoiler] layout
|
||||
$SpoilerLayout = '<blockquote class="spoiler">$1</blockquote>';
|
||||
$SpoilerLayout = '<details class="spoiler"><summary>' . L10n::t('Click to open/close') . '</summary>$1</details>';
|
||||
|
||||
// Check for [spoiler] text
|
||||
// handle nested quotes
|
||||
$endlessloop = 0;
|
||||
while ((strpos($text, "[/spoiler]") !== false) && (strpos($text, "[spoiler]") !== false) && (++$endlessloop < 20)) {
|
||||
$text = preg_replace("/\[spoiler\](.*?)\[\/spoiler\]/ism", "$SpoilerLayout", $text);
|
||||
$text = preg_replace("/\[spoiler\](.*?)\[\/spoiler\]/ism", $SpoilerLayout, $text);
|
||||
}
|
||||
|
||||
// Check for [spoiler=Author] text
|
||||
|
||||
$t_wrote = L10n::t('$1 wrote:');
|
||||
// Check for [spoiler=Title] text
|
||||
|
||||
// handle nested quotes
|
||||
$endlessloop = 0;
|
||||
while ((strpos($text, "[/spoiler]")!== false) && (strpos($text, "[spoiler=") !== false) && (++$endlessloop < 20)) {
|
||||
$text = preg_replace("/\[spoiler=[\"\']*(.*?)[\"\']*\](.*?)\[\/spoiler\]/ism",
|
||||
"<br /><strong class=".'"spoiler"'.">" . $t_wrote . "</strong><blockquote class=".'"spoiler"'.">$2</blockquote>",
|
||||
'<details class="spoiler"><summary>$1</summary>$2</details>',
|
||||
$text);
|
||||
}
|
||||
|
||||
|
@ -1629,12 +1662,10 @@ class BBCode extends BaseObject
|
|||
$text = Smilies::replace($text);
|
||||
}
|
||||
|
||||
// if the HTML is used to generate plain text, then don't do this search, but replace all URL of that kind to text
|
||||
if (!$for_plaintext) {
|
||||
$text = preg_replace(Strings::autoLinkRegEx(), '[url]$1[/url]', $text);
|
||||
if (in_array($simple_html, [7, 9])) {
|
||||
$text = preg_replace_callback("/\[url\](.*?)\[\/url\]/ism", 'self::convertUrlForOStatusCallback', $text);
|
||||
$text = preg_replace_callback("/\[url\=(.*?)\](.*?)\[\/url\]/ism", 'self::convertUrlForOStatusCallback', $text);
|
||||
$text = preg_replace_callback("/\[url\](.*?)\[\/url\]/ism", 'self::convertUrlForActivityPubCallback', $text);
|
||||
$text = preg_replace_callback("/\[url\=(.*?)\](.*?)\[\/url\]/ism", 'self::convertUrlForActivityPubCallback', $text);
|
||||
}
|
||||
} else {
|
||||
$text = preg_replace("(\[url\](.*?)\[\/url\])ism", " $1 ", $text);
|
||||
|
@ -1810,7 +1841,7 @@ class BBCode extends BaseObject
|
|||
// Clean up the HTML by loading and saving the HTML with the DOM.
|
||||
// Bad structured html can break a whole page.
|
||||
// For performance reasons do it only with activated item cache or at export.
|
||||
if (!$try_oembed || (get_itemcachepath() != "")) {
|
||||
if (!$try_oembed || (get_itemcachepath() != '')) {
|
||||
$doc = new DOMDocument();
|
||||
$doc->preserveWhiteSpace = false;
|
||||
|
||||
|
@ -1818,10 +1849,10 @@ class BBCode extends BaseObject
|
|||
|
||||
$doctype = '<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">';
|
||||
$encoding = '<?xml encoding="UTF-8">';
|
||||
@$doc->loadHTML($encoding.$doctype."<html><body>".$text."</body></html>");
|
||||
@$doc->loadHTML($encoding . $doctype . '<html><body>' . $text . '</body></html>');
|
||||
$doc->encoding = 'UTF-8';
|
||||
$text = $doc->saveHTML();
|
||||
$text = str_replace(["<html><body>", "</body></html>", $doctype, $encoding], ["", "", "", ""], $text);
|
||||
$text = str_replace(['<html><body>', '</body></html>', $doctype, $encoding], ['', '', '', ''], $text);
|
||||
|
||||
$text = str_replace('<br></li>', '</li>', $text);
|
||||
|
||||
|
@ -1861,9 +1892,9 @@ class BBCode extends BaseObject
|
|||
* @param string $addon The addon for which the abstract is meant for
|
||||
* @return string The abstract
|
||||
*/
|
||||
public static function getAbstract($text, $addon = "")
|
||||
public static function getAbstract($text, $addon = '')
|
||||
{
|
||||
$abstract = "";
|
||||
$abstract = '';
|
||||
$abstracts = [];
|
||||
$addon = strtolower($addon);
|
||||
|
||||
|
@ -1877,7 +1908,7 @@ class BBCode extends BaseObject
|
|||
$abstract = $abstracts[$addon];
|
||||
}
|
||||
|
||||
if ($abstract == "" && preg_match("/\[abstract\](.*?)\[\/abstract\]/ism", $text, $result)) {
|
||||
if ($abstract == '' && preg_match("/\[abstract\](.*?)\[\/abstract\]/ism", $text, $result)) {
|
||||
$abstract = $result[1];
|
||||
}
|
||||
|
||||
|
@ -1953,7 +1984,7 @@ class BBCode extends BaseObject
|
|||
|
||||
// Add all tags that maybe were removed
|
||||
if (preg_match_all("/#\[url\=([$url_search_string]*)\](.*?)\[\/url\]/ism", $original_text, $tags)) {
|
||||
$tagline = "";
|
||||
$tagline = '';
|
||||
foreach ($tags[2] as $tag) {
|
||||
$tag = html_entity_decode($tag, ENT_QUOTES, 'UTF-8');
|
||||
if (!strpos(html_entity_decode($text, ENT_QUOTES, 'UTF-8'), '#' . $tag)) {
|
||||
|
@ -1971,7 +2002,7 @@ class BBCode extends BaseObject
|
|||
|
||||
// If a link is followed by a quote then there should be a newline before it
|
||||
// Maybe we should make this newline at every time before a quote.
|
||||
$text = str_replace(["</a><blockquote>"], ["</a><br><blockquote>"], $text);
|
||||
$text = str_replace(['</a><blockquote>'], ['</a><br><blockquote>'], $text);
|
||||
|
||||
$stamp1 = microtime(true);
|
||||
|
||||
|
|
|
@ -42,14 +42,32 @@ class HTML
|
|||
return $cleaned;
|
||||
}
|
||||
|
||||
private static function tagToBBCode(DOMDocument $doc, $tag, $attributes, $startbb, $endbb)
|
||||
/**
|
||||
* Search all instances of a specific HTML tag node in the provided DOM document and replaces them with BBCode text nodes.
|
||||
*
|
||||
* @see HTML::tagToBBCodeSub()
|
||||
*/
|
||||
private static function tagToBBCode(DOMDocument $doc, string $tag, array $attributes, string $startbb, string $endbb, bool $ignoreChildren = false)
|
||||
{
|
||||
do {
|
||||
$done = self::tagToBBCodeSub($doc, $tag, $attributes, $startbb, $endbb);
|
||||
$done = self::tagToBBCodeSub($doc, $tag, $attributes, $startbb, $endbb, $ignoreChildren);
|
||||
} while ($done);
|
||||
}
|
||||
|
||||
private static function tagToBBCodeSub(DOMDocument $doc, $tag, $attributes, $startbb, $endbb)
|
||||
/**
|
||||
* Search the first specific HTML tag node in the provided DOM document and replaces it with BBCode text nodes.
|
||||
*
|
||||
* @param DOMDocument $doc
|
||||
* @param string $tag HTML tag name
|
||||
* @param array $attributes Array of attributes to match and optionally use the value from
|
||||
* @param string $startbb BBCode tag opening
|
||||
* @param string $endbb BBCode tag closing
|
||||
* @param bool $ignoreChildren If set to false, the HTML tag children will be appended as text inside the BBCode tag
|
||||
* Otherwise, they will be entirely ignored. Useful for simple BBCode that draw their
|
||||
* inner value from an attribute value and disregard the tag children.
|
||||
* @return bool Whether a replacement was done
|
||||
*/
|
||||
private static function tagToBBCodeSub(DOMDocument $doc, string $tag, array $attributes, string $startbb, string $endbb, bool $ignoreChildren = false)
|
||||
{
|
||||
$savestart = str_replace('$', '\x01', $startbb);
|
||||
$replace = false;
|
||||
|
@ -98,7 +116,7 @@ class HTML
|
|||
|
||||
$node->parentNode->insertBefore($StartCode, $node);
|
||||
|
||||
if ($node->hasChildNodes()) {
|
||||
if (!$ignoreChildren && $node->hasChildNodes()) {
|
||||
/** @var \DOMNode $child */
|
||||
foreach ($node->childNodes as $key => $child) {
|
||||
/* Remove empty text nodes at the start or at the end of the children list */
|
||||
|
@ -296,14 +314,14 @@ class HTML
|
|||
self::tagToBBCode($doc, 'a', ['href' => '/mailto:(.+)/'], '[mail=$1]', '[/mail]');
|
||||
self::tagToBBCode($doc, 'a', ['href' => '/(.+)/'], '[url=$1]', '[/url]');
|
||||
|
||||
self::tagToBBCode($doc, 'img', ['src' => '/(.+)/', 'alt' => '/(.+)/'], '[img=$1]$2', '[/img]');
|
||||
self::tagToBBCode($doc, 'img', ['src' => '/(.+)/', 'width' => '/(\d+)/', 'height' => '/(\d+)/'], '[img=$2x$3]$1', '[/img]');
|
||||
self::tagToBBCode($doc, 'img', ['src' => '/(.+)/'], '[img]$1', '[/img]');
|
||||
self::tagToBBCode($doc, 'img', ['src' => '/(.+)/', 'alt' => '/(.+)/'], '[img=$1]$2', '[/img]', true);
|
||||
self::tagToBBCode($doc, 'img', ['src' => '/(.+)/', 'width' => '/(\d+)/', 'height' => '/(\d+)/'], '[img=$2x$3]$1', '[/img]', true);
|
||||
self::tagToBBCode($doc, 'img', ['src' => '/(.+)/'], '[img]$1', '[/img]', true);
|
||||
|
||||
|
||||
self::tagToBBCode($doc, 'video', ['src' => '/(.+)/'], '[video]$1', '[/video]');
|
||||
self::tagToBBCode($doc, 'audio', ['src' => '/(.+)/'], '[audio]$1', '[/audio]');
|
||||
self::tagToBBCode($doc, 'iframe', ['src' => '/(.+)/'], '[iframe]$1', '[/iframe]');
|
||||
self::tagToBBCode($doc, 'video', ['src' => '/(.+)/'], '[video]$1', '[/video]', true);
|
||||
self::tagToBBCode($doc, 'audio', ['src' => '/(.+)/'], '[audio]$1', '[/audio]', true);
|
||||
self::tagToBBCode($doc, 'iframe', ['src' => '/(.+)/'], '[iframe]$1', '[/iframe]', true);
|
||||
|
||||
self::tagToBBCode($doc, 'key', [], '[code]', '[/code]');
|
||||
self::tagToBBCode($doc, 'code', [], '[code]', '[/code]');
|
||||
|
@ -854,8 +872,8 @@ class HTML
|
|||
$url = '';
|
||||
}
|
||||
|
||||
return Renderer::replaceMacros(Renderer::getMarkupTemplate(($textmode)?'micropro_txt.tpl':'micropro_img.tpl'), [
|
||||
'$click' => defaults($contact, 'click', ''),
|
||||
return Renderer::replaceMacros(Renderer::getMarkupTemplate($textmode ? 'micropro_txt.tpl' : 'micropro_img.tpl'), [
|
||||
'$click' => $contact['click'] ?? '',
|
||||
'$class' => $class,
|
||||
'$url' => $url,
|
||||
'$photo' => ProxyUtils::proxifyUrl($contact['thumb'], false, ProxyUtils::SIZE_THUMB),
|
||||
|
@ -875,9 +893,9 @@ class HTML
|
|||
* @param bool $aside Display the search widgit aside.
|
||||
*
|
||||
* @return string Formatted HTML.
|
||||
* @throws \Friendica\Network\HTTPException\InternalServerErrorException
|
||||
* @throws \Exception
|
||||
*/
|
||||
public static function search($s, $id = 'search-box', $url = 'search', $aside = true)
|
||||
public static function search($s, $id = 'search-box', $aside = true)
|
||||
{
|
||||
$mode = 'text';
|
||||
|
||||
|
@ -887,24 +905,25 @@ class HTML
|
|||
$save_label = $mode === 'text' ? L10n::t('Save') : L10n::t('Follow');
|
||||
|
||||
$values = [
|
||||
'$s' => $s,
|
||||
'$id' => $id,
|
||||
'$action_url' => $url,
|
||||
'$search_label' => L10n::t('Search'),
|
||||
'$save_label' => $save_label,
|
||||
'$savedsearch' => 'savedsearch',
|
||||
'$search_hint' => L10n::t('@name, !forum, #tags, content'),
|
||||
'$mode' => $mode
|
||||
];
|
||||
'$s' => $s,
|
||||
'$q' => urlencode($s),
|
||||
'$id' => $id,
|
||||
'$search_label' => L10n::t('Search'),
|
||||
'$save_label' => $save_label,
|
||||
'$search_hint' => L10n::t('@name, !forum, #tags, content'),
|
||||
'$mode' => $mode,
|
||||
'$return_url' => urlencode('search?q=' . urlencode($s)),
|
||||
];
|
||||
|
||||
if (!$aside) {
|
||||
$values['$searchoption'] = [
|
||||
L10n::t("Full Text"),
|
||||
L10n::t("Tags"),
|
||||
L10n::t("Contacts")];
|
||||
$values['$search_options'] = [
|
||||
'fulltext' => L10n::t('Full Text'),
|
||||
'tags' => L10n::t('Tags'),
|
||||
'contacts' => L10n::t('Contacts')
|
||||
];
|
||||
|
||||
if (Config::get('system', 'poco_local_search')) {
|
||||
$values['$searchoption'][] = L10n::t("Forums");
|
||||
$values['$searchoption']['forums'] = L10n::t('Forums');
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -11,6 +11,7 @@ use Friendica\Core\PConfig;
|
|||
use Friendica\Core\Protocol;
|
||||
use Friendica\Core\Renderer;
|
||||
use Friendica\Core\System;
|
||||
use Friendica\Core\Session;
|
||||
use Friendica\Database\DBA;
|
||||
use Friendica\Model\Contact;
|
||||
use Friendica\Model\FileTag;
|
||||
|
@ -337,16 +338,9 @@ class Widget
|
|||
return;
|
||||
}
|
||||
|
||||
$cid = $zcid = 0;
|
||||
$zcid = 0;
|
||||
|
||||
if (!empty($_SESSION['remote'])) {
|
||||
foreach ($_SESSION['remote'] as $visitor) {
|
||||
if ($visitor['uid'] == $profile_uid) {
|
||||
$cid = $visitor['cid'];
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
$cid = Session::getRemoteContactID($profile_uid);
|
||||
|
||||
if (!$cid) {
|
||||
if (Profile::getMyURL()) {
|
||||
|
|
|
@ -57,7 +57,7 @@ class CalendarExport
|
|||
|
||||
// $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 = defaults($a->data['user'], 'nickname', $a->user['nickname']);
|
||||
$user = ($a->data['user']['nickname'] ?? '') ?: $a->user['nickname'];
|
||||
|
||||
$tpl = Renderer::getMarkupTemplate("widget/events.tpl");
|
||||
$return = Renderer::replaceMacros($tpl, [
|
||||
|
|
|
@ -61,7 +61,7 @@ class ContactBlock
|
|||
|
||||
if ($total) {
|
||||
// Only show followed for personal accounts, followers for pages
|
||||
if (defaults($profile, 'account-type', User::ACCOUNT_TYPE_PERSON) == User::ACCOUNT_TYPE_PERSON) {
|
||||
if ((($profile['account-type'] ?? '') ?: User::ACCOUNT_TYPE_PERSON) == User::ACCOUNT_TYPE_PERSON) {
|
||||
$rel = [Contact::SHARING, Contact::FRIEND];
|
||||
} else {
|
||||
$rel = [Contact::FOLLOWER, Contact::FRIEND];
|
||||
|
|
47
src/Content/Widget/SavedSearches.php
Normal file
47
src/Content/Widget/SavedSearches.php
Normal file
|
@ -0,0 +1,47 @@
|
|||
<?php
|
||||
|
||||
namespace Friendica\Content\Widget;
|
||||
|
||||
use Friendica\Core\L10n;
|
||||
use Friendica\Core\Renderer;
|
||||
use Friendica\Database\DBA;
|
||||
|
||||
class SavedSearches
|
||||
{
|
||||
/**
|
||||
* @param string $return_url
|
||||
* @param string $search
|
||||
* @return string
|
||||
* @throws \Exception
|
||||
*/
|
||||
public static function getHTML($return_url, $search = '')
|
||||
{
|
||||
$o = '';
|
||||
|
||||
$saved_searches = DBA::select('search', ['id', 'term'], ['uid' => local_user()]);
|
||||
if (DBA::isResult($saved_searches)) {
|
||||
$saved = [];
|
||||
foreach ($saved_searches as $saved_search) {
|
||||
$saved[] = [
|
||||
'id' => $saved_search['id'],
|
||||
'term' => $saved_search['term'],
|
||||
'encodedterm' => urlencode($saved_search['term']),
|
||||
'delete' => L10n::t('Remove term'),
|
||||
'selected' => $search == $saved_search['term'],
|
||||
];
|
||||
}
|
||||
|
||||
$tpl = Renderer::getMarkupTemplate('widget/saved_searches.tpl');
|
||||
|
||||
$o = Renderer::replaceMacros($tpl, [
|
||||
'$title' => L10n::t('Saved Searches'),
|
||||
'$add' => '',
|
||||
'$searchbox' => '',
|
||||
'$saved' => $saved,
|
||||
'$return_url' => urlencode($return_url),
|
||||
]);
|
||||
}
|
||||
|
||||
return $o;
|
||||
}
|
||||
}
|
|
@ -11,6 +11,7 @@ use Friendica\Content\Feature;
|
|||
use Friendica\Database\DBA;
|
||||
use Friendica\Model\Contact;
|
||||
use Friendica\Model\GContact;
|
||||
use Friendica\Core\Session;
|
||||
use Friendica\Util\Network;
|
||||
|
||||
/**
|
||||
|
@ -40,12 +41,12 @@ class ACL extends BaseObject
|
|||
|
||||
$networks = null;
|
||||
|
||||
$size = defaults($options, 'size', 4);
|
||||
$size = ($options['size'] ?? 0) ?: 4;
|
||||
$mutual = !empty($options['mutual_friends']);
|
||||
$single = !empty($options['single']) && empty($options['multiple']);
|
||||
$exclude = defaults($options, 'exclude', false);
|
||||
$exclude = $options['exclude'] ?? false;
|
||||
|
||||
switch (defaults($options, 'networks', Protocol::PHANTOM)) {
|
||||
switch (($options['networks'] ?? '') ?: Protocol::PHANTOM) {
|
||||
case 'DFRN_ONLY':
|
||||
$networks = [Protocol::DFRN];
|
||||
break;
|
||||
|
@ -225,13 +226,13 @@ class ACL extends BaseObject
|
|||
|
||||
$acl_regex = '/<([0-9]+)>/i';
|
||||
|
||||
preg_match_all($acl_regex, defaults($user, 'allow_cid', ''), $matches);
|
||||
preg_match_all($acl_regex, $user['allow_cid'] ?? '', $matches);
|
||||
$allow_cid = $matches[1];
|
||||
preg_match_all($acl_regex, defaults($user, 'allow_gid', ''), $matches);
|
||||
preg_match_all($acl_regex, $user['allow_gid'] ?? '', $matches);
|
||||
$allow_gid = $matches[1];
|
||||
preg_match_all($acl_regex, defaults($user, 'deny_cid', ''), $matches);
|
||||
preg_match_all($acl_regex, $user['deny_cid'] ?? '', $matches);
|
||||
$deny_cid = $matches[1];
|
||||
preg_match_all($acl_regex, defaults($user, 'deny_gid', ''), $matches);
|
||||
preg_match_all($acl_regex, $user['deny_gid'] ?? '', $matches);
|
||||
$deny_gid = $matches[1];
|
||||
|
||||
// Reformats the ACL data so that it is accepted by the JS frontend
|
||||
|
@ -300,10 +301,10 @@ class ACL extends BaseObject
|
|||
'$showall' => L10n::t('Visible to everybody'),
|
||||
'$show' => L10n::t('show'),
|
||||
'$hide' => L10n::t('don\'t show'),
|
||||
'$allowcid' => json_encode(defaults($default_permissions, 'allow_cid', [])), // we need arrays for Javascript since we call .remove() and .push() on this values
|
||||
'$allowgid' => json_encode(defaults($default_permissions, 'allow_gid', [])),
|
||||
'$denycid' => json_encode(defaults($default_permissions, 'deny_cid', [])),
|
||||
'$denygid' => json_encode(defaults($default_permissions, 'deny_gid', [])),
|
||||
'$allowcid' => json_encode(($default_permissions['allow_cid'] ?? '') ?: []), // We need arrays for
|
||||
'$allowgid' => json_encode(($default_permissions['allow_gid'] ?? '') ?: []), // Javascript since we
|
||||
'$denycid' => json_encode(($default_permissions['deny_cid'] ?? '') ?: []), // call .remove() and
|
||||
'$denygid' => json_encode(($default_permissions['deny_gid'] ?? '') ?: []), // .push() on these values
|
||||
'$networks' => $show_jotnets,
|
||||
'$emailcc' => L10n::t('CC: email addresses'),
|
||||
'$emtitle' => L10n::t('Example: bob@example.com, mary@example.com'),
|
||||
|
@ -320,46 +321,4 @@ class ACL extends BaseObject
|
|||
|
||||
return $o;
|
||||
}
|
||||
|
||||
/**
|
||||
* Searching for global contacts for autocompletion
|
||||
*
|
||||
* @brief Searching for global contacts for autocompletion
|
||||
* @param string $search Name or part of a name or nick
|
||||
* @param string $mode Search mode (e.g. "community")
|
||||
* @return array with the search results
|
||||
* @throws \Friendica\Network\HTTPException\InternalServerErrorException
|
||||
*/
|
||||
public static function contactAutocomplete($search, $mode)
|
||||
{
|
||||
if (Config::get('system', 'block_public') && !local_user() && !remote_user()) {
|
||||
return [];
|
||||
}
|
||||
|
||||
// don't search if search term has less than 2 characters
|
||||
if (!$search || mb_strlen($search) < 2) {
|
||||
return [];
|
||||
}
|
||||
|
||||
if (substr($search, 0, 1) === '@') {
|
||||
$search = substr($search, 1);
|
||||
}
|
||||
|
||||
// check if searching in the local global contact table is enabled
|
||||
if (Config::get('system', 'poco_local_search')) {
|
||||
$return = GContact::searchByName($search, $mode);
|
||||
} else {
|
||||
$p = defaults($_GET, 'page', 1) != 1 ? '&p=' . defaults($_GET, 'page', 1) : '';
|
||||
|
||||
$curlResult = Network::curl(get_server() . '/lsearch?f=' . $p . '&search=' . urlencode($search));
|
||||
if ($curlResult->isSuccess()) {
|
||||
$lsearch = json_decode($curlResult->getBody(), true);
|
||||
if (!empty($lsearch['results'])) {
|
||||
$return = $lsearch['results'];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return defaults($return, []);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* @file /src/Core/Authentication.php
|
||||
*/
|
||||
|
@ -10,8 +11,8 @@ use Friendica\BaseObject;
|
|||
use Friendica\Network\HTTPException\ForbiddenException;
|
||||
|
||||
/**
|
||||
* Handle Authentification, Session and Cookies
|
||||
*/
|
||||
* Handle Authentification, Session and Cookies
|
||||
*/
|
||||
class Authentication extends BaseObject
|
||||
{
|
||||
/**
|
||||
|
@ -24,9 +25,11 @@ class Authentication extends BaseObject
|
|||
*/
|
||||
public static function getCookieHashForUser($user)
|
||||
{
|
||||
return(hash("sha256", Config::get("system", "site_prvkey") .
|
||||
$user["prvkey"] .
|
||||
$user["password"]));
|
||||
return hash_hmac(
|
||||
"sha256",
|
||||
hash_hmac("sha256", $user["password"], $user["prvkey"]),
|
||||
Config::get("system", "site_prvkey")
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -43,9 +46,11 @@ class Authentication extends BaseObject
|
|||
}
|
||||
|
||||
if ($user) {
|
||||
$value = json_encode(["uid" => $user["uid"],
|
||||
$value = json_encode([
|
||||
"uid" => $user["uid"],
|
||||
"hash" => self::getCookieHashForUser($user),
|
||||
"ip" => defaults($_SERVER, 'REMOTE_ADDR', '0.0.0.0')]);
|
||||
"ip" => ($_SERVER['REMOTE_ADDR'] ?? '') ?: '0.0.0.0'
|
||||
]);
|
||||
} else {
|
||||
$value = "";
|
||||
}
|
||||
|
@ -88,4 +93,3 @@ class Authentication extends BaseObject
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue