mirror of
https://framagit.org/hubzilla/core.git
synced 2026-06-21 17:07:39 -04:00
Compare commits
379 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ef2448e17e | ||
|
|
99a5cf1ad4 | ||
|
|
bc3113ae16 | ||
|
|
fb475da008 | ||
|
|
d5fc3ad646 | ||
|
|
8b7da6e318 | ||
|
|
ed208c4bcc | ||
|
|
6ab65519a0 | ||
|
|
4549bc89ec | ||
|
|
a0430f91bd | ||
|
|
624bb1db8d | ||
|
|
9f522bbe6c | ||
|
|
931da3b4f7 | ||
|
|
5a25fd54a4 | ||
|
|
9f0f4c50a4 | ||
|
|
0bf3d31578 | ||
|
|
8ca293c3e4 | ||
|
|
ba0c877ffc | ||
|
|
b8e00c2dc9 | ||
|
|
2dd48898a8 | ||
|
|
66fc807655 | ||
|
|
653eb2909b | ||
|
|
72520a2dd9 | ||
|
|
a7d4666a70 | ||
|
|
13476d5003 | ||
|
|
879cdedec3 | ||
|
|
05bd2a1f9e | ||
|
|
c49d1547c4 | ||
|
|
ad35363c2e | ||
|
|
b3f70140e5 | ||
|
|
2f21dc50b4 | ||
|
|
cbd8c2483b | ||
|
|
03475bfb15 | ||
|
|
bb9411e7dc | ||
|
|
bce4e2d022 | ||
|
|
7cfc14fef7 | ||
|
|
f220cf3173 | ||
|
|
725359b1aa | ||
|
|
937d6cb1ef | ||
|
|
118a5edebc | ||
|
|
1b4333e8d9 | ||
|
|
d66a0b50e9 | ||
|
|
1d56b9a1bb | ||
|
|
96535ee4df | ||
|
|
b55f314d7e | ||
|
|
480862d714 | ||
|
|
990a3af2a7 | ||
|
|
1f5a23143a | ||
|
|
fcfb9e9758 | ||
|
|
9beee689ce | ||
|
|
2c388c3833 | ||
|
|
1a75066616 | ||
|
|
3dfb0bcae9 | ||
|
|
9ac0b77e92 | ||
|
|
6421a32520 | ||
|
|
fdcae52740 | ||
|
|
a8752844ef | ||
|
|
e04ce5028e | ||
|
|
f2c4d80ac0 | ||
|
|
d8a6226805 | ||
|
|
fedf60a32c | ||
|
|
b3548fefc1 | ||
|
|
febd64c527 | ||
|
|
d67a5c5070 | ||
|
|
aefe7ddd8f | ||
|
|
254dea7558 | ||
|
|
b1550f7922 | ||
|
|
2d07c3e45d | ||
|
|
e5f3406cb5 | ||
|
|
185ddf1eaf | ||
|
|
2734335869 | ||
|
|
0132c4e36e | ||
|
|
7dee47183d | ||
|
|
9c4988c297 | ||
|
|
3bfbc70587 | ||
|
|
34858fce1c | ||
|
|
b47dab0ee9 | ||
|
|
6eeb033b96 | ||
|
|
0679cb8e00 | ||
|
|
3abc9ee387 | ||
|
|
2e9211cf41 | ||
|
|
40377796ed | ||
|
|
fedad7f31a | ||
|
|
d2a34e0107 | ||
|
|
769c822568 | ||
|
|
c452a621fe | ||
|
|
231ab95ef6 | ||
|
|
7c01b59ffb | ||
|
|
e79668ddf4 | ||
|
|
dc6b6fc353 | ||
|
|
34ea58cf38 | ||
|
|
199168c318 | ||
|
|
063d4bbd7d | ||
|
|
29fd9b9d64 | ||
|
|
c301baafb5 | ||
|
|
4282672201 | ||
|
|
ae705dd865 | ||
|
|
f0fa2ce171 | ||
|
|
d6a9a9927c | ||
|
|
40b4636858 | ||
|
|
97fe499b63 | ||
|
|
e0915cffda | ||
|
|
7602de85c3 | ||
|
|
0787817eb8 | ||
|
|
e030648957 | ||
|
|
b815935fd7 | ||
|
|
a5000ba311 | ||
|
|
5e2bb874c8 | ||
|
|
fcb5a7f645 | ||
|
|
b8c6520abb | ||
|
|
1d99c3d3f7 | ||
|
|
5e112b395d | ||
|
|
d1a8e7813a | ||
|
|
a0582fec12 | ||
|
|
2cd3a7b3f0 | ||
|
|
47448b11cd | ||
|
|
e63f043841 | ||
|
|
33dd0c83e3 | ||
|
|
32dad136f8 | ||
|
|
073ed52538 | ||
|
|
eef828cf3e | ||
|
|
d0b5930a3a | ||
|
|
c66ad9ccc8 | ||
|
|
9959a15c8e | ||
|
|
f0e4b4dc84 | ||
|
|
f62f808368 | ||
|
|
530a521679 | ||
|
|
50782dfb83 | ||
|
|
27a142d5c5 | ||
|
|
6d00b2e63d | ||
|
|
7be1415a3a | ||
|
|
0a30b12f7d | ||
|
|
3058cbfbb2 | ||
|
|
ae780c977b | ||
|
|
e146a67f4b | ||
|
|
162d86983a | ||
|
|
8534366a31 | ||
|
|
d1c6617dc9 | ||
|
|
6f994709b9 | ||
|
|
55d833a9c8 | ||
|
|
8ba4745097 | ||
|
|
940a0c8b10 | ||
|
|
8928b24e23 | ||
|
|
ae9a9191f3 | ||
|
|
cb553bd016 | ||
|
|
a75c61d71e | ||
|
|
c1dc16a89d | ||
|
|
66436ce4a2 | ||
|
|
62b1ff4ba1 | ||
|
|
304d136437 | ||
|
|
1b4268b9b0 | ||
|
|
a7968e6525 | ||
|
|
e59cc3d404 | ||
|
|
3a2d126877 | ||
|
|
ee3d6fcfee | ||
|
|
09d929bd56 | ||
|
|
bd55ae15f2 | ||
|
|
2ca80118bf | ||
|
|
04eb20ac35 | ||
|
|
f299391aa1 | ||
|
|
c334fc9d22 | ||
|
|
8520088376 | ||
|
|
9ada8518dc | ||
|
|
f0c09b374c | ||
|
|
c5f33baf27 | ||
|
|
2efcdd92e0 | ||
|
|
38fda98b6d | ||
|
|
f9fd195c24 | ||
|
|
01e82090b2 | ||
|
|
39602ede37 | ||
|
|
98a311ae40 | ||
|
|
5c398b3e8f | ||
|
|
83e585ee9b | ||
|
|
e386499bfa | ||
|
|
4552630bf8 | ||
|
|
2d8065a780 | ||
|
|
b94da93c74 | ||
|
|
695045f197 | ||
|
|
376733bd08 | ||
|
|
4c7c5137c5 | ||
|
|
930b9820f2 | ||
|
|
b2fa63f2c8 | ||
|
|
1390e1db39 | ||
|
|
e7768ae954 | ||
|
|
38d977e546 | ||
|
|
3e38a24f0a | ||
|
|
0784cd593a | ||
|
|
9c5d2ee563 | ||
|
|
be5f7c2e67 | ||
|
|
0d0f73fb67 | ||
|
|
680be6cfec | ||
|
|
2ab3d072b0 | ||
|
|
943ecff623 | ||
|
|
03973f5d1d | ||
|
|
c42a0fa9b6 | ||
|
|
61522ed31d | ||
|
|
29a527426a | ||
|
|
62ac0ff21e | ||
|
|
a41c7caa18 | ||
|
|
b3ca31bce7 | ||
|
|
b02f6a1dae | ||
|
|
d35609f33a | ||
|
|
8c19ab8f9f | ||
|
|
30ae198b89 | ||
|
|
bddeab3ac1 | ||
|
|
591349ee74 | ||
|
|
9081a25e64 | ||
|
|
1beadfc6e7 | ||
|
|
f4af532c5a | ||
|
|
76eb1a9d78 | ||
|
|
14a2790dcb | ||
|
|
46f54db197 | ||
|
|
4ffd7587a9 | ||
|
|
c48c62c7a8 | ||
|
|
9e7fd20ade | ||
|
|
efa1d381ba | ||
|
|
740fa058aa | ||
|
|
37f56e1efd | ||
|
|
6294be371a | ||
|
|
bee7549a1e | ||
|
|
db14dbacc9 | ||
|
|
27058e6297 | ||
|
|
b41175e0e2 | ||
|
|
eeea3251ad | ||
|
|
34ffff3947 | ||
|
|
65ed3818ec | ||
|
|
c8417df6f1 | ||
|
|
dc3be7ecf7 | ||
|
|
cf3c0b593b | ||
|
|
34f64148e8 | ||
|
|
fc5dad1983 | ||
|
|
c3c40548b9 | ||
|
|
0e2e932102 | ||
|
|
6930c4e23b | ||
|
|
01b9f2dfcf | ||
|
|
0cc6f66a26 | ||
|
|
d384f55dd1 | ||
|
|
1893368aa5 | ||
|
|
a520063265 | ||
|
|
1e171a72a0 | ||
|
|
5b1a0d93b9 | ||
|
|
7e04662a9c | ||
|
|
a804549781 | ||
|
|
2a60f1cc6e | ||
|
|
2ddff785e5 | ||
|
|
38882efb5c | ||
|
|
6f7786b068 | ||
|
|
0819141f03 | ||
|
|
329ef5049f | ||
|
|
34bb8c65d6 | ||
|
|
575ccae6f9 | ||
|
|
486be87e33 | ||
|
|
c0350861ef | ||
|
|
a7ec1805e3 | ||
|
|
4b06bc552f | ||
|
|
76ee7b7eea | ||
|
|
04b1e7e34f | ||
|
|
17dbb156e1 | ||
|
|
135117c637 | ||
|
|
d3348f7855 | ||
|
|
39bbcb66c8 | ||
|
|
d45e8e4d20 | ||
|
|
d65052c1ac | ||
|
|
2fbc42753f | ||
|
|
4195865965 | ||
|
|
de3f6fbeba | ||
|
|
6a377120bd | ||
|
|
502226b0a6 | ||
|
|
78206b48f4 | ||
|
|
dc3cec06ca | ||
|
|
5a7688e099 | ||
|
|
c721f01c76 | ||
|
|
463806822c | ||
|
|
b74c2f001d | ||
|
|
9fc7a8b626 | ||
|
|
3ffd92a6c3 | ||
|
|
29b02e5329 | ||
|
|
97584e046f | ||
|
|
09d2fce85d | ||
|
|
fc3060cb29 | ||
|
|
9804a67165 | ||
|
|
21eddefa41 | ||
|
|
9b62e7eedb | ||
|
|
bf30cfd8a4 | ||
|
|
139ffae367 | ||
|
|
51a48cc264 | ||
|
|
abbca12565 | ||
|
|
9e9d96a2ec | ||
|
|
615c9f1cbe | ||
|
|
7d75d0cfbd | ||
|
|
5468de2c6a | ||
|
|
6d8aabab23 | ||
|
|
e74359fcfe | ||
|
|
53c842c614 | ||
|
|
23ececeb34 | ||
|
|
521c9eb566 | ||
|
|
35877b1382 | ||
|
|
c531287170 | ||
|
|
8e79a81b88 | ||
|
|
b95ceb301f | ||
|
|
76a94495c4 | ||
|
|
b6b2299b4e | ||
|
|
34ddea87d3 | ||
|
|
3d318542cb | ||
|
|
4a8c3cdc61 | ||
|
|
c0b6f2d95f | ||
|
|
9ca7fccab8 | ||
|
|
d91fcfc866 | ||
|
|
29b53f3b9d | ||
|
|
30987095c7 | ||
|
|
43b93de570 | ||
|
|
5b310cf315 | ||
|
|
a1c2a57ea6 | ||
|
|
34bf8f1133 | ||
|
|
c708ec577e | ||
|
|
c185685f2d | ||
|
|
daee5b3477 | ||
|
|
5d0346ee30 | ||
|
|
85ad5355cf | ||
|
|
4c8b84633a | ||
|
|
c0dd4d748d | ||
|
|
c94f25570b | ||
|
|
ffa5e08832 | ||
|
|
63243c8e04 | ||
|
|
21c4ec2de0 | ||
|
|
a8d87af418 | ||
|
|
7b084a065e | ||
|
|
47f6b202e5 | ||
|
|
f588d8379b | ||
|
|
58827e130b | ||
|
|
d702334604 | ||
|
|
b04aa799e3 | ||
|
|
e113f6cb9d | ||
|
|
bc13b7eb72 | ||
|
|
f50b395da6 | ||
|
|
a0e8e40f1c | ||
|
|
cb6055c1b8 | ||
|
|
25424c16e4 | ||
|
|
99dcdee67a | ||
|
|
99928f1aea | ||
|
|
1740ae2104 | ||
|
|
d8372f8433 | ||
|
|
2a15d2c421 | ||
|
|
bacf19688f | ||
|
|
31fbdcf6c5 | ||
|
|
c8818cb7b3 | ||
|
|
eb20789821 | ||
|
|
c90862217e | ||
|
|
df87d6feeb | ||
|
|
6c808abcfc | ||
|
|
f1822bdfab | ||
|
|
c3428acd80 | ||
|
|
d619192b22 | ||
|
|
5bdc713afe | ||
|
|
46eff1c937 | ||
|
|
76e1ea1c02 | ||
|
|
755076a8e5 | ||
|
|
b49f7b8b34 | ||
|
|
c4dd8885e4 | ||
|
|
4c82952b58 | ||
|
|
0da69cb9c7 | ||
|
|
36e244060c | ||
|
|
b13a9f57af | ||
|
|
0aa67ad7f9 | ||
|
|
195a3a6827 | ||
|
|
38ecff1220 | ||
|
|
67e64287af | ||
|
|
b022703b0b | ||
|
|
e8069c0d93 | ||
|
|
7a1c6b64c2 | ||
|
|
8250cb1e8d | ||
|
|
ffe2c4d42b | ||
|
|
f06c970628 | ||
|
|
99bce46b32 | ||
|
|
f711913778 | ||
|
|
a8ac231667 | ||
|
|
f7c8791a6d | ||
|
|
7acc775c91 | ||
|
|
481ecee9e8 |
101
.gitlab-ci.yml
101
.gitlab-ci.yml
@@ -1,7 +1,9 @@
|
||||
# Select image from https://hub.docker.com/_/php/
|
||||
#image: php:7.3
|
||||
# Use a prepared Hubzilla image to optimise pipeline duration
|
||||
image: registry.gitlab.com/dawnbreak/hubzilla/core:php7.3
|
||||
# image: registry.gitlab.com/dawnbreak/hubzilla/core:php7.3
|
||||
|
||||
image: php:8.0
|
||||
|
||||
stages:
|
||||
- test
|
||||
@@ -35,7 +37,12 @@ before_script:
|
||||
- if [ -f /usr/local/etc/php/conf.d/z_prod.ini ]; then mv /usr/local/etc/php/conf.d/z_prod.ini /usr/local/etc/php/conf.d/z_prod.ini.off; fi
|
||||
# Install & enable Xdebug for code coverage reports
|
||||
- pecl install xdebug
|
||||
- apt-get update
|
||||
- apt-get install zip unzip libjpeg-dev libpng-dev -yqq
|
||||
- docker-php-ext-enable xdebug
|
||||
- docker-php-ext-install gd
|
||||
|
||||
|
||||
# Install composer
|
||||
- curl -sS https://getcomposer.org/installer | php
|
||||
# Install dev libraries from composer
|
||||
@@ -43,31 +50,38 @@ before_script:
|
||||
# php.ini settings
|
||||
- echo 'xdebug.mode=coverage' >> /usr/local/etc/php/php.ini
|
||||
|
||||
# hidden job definition with template for MySQL/MariaDB
|
||||
.job_template_mysql: &job_definition_mysql
|
||||
# hidden job definition with template for PHP
|
||||
.job_template_php: &job_definition_php
|
||||
stage: test
|
||||
script:
|
||||
- echo "USE $MYSQL_DATABASE; $(cat ./install/schema_mysql.sql)" | mysql --user=root --password="$MYSQL_ROOT_PASSWORD" --host=mysql "$MYSQL_DATABASE"
|
||||
- echo "SHOW DATABASES;" | mysql --user=root --password="$MYSQL_ROOT_PASSWORD" --host=mysql "$MYSQL_DATABASE"
|
||||
- echo "USE $MYSQL_DATABASE; SHOW TABLES;" | mysql --user=root --password="$MYSQL_ROOT_PASSWORD" --host=mysql "$MYSQL_DATABASE"
|
||||
- vendor/bin/phpunit --configuration tests/phpunit.xml --coverage-text
|
||||
|
||||
|
||||
# hidden job definition with template for MySQL/MariaDB
|
||||
#.job_template_mysql: &job_definition_mysql
|
||||
# stage: test
|
||||
# script:
|
||||
# - echo "USE $MYSQL_DATABASE; $(cat ./install/schema_mysql.sql)" | mysql --user=root --password="$MYSQL_ROOT_PASSWORD" --host=mysql "$MYSQL_DATABASE"
|
||||
# - echo "SHOW DATABASES;" | mysql --user=root --password="$MYSQL_ROOT_PASSWORD" --host=mysql "$MYSQL_DATABASE"
|
||||
# - echo "USE $MYSQL_DATABASE; SHOW TABLES;" | mysql --user=root --password="$MYSQL_ROOT_PASSWORD" --host=mysql "$MYSQL_DATABASE"
|
||||
# - vendor/bin/phpunit --configuration tests/phpunit.xml --coverage-text
|
||||
|
||||
# hidden job definition with template for PostgreSQL
|
||||
.job_template_postgres: &job_definition_postgres
|
||||
stage: test
|
||||
services:
|
||||
- postgres:latest
|
||||
script:
|
||||
- export PGPASSWORD=$POSTGRES_PASSWORD
|
||||
- psql --version
|
||||
- psql -h "postgres" -U "$POSTGRES_USER" -d "$POSTGRES_DB" -c "SELECT VERSION();"
|
||||
#.job_template_postgres: &job_definition_postgres
|
||||
# stage: test
|
||||
# services:
|
||||
# - postgres:latest
|
||||
# script:
|
||||
# - export PGPASSWORD=$POSTGRES_PASSWORD
|
||||
# - psql --version
|
||||
# - psql -h "postgres" -U "$POSTGRES_USER" -d "$POSTGRES_DB" -c "SELECT VERSION();"
|
||||
# Import hubzilla's DB schema
|
||||
- psql -h "postgres" -U "$POSTGRES_USER" -v ON_ERROR_STOP=1 --quiet "$POSTGRES_DB" < ./install/schema_postgres.sql
|
||||
# - psql -h "postgres" -U "$POSTGRES_USER" -v ON_ERROR_STOP=1 --quiet "$POSTGRES_DB" < ./install/schema_postgres.sql
|
||||
# Show databases and relations/tables of hubzilla's database
|
||||
#- psql -h "postgres" -U "$POSTGRES_USER" -l
|
||||
#- psql -h "postgres" -U "$POSTGRES_USER" -d "$POSTGRES_DB" -c "\dt;"
|
||||
# Run the actual tests
|
||||
- vendor/bin/phpunit --configuration tests/phpunit-pgsql.xml --testdox
|
||||
# - vendor/bin/phpunit --configuration tests/phpunit-pgsql.xml --testdox
|
||||
|
||||
# hidden job definition with artifacts config template
|
||||
.artifacts_template:
|
||||
@@ -82,36 +96,41 @@ before_script:
|
||||
- tests/results/
|
||||
|
||||
|
||||
# PHP7.3 with MySQL 5.7
|
||||
php7.3_mysql5.7:
|
||||
<<: *job_definition_mysql
|
||||
services:
|
||||
- mysql:5.7
|
||||
# PHP8.0
|
||||
php8.0:
|
||||
<<: *job_definition_php
|
||||
|
||||
# PHP8.0 with MySQL 5.7
|
||||
#php8.0_mysql5.7:
|
||||
# <<: *job_definition_mysql
|
||||
# services:
|
||||
# - mysql:5.7
|
||||
|
||||
|
||||
# PHP7.3 with MySQL 8 (latest)
|
||||
php7.3_mysql8:
|
||||
<<: *job_definition_mysql
|
||||
services:
|
||||
- name: mysql:8
|
||||
command: ["--default-authentication-plugin=mysql_native_password"]
|
||||
# PHP8.0 with MySQL 8 (latest)
|
||||
#php8.0_mysql8:
|
||||
# <<: *job_definition_mysql
|
||||
# services:
|
||||
# - name: mysql:8
|
||||
# command: ["--default-authentication-plugin=mysql_native_password"]
|
||||
|
||||
|
||||
# PHP7.3 with MariaDB 10.2
|
||||
php7.3_mariadb10.2:
|
||||
<<: *job_definition_mysql
|
||||
services:
|
||||
- name: mariadb:10.2
|
||||
alias: mysql
|
||||
# PHP8.0 with MariaDB 10.2
|
||||
#php8.0_mariadb10.2:
|
||||
# <<: *job_definition_mysql
|
||||
# services:
|
||||
# - name: mariadb:10.2
|
||||
# alias: mysql
|
||||
|
||||
|
||||
# PHP7.3 with MariaDB 10.3 (latest)
|
||||
php7.3_mariadb10.3:
|
||||
<<: *job_definition_mysql
|
||||
image: registry.gitlab.com/dawnbreak/hubzilla/core:php7.3
|
||||
services:
|
||||
- name: mariadb:10.3
|
||||
alias: mysql
|
||||
# PHP8.0 with MariaDB 10.3 (latest)
|
||||
#php8.0_mariadb10.3:
|
||||
# <<: *job_definition_mysql
|
||||
# image: php:8.0
|
||||
#image: registry.gitlab.com/dawnbreak/hubzilla/core:php7.3
|
||||
# services:
|
||||
# - name: mariadb:10.3
|
||||
# alias: mysql
|
||||
|
||||
|
||||
# PHP7.3 with PostgreSQL latest (11)
|
||||
@@ -131,7 +150,7 @@ php7.3_mariadb10.3:
|
||||
pages:
|
||||
stage: deploy
|
||||
cache: {}
|
||||
image: php:7-cli-alpine
|
||||
image: php:8-cli-alpine
|
||||
before_script:
|
||||
- apk update
|
||||
- apk add doxygen ttf-freefont graphviz
|
||||
|
||||
200
CHANGELOG
200
CHANGELOG
@@ -1,3 +1,203 @@
|
||||
Hubzilla 7.8 (2022-10-10)
|
||||
- Updated spanish translations
|
||||
- Always update hubloc_updated timestamp if a hubloc is updated
|
||||
- Do better with re-installs in various situations
|
||||
- Update htconfig templates
|
||||
- Emit an info if an item is deleted manually (issue #1691)
|
||||
- Updated german translations
|
||||
- Make Activity::actor_store() fetch the actor object if none is provided
|
||||
- Check for various forms of as:Public for compatibility
|
||||
- Cleanup dark schema
|
||||
- Make use of CSS variables in redbasic
|
||||
- Implement link hover color in redbasic
|
||||
- Update to bootstrap version 5.2 which implements CSS variables
|
||||
|
||||
Bugfixes
|
||||
- Fix stream filter for polls and events does not work anymore (issue #1694)
|
||||
- Fix item menu display issue
|
||||
- Fix HQ widget displaying superblocked items
|
||||
- Fix mod poke
|
||||
- Fix link to article or card not processed correctly if umlauts are involved (issue #1687)
|
||||
- Fix mod siteinfo containing a dead link (issue #1690)
|
||||
- Fix permission issue when displaying things (issue #1686).
|
||||
- Fix check for existing profiles (issue #1688)
|
||||
- Fix modal missing for conversation settings
|
||||
- Fix missing closing div tag if there are no recent channel activities
|
||||
- Fix issue where an unkown diaspora author was not imported if the comment arrived via a relayed activity
|
||||
- Fix mangled xchan_url due to escape_tags()
|
||||
- Fix the AP url not decode bin mod search
|
||||
- Fix some php warnings
|
||||
|
||||
Addons
|
||||
- Wiki: move create_missing_page() from widget to module
|
||||
- Superblock: implement blocking for messages widget_item
|
||||
- Diaspora: fix verification of relayed comments and likes
|
||||
- Pubcrawl: make sure to store the attributedTo actor in announce activities
|
||||
- Diaspora: fix issue where an unkown author was not imported if the comment arrived via a relayed activity
|
||||
|
||||
|
||||
Hubzilla 7.6.1 (2022-08-07)
|
||||
Bugfixes
|
||||
- Fix attachments displayed in visible response activities
|
||||
- Fix wrong attribution in unseen like notifications
|
||||
|
||||
Addons
|
||||
- Cards: fix widget not implemented via pdl file (requires re-install)
|
||||
- Articles: fix widget not implemented via pdl file (requires re-install)
|
||||
- Wiki: fix widget not implemented via pdl file (requires re-install)
|
||||
|
||||
|
||||
Hubzilla 7.6 (2022-07-26)
|
||||
- Add filter rule to check for false condition
|
||||
- Implement HQ dashboard to display recently created content for various modules
|
||||
- Updated spanish translations
|
||||
- Implement a max oembed size which defaults to 1MB
|
||||
- Update composer libs
|
||||
|
||||
Addons
|
||||
- Cart: do not attempt oembed
|
||||
- Cards: implement channel_activities_widget for HQ dashboard
|
||||
- Articles: implement channel_activities_widget for HQ dashboard
|
||||
- Wiki: implement channel_activities_widget for HQ dashboard
|
||||
|
||||
Bugfixes
|
||||
- Fix language filter filtering ambigous results
|
||||
- Fix vcard-card background for dark schema
|
||||
- Fix contact edit dialog not displayed in chrome browser
|
||||
- Fix readability of category pills in dark schema
|
||||
- Fix opengraph images inside zmg opening tag
|
||||
- Fix oembed attempted for text previews
|
||||
|
||||
|
||||
Hubzilla 7.4 (2022-06-01)
|
||||
- Updated russian translations
|
||||
- Raise min PHP version to 8.0
|
||||
- Rewrite inbound attachment handling
|
||||
- Move photo flag feature from addon to core
|
||||
- Adjust default production php logging
|
||||
- Update composer libs
|
||||
- Add a hidden config to enable the hs2019 http signature algorithm
|
||||
- Allow starring of pubstream items
|
||||
- Update spanish translations
|
||||
- Add the title in forum post reshares if applicable
|
||||
- Implement inbound pleroma reactions
|
||||
- Add real name info to the navbar template data
|
||||
- Add the updated date to the icon url so that other platforms will pick it up on change
|
||||
- Move wiki from core to addon
|
||||
- Move articles from core to addon
|
||||
- Move cards from core to addon
|
||||
|
||||
Addons
|
||||
- Rendezvous: add missing default value to sql schema
|
||||
- Wiki: moved from core to addons
|
||||
- Articles: moved from core to addons
|
||||
- Cards: moved from core to addons
|
||||
- Photoflag: moved to core
|
||||
- Sse: fix issue where notifications were emited for created tasks
|
||||
|
||||
Bugfixes
|
||||
- Fix issue where inbound activitypub items lost image descriptions (issue 1679)
|
||||
- Fix issue where observer tags were not rendered correctly in event items (issue 1674)
|
||||
- Fix forum posts leaked into network stream
|
||||
- Fix tags not found in search if not logged in (issue 1677)
|
||||
- Fix dislikes causing stuck notifications (issue 1676)
|
||||
|
||||
|
||||
Hubzilla 7.2.2 (2022-04-26)
|
||||
- Fix item_verified not set due to data structure changes
|
||||
|
||||
|
||||
Hubzilla 7.2.1 (2022-04-25)
|
||||
- Fix changing profile image from new member widget - issue #1671
|
||||
- Fix regression with incoming poll answers from activitypub introduced in 7.2
|
||||
- Fix addons not removed from the DB when removed from the filesystem
|
||||
- Fix regression in attaching images for activitypub introduced in 7.2
|
||||
- Move activitypub addressing from core to the pubcrawl addon
|
||||
- Fix hub re-install issues
|
||||
- Fediwordle: slightly improved algorithm
|
||||
|
||||
|
||||
Hubzilla 7.2 (2022-03-29)
|
||||
- Streamline comment policy with downstream project
|
||||
- Add new function is_local_url()
|
||||
- Add helper function to escape URLs
|
||||
- Add signing algorithm to zotinfo()
|
||||
- Store signing algorithm in import_xchan()
|
||||
- Use bootstrap-nightfall for redbasic:dark schema
|
||||
- Add support for hs2019
|
||||
- Remove unused function script_path()
|
||||
- Move login and register button into the hamburger menu for small screens
|
||||
- Collect accept headers in an array instead of a concatenated string
|
||||
- Update composer libs
|
||||
- Enhanced content filters
|
||||
- Improve mod gprobe to also deal with URLs
|
||||
- Adapt unseen forum posts query in mod network to new forum post style
|
||||
- Remove deprecated widgets
|
||||
- Add inbound support for quoteUrl to Lib/Activity
|
||||
- Add widget descriptions
|
||||
- Add a GUI for the PDL editor
|
||||
|
||||
Addons
|
||||
- Pubcrawl: deprecate as.php in favor of core libs
|
||||
- Pubcrawl: rewrite/modernize mod inbox
|
||||
- Pubcrawl: reflect core enhanced content filter changes
|
||||
- Diaspora: reflect core enhanced content filter changes
|
||||
- Fediwordle: new addon - a distributed word game inspired by wordle
|
||||
- Pubcrawl: streamline post_local hook with diaspora
|
||||
|
||||
Bugfixes
|
||||
- Fix comments_closed date on posts where comments are disabled
|
||||
- Fix open redirect via rpath query param (CVE-2022-27256)
|
||||
- Fix cross-site scripting via rpath query param (CVE-2022-27258)
|
||||
- Fix local file inclusion in redbasic theme (CVE-2022-27257)
|
||||
- Fix baseurl for css and js
|
||||
- Fix duplicate IDs in login form
|
||||
- Fix unknown author not fetched if w2w comment arrives
|
||||
- Fix thr_parent lost across edits
|
||||
|
||||
|
||||
Hubzilla 7.0.3 (2022-02-10)
|
||||
- Allow to override the charset for the PDO connection string via $db_charset in .htconfig.php
|
||||
|
||||
|
||||
Hubzilla 7.0.2 (2022-02-09)
|
||||
- Update french templates
|
||||
- Add charset to the PDO connection strings
|
||||
- Introduce delete keytype for get_activitystreams_key()
|
||||
- Fix PHP error in Daemon/Externals
|
||||
- Improved actor cache handling
|
||||
- Implement manual fetch of packed local links
|
||||
- Add JSalmon data to the meta field instead of data in Lib/ActivityStreams
|
||||
- Fix some PHP8.1 deprecation warnings
|
||||
- Fix delivery report for likes not found in some cases
|
||||
- Allow zotfinger to recurse through all known hublocs if the one we got does not exist (404) or got removed (410)
|
||||
- Diaspora: improve relaying of comments
|
||||
- Fix regression in mod hcard
|
||||
- Add the LD signature in Daemon/Notifier in case where there is no signed data available
|
||||
- Prevent zot6 packet being saved as AP raw message
|
||||
- Attach iconfig to the activity instead of the activity object
|
||||
|
||||
Addons
|
||||
- Pubcrawl: make sure the sys channel falls through the app installed check
|
||||
- Pubcrawl: improve local delivery of shared inbox items
|
||||
|
||||
|
||||
Hubzilla 7.0.1 (2022-01-28)
|
||||
- Fix removing contacts from privacy groups in the contact edit modal
|
||||
- Fix escape_tags() messing with URLs in actor_store()
|
||||
- Fix pagination in the cards module if a category is selected
|
||||
- Remove unused entries in webfinger
|
||||
- Remove deprecated mail app from apps
|
||||
- Set item_hidden for forum comment announces
|
||||
- Fix relaying of signed messages for activitypub
|
||||
- Fix contact role permissions not re-assigned if the role permission has changed
|
||||
- Fix default channel role not set in rare cases
|
||||
|
||||
Addons
|
||||
- Pubcrawl: fix webfinger not returning the fetched URL
|
||||
- Pubcrawl: improved queue handling for rejected deliveries
|
||||
|
||||
|
||||
Hubzilla 7.0 (2022-01-21)
|
||||
- Provide theme_color and background_color in App::$theme_info for usage in page meta and manifest
|
||||
- PWA improvements according to lighthouse
|
||||
|
||||
@@ -133,7 +133,9 @@ class Externals {
|
||||
continue;
|
||||
}
|
||||
|
||||
Libzot::fetch_conversation($importer, $message['object']['id']);
|
||||
$obj_id = $message['object']['id'] ?? $message['object'];
|
||||
|
||||
Libzot::fetch_conversation($importer, $obj_id);
|
||||
$total++;
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -15,19 +15,31 @@ class Gprobe {
|
||||
return;
|
||||
|
||||
$url = hex2bin($argv[1]);
|
||||
$is_webbie = false;
|
||||
$r = null;
|
||||
|
||||
if (!strpos($url, '@'))
|
||||
return;
|
||||
if (filter_var($url, FILTER_VALIDATE_EMAIL)) {
|
||||
$is_webbie = true;
|
||||
|
||||
$r = q("select * from hubloc where hubloc_addr = '%s' and hubloc_network = 'zot6' limit 1",
|
||||
dbesc($url)
|
||||
);
|
||||
$r = q("select * from hubloc where hubloc_addr = '%s' and hubloc_network = 'zot6' limit 1",
|
||||
dbesc($url)
|
||||
);
|
||||
}
|
||||
elseif (filter_var($url, FILTER_VALIDATE_URL)) {
|
||||
$r = q("select * from hubloc where hubloc_id_url = '%s' and hubloc_network = 'zot6' limit 1",
|
||||
dbesc($url)
|
||||
);
|
||||
}
|
||||
|
||||
if (!$r) {
|
||||
$href = Webfinger::zot_url(punify($url));
|
||||
if ($href) {
|
||||
$zf = Zotfinger::exec($href, null);
|
||||
if ($is_webbie) {
|
||||
$url = Webfinger::zot_url(punify($url));
|
||||
}
|
||||
|
||||
if ($url) {
|
||||
$zf = Zotfinger::exec($url, null);
|
||||
}
|
||||
|
||||
if (is_array($zf) && array_path_exists('signature/signer', $zf) && $zf['signature']['signer'] === $href && intval($zf['signature']['header_valid'])) {
|
||||
Libzot::import_xchan($zf['data']);
|
||||
}
|
||||
|
||||
@@ -5,6 +5,7 @@ namespace Zotlabs\Daemon;
|
||||
use Zotlabs\Lib\Libzot;
|
||||
use Zotlabs\Lib\Activity;
|
||||
use Zotlabs\Lib\Queue;
|
||||
use Zotlabs\Lib\LDSignatures;
|
||||
|
||||
require_once('include/html2plain.php');
|
||||
require_once('include/conversation.php');
|
||||
@@ -110,6 +111,12 @@ class Notifier {
|
||||
|
||||
$sys = get_sys_channel();
|
||||
$normal_mode = true;
|
||||
$upstream = false;
|
||||
$uplink = false;
|
||||
$target_item = [];
|
||||
$parent_item = [];
|
||||
$top_level_post = false;
|
||||
$relay_to_owner = false;
|
||||
|
||||
if ($cmd === 'keychange') {
|
||||
self::$channel = channelx_by_n($item_id);
|
||||
@@ -336,12 +343,14 @@ class Notifier {
|
||||
self::$encoded_item = json_decode($m, true);
|
||||
}
|
||||
else {
|
||||
|
||||
self::$encoded_item = array_merge(['@context' => [
|
||||
ACTIVITYSTREAMS_JSONLD_REV,
|
||||
'https://w3id.org/security/v1',
|
||||
z_root() . ZOT_APSCHEMA_REV
|
||||
]], Activity::encode_activity($target_item)
|
||||
);
|
||||
self::$encoded_item['signature'] = LDSignatures::sign(self::$encoded_item, self::$channel);
|
||||
}
|
||||
|
||||
logger('target_item: ' . print_r($target_item, true), LOGGER_DEBUG);
|
||||
@@ -357,8 +366,6 @@ class Notifier {
|
||||
// the hostname in the message_id and provides a second (fallback) opinion.
|
||||
|
||||
$relay_to_owner = (!$top_level_post && intval($target_item['item_origin']) && comment_local_origin($target_item));
|
||||
$uplink = false;
|
||||
$upstream = false;
|
||||
|
||||
// $cmd === 'relay' indicates the owner is sending it to the original recipients
|
||||
// don't allow the item in the relay command to relay to owner under any circumstances, it will loop
|
||||
|
||||
@@ -46,6 +46,7 @@ class Onepoll {
|
||||
}
|
||||
|
||||
$contact = $contacts[0];
|
||||
|
||||
$importer_uid = $contact['abook_channel'];
|
||||
|
||||
$importer = channelx_by_n($importer_uid);
|
||||
@@ -53,7 +54,7 @@ class Onepoll {
|
||||
if (!$importer)
|
||||
return;
|
||||
|
||||
logger("onepoll: poll: ({$contact['id']}) IMPORTER: {$importer['xchan_name']}, CONTACT: {$contact['xchan_name']}");
|
||||
logger("onepoll: poll: ($contact_id) IMPORTER: {$importer['xchan_name']}, CONTACT: {$contact['xchan_name']}");
|
||||
|
||||
$last_update = ((($contact['abook_updated'] === $contact['abook_created']) || ($contact['abook_updated'] <= NULL_DATE))
|
||||
? datetime_convert('UTC', 'UTC', 'now - 7 days')
|
||||
|
||||
@@ -160,8 +160,10 @@ class AccessList {
|
||||
return false;
|
||||
}
|
||||
|
||||
static function member_remove($uid, $name, $member) {
|
||||
$gid = self::by_name($uid, $name);
|
||||
static function member_remove($uid, $name, $member, $gid = 0) {
|
||||
if (!$gid) {
|
||||
$gid = self::by_name($uid, $name);
|
||||
}
|
||||
|
||||
if (!($uid && $gid && $member)) {
|
||||
return false;
|
||||
@@ -192,7 +194,8 @@ class AccessList {
|
||||
dbesc($member)
|
||||
);
|
||||
if ($r) {
|
||||
return true; // You might question this, but
|
||||
return true;
|
||||
// You might question this, but
|
||||
// we indicate success because the group member was in fact created
|
||||
// -- It was just created at another time
|
||||
}
|
||||
@@ -308,55 +311,6 @@ class AccessList {
|
||||
return $o;
|
||||
}
|
||||
|
||||
/* deprecated
|
||||
static function widget($every = "connections", $each = "lists", $edit = false, $group_id = 0, $cid = '', $mode = 1) {
|
||||
|
||||
$groups = [];
|
||||
|
||||
$r = q("SELECT * FROM pgrp WHERE deleted = 0 AND uid = %d ORDER BY gname ASC",
|
||||
intval($_SESSION['uid'])
|
||||
);
|
||||
$member_of = [];
|
||||
if ($cid) {
|
||||
$member_of = self::containing(local_channel(), $cid);
|
||||
}
|
||||
|
||||
if ($r) {
|
||||
foreach ($r as $rr) {
|
||||
$selected = (($group_id == $rr['id']) ? ' group-selected' : '');
|
||||
|
||||
if ($edit) {
|
||||
$groupedit = ['href' => "lists/" . $rr['id'], 'title' => t('edit')];
|
||||
}
|
||||
else {
|
||||
$groupedit = null;
|
||||
}
|
||||
|
||||
$groups[] = [
|
||||
'id' => $rr['id'],
|
||||
'enc_cid' => base64url_encode($cid),
|
||||
'cid' => $cid,
|
||||
'text' => $rr['gname'],
|
||||
'selected' => $selected,
|
||||
'href' => (($mode == 0) ? $each . '?f=&gid=' . $rr['id'] : $each . "/" . $rr['id']) . ((x($_GET, 'new')) ? '&new=' . $_GET['new'] : '') . ((x($_GET, 'order')) ? '&order=' . $_GET['order'] : ''),
|
||||
'edit' => $groupedit,
|
||||
'ismember' => in_array($rr['id'], $member_of),
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
return replace_macros(get_markup_template('group_side.tpl'), [
|
||||
'$title' => t('Privacy Groups'),
|
||||
'$edittext' => t('Edit group'),
|
||||
'$createtext' => t('Create new group'),
|
||||
'$ungrouped' => (($every === 'contacts') ? t('Channels not in any privacy group') : ''),
|
||||
'$groups' => $groups,
|
||||
'$add' => t('Add'),
|
||||
]);
|
||||
|
||||
}
|
||||
*/
|
||||
|
||||
static function expand($g) {
|
||||
if (!(is_array($g) && count($g))) {
|
||||
return [];
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -11,6 +11,7 @@ class ActivityStreams {
|
||||
|
||||
public $raw = null;
|
||||
public $data = null;
|
||||
public $meta = null;
|
||||
public $valid = false;
|
||||
public $deleted = false;
|
||||
public $id = '';
|
||||
@@ -36,10 +37,14 @@ class ActivityStreams {
|
||||
*/
|
||||
function __construct($string) {
|
||||
|
||||
if(!$string)
|
||||
return;
|
||||
|
||||
$this->raw = $string;
|
||||
|
||||
if (is_array($string)) {
|
||||
$this->data = $string;
|
||||
$this->raw = json_encode($string, JSON_UNESCAPED_SLASHES);
|
||||
}
|
||||
else {
|
||||
$this->data = json_decode($string, true);
|
||||
@@ -56,18 +61,21 @@ class ActivityStreams {
|
||||
if ($ret['signer']) {
|
||||
$saved = json_encode($this->data, JSON_UNESCAPED_SLASHES);
|
||||
$this->data = $tmp;
|
||||
$this->data['signer'] = $ret['signer'];
|
||||
$this->data['signed_data'] = $saved;
|
||||
$this->meta['signer'] = $ret['signer'];
|
||||
$this->meta['signed_data'] = $saved;
|
||||
if ($ret['hubloc']) {
|
||||
$this->data['hubloc'] = $ret['hubloc'];
|
||||
$this->meta['hubloc'] = $ret['hubloc'];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// This indicates only that we have sucessfully decoded JSON.
|
||||
$this->valid = true;
|
||||
|
||||
if (array_key_exists('type', $this->data) && array_key_exists('actor', $this->data) && array_key_exists('object', $this->data)) {
|
||||
// Special handling for Mastodon "delete actor" activities which will often fail to verify
|
||||
// because the key cannot be fetched. We will catch this condition elsewhere.
|
||||
if (is_array($this->data) && array_key_exists('type', $this->data) && array_key_exists('actor', $this->data) && array_key_exists('object', $this->data)) {
|
||||
if ($this->data['type'] === 'Delete' && $this->data['actor'] === $this->data['object']) {
|
||||
$this->deleted = $this->data['actor'];
|
||||
$this->valid = false;
|
||||
@@ -76,6 +84,7 @@ class ActivityStreams {
|
||||
|
||||
}
|
||||
|
||||
// Attempt to assemble an Activity from what we were given.
|
||||
if ($this->is_valid()) {
|
||||
$this->id = $this->get_property_obj('id');
|
||||
$this->type = $this->get_primary_type();
|
||||
@@ -87,7 +96,7 @@ class ActivityStreams {
|
||||
|
||||
$this->ldsig = $this->get_compound_property('signature');
|
||||
if ($this->ldsig) {
|
||||
$this->signer = $this->get_compound_property('creator', $this->ldsig);
|
||||
$this->signer = $this->get_actor('creator', $this->ldsig);
|
||||
if ($this->signer && is_array($this->signer) && array_key_exists('publicKey', $this->signer) && is_array($this->signer['publicKey']) && $this->signer['publicKey']['publicKeyPem']) {
|
||||
$this->sigok = LDSignatures::verify($this->data, $this->signer['publicKey']['publicKeyPem']);
|
||||
}
|
||||
@@ -107,17 +116,17 @@ class ActivityStreams {
|
||||
$this->obj['object'] = $this->get_compound_property($this->obj['object']);
|
||||
}
|
||||
|
||||
if ($this->obj && is_array($this->obj) && $this->obj['actor'])
|
||||
if ($this->obj && is_array($this->obj) && isset($this->obj['actor']))
|
||||
$this->obj['actor'] = $this->get_actor('actor', $this->obj);
|
||||
if ($this->tgt && is_array($this->tgt) && $this->tgt['actor'])
|
||||
if ($this->tgt && is_array($this->tgt) && isset($this->tgt['actor']))
|
||||
$this->tgt['actor'] = $this->get_actor('actor', $this->tgt);
|
||||
|
||||
$this->parent_id = $this->get_property_obj('inReplyTo');
|
||||
|
||||
if ((!$this->parent_id) && is_array($this->obj)) {
|
||||
if ((!$this->parent_id) && is_array($this->obj) && isset($this->obj['inReplyTo'])) {
|
||||
$this->parent_id = $this->obj['inReplyTo'];
|
||||
}
|
||||
if ((!$this->parent_id) && is_array($this->obj)) {
|
||||
if ((!$this->parent_id) && is_array($this->obj) && isset($this->obj['id'])) {
|
||||
$this->parent_id = $this->obj['id'];
|
||||
}
|
||||
}
|
||||
@@ -285,7 +294,7 @@ class ActivityStreams {
|
||||
if (!$s) {
|
||||
return false;
|
||||
}
|
||||
return (in_array($s, ['Like', 'Dislike', 'Flag', 'Block', 'Announce', 'Accept', 'Reject', 'TentativeAccept', 'TentativeReject', 'emojiReaction', 'EmojiReaction', 'EmojiReact']));
|
||||
return (in_array($s, ['Like', 'Dislike', 'Flag', 'Block', 'Accept', 'Reject', 'TentativeAccept', 'TentativeReject', 'emojiReaction', 'EmojiReaction', 'EmojiReact']));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -299,20 +308,25 @@ class ActivityStreams {
|
||||
|
||||
function get_actor($property, $base = '', $namespace = '') {
|
||||
$x = $this->get_property_obj($property, $base, $namespace);
|
||||
|
||||
if ($this->is_url($x)) {
|
||||
$y = Activity::get_cached_actor($x);
|
||||
if ($y) {
|
||||
return $y;
|
||||
}
|
||||
}
|
||||
|
||||
$actor = $this->get_compound_property($property, $base, $namespace, true);
|
||||
|
||||
if (is_array($actor) && self::is_an_actor($actor['type'])) {
|
||||
if (array_key_exists('id', $actor) && (!array_key_exists('inbox', $actor))) {
|
||||
$actor = $this->fetch_property($actor['id']);
|
||||
}
|
||||
return $actor;
|
||||
}
|
||||
return null;
|
||||
|
||||
return Activity::get_unknown_actor($this->data);
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -343,10 +357,10 @@ class ActivityStreams {
|
||||
if ($ret['signer']) {
|
||||
$saved = json_encode($x, JSON_UNESCAPED_SLASHES);
|
||||
$x = $tmp;
|
||||
$x['signer'] = $ret['signer'];
|
||||
$x['signed_data'] = $saved;
|
||||
$x['meta']['signer'] = $ret['signer'];
|
||||
$x['meta']['signed_data'] = $saved;
|
||||
if ($ret['hubloc']) {
|
||||
$x['hubloc'] = $ret['hubloc'];
|
||||
$x['meta']['hubloc'] = $ret['hubloc'];
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -417,15 +431,19 @@ class ActivityStreams {
|
||||
|
||||
static function get_accept_header_string($channel = null) {
|
||||
|
||||
$ret = '';
|
||||
|
||||
$hookdata = [];
|
||||
if ($channel)
|
||||
$hookdata['channel'] = $channel;
|
||||
|
||||
$hookdata['data'] = 'application/x-zot-activity+json';
|
||||
$hookdata['data'] = ['application/x-zot-activity+json'];
|
||||
|
||||
call_hooks('get_accept_header_string', $hookdata);
|
||||
|
||||
return $hookdata['data'];
|
||||
$ret = implode(', ', $hookdata['data']);
|
||||
|
||||
return $ret;
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -426,7 +426,7 @@ class Apps {
|
||||
|
||||
self::translate_system_apps($papp);
|
||||
|
||||
if(trim($papp['plugin']) && (! plugin_is_installed(trim($papp['plugin']))))
|
||||
if(isset($papp['plugin']) && trim($papp['plugin']) && (! plugin_is_installed(trim($papp['plugin']))))
|
||||
return '';
|
||||
|
||||
$papp['papp'] = self::papp_encode($papp);
|
||||
@@ -521,8 +521,13 @@ class Apps {
|
||||
$hosturl = '';
|
||||
|
||||
if(local_channel()) {
|
||||
if(self::app_installed(local_channel(),$papp) && !$papp['deleted'])
|
||||
if(self::app_installed(local_channel(),$papp)) {
|
||||
$installed = true;
|
||||
}
|
||||
|
||||
if ($installed && isset($papp['deleted']) && $papp['deleted']) {
|
||||
$installed = false;
|
||||
}
|
||||
|
||||
$hosturl = z_root() . '/';
|
||||
}
|
||||
|
||||
@@ -87,6 +87,10 @@ class Crypto {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!$alg) {
|
||||
$alg = 'sha256';
|
||||
}
|
||||
|
||||
try {
|
||||
$verify = openssl_verify($data, $sig, $key, $alg);
|
||||
} catch (Exception $e) {
|
||||
|
||||
@@ -256,8 +256,8 @@ class Enotify {
|
||||
|
||||
$itemlink = $params['link'];
|
||||
|
||||
if (array_key_exists('item',$params) && activity_match($params['item']['verb'],ACTIVITY_LIKE)) {
|
||||
if(! $always_show_in_notices || !($vnotify & VNOTIFY_LIKE)) {
|
||||
if (array_key_exists('item',$params) && (activity_match($params['item']['verb'], ACTIVITY_LIKE) || activity_match($params['item']['verb'], ACTIVITY_DISLIKE))) {
|
||||
if(! $always_show_in_notices || !($vnotify & VNOTIFY_LIKE) || !feature_enabled($recip['channel_id'], 'dislike')) {
|
||||
logger('notification: not a visible activity. Ignoring.');
|
||||
pop_lang();
|
||||
return;
|
||||
@@ -291,22 +291,29 @@ class Enotify {
|
||||
);
|
||||
}
|
||||
|
||||
if (!$p) {
|
||||
pop_lang();
|
||||
return;
|
||||
}
|
||||
|
||||
xchan_query($p);
|
||||
|
||||
//@@FIXME $p can be null (line 285)
|
||||
$item_post_type = item_post_type($p[0]);
|
||||
// $private = $p[0]['item_private'];
|
||||
$parent_id = $p[0]['id'];
|
||||
|
||||
$parent_item = $p[0];
|
||||
|
||||
$verb = ((activity_match($params['item']['verb'], ACTIVITY_DISLIKE)) ? t('disliked') : t('liked'));
|
||||
|
||||
// "your post"
|
||||
if($p[0]['owner']['xchan_name'] === $p[0]['author']['xchan_name'] && intval($p[0]['item_wall']))
|
||||
$dest_str = sprintf(t('%1$s liked [zrl=%2$s]your %3$s[/zrl]'),
|
||||
$dest_str = sprintf(t('%1$s %2$s [zrl=%3$s]your %4$s[/zrl]'),
|
||||
'[zrl=' . $sender['xchan_url'] . ']' . $sender['xchan_name'] . '[/zrl]',
|
||||
$verb,
|
||||
$itemlink,
|
||||
$item_post_type);
|
||||
$item_post_type
|
||||
);
|
||||
else {
|
||||
pop_lang();
|
||||
return;
|
||||
@@ -808,10 +815,10 @@ class Enotify {
|
||||
|
||||
localize_item($item);
|
||||
|
||||
if($item['shortlocalize']) {
|
||||
if(isset($item['shortlocalize'])) {
|
||||
$itemem_text = $item['shortlocalize'];
|
||||
}
|
||||
elseif($item['localize']) {
|
||||
elseif(isset($item['localize'])) {
|
||||
$itemem_text = $item['localize'];
|
||||
}
|
||||
else {
|
||||
@@ -824,6 +831,14 @@ class Enotify {
|
||||
$itemem_text = sprintf( t('repeated %s\'s post'), '[bdi]' . $item['author']['xchan_name'] . '[/bdi]');
|
||||
}
|
||||
|
||||
if($item['verb'] === ACTIVITY_LIKE) {
|
||||
$itemem_text = sprintf( t('liked %s\'s post'), '[bdi]' . $item['author']['xchan_name'] . '[/bdi]');
|
||||
}
|
||||
|
||||
if($item['verb'] === ACTIVITY_DISLIKE) {
|
||||
$itemem_text = sprintf( t('disliked %s\'s post'), '[bdi]' . $item['author']['xchan_name'] . '[/bdi]');
|
||||
}
|
||||
|
||||
if(in_array($item['obj_type'], ['Document', 'Video', 'Audio', 'Image'])) {
|
||||
$itemem_text = t('shared a file with you');
|
||||
}
|
||||
@@ -845,6 +860,10 @@ class Enotify {
|
||||
// convert this logic into a json array just like the system notifications
|
||||
|
||||
$who = (($item['verb'] === ACTIVITY_SHARE) ? 'owner' : 'author');
|
||||
$body = html2plain(bbcode($item['body'], ['drop_media' => true, 'tryoembed' => false]), 75, true);
|
||||
if ($body) {
|
||||
$body = htmlentities($body, ENT_QUOTES, 'UTF-8', false);
|
||||
}
|
||||
|
||||
$x = array(
|
||||
'notify_link' => $item['llink'],
|
||||
@@ -858,7 +877,7 @@ class Enotify {
|
||||
//'b64mid' => ((in_array($item['verb'], [ACTIVITY_LIKE, ACTIVITY_DISLIKE])) ? gen_link_id($item['thr_parent']) : gen_link_id($item['mid'])),
|
||||
'thread_top' => (($item['item_thread_top']) ? true : false),
|
||||
'message' => bbcode(escape_tags($itemem_text)),
|
||||
'body' => htmlentities(html2plain(bbcode($item['body'], ['drop_media', true]), 75, true), ENT_QUOTES, 'UTF-8', false),
|
||||
'body' => $body,
|
||||
// these are for the superblock addon
|
||||
'hash' => $item[$who]['xchan_hash'],
|
||||
'uid' => $item['uid'],
|
||||
|
||||
@@ -75,22 +75,23 @@ class LDSignatures {
|
||||
}
|
||||
|
||||
static function hash($obj) {
|
||||
|
||||
return hash('sha256',self::normalise($obj));
|
||||
return hash('sha256', self::normalise($obj));
|
||||
}
|
||||
|
||||
static function normalise($data) {
|
||||
$ret = '';
|
||||
|
||||
if(is_string($data)) {
|
||||
$data = json_decode($data);
|
||||
}
|
||||
|
||||
if(! is_object($data))
|
||||
return '';
|
||||
return $ret;
|
||||
|
||||
jsonld_set_document_loader('jsonld_document_loader');
|
||||
|
||||
try {
|
||||
$d = jsonld_normalize($data,[ 'algorithm' => 'URDNA2015', 'format' => 'application/nquads' ]);
|
||||
$ret = jsonld_normalize($data,[ 'algorithm' => 'URDNA2015', 'format' => 'application/nquads' ]);
|
||||
}
|
||||
catch (\Exception $e) {
|
||||
// Don't log the exception - this can exhaust memory
|
||||
@@ -98,7 +99,7 @@ class LDSignatures {
|
||||
logger('normalise error: ' . print_r($data,true));
|
||||
}
|
||||
|
||||
return $d;
|
||||
return $ret;
|
||||
}
|
||||
|
||||
static function salmon_sign($data,$channel) {
|
||||
|
||||
@@ -251,7 +251,7 @@ class Libzot {
|
||||
|
||||
$url = null;
|
||||
|
||||
if ($them['hubloc_id_url']) {
|
||||
if (isset($them['hubloc_id_url']) && $them['hubloc_id_url']) {
|
||||
$url = $them['hubloc_id_url'];
|
||||
}
|
||||
else {
|
||||
@@ -304,8 +304,14 @@ class Libzot {
|
||||
|
||||
$record = Zotfinger::exec($url, $channel);
|
||||
|
||||
if (!$record) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Check the HTTP signature
|
||||
$hsig = $record['signature'];
|
||||
$hsig_valid = false;
|
||||
|
||||
if ($hsig && $hsig['signer'] === $url && $hsig['header_valid'] === true && $hsig['content_valid'] === true) {
|
||||
$hsig_valid = true;
|
||||
}
|
||||
@@ -676,6 +682,10 @@ class Libzot {
|
||||
|
||||
logger('import_xchan: ' . $xchan_hash, LOGGER_DEBUG);
|
||||
|
||||
if (isset($arr['signing_algorithm']) && $arr['signing_algorithm']) {
|
||||
set_xconfig($xchan_hash, 'system', 'signing_algorithm', $arr['signing_algorithm']);
|
||||
}
|
||||
|
||||
$r = q("select * from xchan where xchan_hash = '%s' limit 1",
|
||||
dbesc($xchan_hash)
|
||||
);
|
||||
@@ -894,11 +904,11 @@ class Libzot {
|
||||
$s = Libsync::sync_locations($arr, $arr);
|
||||
|
||||
if ($s) {
|
||||
if ($s['change_message'])
|
||||
if (isset($s['change_message']))
|
||||
$what .= $s['change_message'];
|
||||
if ($s['changed'])
|
||||
if (isset($s['changed']))
|
||||
$changed = $s['changed'];
|
||||
if ($s['message'])
|
||||
if (isset($s['message']))
|
||||
$ret['message'] .= $s['message'];
|
||||
}
|
||||
|
||||
@@ -1003,7 +1013,7 @@ class Libzot {
|
||||
|
||||
$x = Crypto::unencapsulate($x, get_config('system', 'prvkey'));
|
||||
|
||||
if (!is_array($x)) {
|
||||
if ($x && !is_array($x)) {
|
||||
$x = json_decode($x, true);
|
||||
}
|
||||
|
||||
@@ -1223,10 +1233,20 @@ class Libzot {
|
||||
return;
|
||||
}
|
||||
|
||||
$r = q("select hubloc_hash, hubloc_network, hubloc_url from hubloc where hubloc_id_url = '%s'",
|
||||
$r = q("select hubloc_hash, hubloc_network, hubloc_url from hubloc where hubloc_id_url = '%s' order by hubloc_id desc",
|
||||
dbesc($AS->actor['id'])
|
||||
);
|
||||
|
||||
if (! $r) {
|
||||
// Author is unknown to this site. Perform channel discovery and try again.
|
||||
$z = discover_by_webbie($AS->actor['id']);
|
||||
if ($z) {
|
||||
$r = q("select hubloc_hash, hubloc_network, hubloc_url from hubloc where hubloc_id_url = '%s' order by hubloc_id desc",
|
||||
dbesc($AS->actor['id'])
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
if ($r) {
|
||||
$r = self::zot_record_preferred($r);
|
||||
$arr['author_xchan'] = $r['hubloc_hash'];
|
||||
@@ -1241,7 +1261,7 @@ class Libzot {
|
||||
|
||||
if(filter_var($env['sender'], FILTER_VALIDATE_URL)) {
|
||||
// in individual delivery, change owner if needed
|
||||
$s = q("select hubloc_hash, hubloc_url from hubloc where hubloc_id_url = '%s' and hubloc_network = 'zot6' limit 1",
|
||||
$s = q("select hubloc_hash, hubloc_url from hubloc where hubloc_id_url = '%s' and hubloc_network = 'zot6' order by hubloc_id desc limit 1",
|
||||
dbesc($env['sender'])
|
||||
);
|
||||
|
||||
@@ -1278,27 +1298,16 @@ class Libzot {
|
||||
}
|
||||
}
|
||||
|
||||
if ($AS->data['hubloc']) {
|
||||
if ($AS->meta['hubloc']) {
|
||||
$arr['item_verified'] = true;
|
||||
|
||||
if (!array_key_exists('comment_policy', $arr)) {
|
||||
// set comment policy depending on source hub. Unknown or osada is ActivityPub.
|
||||
// Anything else we'll say is zot - which could have a range of project names
|
||||
$s = q("select site_project from site where site_url = '%s' limit 1",
|
||||
dbesc($r[0]['hubloc_url'])
|
||||
);
|
||||
|
||||
if ((!$s) || (in_array($s[0]['site_project'], ['', 'osada']))) {
|
||||
$arr['comment_policy'] = 'authenticated';
|
||||
}
|
||||
else {
|
||||
$arr['comment_policy'] = 'contacts';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ($AS->data['signed_data']) {
|
||||
IConfig::Set($arr, 'activitypub', 'signed_data', $AS->data['signed_data'], false);
|
||||
if (!array_key_exists('comment_policy', $arr)) {
|
||||
$arr['comment_policy'] = 'authenticated';
|
||||
}
|
||||
|
||||
if ($AS->meta['signed_data']) {
|
||||
IConfig::Set($arr, 'activitypub', 'signed_data', $AS->meta['signed_data'], false);
|
||||
}
|
||||
|
||||
logger('Activity received: ' . print_r($arr, true), LOGGER_DATA, LOG_DEBUG);
|
||||
@@ -1569,7 +1578,11 @@ class Libzot {
|
||||
$local_public = false;
|
||||
continue;
|
||||
}
|
||||
if (!MessageFilter::evaluate($arr, get_config('system', 'pubstream_incl'), get_config('system', 'pubstream_excl'))) {
|
||||
|
||||
$incl = get_config('system','pubstream_incl');
|
||||
$excl = get_config('system','pubstream_excl');
|
||||
|
||||
if(($incl || $excl) && !MessageFilter::evaluate($arr, $incl, $excl)) {
|
||||
$local_public = false;
|
||||
continue;
|
||||
}
|
||||
@@ -1620,7 +1633,7 @@ class Libzot {
|
||||
// doesn't exist.
|
||||
|
||||
if ($perm === 'send_stream') {
|
||||
if ($force || get_pconfig($channel['channel_id'], 'system', 'hyperdrive', false) || $arr['verb'] === ACTIVITY_SHARE) {
|
||||
if ($force || get_pconfig($channel['channel_id'], 'system', 'hyperdrive', false)) {
|
||||
$allowed = true;
|
||||
}
|
||||
}
|
||||
@@ -1666,6 +1679,10 @@ class Libzot {
|
||||
$DR->update('comment parent not found');
|
||||
$result[] = $DR->get();
|
||||
|
||||
if ($relay || $request || $local_public) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// We don't seem to have a copy of this conversation or at least the parent
|
||||
// - so request a copy of the entire conversation to date.
|
||||
// Don't do this if it's a relay post as we're the ones who are supposed to
|
||||
@@ -1677,10 +1694,10 @@ class Libzot {
|
||||
// the top level post is unlikely to be imported and
|
||||
// this is just an exercise in futility.
|
||||
|
||||
if ((!$relay) && (!$request) && (!$local_public)
|
||||
&& perm_is_allowed($channel['channel_id'], $sender, 'send_stream')) {
|
||||
if (perm_is_allowed($channel['channel_id'], $sender, 'send_stream')) {
|
||||
self::fetch_conversation($channel, $arr['parent_mid']);
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -1727,7 +1744,7 @@ class Libzot {
|
||||
if (in_array('undefined', $existing_route) || $last_hop == 'undefined' || $sender == 'undefined')
|
||||
$last_hop = '';
|
||||
|
||||
$current_route = (($arr['route']) ? $arr['route'] . ',' : '') . $sender;
|
||||
$current_route = ((isset($arr['route']) && $arr['route']) ? $arr['route'] . ',' : '') . $sender;
|
||||
|
||||
if ($last_hop && $last_hop != $sender) {
|
||||
logger('comment route mismatch: parent route = ' . $r[0]['route'] . ' expected = ' . $current_route, LOGGER_DEBUG);
|
||||
@@ -1744,13 +1761,15 @@ class Libzot {
|
||||
}
|
||||
}
|
||||
|
||||
$ab = q("select * from abook where abook_channel = %d and abook_xchan = '%s'",
|
||||
// This is used to fetch allow/deny rules if either the sender
|
||||
// or owner is a connection. post_is_importable() evaluates all of them
|
||||
$abook = q("select * from abook where abook_channel = %d and ( abook_xchan = '%s' OR abook_xchan = '%s' )",
|
||||
intval($channel['channel_id']),
|
||||
dbesc($arr['owner_xchan'])
|
||||
dbesc($arr['owner_xchan']),
|
||||
dbesc($arr['author_xchan'])
|
||||
);
|
||||
$abook = (($ab) ? $ab[0] : null);
|
||||
|
||||
if (intval($arr['item_deleted'])) {
|
||||
if (isset($arr['item_deleted']) && $arr['item_deleted']) {
|
||||
|
||||
// remove_community_tag is a no-op if this isn't a community tag activity
|
||||
self::remove_community_tag($sender, $arr, $channel['channel_id']);
|
||||
@@ -1799,17 +1818,18 @@ class Libzot {
|
||||
elseif ($arr['edited'] > $r[0]['edited']) {
|
||||
$arr['id'] = $r[0]['id'];
|
||||
$arr['uid'] = $channel['channel_id'];
|
||||
if (($arr['mid'] == $arr['parent_mid']) && (!post_is_importable($arr, $abook))) {
|
||||
$DR->update('update ignored');
|
||||
$result[] = $DR->get();
|
||||
}
|
||||
else {
|
||||
$item_result = self::update_imported_item($sender, $arr, $r[0], $channel['channel_id'], $tag_delivery);
|
||||
$DR->update('updated');
|
||||
$result[] = $DR->get();
|
||||
if (!$relay)
|
||||
add_source_route($item_id, $sender);
|
||||
}
|
||||
|
||||
if (post_is_importable($channel['channel_id'], $arr, $abook)) {
|
||||
$item_result = self::update_imported_item($sender, $arr, $r[0], $channel['channel_id'], $tag_delivery);
|
||||
$DR->update('updated');
|
||||
$result[] = $DR->get();
|
||||
if (!$relay) {
|
||||
add_source_route($item_id, $sender);
|
||||
}
|
||||
} else {
|
||||
$DR->update('update ignored');
|
||||
$result[] = $DR->get();
|
||||
}
|
||||
}
|
||||
else {
|
||||
$DR->update('update ignored');
|
||||
@@ -1839,20 +1859,29 @@ class Libzot {
|
||||
|
||||
$item_id = 0;
|
||||
|
||||
if (($arr['mid'] == $arr['parent_mid']) && (!post_is_importable($arr, $abook))) {
|
||||
$DR->update('post ignored');
|
||||
$result[] = $DR->get();
|
||||
$maxlen = get_max_import_size();
|
||||
|
||||
if ($maxlen && mb_strlen($arr['body']) > $maxlen) {
|
||||
$arr['body'] = mb_substr($arr['body'], 0, $maxlen, 'UTF-8');
|
||||
logger('message length exceeds max_import_size: truncated');
|
||||
}
|
||||
else {
|
||||
|
||||
if ($maxlen && mb_strlen($arr['summary']) > $maxlen) {
|
||||
$arr['summary'] = mb_substr($arr['summary'], 0, $maxlen, 'UTF-8');
|
||||
logger('message summary length exceeds max_import_size: truncated');
|
||||
}
|
||||
|
||||
if (post_is_importable($arr['uid'], $arr, $abook)) {
|
||||
$item_result = item_store($arr);
|
||||
if ($item_result['success']) {
|
||||
$item_id = $item_result['item_id'];
|
||||
$parr = [
|
||||
$parr = [
|
||||
'item_id' => $item_id,
|
||||
'item' => $arr,
|
||||
'sender' => $sender,
|
||||
'item' => $arr,
|
||||
'sender' => $sender,
|
||||
'channel' => $channel
|
||||
];
|
||||
|
||||
/**
|
||||
* @hooks activity_received
|
||||
* Called when an activity (post, comment, like, etc.) has been received from a zot source.
|
||||
@@ -1862,13 +1891,19 @@ class Libzot {
|
||||
* * \e array \b channel
|
||||
*/
|
||||
call_hooks('activity_received', $parr);
|
||||
|
||||
// don't add a source route if it's a relay or later recipients will get a route mismatch
|
||||
if (!$relay)
|
||||
if (!$relay) {
|
||||
add_source_route($item_id, $sender);
|
||||
}
|
||||
}
|
||||
$DR->update(($item_id) ? 'posted' : 'storage failed: ' . $item_result['message']);
|
||||
$result[] = $DR->get();
|
||||
} else {
|
||||
$DR->update('post ignored');
|
||||
$result[] = $DR->get();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// preserve conversations with which you are involved from expiration
|
||||
@@ -1927,6 +1962,7 @@ class Libzot {
|
||||
dbesc($a['signature']['signer'])
|
||||
);
|
||||
|
||||
|
||||
foreach ($items as $activity) {
|
||||
|
||||
$AS = new ActivityStreams($activity);
|
||||
@@ -1984,13 +2020,13 @@ class Libzot {
|
||||
$arr['owner_xchan'] = $a['signature']['signer'];
|
||||
}
|
||||
|
||||
if ($AS->data['hubloc'] || $arr['author_xchan'] === $arr['owner_xchan']) {
|
||||
if (isset($AS->meta['hubloc']) || $arr['author_xchan'] === $arr['owner_xchan']) {
|
||||
$arr['item_verified'] = true;
|
||||
}
|
||||
|
||||
if ($AS->data['signed_data']) {
|
||||
IConfig::Set($arr, 'activitypub', 'signed_data', $AS->data['signed_data'], false);
|
||||
$j = json_decode($AS->data['signed_data'], true);
|
||||
if (isset($AS->meta['signed_data'])) {
|
||||
IConfig::Set($arr, 'activitypub', 'signed_data', $AS->meta['signed_data'], false);
|
||||
$j = json_decode($AS->meta['signed_data'], true);
|
||||
if ($j) {
|
||||
IConfig::Set($arr, 'activitypub', 'rawmsg', json_encode(JSalmon::unpack($j['data'])), true);
|
||||
}
|
||||
@@ -2482,14 +2518,14 @@ class Libzot {
|
||||
$access_policy = ACCESS_PRIVATE;
|
||||
}
|
||||
|
||||
$directory_url = htmlspecialchars($arr['directory_url'], ENT_COMPAT, 'UTF-8', false);
|
||||
$url = htmlspecialchars(strtolower($arr['url']), ENT_COMPAT, 'UTF-8', false);
|
||||
$sellpage = htmlspecialchars($arr['sellpage'], ENT_COMPAT, 'UTF-8', false);
|
||||
$site_location = htmlspecialchars($arr['location'], ENT_COMPAT, 'UTF-8', false);
|
||||
$site_realm = htmlspecialchars($arr['realm'], ENT_COMPAT, 'UTF-8', false);
|
||||
$site_project = htmlspecialchars($arr['project'], ENT_COMPAT, 'UTF-8', false);
|
||||
$site_crypto = ((array_key_exists('encryption', $arr) && is_array($arr['encryption'])) ? htmlspecialchars(implode(',', $arr['encryption']), ENT_COMPAT, 'UTF-8', false) : '');
|
||||
$site_version = ((array_key_exists('version', $arr)) ? htmlspecialchars($arr['version'], ENT_COMPAT, 'UTF-8', false) : '');
|
||||
$directory_url = ((isset($arr['directory_url'])) ? htmlspecialchars($arr['directory_url'], ENT_COMPAT, 'UTF-8', false) : '');
|
||||
$url = ((isset($arr['url'])) ? htmlspecialchars(strtolower($arr['url']), ENT_COMPAT, 'UTF-8', false) : '');
|
||||
$sellpage = ((isset($arr['sellpage'])) ? htmlspecialchars($arr['sellpage'], ENT_COMPAT, 'UTF-8', false) : '');
|
||||
$site_location = ((isset($arr['location'])) ? htmlspecialchars($arr['location'], ENT_COMPAT, 'UTF-8', false) : '');
|
||||
$site_realm = ((isset($arr['realm'])) ? htmlspecialchars($arr['realm'], ENT_COMPAT, 'UTF-8', false) : '');
|
||||
$site_project = ((isset($arr['project'])) ? htmlspecialchars($arr['project'], ENT_COMPAT, 'UTF-8', false) : '');
|
||||
$site_crypto = ((isset($arr['encryption']) && is_array($arr['encryption'])) ? htmlspecialchars(implode(',', $arr['encryption']), ENT_COMPAT, 'UTF-8', false) : '');
|
||||
$site_version = ((isset($arr['version'])) ? htmlspecialchars($arr['version'], ENT_COMPAT, 'UTF-8', false) : '');
|
||||
|
||||
// You can have one and only one primary directory per realm.
|
||||
// Downgrade any others claiming to be primary. As they have
|
||||
@@ -2699,14 +2735,15 @@ class Libzot {
|
||||
$token = ((x($arr, 'token')) ? $arr['token'] : '');
|
||||
$feed = ((x($arr, 'feed')) ? intval($arr['feed']) : 0);
|
||||
|
||||
$ztarget_hash = EMPTY_STR;
|
||||
|
||||
if ($ztarget) {
|
||||
$t = q("select * from hubloc where hubloc_id_url = '%s' and hubloc_network = 'zot6' limit 1",
|
||||
$t = q("select * from hubloc where hubloc_id_url = '%s' and hubloc_network = 'zot6' order by hubloc_id desc limit 1",
|
||||
dbesc($ztarget)
|
||||
);
|
||||
if ($t) {
|
||||
|
||||
$ztarget_hash = $t[0]['hubloc_hash'];
|
||||
|
||||
}
|
||||
else {
|
||||
|
||||
@@ -2714,7 +2751,6 @@ class Libzot {
|
||||
// permissions we would know about them and we only want to know who they are to
|
||||
// enumerate their specific permissions
|
||||
|
||||
$ztarget_hash = EMPTY_STR;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2845,6 +2881,7 @@ class Libzot {
|
||||
];
|
||||
|
||||
$ret['public_key'] = $e['xchan_pubkey'];
|
||||
$ret['signing_algorithm'] = 'rsa-sha256';
|
||||
$ret['username'] = $e['channel_address'];
|
||||
$ret['name'] = $e['xchan_name'];
|
||||
$ret['name_updated'] = $e['xchan_name_date'];
|
||||
@@ -2889,12 +2926,11 @@ class Libzot {
|
||||
// This is a template - %s will be replaced with the follow_url we discover for the return channel.
|
||||
|
||||
if ($special_channel) {
|
||||
$ret['connect_url'] = (($e['xchan_connpage']) ? $e['xchan_connpage'] : z_root() . '/connect/' . $e['channel_address']);
|
||||
$ret['connect_url'] = $e['xchan_connpage'] ?? z_root() . '/connect/' . $e['channel_address'];
|
||||
}
|
||||
|
||||
// This is a template for our follow url, %s will be replaced with a webbie
|
||||
if (!$ret['follow_url'])
|
||||
$ret['follow_url'] = z_root() . '/follow?f=&url=%s';
|
||||
$ret['follow_url'] = $ret['follow_url'] ?? z_root() . '/follow?f=&url=%s';
|
||||
|
||||
$permissions = get_all_perms($e['channel_id'], $ztarget_hash, false, false);
|
||||
|
||||
@@ -3070,7 +3106,8 @@ class Libzot {
|
||||
|
||||
$t = datetime_convert('UTC', 'UTC', 'now - 15 minutes');
|
||||
|
||||
$r = q("update hubloc set hubloc_connected = '%s' where hubloc_id = %d and hubloc_site_id = '%s' and hubloc_connected < '%s' ",
|
||||
q("update hubloc set hubloc_connected = '%s', hubloc_updated = '%s' where hubloc_id = %d and hubloc_site_id = '%s' and hubloc_connected < '%s' ",
|
||||
dbesc(datetime_convert()),
|
||||
dbesc(datetime_convert()),
|
||||
intval($hub['hubloc_id']),
|
||||
dbesc($site_id),
|
||||
@@ -3162,7 +3199,7 @@ class Libzot {
|
||||
}
|
||||
|
||||
foreach ($arr as $v) {
|
||||
if ($v[$check] === 'zot6') {
|
||||
if (isset($v[$check]) && $v[$check] === 'zot6') {
|
||||
return $v;
|
||||
}
|
||||
}
|
||||
@@ -3172,7 +3209,7 @@ class Libzot {
|
||||
}
|
||||
|
||||
static function update_cached_hubloc($hubloc) {
|
||||
if ($hubloc['hubloc_updated'] > datetime_convert('UTC','UTC','now - 1 week') || $hubloc['hubloc_url'] === z_root()) {
|
||||
if ($hubloc['hubloc_updated'] > datetime_convert('UTC','UTC','now - 3 days') || $hubloc['hubloc_url'] === z_root()) {
|
||||
return;
|
||||
}
|
||||
self::refresh( [ 'hubloc_id_url' => $hubloc['hubloc_id_url'] ] );
|
||||
|
||||
@@ -2,85 +2,120 @@
|
||||
|
||||
namespace Zotlabs\Lib;
|
||||
|
||||
|
||||
require_once('include/html2plain.php');
|
||||
|
||||
class MessageFilter {
|
||||
|
||||
public static function evaluate($item, $incl, $excl) {
|
||||
|
||||
static public function evaluate($item,$incl,$excl) {
|
||||
|
||||
require_once('include/html2plain.php');
|
||||
|
||||
$text = prepare_text($item['body'],$item['mimetype']);
|
||||
$text = prepare_text($item['body'],((isset($item['mimetype'])) ? $item['mimetype'] : 'text/bbcode'));
|
||||
$text = html2plain(($item['title']) ? $item['title'] . ' ' . $text : $text);
|
||||
|
||||
|
||||
$lang = null;
|
||||
|
||||
if((strpos($incl,'lang=') !== false) || (strpos($excl,'lang=') !== false) || (strpos($incl,'lang!=') !== false) || (strpos($excl,'lang!=') !== false)) {
|
||||
if ((strpos($incl, 'lang=') !== false) || (strpos($excl, 'lang=') !== false) || (strpos($incl, 'lang!=') !== false) || (strpos($excl, 'lang!=') !== false)) {
|
||||
$lang = detect_language($text);
|
||||
}
|
||||
|
||||
$tags = ((is_array($item['term']) && count($item['term'])) ? $item['term'] : false);
|
||||
$tags = ((isset($item['term']) && is_array($item['term']) && count($item['term'])) ? $item['term'] : false);
|
||||
|
||||
// exclude always has priority
|
||||
|
||||
$exclude = (($excl) ? explode("\n",$excl) : null);
|
||||
$exclude = (($excl) ? explode("\n", $excl) : null);
|
||||
|
||||
if($exclude) {
|
||||
foreach($exclude as $word) {
|
||||
if ($exclude) {
|
||||
foreach ($exclude as $word) {
|
||||
$word = trim($word);
|
||||
if(! $word)
|
||||
if (! $word) {
|
||||
continue;
|
||||
if(substr($word,0,1) === '#' && $tags) {
|
||||
foreach($tags as $t)
|
||||
if((($t['ttype'] == TERM_HASHTAG) || ($t['ttype'] == TERM_COMMUNITYTAG)) && (($t['term'] === substr($word,1)) || (substr($word,1) === '*')))
|
||||
return false;
|
||||
}
|
||||
elseif(substr($word,0,1) === '$' && $tags) {
|
||||
foreach($tags as $t)
|
||||
if(($t['ttype'] == TERM_CATEGORY) && (($t['term'] === substr($word,1)) || (substr($word,1) === '*')))
|
||||
return false;
|
||||
if (isset($lang) && ((strpos($word, 'lang=') === 0) || (strpos($word, 'lang!=') === 0))) {
|
||||
if (!strlen($lang)) {
|
||||
// Result is ambiguous. As we are matching deny rules only at this time, continue tests.
|
||||
// Any matching deny rule concludes testing.
|
||||
continue;
|
||||
}
|
||||
if (strpos($word, 'lang=') === 0 && strcasecmp($lang, trim(substr($word, 5))) == 0) {
|
||||
return false;
|
||||
} elseif (strpos($word, 'lang!=') === 0 && strcasecmp($lang, trim(substr($word, 6))) != 0) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
elseif((strpos($word,'/') === 0) && preg_match($word,$text))
|
||||
elseif (substr($word, 0, 1) === '#' && $tags) {
|
||||
foreach ($tags as $t) {
|
||||
if ((($t['ttype'] == TERM_HASHTAG) || ($t['ttype'] == TERM_COMMUNITYTAG)) && (($t['term'] === substr($word, 1)) || (substr($word, 1) === '*'))) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
} elseif (substr($word, 0, 1) === '$' && $tags) {
|
||||
foreach ($tags as $t) {
|
||||
if (($t['ttype'] == TERM_CATEGORY) && (($t['term'] === substr($word, 1)) || (substr($word, 1) === '*'))) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
} elseif (substr($word, 0, 2) === '?+') {
|
||||
if (self::test_condition(substr($word, 2), $item['obj'])) {
|
||||
return false;
|
||||
}
|
||||
} elseif (substr($word, 0, 1) === '?') {
|
||||
if (self::test_condition(substr($word, 1), $item)) {
|
||||
return false;
|
||||
}
|
||||
} elseif ((strpos($word, '/') === 0) && preg_match($word, $text)) {
|
||||
return false;
|
||||
elseif((strpos($word,'lang=') === 0) && ($lang) && (strcasecmp($lang,trim(substr($word,5))) == 0))
|
||||
return false;
|
||||
elseif((strpos($word,'lang!=') === 0) && ($lang) && (strcasecmp($lang,trim(substr($word,6))) != 0))
|
||||
return false;
|
||||
elseif(stristr($text,$word) !== false)
|
||||
} elseif (stristr($text, $word) !== false) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$include = (($incl) ? explode("\n",$incl) : null);
|
||||
$include = (($incl) ? explode("\n", $incl) : null);
|
||||
|
||||
if($include) {
|
||||
foreach($include as $word) {
|
||||
if ($include) {
|
||||
foreach ($include as $word) {
|
||||
$word = trim($word);
|
||||
if(! $word)
|
||||
if (! $word) {
|
||||
continue;
|
||||
if(substr($word,0,1) === '#' && $tags) {
|
||||
foreach($tags as $t)
|
||||
if((($t['ttype'] == TERM_HASHTAG) || ($t['ttype'] == TERM_COMMUNITYTAG)) && (($t['term'] === substr($word,1)) || (substr($word,1) === '*')))
|
||||
return true;
|
||||
}
|
||||
elseif(substr($word,0,1) === '$' && $tags) {
|
||||
foreach($tags as $t)
|
||||
if(($t['ttype'] == TERM_CATEGORY) && (($t['term'] === substr($word,1)) || (substr($word,1) === '*')))
|
||||
return true;
|
||||
if (isset($lang) && ((strpos($word, 'lang=') === 0) || (strpos($word, 'lang!=') === 0))) {
|
||||
if (!strlen($lang)) {
|
||||
// Result is ambiguous. However we are checking allow rules
|
||||
// and an ambiguous language is always permitted.
|
||||
return true;
|
||||
}
|
||||
if (strpos($word, 'lang=') === 0 && strcasecmp($lang, trim(substr($word, 5))) == 0) {
|
||||
return true;
|
||||
} elseif (strpos($word, 'lang!=') === 0 && strcasecmp($lang, trim(substr($word, 6))) != 0) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
elseif((strpos($word,'/') === 0) && preg_match($word,$text))
|
||||
elseif (substr($word, 0, 1) === '#' && $tags) {
|
||||
foreach ($tags as $t) {
|
||||
if ((($t['ttype'] == TERM_HASHTAG) || ($t['ttype'] == TERM_COMMUNITYTAG)) && (($t['term'] === substr($word, 1)) || (substr($word, 1) === '*'))) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
} elseif (substr($word, 0, 1) === '$' && $tags) {
|
||||
foreach ($tags as $t) {
|
||||
if (($t['ttype'] == TERM_CATEGORY) && (($t['term'] === substr($word, 1)) || (substr($word, 1) === '*'))) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
} elseif (substr($word, 0, 2) === '?+') {
|
||||
if (self::test_condition(substr($word, 2), $item['obj'])) {
|
||||
return true;
|
||||
}
|
||||
} elseif (substr($word, 0, 1) === '?') {
|
||||
if (self::test_condition(substr($word, 1), $item)) {
|
||||
return true;
|
||||
}
|
||||
} elseif ((strpos($word, '/') === 0) && preg_match($word, $text)) {
|
||||
return true;
|
||||
elseif((strpos($word,'lang=') === 0) && ($lang) && (strcasecmp($lang,trim(substr($word,5))) == 0))
|
||||
return true;
|
||||
elseif((strpos($word,'lang!=') === 0) && ($lang) && (strcasecmp($lang,trim(substr($word,6))) != 0))
|
||||
return true;
|
||||
elseif(stristr($text,$word) !== false)
|
||||
} elseif (stristr($text, $word) !== false) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -88,4 +123,123 @@ class MessageFilter {
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief Test for Conditional Execution conditions. Shamelessly ripped off from Code/Render/Comanche
|
||||
*
|
||||
* This is extensible. The first version of variable testing supports tests of the forms:
|
||||
*
|
||||
* - ?foo ~= baz which will check if item.foo contains the string 'baz';
|
||||
* - ?foo == baz which will check if item.foo is the string 'baz';
|
||||
* - ?foo != baz which will check if item.foo is not the string 'baz';
|
||||
* - ?foo >= 3 which will check if item.foo is greater than or equal to 3;
|
||||
* - ?foo > 3 which will check if item.foo is greater than 3;
|
||||
* - ?foo <= 3 which will check if item.foo is less than or equal to 3;
|
||||
* - ?foo < 3 which will check if item.foo is less than 3;
|
||||
*
|
||||
* - ?foo {} baz which will check if 'baz' is an array element in item.foo
|
||||
* - ?foo {*} baz which will check if 'baz' is an array key in item.foo
|
||||
* - ?foo which will check for a return of a true condition for item.foo;
|
||||
* - ?!foo which will check for a return of a false condition for item.foo;
|
||||
*
|
||||
* The values 0, '', an empty array, and an unset value will all evaluate to false.
|
||||
*
|
||||
* @param string $s
|
||||
* @param array $item
|
||||
* @return bool
|
||||
*/
|
||||
|
||||
public static function test_condition($s,$item) {
|
||||
|
||||
if (preg_match('/(.*?)\s\~\=\s(.*?)$/', $s, $matches)) {
|
||||
$x = ((array_key_exists(trim($matches[1]),$item)) ? $item[trim($matches[1])] : EMPTY_STR);
|
||||
if (stripos($x, trim($matches[2])) !== false) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
if (preg_match('/(.*?)\s\=\=\s(.*?)$/', $s, $matches)) {
|
||||
$x = ((array_key_exists(trim($matches[1]),$item)) ? $item[trim($matches[1])] : EMPTY_STR);
|
||||
if ($x == trim($matches[2])) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
if (preg_match('/(.*?)\s\!\=\s(.*?)$/', $s, $matches)) {
|
||||
$x = ((array_key_exists(trim($matches[1]),$item)) ? $item[trim($matches[1])] : EMPTY_STR);
|
||||
if ($x != trim($matches[2])) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
if (preg_match('/(.*?)\s\>\=\s(.*?)$/', $s, $matches)) {
|
||||
$x = ((array_key_exists(trim($matches[1]),$item)) ? $item[trim($matches[1])] : EMPTY_STR);
|
||||
if ($x >= trim($matches[2])) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
if (preg_match('/(.*?)\s\<\=\s(.*?)$/', $s, $matches)) {
|
||||
$x = ((array_key_exists(trim($matches[1]),$item)) ? $item[trim($matches[1])] : EMPTY_STR);
|
||||
if ($x <= trim($matches[2])) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
if (preg_match('/(.*?)\s\>\s(.*?)$/', $s, $matches)) {
|
||||
$x = ((array_key_exists(trim($matches[1]),$item)) ? $item[trim($matches[1])] : EMPTY_STR);
|
||||
if ($x > trim($matches[2])) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
if (preg_match('/(.*?)\s\>\s(.*?)$/', $s, $matches)) {
|
||||
$x = ((array_key_exists(trim($matches[1]),$item)) ? $item[trim($matches[1])] : EMPTY_STR);
|
||||
if ($x < trim($matches[2])) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
if (preg_match('/[\$](.*?)\s\{\}\s(.*?)$/', $s, $matches)) {
|
||||
$x = ((array_key_exists(trim($matches[1]),$item)) ? $item[trim($matches[1])] : EMPTY_STR);
|
||||
if (is_array($x) && in_array(trim($matches[2]), $x)) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
if (preg_match('/(.*?)\s\{\*\}\s(.*?)$/', $s, $matches)) {
|
||||
$x = ((array_key_exists(trim($matches[1]),$item)) ? $item[trim($matches[1])] : EMPTY_STR);
|
||||
if (is_array($x) && array_key_exists(trim($matches[2]), $x)) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// Ordering of this check (for falsiness) with relation to the following one (check for truthiness) is important.
|
||||
if (preg_match('/\!(.*?)$/', $s, $matches)) {
|
||||
$x = ((array_key_exists(trim($matches[1]),$item)) ? $item[trim($matches[1])] : EMPTY_STR);
|
||||
if (!$x) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
if (preg_match('/(.*?)$/', $s, $matches)) {
|
||||
$x = ((array_key_exists(trim($matches[1]),$item)) ? $item[trim($matches[1])] : EMPTY_STR);
|
||||
if ($x) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,322 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace Zotlabs\Lib;
|
||||
|
||||
use Zotlabs\Lib\Libsync;
|
||||
|
||||
define ( 'NWIKI_ITEM_RESOURCE_TYPE', 'nwiki' );
|
||||
|
||||
class NativeWiki {
|
||||
|
||||
|
||||
public static function listwikis($channel, $observer_hash) {
|
||||
|
||||
$sql_extra = item_permissions_sql($channel['channel_id'], $observer_hash);
|
||||
$wikis = q("SELECT * FROM item
|
||||
WHERE resource_type = '%s' AND mid = parent_mid AND uid = %d AND item_deleted = 0 $sql_extra",
|
||||
dbesc(NWIKI_ITEM_RESOURCE_TYPE),
|
||||
intval($channel['channel_id'])
|
||||
);
|
||||
|
||||
if($wikis) {
|
||||
foreach($wikis as &$w) {
|
||||
|
||||
$w['json_allow_cid'] = acl2json($w['allow_cid']);
|
||||
$w['json_allow_gid'] = acl2json($w['allow_gid']);
|
||||
$w['json_deny_cid'] = acl2json($w['deny_cid']);
|
||||
$w['json_deny_gid'] = acl2json($w['deny_gid']);
|
||||
|
||||
$w['rawName'] = get_iconfig($w, 'wiki', 'rawName');
|
||||
$w['htmlName'] = escape_tags($w['rawName']);
|
||||
//$w['urlName'] = urlencode(urlencode($w['rawName']));
|
||||
$w['urlName'] = self::name_encode($w['rawName']);
|
||||
$w['mimeType'] = get_iconfig($w, 'wiki', 'mimeType');
|
||||
$w['typelock'] = get_iconfig($w, 'wiki', 'typelock');
|
||||
$w['lockstate'] = (($w['allow_cid'] || $w['allow_gid'] || $w['deny_cid'] || $w['deny_gid']) ? 'lock' : 'unlock');
|
||||
}
|
||||
}
|
||||
// TODO: query db for wikis the observer can access. Return with two lists, for read and write access
|
||||
return array('wikis' => $wikis);
|
||||
}
|
||||
|
||||
|
||||
public static function create_wiki($channel, $observer_hash, $wiki, $acl) {
|
||||
|
||||
$resource_id = new_uuid();
|
||||
$uuid = new_uuid();
|
||||
|
||||
$ac = $acl->get();
|
||||
$mid = z_root() . '/item/' . $uuid;
|
||||
|
||||
$arr = array(); // Initialize the array of parameters for the post
|
||||
$item_hidden = ((intval($wiki['postVisible']) === 0) ? 1 : 0);
|
||||
$wiki_url = z_root() . '/wiki/' . $channel['channel_address'] . '/' . $wiki['urlName'];
|
||||
$arr['aid'] = $channel['channel_account_id'];
|
||||
$arr['uuid'] = $uuid;
|
||||
$arr['uid'] = $channel['channel_id'];
|
||||
$arr['mid'] = $mid;
|
||||
$arr['parent_mid'] = $mid;
|
||||
$arr['item_hidden'] = $item_hidden;
|
||||
$arr['resource_type'] = NWIKI_ITEM_RESOURCE_TYPE;
|
||||
$arr['resource_id'] = $resource_id;
|
||||
$arr['owner_xchan'] = $channel['channel_hash'];
|
||||
$arr['author_xchan'] = $observer_hash;
|
||||
$arr['plink'] = $mid;
|
||||
$arr['llink'] = z_root() . '/display/' . gen_link_id($mid);
|
||||
$arr['title'] = $wiki['htmlName']; // name of new wiki;
|
||||
$arr['allow_cid'] = $ac['allow_cid'];
|
||||
$arr['allow_gid'] = $ac['allow_gid'];
|
||||
$arr['deny_cid'] = $ac['deny_cid'];
|
||||
$arr['deny_gid'] = $ac['deny_gid'];
|
||||
$arr['item_wall'] = 1;
|
||||
$arr['item_origin'] = 1;
|
||||
$arr['item_thread_top'] = 1;
|
||||
$arr['item_private'] = intval($acl->is_private());
|
||||
$arr['verb'] = ACTIVITY_CREATE;
|
||||
$arr['obj_type'] = 'Document';
|
||||
$arr['body'] = '[table][tr][td][h1]New Wiki[/h1][/td][/tr][tr][td][zrl=' . $wiki_url . ']' . $wiki['htmlName'] . '[/zrl][/td][/tr][/table]';
|
||||
|
||||
$arr['public_policy'] = map_scope(\Zotlabs\Access\PermissionLimits::Get($channel['channel_id'],'view_wiki'),true);
|
||||
|
||||
// Save the wiki name information using iconfig. This is shareable.
|
||||
if(! set_iconfig($arr, 'wiki', 'rawName', $wiki['rawName'], true)) {
|
||||
return array('item' => null, 'success' => false);
|
||||
}
|
||||
if(! set_iconfig($arr, 'wiki', 'mimeType', $wiki['mimeType'], true)) {
|
||||
return array('item' => null, 'success' => false);
|
||||
}
|
||||
|
||||
set_iconfig($arr,'wiki','typelock',$wiki['typelock'],true);
|
||||
|
||||
$post = item_store($arr);
|
||||
|
||||
$item_id = $post['item_id'];
|
||||
|
||||
if($item_id) {
|
||||
\Zotlabs\Daemon\Master::Summon(array('Notifier', 'activity', $item_id));
|
||||
return array('item' => $post['item'], 'item_id' => $item_id, 'success' => true);
|
||||
}
|
||||
else {
|
||||
return array('item' => null, 'success' => false);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static function update_wiki($channel_id, $observer_hash, $arr, $acl) {
|
||||
|
||||
$w = self::get_wiki($channel_id, $observer_hash, $arr['resource_id']);
|
||||
$item = $w['wiki'];
|
||||
|
||||
if(! $item) {
|
||||
return array('item' => null, 'success' => false);
|
||||
}
|
||||
|
||||
$x = $acl->get();
|
||||
|
||||
$item['allow_cid'] = $x['allow_cid'];
|
||||
$item['allow_gid'] = $x['allow_gid'];
|
||||
$item['deny_cid'] = $x['deny_cid'];
|
||||
$item['deny_gid'] = $x['deny_gid'];
|
||||
$item['item_private'] = intval($acl->is_private());
|
||||
|
||||
$update_title = false;
|
||||
|
||||
if($item['title'] !== $arr['updateRawName']) {
|
||||
$update_title = true;
|
||||
$item['title'] = $arr['updateRawName'];
|
||||
}
|
||||
|
||||
$update = item_store_update($item);
|
||||
|
||||
$item_id = $update['item_id'];
|
||||
|
||||
// update acl for any existing wiki pages
|
||||
|
||||
q("update item set allow_cid = '%s', allow_gid = '%s', deny_cid = '%s', deny_gid = '%s', item_private = %d where resource_type = 'nwikipage' and resource_id = '%s'",
|
||||
dbesc($item['allow_cid']),
|
||||
dbesc($item['allow_gid']),
|
||||
dbesc($item['deny_cid']),
|
||||
dbesc($item['deny_gid']),
|
||||
dbesc($item['item_private']),
|
||||
dbesc($arr['resource_id'])
|
||||
);
|
||||
|
||||
|
||||
if($update['item_id']) {
|
||||
info( t('Wiki updated successfully'));
|
||||
if($update_title) {
|
||||
// Update the wiki name information using iconfig.
|
||||
if(! set_iconfig($update['item_id'], 'wiki', 'rawName', $arr['updateRawName'], true)) {
|
||||
return array('item' => null, 'success' => false);
|
||||
}
|
||||
}
|
||||
return array('item' => $update['item'], 'item_id' => $update['item_id'], 'success' => $update['success']);
|
||||
}
|
||||
else {
|
||||
return array('item' => null, 'success' => false);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static function sync_a_wiki_item($uid,$id,$resource_id) {
|
||||
|
||||
$r = q("SELECT * from item WHERE uid = %d AND ( id = %d OR ( resource_type = '%s' and resource_id = '%s' )) ",
|
||||
intval($uid),
|
||||
intval($id),
|
||||
dbesc(NWIKI_ITEM_RESOURCE_TYPE),
|
||||
dbesc($resource_id)
|
||||
);
|
||||
if($r) {
|
||||
|
||||
$q = q("select * from item where resource_type = 'nwikipage' and resource_id = '%s'",
|
||||
dbesc($r[0]['resource_id'])
|
||||
);
|
||||
if($q) {
|
||||
$r = array_merge($r,$q);
|
||||
}
|
||||
xchan_query($r);
|
||||
$sync_item = fetch_post_tags($r);
|
||||
if($sync_item) {
|
||||
$pkt = [];
|
||||
foreach($sync_item as $w) {
|
||||
$pkt[] = encode_item($w,true);
|
||||
}
|
||||
Libsync::build_sync_packet($uid,array('wiki' => $pkt));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static function delete_wiki($channel_id,$observer_hash,$resource_id) {
|
||||
|
||||
$w = self::get_wiki($channel_id,$observer_hash,$resource_id);
|
||||
if(! $w['wiki']) {
|
||||
return [ 'success' => false ];
|
||||
}
|
||||
else {
|
||||
|
||||
$r = q("SELECT id FROM item WHERE uid = %s AND resource_id = '%s'",
|
||||
intval($channel_id),
|
||||
dbesc($resource_id)
|
||||
);
|
||||
|
||||
$ids = array_column($r, 'id');
|
||||
drop_items($ids, true, DROPITEM_PHASE1);
|
||||
|
||||
info(t('Wiki files deleted successfully'));
|
||||
|
||||
return [ 'success' => true ];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static function get_wiki($channel_id, $observer_hash, $resource_id) {
|
||||
|
||||
$sql_extra = item_permissions_sql($channel_id,$observer_hash);
|
||||
|
||||
$item = q("SELECT * FROM item WHERE uid = %d AND resource_type = '%s' AND resource_id = '%s' AND item_deleted = 0
|
||||
$sql_extra ORDER BY id LIMIT 1",
|
||||
intval($channel_id),
|
||||
dbesc(NWIKI_ITEM_RESOURCE_TYPE),
|
||||
dbesc($resource_id)
|
||||
);
|
||||
if(! $item) {
|
||||
return [ 'wiki' => null ];
|
||||
}
|
||||
else {
|
||||
|
||||
$w = $item[0]; // wiki item table record
|
||||
// Get wiki metadata
|
||||
$rawName = get_iconfig($w, 'wiki', 'rawName');
|
||||
$mimeType = get_iconfig($w, 'wiki', 'mimeType');
|
||||
$typelock = get_iconfig($w, 'wiki', 'typelock');
|
||||
|
||||
return array(
|
||||
'wiki' => $w,
|
||||
'rawName' => $rawName,
|
||||
'htmlName' => escape_tags($rawName),
|
||||
//'urlName' => urlencode(urlencode($rawName)),
|
||||
'urlName' => self::name_encode($rawName),
|
||||
'mimeType' => $mimeType,
|
||||
'typelock' => $typelock
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static function exists_by_name($uid, $urlName) {
|
||||
|
||||
$sql_extra = item_permissions_sql($uid);
|
||||
|
||||
$item = q("SELECT item.id, resource_id FROM item left join iconfig on iconfig.iid = item.id
|
||||
WHERE resource_type = '%s' AND iconfig.v = '%s' AND uid = %d
|
||||
AND item_deleted = 0 $sql_extra limit 1",
|
||||
dbesc(NWIKI_ITEM_RESOURCE_TYPE),
|
||||
//dbesc(urldecode($urlName)),
|
||||
dbesc(self::name_decode($urlName)),
|
||||
intval($uid)
|
||||
);
|
||||
|
||||
if($item) {
|
||||
return array('id' => $item[0]['id'], 'resource_id' => $item[0]['resource_id']);
|
||||
}
|
||||
else {
|
||||
return array('id' => null, 'resource_id' => null);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static function get_permissions($resource_id, $owner_id, $observer_hash) {
|
||||
|
||||
// TODO: For now, only the owner can edit
|
||||
$sql_extra = item_permissions_sql($owner_id, $observer_hash);
|
||||
|
||||
if(local_channel() && local_channel() == $owner_id) {
|
||||
return [ 'read' => true, 'write' => true, 'success' => true ];
|
||||
}
|
||||
|
||||
$r = q("SELECT * FROM item WHERE uid = %d and resource_type = '%s' AND resource_id = '%s' $sql_extra LIMIT 1",
|
||||
intval($owner_id),
|
||||
dbesc(NWIKI_ITEM_RESOURCE_TYPE),
|
||||
dbesc($resource_id)
|
||||
);
|
||||
|
||||
if(! $r) {
|
||||
return array('read' => false, 'write' => false, 'success' => true);
|
||||
}
|
||||
else {
|
||||
$write = perm_is_allowed($owner_id, $observer_hash,'write_wiki');
|
||||
return array('read' => true, 'write' => $write, 'success' => true);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static function name_encode ($string) {
|
||||
|
||||
$string = html_entity_decode($string);
|
||||
$encoding = mb_internal_encoding();
|
||||
mb_internal_encoding("UTF-8");
|
||||
$ret = mb_ereg_replace_callback ('[^A-Za-z0-9\-\_\.\~]',function ($char) {
|
||||
$charhex = unpack('H*',$char[0]);
|
||||
$ret = '('.$charhex[1].')';
|
||||
return $ret;
|
||||
}
|
||||
,$string);
|
||||
mb_internal_encoding($encoding);
|
||||
return $ret;
|
||||
}
|
||||
|
||||
|
||||
public static function name_decode ($string) {
|
||||
|
||||
$encoding = mb_internal_encoding();
|
||||
mb_internal_encoding("UTF-8");
|
||||
$ret = mb_ereg_replace_callback ('(\(([0-9a-f]+)\))',function ($chars) {
|
||||
return pack('H*',$chars[2]);
|
||||
}
|
||||
,$string);
|
||||
mb_internal_encoding($encoding);
|
||||
return $ret;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,725 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace Zotlabs\Lib;
|
||||
|
||||
use App;
|
||||
use Zotlabs\Access\PermissionLimits;
|
||||
|
||||
class NativeWikiPage {
|
||||
|
||||
static public function page_list($channel_id, $observer_hash, $resource_id) {
|
||||
|
||||
// TODO: Create item table records for pages so that metadata like title can be applied
|
||||
$w = NativeWiki::get_wiki($channel_id, $observer_hash, $resource_id);
|
||||
|
||||
$pages[] = [
|
||||
'resource_id' => '',
|
||||
'title' => 'Home',
|
||||
'url' => 'Home',
|
||||
'link_id' => 'id_wiki_home_0'
|
||||
];
|
||||
|
||||
$sql_extra = item_permissions_sql($channel_id, $observer_hash);
|
||||
|
||||
$r = q("select * from item where resource_type = 'nwikipage' and resource_id = '%s' and uid = %d and item_deleted = 0
|
||||
$sql_extra order by title asc",
|
||||
dbesc($resource_id),
|
||||
intval($channel_id)
|
||||
);
|
||||
if ($r) {
|
||||
$x = [];
|
||||
$y = [];
|
||||
|
||||
foreach ($r as $rv) {
|
||||
if (!in_array($rv['mid'], $x)) {
|
||||
$y[] = $rv;
|
||||
$x[] = $rv['mid'];
|
||||
}
|
||||
}
|
||||
|
||||
$items = fetch_post_tags($y, true);
|
||||
|
||||
foreach ($items as $page_item) {
|
||||
$title = get_iconfig($page_item['id'], 'nwikipage', 'pagetitle', t('(No Title)'));
|
||||
if (urldecode($title) !== 'Home') {
|
||||
$pages[] = [
|
||||
'resource_id' => $resource_id,
|
||||
'title' => escape_tags($title),
|
||||
//'url' => str_replace('%2F','/',urlencode(str_replace('%2F','/',urlencode($title)))),
|
||||
'url' => NativeWiki::name_encode($title),
|
||||
'link_id' => 'id_' . substr($resource_id, 0, 10) . '_' . $page_item['id']
|
||||
];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return ['pages' => $pages, 'wiki' => $w];
|
||||
}
|
||||
|
||||
|
||||
static public function create_page($channel, $observer_hash, $name, $resource_id, $mimetype = 'text/bbcode') {
|
||||
|
||||
logger('mimetype: ' . $mimetype);
|
||||
|
||||
if (!in_array($mimetype, ['text/markdown', 'text/bbcode', 'text/plain', 'text/html']))
|
||||
$mimetype = 'text/markdown';
|
||||
|
||||
$w = NativeWiki::get_wiki($channel['channel_id'], $observer_hash, $resource_id);
|
||||
|
||||
if (!$w['wiki']) {
|
||||
return ['content' => null, 'message' => 'Error reading wiki', 'success' => false];
|
||||
}
|
||||
|
||||
// backslashes won't work well in the javascript functions
|
||||
$name = str_replace('\\', '', $name);
|
||||
|
||||
$uuid = new_uuid();
|
||||
$mid = z_root() . '/item/' . $uuid;
|
||||
|
||||
// create an empty activity
|
||||
$arr = [];
|
||||
$arr['aid'] = $channel['channel_account_id'];
|
||||
$arr['uid'] = $channel['channel_id'];
|
||||
$arr['mid'] = $mid;
|
||||
$arr['parent_mid'] = $w['wiki']['mid'];
|
||||
$arr['parent'] = $w['wiki']['parent'];
|
||||
$arr['uuid'] = $uuid;
|
||||
$arr['item_hidden'] = $w['wiki']['item_hidden'];
|
||||
$arr['plink'] = $mid;
|
||||
$arr['llink'] = z_root() . '/display/' . gen_link_id($mid);
|
||||
$arr['author_xchan'] = $observer_hash;
|
||||
$arr['mimetype'] = $mimetype;
|
||||
$arr['title'] = $name;
|
||||
$arr['resource_type'] = 'nwikipage';
|
||||
$arr['resource_id'] = $resource_id;
|
||||
$arr['allow_cid'] = $w['wiki']['allow_cid'];
|
||||
$arr['allow_gid'] = $w['wiki']['allow_gid'];
|
||||
$arr['deny_cid'] = $w['wiki']['deny_cid'];
|
||||
$arr['deny_gid'] = $w['wiki']['deny_gid'];
|
||||
$arr['item_private'] = $w['wiki']['item_private'];
|
||||
$arr['item_wall'] = 1;
|
||||
$arr['item_origin'] = 1;
|
||||
$arr['item_thread_top'] = 1;
|
||||
$arr['verb'] = ACTIVITY_CREATE;
|
||||
$arr['obj_type'] = 'Document';
|
||||
// TODO: add an object?
|
||||
$arr['public_policy'] = map_scope(PermissionLimits::Get($channel['channel_id'], 'view_wiki'), true);
|
||||
|
||||
// We may wish to change this some day.
|
||||
$arr['item_unpublished'] = 1;
|
||||
|
||||
set_iconfig($arr, 'nwikipage', 'pagetitle', (($name) ? $name : t('(No Title)')), true);
|
||||
$p = item_store($arr, false, false);
|
||||
|
||||
if ($p['item_id']) {
|
||||
$page = [
|
||||
'rawName' => $name,
|
||||
'htmlName' => escape_tags($name),
|
||||
//'urlName' => urlencode($name),
|
||||
'urlName' => NativeWiki::name_encode($name)
|
||||
|
||||
];
|
||||
|
||||
return ['page' => $page, 'item_id' => $p['item_id'], 'item' => $p['activity'], 'wiki' => $w, 'message' => '', 'success' => true];
|
||||
}
|
||||
return ['success' => false, 'message' => t('Wiki page create failed.')];
|
||||
}
|
||||
|
||||
|
||||
static public function rename_page($arr) {
|
||||
|
||||
$pageUrlName = ((array_key_exists('pageUrlName', $arr)) ? $arr['pageUrlName'] : '');
|
||||
$pageNewName = ((array_key_exists('pageNewName', $arr)) ? $arr['pageNewName'] : '');
|
||||
$resource_id = ((array_key_exists('resource_id', $arr)) ? $arr['resource_id'] : '');
|
||||
$observer_hash = ((array_key_exists('observer_hash', $arr)) ? $arr['observer_hash'] : '');
|
||||
$channel_id = ((array_key_exists('channel_id', $arr)) ? $arr['channel_id'] : 0);
|
||||
|
||||
$w = NativeWiki::get_wiki($channel_id, $observer_hash, $resource_id);
|
||||
if (!$w['wiki']) {
|
||||
return ['message' => t('Wiki not found.'), 'success' => false];
|
||||
}
|
||||
|
||||
|
||||
$ic = q("select * from iconfig left join item on iconfig.iid = item.id
|
||||
where uid = %d and cat = 'nwikipage' and k = 'pagetitle' and v = '%s'",
|
||||
intval($channel_id),
|
||||
dbesc($pageNewName)
|
||||
);
|
||||
|
||||
if ($ic) {
|
||||
return ['success' => false, 'message' => t('Destination name already exists')];
|
||||
}
|
||||
|
||||
|
||||
$ids = [];
|
||||
|
||||
$ic = q("select *, item.id as item_id from iconfig left join item on iconfig.iid = item.id
|
||||
where uid = %d and cat = 'nwikipage' and k = 'pagetitle' and v = '%s'",
|
||||
intval($channel_id),
|
||||
dbesc($pageUrlName)
|
||||
);
|
||||
|
||||
if ($ic) {
|
||||
foreach ($ic as $c) {
|
||||
set_iconfig($c['item_id'], 'nwikipage', 'pagetitle', $pageNewName);
|
||||
$ids[] = $c['item_id'];
|
||||
}
|
||||
|
||||
$str_ids = implode(',', $ids);
|
||||
q("update item set title = '%s' where id in ($str_ids)",
|
||||
dbesc($pageNewName)
|
||||
);
|
||||
|
||||
$page = [
|
||||
'rawName' => $pageNewName,
|
||||
'htmlName' => escape_tags($pageNewName),
|
||||
//'urlName' => urlencode(escape_tags($pageNewName))
|
||||
'urlName' => NativeWiki::name_encode($pageNewName)
|
||||
];
|
||||
|
||||
return ['success' => true, 'page' => $page];
|
||||
}
|
||||
|
||||
return ['success' => false, 'message' => t('Page not found')];
|
||||
|
||||
}
|
||||
|
||||
|
||||
static public function get_page_content($arr) {
|
||||
|
||||
$resource_id = ((array_key_exists('resource_id', $arr)) ? $arr['resource_id'] : '');
|
||||
$observer_hash = ((array_key_exists('observer_hash', $arr)) ? $arr['observer_hash'] : '');
|
||||
$channel_id = ((array_key_exists('channel_id', $arr)) ? intval($arr['channel_id']) : 0);
|
||||
|
||||
$w = NativeWiki::get_wiki($channel_id, $observer_hash, $resource_id);
|
||||
if (!$w['wiki']) {
|
||||
return ['content' => null, 'message' => 'Error reading wiki', 'success' => false];
|
||||
}
|
||||
|
||||
$item = self::load_page($arr);
|
||||
|
||||
if ($item) {
|
||||
$content = $item['body'];
|
||||
|
||||
return [
|
||||
'content' => $content,
|
||||
'mimeType' => $w['mimeType'],
|
||||
'pageMimeType' => $item['mimetype'],
|
||||
'message' => '',
|
||||
'success' => true
|
||||
];
|
||||
}
|
||||
|
||||
return ['content' => null, 'message' => t('Error reading page content'), 'success' => false];
|
||||
|
||||
}
|
||||
|
||||
|
||||
static public function page_history($arr) {
|
||||
|
||||
$resource_id = ((array_key_exists('resource_id', $arr)) ? $arr['resource_id'] : '');
|
||||
$observer_hash = ((array_key_exists('observer_hash', $arr)) ? $arr['observer_hash'] : '');
|
||||
$channel_id = ((array_key_exists('channel_id', $arr)) ? $arr['channel_id'] : 0);
|
||||
|
||||
$w = NativeWiki::get_wiki($channel_id, $observer_hash, $resource_id);
|
||||
if (!$w['wiki']) {
|
||||
return ['history' => null, 'message' => 'Error reading wiki', 'success' => false];
|
||||
}
|
||||
|
||||
$items = self::load_page_history($arr);
|
||||
|
||||
$history = [];
|
||||
|
||||
if ($items) {
|
||||
$processed = 0;
|
||||
foreach ($items as $item) {
|
||||
if ($processed > 1000)
|
||||
break;
|
||||
$processed++;
|
||||
$history[] = [
|
||||
'revision' => $item['revision'],
|
||||
'date' => datetime_convert('UTC', date_default_timezone_get(), $item['edited']),
|
||||
'name' => $item['author']['xchan_name'],
|
||||
'title' => get_iconfig($item, 'nwikipage', 'commit_msg')
|
||||
];
|
||||
|
||||
}
|
||||
|
||||
return ['success' => true, 'history' => $history];
|
||||
}
|
||||
|
||||
return ['success' => false];
|
||||
|
||||
}
|
||||
|
||||
|
||||
static public function load_page($arr) {
|
||||
|
||||
$pageUrlName = ((array_key_exists('pageUrlName', $arr)) ? $arr['pageUrlName'] : '');
|
||||
$resource_id = ((array_key_exists('resource_id', $arr)) ? $arr['resource_id'] : '');
|
||||
$observer_hash = ((array_key_exists('observer_hash', $arr)) ? $arr['observer_hash'] : '');
|
||||
$channel_id = ((array_key_exists('channel_id', $arr)) ? $arr['channel_id'] : 0);
|
||||
$revision = ((array_key_exists('revision', $arr)) ? $arr['revision'] : (-1));
|
||||
|
||||
$w = NativeWiki::get_wiki($channel_id, $observer_hash, $resource_id);
|
||||
|
||||
if (!$w['wiki']) {
|
||||
return ['content' => null, 'message' => 'Error reading wiki', 'success' => false];
|
||||
}
|
||||
|
||||
$ids = '';
|
||||
|
||||
$ic = q("select * from iconfig left join item on iconfig.iid = item.id where uid = %d and cat = 'nwikipage' and k = 'pagetitle' and v = '%s'",
|
||||
intval($channel_id),
|
||||
dbesc($pageUrlName)
|
||||
);
|
||||
|
||||
if ($ic) {
|
||||
foreach ($ic as $c) {
|
||||
if ($ids)
|
||||
$ids .= ',';
|
||||
$ids .= intval($c['iid']);
|
||||
}
|
||||
}
|
||||
|
||||
$sql_extra = item_permissions_sql($channel_id, $observer_hash);
|
||||
|
||||
if ($revision == (-1))
|
||||
$sql_extra .= " order by revision desc ";
|
||||
elseif ($revision)
|
||||
$sql_extra .= " and revision = " . intval($revision) . " ";
|
||||
|
||||
$r = null;
|
||||
|
||||
|
||||
if ($ids) {
|
||||
$r = q("select * from item where resource_type = 'nwikipage' and resource_id = '%s' and uid = %d and id in ( $ids ) $sql_extra limit 1",
|
||||
dbesc($resource_id),
|
||||
intval($channel_id)
|
||||
);
|
||||
|
||||
if ($r) {
|
||||
$items = fetch_post_tags($r, true);
|
||||
return $items[0];
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
static public function load_page_history($arr) {
|
||||
|
||||
$pageUrlName = ((array_key_exists('pageUrlName', $arr)) ? $arr['pageUrlName'] : '');
|
||||
$resource_id = ((array_key_exists('resource_id', $arr)) ? $arr['resource_id'] : '');
|
||||
$observer_hash = ((array_key_exists('observer_hash', $arr)) ? $arr['observer_hash'] : '');
|
||||
$channel_id = ((array_key_exists('channel_id', $arr)) ? $arr['channel_id'] : 0);
|
||||
|
||||
$w = NativeWiki::get_wiki($channel_id, $observer_hash, $resource_id);
|
||||
if (!$w['wiki']) {
|
||||
return ['content' => null, 'message' => 'Error reading wiki', 'success' => false];
|
||||
}
|
||||
|
||||
$ids = '';
|
||||
|
||||
$ic = q("select * from iconfig left join item on iconfig.iid = item.id where uid = %d and cat = 'nwikipage' and k = 'pagetitle' and v = '%s'",
|
||||
intval($channel_id),
|
||||
dbesc($pageUrlName)
|
||||
);
|
||||
|
||||
if ($ic) {
|
||||
foreach ($ic as $c) {
|
||||
if ($ids)
|
||||
$ids .= ',';
|
||||
$ids .= intval($c['iid']);
|
||||
}
|
||||
}
|
||||
|
||||
$sql_extra = item_permissions_sql($channel_id, $observer_hash);
|
||||
|
||||
$sql_extra .= " order by revision desc ";
|
||||
|
||||
$r = null;
|
||||
if ($ids) {
|
||||
$r = q("select * from item where resource_type = 'nwikipage' and resource_id = '%s' and uid = %d and id in ( $ids ) and item_deleted = 0 $sql_extra",
|
||||
dbesc($resource_id),
|
||||
intval($channel_id)
|
||||
);
|
||||
if ($r) {
|
||||
xchan_query($r);
|
||||
$items = fetch_post_tags($r, true);
|
||||
return $items;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
static public function save_page($arr) {
|
||||
$pageUrlName = ((array_key_exists('pageUrlName', $arr)) ? $arr['pageUrlName'] : '');
|
||||
$content = ((array_key_exists('content', $arr)) ? $arr['content'] : '');
|
||||
$resource_id = ((array_key_exists('resource_id', $arr)) ? $arr['resource_id'] : '');
|
||||
$observer_hash = ((array_key_exists('observer_hash', $arr)) ? $arr['observer_hash'] : '');
|
||||
$channel_id = ((array_key_exists('channel_id', $arr)) ? $arr['channel_id'] : 0);
|
||||
|
||||
$w = NativeWiki::get_wiki($channel_id, $observer_hash, $resource_id);
|
||||
|
||||
if (!$w['wiki']) {
|
||||
return ['message' => t('Error reading wiki'), 'success' => false];
|
||||
}
|
||||
|
||||
|
||||
// fetch the most recently saved revision.
|
||||
|
||||
$item = self::load_page($arr);
|
||||
|
||||
if (!$item) {
|
||||
return ['message' => t('Page not found'), 'success' => false];
|
||||
}
|
||||
|
||||
$mimetype = $item['mimetype'];
|
||||
|
||||
// change just the fields we need to change to create a revision;
|
||||
|
||||
unset($item['id']);
|
||||
unset($item['author']);
|
||||
$item['parent'] = 0;
|
||||
$item['body'] = $content;
|
||||
$item['author_xchan'] = $observer_hash;
|
||||
$item['revision'] = (($arr['revision']) ? intval($arr['revision']) + 1 : intval($item['revision']) + 1);
|
||||
$item['edited'] = datetime_convert();
|
||||
$item['mimetype'] = $mimetype;
|
||||
|
||||
if ($item['iconfig'] && is_array($item['iconfig']) && count($item['iconfig'])) {
|
||||
for ($x = 0; $x < count($item['iconfig']); $x++) {
|
||||
unset($item['iconfig'][$x]['id']);
|
||||
unset($item['iconfig'][$x]['iid']);
|
||||
}
|
||||
}
|
||||
|
||||
$ret = item_store($item, false, false);
|
||||
|
||||
if ($ret['item_id'])
|
||||
return ['message' => '', 'item_id' => $ret['item_id'], 'filename' => $pageUrlName, 'success' => true];
|
||||
else
|
||||
return ['message' => t('Page update failed.'), 'success' => false];
|
||||
}
|
||||
|
||||
|
||||
static public function delete_page($arr) {
|
||||
|
||||
$pageUrlName = (array_key_exists('pageUrlName', $arr) ? $arr['pageUrlName'] : '');
|
||||
$resource_id = (array_key_exists('resource_id', $arr) ? $arr['resource_id'] : '');
|
||||
$observer_hash = (array_key_exists('observer_hash', $arr) ? $arr['observer_hash'] : '');
|
||||
$channel_id = (array_key_exists('channel_id', $arr) ? $arr['channel_id'] : 0);
|
||||
|
||||
$w = NativeWiki::get_wiki($channel_id, $observer_hash, $resource_id);
|
||||
if (!$w['wiki']) {
|
||||
return ['success' => false, 'message' => t('Error reading wiki')];
|
||||
}
|
||||
|
||||
$ids = [];
|
||||
|
||||
$ic = q("select * from iconfig left join item on iconfig.iid = item.id
|
||||
where uid = %d and cat = 'nwikipage' and k = 'pagetitle' and v = '%s'",
|
||||
intval($channel_id),
|
||||
dbesc($pageUrlName)
|
||||
);
|
||||
|
||||
if ($ic) {
|
||||
foreach ($ic as $c) {
|
||||
$ids[] = intval($c['iid']);
|
||||
}
|
||||
}
|
||||
|
||||
if ($ids) {
|
||||
drop_items($ids, true, DROPITEM_PHASE1);
|
||||
return ['success' => true];
|
||||
}
|
||||
|
||||
return ['success' => false, 'message' => t('Nothing deleted')];
|
||||
}
|
||||
|
||||
|
||||
static public function revert_page($arr) {
|
||||
|
||||
$resource_id = ((array_key_exists('resource_id', $arr)) ? $arr['resource_id'] : '');
|
||||
$commitHash = ((array_key_exists('commitHash', $arr)) ? $arr['commitHash'] : null);
|
||||
$observer_hash = ((array_key_exists('observer_hash', $arr)) ? $arr['observer_hash'] : '');
|
||||
$channel_id = ((array_key_exists('channel_id', $arr)) ? $arr['channel_id'] : 0);
|
||||
|
||||
if (!$commitHash) {
|
||||
return ['message' => 'No commit was provided', 'success' => false];
|
||||
}
|
||||
|
||||
$w = NativeWiki::get_wiki($channel_id, $observer_hash, $resource_id);
|
||||
if (!$w['wiki']) {
|
||||
return ['message' => 'Error reading wiki', 'success' => false];
|
||||
}
|
||||
|
||||
$x = $arr;
|
||||
|
||||
if (intval($commitHash) > 0) {
|
||||
unset($x['commitHash']);
|
||||
$x['revision'] = intval($commitHash) - 1;
|
||||
$loaded = self::load_page($x);
|
||||
|
||||
if ($loaded) {
|
||||
$content = $loaded['body'];
|
||||
return ['content' => $content, 'success' => true];
|
||||
}
|
||||
return ['success' => false];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static public function compare_page($arr) {
|
||||
|
||||
$resource_id = ((array_key_exists('resource_id', $arr)) ? $arr['resource_id'] : '');
|
||||
$compareCommit = ((array_key_exists('compareCommit', $arr)) ? $arr['compareCommit'] : 0);
|
||||
$observer_hash = ((array_key_exists('observer_hash', $arr)) ? $arr['observer_hash'] : '');
|
||||
$channel_id = ((array_key_exists('channel_id', $arr)) ? $arr['channel_id'] : 0);
|
||||
|
||||
$w = NativeWiki::get_wiki($channel_id, $observer_hash, $resource_id);
|
||||
|
||||
if (!$w['wiki']) {
|
||||
return ['message' => t('Error reading wiki'), 'success' => false];
|
||||
}
|
||||
|
||||
$x = $arr;
|
||||
$x['revision'] = (-1);
|
||||
|
||||
$currpage = self::load_page($x);
|
||||
if ($currpage)
|
||||
$currentContent = $currpage['body'];
|
||||
|
||||
$x['revision'] = $compareCommit;
|
||||
$comppage = self::load_page($x);
|
||||
if ($comppage)
|
||||
$compareContent = $comppage['body'];
|
||||
|
||||
if ($currpage && $comppage) {
|
||||
require_once('library/class.Diff.php');
|
||||
$diff = \Diff::toTable(\Diff::compare($currentContent, $compareContent));
|
||||
|
||||
return ['success' => true, 'diff' => $diff];
|
||||
}
|
||||
return ['success' => false, 'message' => t('Compare: object not found.')];
|
||||
|
||||
}
|
||||
|
||||
|
||||
static public function commit($arr) {
|
||||
|
||||
$commit_msg = ((array_key_exists('commit_msg', $arr)) ? $arr['commit_msg'] : t('Page updated'));
|
||||
$observer_hash = ((array_key_exists('observer_hash', $arr)) ? $arr['observer_hash'] : '');
|
||||
$channel_id = ((array_key_exists('channel_id', $arr)) ? $arr['channel_id'] : 0);
|
||||
|
||||
if (array_key_exists('resource_id', $arr)) {
|
||||
$resource_id = $arr['resource_id'];
|
||||
}
|
||||
else {
|
||||
return ['message' => t('Wiki resource_id required for git commit'), 'success' => false];
|
||||
}
|
||||
|
||||
$w = NativeWiki::get_wiki($channel_id, $observer_hash, $resource_id);
|
||||
if (!$w['wiki']) {
|
||||
return ['message' => t('Error reading wiki'), 'success' => false];
|
||||
}
|
||||
|
||||
|
||||
$page = self::load_page($arr);
|
||||
|
||||
if ($page) {
|
||||
set_iconfig($page['id'], 'nwikipage', 'commit_msg', escape_tags($commit_msg), true);
|
||||
return ['success' => true, 'item_id' => $page['id'], 'page' => $page];
|
||||
}
|
||||
|
||||
return ['success' => false, 'message' => t('Page not found.')];
|
||||
|
||||
}
|
||||
|
||||
static public function convert_links($s, $wikiURL) {
|
||||
|
||||
if (strpos($s, '[[') !== false) {
|
||||
preg_match_all("/\[\[(.*?)\]\]/", $s, $match);
|
||||
$pages = $pageURLs = [];
|
||||
foreach ($match[1] as $m) {
|
||||
// TODO: Why do we need to double urlencode for this to work?
|
||||
//$pageURLs[] = urlencode(urlencode(escape_tags($m)));
|
||||
$titleUri = explode('|', $m);
|
||||
$page = $titleUri[0] ?? '';
|
||||
$title = $titleUri[1] ?? $page;
|
||||
$pageURLs[] = NativeWiki::name_encode(escape_tags($page));
|
||||
$pages[] = $title;
|
||||
}
|
||||
$idx = 0;
|
||||
while (strpos($s, '[[') !== false) {
|
||||
$replace = '<a href="' . $wikiURL . '/' . $pageURLs[$idx] . '">' . $pages[$idx] . '</a>';
|
||||
$s = preg_replace("/\[\[(.*?)\]\]/", $replace, $s, 1);
|
||||
$idx++;
|
||||
}
|
||||
}
|
||||
return $s;
|
||||
}
|
||||
|
||||
static public function render_page_history($arr) {
|
||||
|
||||
$pageUrlName = ((array_key_exists('pageUrlName', $arr)) ? $arr['pageUrlName'] : '');
|
||||
$resource_id = ((array_key_exists('resource_id', $arr)) ? $arr['resource_id'] : '');
|
||||
|
||||
$pageHistory = self::page_history([
|
||||
'channel_id' => App::$profile_uid,
|
||||
'observer_hash' => get_observer_hash(),
|
||||
'resource_id' => $resource_id,
|
||||
'pageUrlName' => $pageUrlName
|
||||
]);
|
||||
|
||||
return replace_macros(get_markup_template('nwiki_page_history.tpl'), [
|
||||
'$pageHistory' => $pageHistory['history'],
|
||||
'$permsWrite' => $arr['permsWrite'],
|
||||
'$name_lbl' => t('Name'),
|
||||
'$msg_label' => t('Message', 'wiki_history'),
|
||||
'$date_lbl' => t('Date'),
|
||||
'$revert_btn' => t('Revert'),
|
||||
'$compare_btn' => t('Compare')
|
||||
]);
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Replace the instances of the string [toc] with a list element that will be populated by
|
||||
* a table of contents by the JavaScript library
|
||||
* @param string $s
|
||||
* @return string
|
||||
*/
|
||||
static public function generate_toc($s) {
|
||||
if (strpos($s, '[toc]') !== false) {
|
||||
//$toc_md = wiki_toc($s); // Generate Markdown-formatted list prior to HTML render
|
||||
$toc_md = '<ul id="wiki-toc"></ul>'; // use the available jQuery plugin http://ndabas.github.io/toc/
|
||||
$s = preg_replace("/\[toc\]/", $toc_md, $s, -1);
|
||||
}
|
||||
return $s;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Converts a select set of bbcode tags. Much of the code is copied from include/bbcode.php
|
||||
* @param string $s
|
||||
* @return string
|
||||
*/
|
||||
static public function bbcode($s) {
|
||||
|
||||
$s = str_replace(['[baseurl]', '[sitename]'], [z_root(), get_config('system', 'sitename')], $s);
|
||||
|
||||
$s = preg_replace_callback("/\[observer\.language\=(.*?)\](.*?)\[\/observer\]/ism", 'oblanguage_callback', $s);
|
||||
|
||||
$s = preg_replace_callback("/\[observer\.language\!\=(.*?)\](.*?)\[\/observer\]/ism", 'oblanguage_necallback', $s);
|
||||
|
||||
|
||||
$observer = App::get_observer();
|
||||
if ($observer) {
|
||||
$s1 = '<span class="bb_observer" title="' . t('Different viewers will see this text differently') . '">';
|
||||
$s2 = '</span>';
|
||||
$obsBaseURL = $observer['xchan_connurl'];
|
||||
$obsBaseURL = preg_replace("/\/poco\/.*$/", '', $obsBaseURL);
|
||||
$s = str_replace('[observer.baseurl]', $obsBaseURL, $s);
|
||||
$s = str_replace('[observer.url]', $observer['xchan_url'], $s);
|
||||
$s = str_replace('[observer.name]', $s1 . $observer['xchan_name'] . $s2, $s);
|
||||
$s = str_replace('[observer.address]', $s1 . $observer['xchan_addr'] . $s2, $s);
|
||||
$s = str_replace('[observer.webname]', substr($observer['xchan_addr'], 0, strpos($observer['xchan_addr'], '@')), $s);
|
||||
$s = str_replace('[observer.photo]', '', $s);
|
||||
}
|
||||
else {
|
||||
$s = str_replace('[observer.baseurl]', '', $s);
|
||||
$s = str_replace('[observer.url]', '', $s);
|
||||
$s = str_replace('[observer.name]', '', $s);
|
||||
$s = str_replace('[observer.address]', '', $s);
|
||||
$s = str_replace('[observer.webname]', '', $s);
|
||||
$s = str_replace('[observer.photo]', '', $s);
|
||||
}
|
||||
|
||||
return $s;
|
||||
}
|
||||
|
||||
|
||||
static public function get_file_ext($arr) {
|
||||
|
||||
if ($arr['mimetype'] === 'text/bbcode')
|
||||
return '.bb';
|
||||
elseif ($arr['mimetype'] === 'text/markdown')
|
||||
return '.md';
|
||||
elseif ($arr['mimetype'] === 'text/plain')
|
||||
return '.txt';
|
||||
|
||||
}
|
||||
|
||||
// This function is derived from
|
||||
// http://stackoverflow.com/questions/32068537/generate-table-of-contents-from-markdown-in-php
|
||||
static public function toc($content) {
|
||||
// ensure using only "\n" as line-break
|
||||
$source = str_replace(["\r\n", "\r"], "\n", $content);
|
||||
|
||||
// look for markdown TOC items
|
||||
preg_match_all(
|
||||
'/^(?:=|-|#).*$/m',
|
||||
$source,
|
||||
$matches,
|
||||
PREG_PATTERN_ORDER | PREG_OFFSET_CAPTURE
|
||||
);
|
||||
|
||||
// preprocess: iterate matched lines to create an array of items
|
||||
// where each item is an array(level, text)
|
||||
$file_size = strlen($source);
|
||||
foreach ($matches[0] as $item) {
|
||||
$found_mark = substr($item[0], 0, 1);
|
||||
if ($found_mark == '#') {
|
||||
// text is the found item
|
||||
$item_text = $item[0];
|
||||
$item_level = strrpos($item_text, '#') + 1;
|
||||
$item_text = substr($item_text, $item_level);
|
||||
}
|
||||
else {
|
||||
// text is the previous line (empty if <hr>)
|
||||
$item_offset = $item[1];
|
||||
$prev_line_offset = strrpos($source, "\n", -($file_size - $item_offset + 2));
|
||||
$item_text =
|
||||
substr($source, $prev_line_offset, $item_offset - $prev_line_offset - 1);
|
||||
$item_text = trim($item_text);
|
||||
$item_level = $found_mark == '=' ? 1 : 2;
|
||||
}
|
||||
if (!trim($item_text) or strpos($item_text, '|') !== FALSE) {
|
||||
// item is an horizontal separator or a table header, don't mind
|
||||
continue;
|
||||
}
|
||||
$raw_toc[] = ['level' => $item_level, 'text' => trim($item_text)];
|
||||
}
|
||||
$o = '';
|
||||
foreach ($raw_toc as $t) {
|
||||
$level = intval($t['level']);
|
||||
$text = $t['text'];
|
||||
switch ($level) {
|
||||
case 1:
|
||||
$li = '* ';
|
||||
break;
|
||||
case 2:
|
||||
$li = ' * ';
|
||||
break;
|
||||
case 3:
|
||||
$li = ' * ';
|
||||
break;
|
||||
case 4:
|
||||
$li = ' * ';
|
||||
break;
|
||||
default:
|
||||
$li = '* ';
|
||||
break;
|
||||
}
|
||||
$o .= $li . $text . "\n";
|
||||
}
|
||||
return $o;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -4,7 +4,6 @@ namespace Zotlabs\Lib;
|
||||
|
||||
use Zotlabs\Access\PermissionRoles;
|
||||
use Zotlabs\Access\Permissions;
|
||||
use Zotlabs\Lib\Libsync;
|
||||
use Zotlabs\Daemon\Master;
|
||||
|
||||
/**
|
||||
@@ -40,33 +39,33 @@ class Permcat {
|
||||
|
||||
// first check role perms for a perms_connect setting
|
||||
|
||||
$role = get_pconfig($channel_id,'system','permissions_role');
|
||||
if($role) {
|
||||
$role = get_pconfig($channel_id, 'system', 'permissions_role');
|
||||
if ($role) {
|
||||
$x = PermissionRoles::role_perms($role);
|
||||
if($x['perms_connect']) {
|
||||
if ($x['perms_connect']) {
|
||||
$perms = Permissions::FilledPerms($x['perms_connect']);
|
||||
}
|
||||
}
|
||||
|
||||
// if no role perms it may be a custom role, see if there any autoperms
|
||||
|
||||
if(! $perms) {
|
||||
if (!$perms) {
|
||||
$perms = Permissions::FilledAutoPerms($channel_id);
|
||||
}
|
||||
|
||||
// if no autoperms it may be a custom role with manual perms
|
||||
|
||||
if(! $perms) {
|
||||
if (!$perms) {
|
||||
$r = q("select channel_hash from channel where channel_id = %d",
|
||||
intval($channel_id)
|
||||
);
|
||||
if($r) {
|
||||
if ($r) {
|
||||
$x = q("select * from abconfig where chan = %d and xchan = '%s' and cat = 'my_perms'",
|
||||
intval($channel_id),
|
||||
dbesc($r[0]['channel_hash'])
|
||||
);
|
||||
if($x) {
|
||||
foreach($x as $xv) {
|
||||
if ($x) {
|
||||
foreach ($x as $xv) {
|
||||
$perms[$xv['k']] = intval($xv['v']);
|
||||
}
|
||||
}
|
||||
@@ -75,13 +74,13 @@ class Permcat {
|
||||
|
||||
// nothing was found - create a filled permission array where all permissions are 0
|
||||
|
||||
if(! $perms) {
|
||||
if (!$perms) {
|
||||
$perms = Permissions::FilledPerms([]);
|
||||
}
|
||||
|
||||
$this->permcats[] = [
|
||||
'name' => 'default',
|
||||
'localname' => t('Default','permcat'),
|
||||
'localname' => t('Default', 'permcat'),
|
||||
'perms' => Permissions::Operms($perms),
|
||||
'raw_perms' => $perms,
|
||||
'system' => 1
|
||||
@@ -89,8 +88,8 @@ class Permcat {
|
||||
|
||||
|
||||
$p = $this->load_permcats($channel_id);
|
||||
if($p) {
|
||||
for($x = 0; $x < count($p); $x++) {
|
||||
if ($p) {
|
||||
for ($x = 0; $x < count($p); $x++) {
|
||||
$this->permcats[] = [
|
||||
'name' => $p[$x][0],
|
||||
'localname' => $p[$x][1],
|
||||
@@ -120,9 +119,9 @@ class Permcat {
|
||||
* * \e bool \b error if $name not found in permcats true
|
||||
*/
|
||||
public function fetch($name) {
|
||||
if($name && $this->permcats) {
|
||||
foreach($this->permcats as $permcat) {
|
||||
if(strcasecmp($permcat['name'], $name) === 0) {
|
||||
if ($name && $this->permcats) {
|
||||
foreach ($this->permcats as $permcat) {
|
||||
if (strcasecmp($permcat['name'], $name) === 0) {
|
||||
return $permcat;
|
||||
}
|
||||
}
|
||||
@@ -132,7 +131,7 @@ class Permcat {
|
||||
}
|
||||
|
||||
public function load_permcats($uid) {
|
||||
/*
|
||||
/*
|
||||
$permcats = [
|
||||
[ 'contributor', t('Contributor','permcat'),
|
||||
[ 'view_stream','view_profile','view_contacts','view_storage','view_pages',
|
||||
@@ -144,16 +143,16 @@ class Permcat {
|
||||
'post_comments','write_wiki','post_like' ], 1
|
||||
],
|
||||
];
|
||||
*/
|
||||
if($uid) {
|
||||
*/
|
||||
if ($uid) {
|
||||
$x = q("select * from pconfig where uid = %d and cat = 'permcat'",
|
||||
intval($uid)
|
||||
);
|
||||
|
||||
if($x) {
|
||||
foreach($x as $xv) {
|
||||
$value = ((preg_match('|^a:[0-9]+:{.*}$|s', $xv['v'])) ? unserialize($xv['v']) : $xv['v']);
|
||||
$permcats[] = [ $xv['k'], $xv['k'], $value, 0 ];
|
||||
if ($x) {
|
||||
foreach ($x as $xv) {
|
||||
$value = ((preg_match('|^a:[0-9]+:{.*}$|s', $xv['v'])) ? unserialize($xv['v']) : $xv['v']);
|
||||
$permcats[] = [$xv['k'], $xv['k'], $value, 0];
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -168,11 +167,11 @@ class Permcat {
|
||||
}
|
||||
|
||||
static public function find_permcat($arr, $name) {
|
||||
if((! $arr) || (! $name))
|
||||
if ((!$arr) || (!$name))
|
||||
return false;
|
||||
|
||||
foreach($arr as $p)
|
||||
if($p['name'] == $name)
|
||||
foreach ($arr as $p)
|
||||
if ($p['name'] == $name)
|
||||
return $p['value'];
|
||||
}
|
||||
|
||||
@@ -187,23 +186,23 @@ class Permcat {
|
||||
/**
|
||||
* @brief assign a contact role to contacts
|
||||
*
|
||||
* @param int $channel_id
|
||||
* @param array $channel
|
||||
* @param string $role the name of the role
|
||||
* @param array $contacts an array of contact hashes
|
||||
*/
|
||||
public static function assign($channel, $role, $contacts) {
|
||||
|
||||
if(!isset($channel['channel_id'])) {
|
||||
if (!isset($channel['channel_id'])) {
|
||||
return;
|
||||
}
|
||||
|
||||
if(!is_array($contacts) || empty($contacts)) {
|
||||
if (!is_array($contacts) || empty($contacts)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if(!$role) {
|
||||
if (!$role) {
|
||||
// lookup the default
|
||||
$role = get_pconfig($channel_id, 'system', 'default_permcat', 'default');
|
||||
$role = get_pconfig($channel['channel_id'], 'system', 'default_permcat', 'default');
|
||||
}
|
||||
|
||||
|
||||
@@ -231,10 +230,10 @@ class Permcat {
|
||||
foreach ($contacts as $contact) {
|
||||
foreach ($all_perms as $perm => $desc) {
|
||||
if (array_key_exists($perm, $perms)) {
|
||||
$values_sql .= " (" . intval($channel['channel_id']) . ", " . protect_sprintf($contact) . ", 'my_perms', '" . dbesc($perm) . "', " . intval($perms[$perm]) . "),";
|
||||
$values_sql .= " (" . intval($channel['channel_id']) . ", " . protect_sprintf($contact) . ", 'my_perms', '" . dbesc($perm) . "', " . intval($perms[$perm]) . "),";
|
||||
}
|
||||
else {
|
||||
$values_sql .= " (" . intval($channel['channel_id']) . ", " . protect_sprintf($contact) . ", 'my_perms', '" . dbesc($perm) . "', 0), ";
|
||||
$values_sql .= " (" . intval($channel['channel_id']) . ", " . protect_sprintf($contact) . ", 'my_perms', '" . dbesc($perm) . "', 0), ";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -110,21 +110,30 @@ class Queue {
|
||||
return false;
|
||||
}
|
||||
|
||||
$hash = $arr['hash'] ?? '';
|
||||
$account_id = $arr['account_id'] ?? 0;
|
||||
$channel_id = $arr['channel_id'] ?? 0;
|
||||
$driver = $arr['driver'] ?? 'zot6';
|
||||
$posturl = $arr['posturl'] ?? '';
|
||||
$priority = $arr['priority'] ?? 0;
|
||||
$notify = $arr['notify'] ?? '';
|
||||
$msg = $arr['msg'] ?? '';
|
||||
|
||||
$x = q("insert into outq ( outq_hash, outq_account, outq_channel, outq_driver, outq_posturl, outq_async, outq_priority,
|
||||
outq_created, outq_updated, outq_scheduled, outq_notify, outq_msg )
|
||||
values ( '%s', %d, %d, '%s', '%s', %d, %d, '%s', '%s', '%s', '%s', '%s' )",
|
||||
dbesc($arr['hash']),
|
||||
intval($arr['account_id']),
|
||||
intval($arr['channel_id']),
|
||||
dbesc(($arr['driver']) ? $arr['driver'] : 'zot6'),
|
||||
dbesc($arr['posturl']),
|
||||
dbesc($hash),
|
||||
intval($account_id),
|
||||
intval($channel_id),
|
||||
dbesc($driver),
|
||||
dbesc($posturl),
|
||||
intval(1),
|
||||
intval(isset($arr['priority']) ? $arr['priority'] : 0),
|
||||
intval($priority),
|
||||
dbesc(datetime_convert()),
|
||||
dbesc(datetime_convert()),
|
||||
dbesc(datetime_convert()),
|
||||
dbesc($arr['notify']),
|
||||
dbesc(($arr['msg']) ? $arr['msg'] : '')
|
||||
dbesc($notify),
|
||||
dbesc($msg)
|
||||
);
|
||||
return $x;
|
||||
|
||||
@@ -202,7 +211,7 @@ class Queue {
|
||||
|
||||
if($channel && $base) {
|
||||
$h = q("SELECT hubloc_sitekey, site_crypto FROM hubloc LEFT JOIN site ON hubloc_url = site_url
|
||||
WHERE site_url = '%s' AND hubloc_network = 'zot6' ORDER BY hubloc_id DESC LIMIT 1",
|
||||
WHERE site_url = '%s' AND hubloc_network = 'zot6' AND hubloc_deleted = 0 ORDER BY hubloc_primary DESC, hubloc_id DESC LIMIT 1",
|
||||
dbesc($base)
|
||||
);
|
||||
if($h) {
|
||||
|
||||
@@ -16,13 +16,13 @@ class System {
|
||||
}
|
||||
|
||||
static public function get_site_name() {
|
||||
if(is_array(\App::$config) && is_array(\App::$config['system']) && \App::$config['system']['sitename'])
|
||||
if(is_array(\App::$config) && is_array(\App::$config['system']) && isset(\App::$config['system']['sitename']))
|
||||
return \App::$config['system']['sitename'];
|
||||
return '';
|
||||
}
|
||||
|
||||
static public function get_project_version() {
|
||||
if(is_array(\App::$config) && is_array(\App::$config['system']) && \App::$config['system']['hide_version'])
|
||||
if(is_array(\App::$config) && is_array(\App::$config['system']) && isset(\App::$config['system']['hide_version']))
|
||||
return '';
|
||||
if(is_array(\App::$config) && is_array(\App::$config['system']) && array_key_exists('std_version',\App::$config['system']))
|
||||
return \App::$config['system']['std_version'];
|
||||
@@ -31,33 +31,33 @@ class System {
|
||||
}
|
||||
|
||||
static public function get_update_version() {
|
||||
if(is_array(\App::$config) && is_array(\App::$config['system']) && \App::$config['system']['hide_version'])
|
||||
if(is_array(\App::$config) && is_array(\App::$config['system']) && isset(\App::$config['system']['hide_version']))
|
||||
return '';
|
||||
return DB_UPDATE_VERSION;
|
||||
}
|
||||
|
||||
|
||||
static public function get_notify_icon() {
|
||||
if(is_array(\App::$config) && is_array(\App::$config['system']) && \App::$config['system']['email_notify_icon_url'])
|
||||
if(is_array(\App::$config) && is_array(\App::$config['system']) && isset(\App::$config['system']['email_notify_icon_url']))
|
||||
return \App::$config['system']['email_notify_icon_url'];
|
||||
return z_root() . DEFAULT_NOTIFY_ICON;
|
||||
}
|
||||
|
||||
static public function get_site_icon() {
|
||||
if(is_array(\App::$config) && is_array(\App::$config['system']) && \App::$config['system']['site_icon_url'])
|
||||
if(is_array(\App::$config) && is_array(\App::$config['system']) && isset(\App::$config['system']['site_icon_url']))
|
||||
return \App::$config['system']['site_icon_url'];
|
||||
return z_root() . DEFAULT_PLATFORM_ICON ;
|
||||
}
|
||||
|
||||
|
||||
static public function get_project_link() {
|
||||
if(is_array(\App::$config) && is_array(\App::$config['system']) && \App::$config['system']['project_link'])
|
||||
if(is_array(\App::$config) && is_array(\App::$config['system']) && isset(\App::$config['system']['project_link']))
|
||||
return \App::$config['system']['project_link'];
|
||||
return 'https://hubzilla.org';
|
||||
}
|
||||
|
||||
static public function get_project_srclink() {
|
||||
if(is_array(\App::$config) && is_array(\App::$config['system']) && \App::$config['system']['project_srclink'])
|
||||
if(is_array(\App::$config) && is_array(\App::$config['system']) && isset(\App::$config['system']['project_srclink']))
|
||||
return \App::$config['system']['project_srclink'];
|
||||
return 'https://framagit.org/hubzilla/core.git';
|
||||
}
|
||||
@@ -68,7 +68,7 @@ class System {
|
||||
|
||||
|
||||
static public function get_zot_revision() {
|
||||
$x = [ 'revision' => ZOT_REVISION ];
|
||||
$x = [ 'revision' => ZOT_REVISION ];
|
||||
call_hooks('zot_revision',$x);
|
||||
return $x['revision'];
|
||||
}
|
||||
|
||||
@@ -98,7 +98,7 @@ class ThreadItem {
|
||||
$is_item = false;
|
||||
$osparkle = '';
|
||||
$total_children = $this->count_descendants();
|
||||
$unseen_comments = (($item['real_uid']) ? 0 : $this->count_unseen_descendants());
|
||||
$unseen_comments = ((isset($item['real_uid']) && $item['real_uid']) ? 0 : $this->count_unseen_descendants());
|
||||
|
||||
$conv = $this->get_conversation();
|
||||
$observer = $conv->get_observer();
|
||||
@@ -148,7 +148,7 @@ class ThreadItem {
|
||||
}
|
||||
|
||||
if ($lock) {
|
||||
if (($item['mid'] == $item['parent_mid']) && count(get_terms_oftype($item['term'],TERM_FORUM))) {
|
||||
if (($item['mid'] == $item['parent_mid']) && isset($item['term']) && count(get_terms_oftype($item['term'], TERM_FORUM))) {
|
||||
$privacy_warning = true;
|
||||
$conv_flags['parent_privacy_warning'] = true;
|
||||
}
|
||||
@@ -162,24 +162,11 @@ class ThreadItem {
|
||||
|
||||
$mode = $conv->get_mode();
|
||||
|
||||
switch($item['item_type']) {
|
||||
case ITEM_TYPE_CARD:
|
||||
$edlink = 'card_edit';
|
||||
break;
|
||||
case ITEM_TYPE_ARTICLE:
|
||||
$edlink = 'article_edit';
|
||||
break;
|
||||
default:
|
||||
$edlink = 'editpost';
|
||||
break;
|
||||
}
|
||||
|
||||
if(local_channel() && $observer['xchan_hash'] === $item['author_xchan'])
|
||||
$edpost = array(z_root() . '/' . $edlink . '/' . $item['id'], t('Edit'));
|
||||
$edpost = array(z_root() . '/editpost/' . $item['id'], t('Edit'));
|
||||
else
|
||||
$edpost = false;
|
||||
|
||||
|
||||
if($observer && $observer['xchan_hash']
|
||||
&& ($observer['xchan_hash'] == $this->get_data_value('author_xchan')
|
||||
|| $observer['xchan_hash'] == $this->get_data_value('owner_xchan')
|
||||
@@ -193,7 +180,7 @@ class ThreadItem {
|
||||
$dropping = false;
|
||||
}
|
||||
|
||||
|
||||
$drop = [];
|
||||
if($dropping) {
|
||||
$drop = array(
|
||||
'dropping' => $dropping,
|
||||
@@ -204,13 +191,6 @@ class ThreadItem {
|
||||
$drop = [ 'dropping' => true, 'delete' => t('Admin Delete') ];
|
||||
}
|
||||
|
||||
// FIXME
|
||||
if($observer_is_pageowner) {
|
||||
$multidrop = array(
|
||||
'select' => t('Select'),
|
||||
);
|
||||
}
|
||||
|
||||
$filer = ((($conv->get_profile_owner() == local_channel()) && (! array_key_exists('real_uid',$item))) ? t("Save to Folder") : false);
|
||||
|
||||
$profile_avatar = $item['author']['xchan_photo_m'];
|
||||
@@ -220,7 +200,6 @@ class ThreadItem {
|
||||
$location = format_location($item);
|
||||
$isevent = false;
|
||||
$attend = null;
|
||||
$canvote = false;
|
||||
|
||||
// process action responses - e.g. like/dislike/attend/agree/whatever
|
||||
$response_verbs = array('like');
|
||||
@@ -240,17 +219,6 @@ class ThreadItem {
|
||||
$response_verbs[] = 'answer';
|
||||
}
|
||||
|
||||
$consensus = (intval($item['item_consensus']) ? true : false);
|
||||
if($consensus) {
|
||||
$response_verbs[] = 'agree';
|
||||
$response_verbs[] = 'disagree';
|
||||
$response_verbs[] = 'abstain';
|
||||
if($this->is_commentable() && $observer) {
|
||||
$conlabels = array( t('I agree'), t('I disagree'), t('I abstain'));
|
||||
$canvote = true;
|
||||
}
|
||||
}
|
||||
|
||||
if(! feature_enabled($conv->get_profile_owner(),'dislike'))
|
||||
unset($conv_responses['dislike']);
|
||||
|
||||
@@ -258,7 +226,8 @@ class ThreadItem {
|
||||
|
||||
$my_responses = [];
|
||||
foreach($response_verbs as $v) {
|
||||
$my_responses[$v] = (($conv_responses[$v][$item['mid'] . '-m']) ? 1 : 0);
|
||||
|
||||
$my_responses[$v] = ((isset($conv_responses[$v][$item['mid'] . '-m'])) ? 1 : 0);
|
||||
}
|
||||
|
||||
$like_count = ((x($conv_responses['like'],$item['mid'])) ? $conv_responses['like'][$item['mid']] : '');
|
||||
@@ -296,14 +265,11 @@ class ThreadItem {
|
||||
$this->check_wall_to_wall();
|
||||
|
||||
if($this->is_toplevel()) {
|
||||
// FIXME check this permission
|
||||
if(($conv->get_profile_owner() == local_channel()) && (! array_key_exists('real_uid',$item))) {
|
||||
|
||||
$star = array(
|
||||
if((local_channel() && $conv->get_profile_owner() === local_channel()) || (local_channel() && App::$module === 'pubstream')) {
|
||||
$star = [
|
||||
'toggle' => t("Toggle Star Status"),
|
||||
'isstarred' => ((intval($item['item_starred'])) ? true : false),
|
||||
);
|
||||
|
||||
];
|
||||
}
|
||||
}
|
||||
else {
|
||||
@@ -320,7 +286,7 @@ class ThreadItem {
|
||||
$tagger = [];
|
||||
|
||||
// FIXME - check this permission
|
||||
if($conv->get_profile_owner() == local_channel()) {
|
||||
if(local_channel() && $conv->get_profile_owner() == local_channel()) {
|
||||
/* disable until we agree on how to implemnt this in zot6/activitypub
|
||||
$tagger = array(
|
||||
'tagit' => t("Add Tag"),
|
||||
@@ -343,20 +309,26 @@ class ThreadItem {
|
||||
if(($item['obj_type'] === ACTIVITY_OBJ_EVENT) && $conv->get_profile_owner() == local_channel())
|
||||
$has_event = true;
|
||||
|
||||
$like = [];
|
||||
$dislike = [];
|
||||
$reply_to = [];
|
||||
|
||||
if($this->is_commentable() && $observer) {
|
||||
$like = array( t("I like this \x28toggle\x29"), t("like"));
|
||||
$dislike = array( t("I don't like this \x28toggle\x29"), t("dislike"));
|
||||
$reply_to = array( t("Reply on this comment"), t("reply"), t("Reply to"));
|
||||
}
|
||||
|
||||
$share = [];
|
||||
$embed = [];
|
||||
if ($shareable) {
|
||||
// This actually turns out not to be possible in some protocol stacks without opening up hundreds of new issues.
|
||||
// Will allow it only for uri resolvable sources.
|
||||
if(strpos($item['mid'],'http') === 0) {
|
||||
$share = []; //Not yet ready for primetime
|
||||
//Not yet ready for primetime
|
||||
//$share = array( t('Repeat This'), t('repeat'));
|
||||
}
|
||||
$embed = array( t('Share This'), t('share'));
|
||||
$embed = [t('Share This'), t('share')];
|
||||
}
|
||||
|
||||
$dreport = '';
|
||||
@@ -365,11 +337,13 @@ class ThreadItem {
|
||||
if($keep_reports === 0)
|
||||
$keep_reports = 10;
|
||||
|
||||
if((! get_config('system','disable_dreport')) && strcmp(datetime_convert('UTC','UTC',$item['created']),datetime_convert('UTC','UTC',"now - $keep_reports days")) > 0) {
|
||||
$dreport_link = '';
|
||||
if((intval($item['item_type']) == ITEM_TYPE_POST) && (! get_config('system','disable_dreport')) && strcmp(datetime_convert('UTC','UTC',$item['created']),datetime_convert('UTC','UTC',"now - $keep_reports days")) > 0) {
|
||||
$dreport = t('Delivery Report');
|
||||
$dreport_link = gen_link_id($item['mid']);
|
||||
}
|
||||
|
||||
$is_new = false;
|
||||
if(strcmp(datetime_convert('UTC','UTC',$item['created']),datetime_convert('UTC','UTC','now - 12 hours')) > 0)
|
||||
$is_new = true;
|
||||
|
||||
@@ -439,9 +413,6 @@ class ThreadItem {
|
||||
'author_is_group_actor' => (($item['author']['xchan_pubforum']) ? t('Forum') : ''),
|
||||
'isevent' => $isevent,
|
||||
'attend' => $attend,
|
||||
'consensus' => $consensus,
|
||||
'conlabels' => $conlabels,
|
||||
'canvote' => $canvote,
|
||||
'linktitle' => (($item['author']['xchan_addr']) ? $item['author']['xchan_addr'] : $item['author']['xchan_url']),
|
||||
'olinktitle' => (($item['owner']['xchan_addr']) ? $item['owner']['xchan_addr'] : $item['owner']['xchan_url']),
|
||||
'llink' => $item['llink'],
|
||||
@@ -510,7 +481,6 @@ class ThreadItem {
|
||||
'bookmark' => (($conv->get_profile_owner() == local_channel() && local_channel() && $has_bookmarks) ? t('Save Bookmarks') : ''),
|
||||
'addtocal' => (($has_event) ? t('Add to Calendar') : ''),
|
||||
'drop' => $drop,
|
||||
'multidrop' => ((feature_enabled($conv->get_profile_owner(),'multi_delete')) ? $multidrop : ''),
|
||||
'dropdown_extras' => $dropdown_extras,
|
||||
// end toolbar buttons
|
||||
'unseen_comments' => $unseen_comments,
|
||||
@@ -533,7 +503,7 @@ class ThreadItem {
|
||||
'modal_dismiss' => t('Close'),
|
||||
'showlike' => $showlike,
|
||||
'showdislike' => $showdislike,
|
||||
'comment' => ($item['item_delayed'] ? '' : $this->get_comment_box($indent)),
|
||||
'comment' => ($item['item_delayed'] ? '' : $this->get_comment_box()),
|
||||
'previewing' => ($conv->is_preview() ? true : false ),
|
||||
'preview_lbl' => t('This is an unsaved preview'),
|
||||
'wait' => t('Please wait'),
|
||||
@@ -827,7 +797,7 @@ class ThreadItem {
|
||||
* _ The comment box string (empty if no comment box)
|
||||
* _ false on failure
|
||||
*/
|
||||
private function get_comment_box($indent) {
|
||||
private function get_comment_box() {
|
||||
|
||||
if(!$this->is_toplevel() && !get_config('system','thread_allow')) {
|
||||
return '';
|
||||
@@ -873,7 +843,6 @@ class ThreadItem {
|
||||
'$edurl' => t('Insert Link'),
|
||||
'$edvideo' => t('Video'),
|
||||
'$preview' => t('Preview'), // ((feature_enabled($conv->get_profile_owner(),'preview')) ? t('Preview') : ''),
|
||||
'$indent' => $indent,
|
||||
'$can_upload' => (perm_is_allowed($conv->get_profile_owner(),get_observer_hash(),'write_storage') && $conv->is_uploadable()),
|
||||
'$feature_encrypt' => ((feature_enabled($conv->get_profile_owner(),'content_encrypt')) ? true : false),
|
||||
'$encrypt' => t('Encrypt text'),
|
||||
|
||||
@@ -69,12 +69,12 @@ class ThreadStream {
|
||||
case 'cards':
|
||||
$this->profile_owner = \App::$profile['profile_uid'];
|
||||
$this->writable = perm_is_allowed($this->profile_owner,$ob_hash,'post_comments');
|
||||
$this->reload = $_SESSION['return_url'];
|
||||
//$this->reload = $_SESSION['return_url'];
|
||||
break;
|
||||
case 'articles':
|
||||
$this->profile_owner = \App::$profile['profile_uid'];
|
||||
$this->writable = perm_is_allowed($this->profile_owner,$ob_hash,'post_comments');
|
||||
$this->reload = $_SESSION['return_url'];
|
||||
//$this->reload = $_SESSION['return_url'];
|
||||
break;
|
||||
case 'display':
|
||||
// in this mode we set profile_owner after initialisation (from conversation()) and then
|
||||
|
||||
@@ -56,7 +56,7 @@ class Webfinger {
|
||||
if($m['scheme'] !== 'https') {
|
||||
return false;
|
||||
}
|
||||
self::$server = $m['host'] . (($m['port']) ? ':' . $m['port'] : '');
|
||||
self::$server = $m['host'] . ((isset($m['port'])) ? ':' . $m['port'] : '');
|
||||
}
|
||||
else {
|
||||
return false;
|
||||
@@ -86,7 +86,7 @@ class Webfinger {
|
||||
/**
|
||||
* @brief fetch a webfinger resource and return a zot6 discovery url if present
|
||||
*
|
||||
*/
|
||||
*/
|
||||
|
||||
static function zot_url($resource) {
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@ use Zotlabs\Web\HTTPSig;
|
||||
|
||||
class Zotfinger {
|
||||
|
||||
static function exec($resource,$channel = null, $verify = true) {
|
||||
static function exec($resource, $channel = null, $verify = true, $recurse = true) {
|
||||
|
||||
if(! $resource) {
|
||||
return false;
|
||||
@@ -39,6 +39,30 @@ class Zotfinger {
|
||||
|
||||
logger('fetch: ' . print_r($x,true));
|
||||
|
||||
if (in_array(intval($x['return_code']), [ 404, 410 ]) && $recurse) {
|
||||
|
||||
// The resource has been deleted or doesn't exist at this location.
|
||||
// Try to find another nomadic resource for this channel and return that.
|
||||
|
||||
// First, see if there's a hubloc for this site. Fetch that record to
|
||||
// obtain the nomadic identity hash. Then use that to find any additional
|
||||
// nomadic locations.
|
||||
|
||||
$h = Activity::get_actor_hublocs($resource, 'zot6');
|
||||
if ($h) {
|
||||
// mark this location deleted
|
||||
hubloc_delete($h[0]);
|
||||
$hubs = Activity::get_actor_hublocs($h[0]['hubloc_hash']);
|
||||
if ($hubs) {
|
||||
foreach ($hubs as $hub) {
|
||||
if ($hub['hubloc_id_url'] !== $resource && !$hub['hubloc_deleted']) {
|
||||
return self::exec($hub['hubloc_id_url'], $channel, $verify);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if($x['success']) {
|
||||
if ($verify) {
|
||||
$result['signature'] = HTTPSig::verify($x, EMPTY_STR, 'zot6');
|
||||
|
||||
@@ -66,6 +66,11 @@ class Acl extends \Zotlabs\Web\Controller {
|
||||
killme();
|
||||
|
||||
$permitted = [];
|
||||
$sql_extra = '';
|
||||
$sql_extra2 = '';
|
||||
$sql_extra3 = '';
|
||||
$sql_extra2_xchan = '';
|
||||
$order_extra2 = '';
|
||||
|
||||
if(in_array($type, [ 'm', 'a', 'c', 'f' ])) {
|
||||
|
||||
@@ -81,7 +86,6 @@ class Acl extends \Zotlabs\Web\Controller {
|
||||
|
||||
}
|
||||
|
||||
|
||||
if($search) {
|
||||
$sql_extra = " AND pgrp.gname LIKE " . protect_sprintf( "'%" . dbesc($search) . "%'" ) . " ";
|
||||
$sql_extra2 = "AND ( xchan_name LIKE " . protect_sprintf( "'%" . dbesc($search) . "%'" ) . " OR xchan_addr LIKE " . protect_sprintf( "'%" . dbesc(punify($search)) . ((strpos($search,'@') === false) ? "%@%'" : "%'")) . ") ";
|
||||
@@ -100,10 +104,6 @@ class Acl extends \Zotlabs\Web\Controller {
|
||||
$sql_extra3 = "AND ( xchan_addr like " . protect_sprintf( "'%" . dbesc(punify($search)) . "%'" ) . " OR xchan_name like " . protect_sprintf( "'%" . dbesc($search) . "%'" ) . " ) ";
|
||||
|
||||
}
|
||||
else {
|
||||
$sql_extra = $sql_extra2 = $sql_extra3 = "";
|
||||
}
|
||||
|
||||
|
||||
$groups = array();
|
||||
$contacts = array();
|
||||
@@ -342,7 +342,7 @@ class Acl extends \Zotlabs\Web\Controller {
|
||||
$x = [];
|
||||
foreach($r as $g) {
|
||||
|
||||
if(in_array($g['net'],['rss','anon','unknown']) && ($type != 'a'))
|
||||
if(isset($g['net']) && in_array($g['net'], ['rss','anon','unknown']) && ($type != 'a'))
|
||||
continue;
|
||||
|
||||
$g['hash'] = urlencode($g['hash']);
|
||||
@@ -383,7 +383,7 @@ class Acl extends \Zotlabs\Web\Controller {
|
||||
"self" => (intval($g['abook_self']) ? 'abook-self' : ''),
|
||||
"taggable" => '',
|
||||
"label" => '',
|
||||
"net" => $g['net']
|
||||
"net" => $g['net'] ?? ''
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,23 +12,33 @@ class Queue {
|
||||
|
||||
$o = '';
|
||||
|
||||
$expert = ((array_key_exists('expert',$_REQUEST)) ? intval($_REQUEST['expert']) : 0);
|
||||
$expert = $_REQUEST['expert'] ?? false;
|
||||
|
||||
if($_REQUEST['drophub']) {
|
||||
if(isset($_REQUEST['drophub'])) {
|
||||
hubloc_mark_as_down($_REQUEST['drophub']);
|
||||
LibQueue::remove_by_posturl($_REQUEST['drophub']);
|
||||
}
|
||||
|
||||
if($_REQUEST['emptyhub']) {
|
||||
if(isset($_REQUEST['emptyhub'])) {
|
||||
LibQueue::remove_by_posturl($_REQUEST['emptyhub']);
|
||||
}
|
||||
|
||||
$r = q("select count(outq_posturl) as total, max(outq_priority) as priority, outq_posturl from outq
|
||||
if(isset($_REQUEST['deliverhub'])) {
|
||||
|
||||
$hubq = q("SELECT * FROM outq WHERE outq_posturl = '%s'",
|
||||
dbesc($_REQUEST['deliverhub'])
|
||||
);
|
||||
|
||||
foreach ($hubq as $q) {
|
||||
LibQueue::deliver($q, true);
|
||||
}
|
||||
}
|
||||
|
||||
$r = dbq("select count(outq_posturl) as total, max(outq_priority) as priority, outq_posturl from outq
|
||||
where outq_delivered = 0 group by outq_posturl order by total desc");
|
||||
|
||||
for($x = 0; $x < count($r); $x ++) {
|
||||
$r[$x]['eurl'] = urlencode($r[$x]['outq_posturl']);
|
||||
$r[$x]['connected'] = datetime_convert('UTC',date_default_timezone_get(),$r[$x]['connected'],'Y-m-d');
|
||||
}
|
||||
|
||||
$o = replace_macros(get_markup_template('admin_queue.tpl'), array(
|
||||
@@ -37,6 +47,7 @@ class Queue {
|
||||
'$priority' => t('Priority'),
|
||||
'$desturl' => t('Destination URL'),
|
||||
'$nukehub' => t('Mark hub permanently offline'),
|
||||
'$deliverhub' => t('Retry delivery to this hub'),
|
||||
'$empty' => t('Empty queue for this hub'),
|
||||
'$lastconn' => t('Last known contact'),
|
||||
'$hasentries' => ((count($r)) ? true : false),
|
||||
|
||||
@@ -340,11 +340,14 @@ class Site {
|
||||
$discover_tab = (1 - $discover_tab);
|
||||
|
||||
$perm_roles = \Zotlabs\Access\PermissionRoles::channel_roles();
|
||||
$default_role = get_config('system','default_permissions_role','personal');
|
||||
$default_role = get_config('system', 'default_permissions_role', 'personal');
|
||||
|
||||
if (!in_array($default_role, array_keys($perm_roles))) {
|
||||
$default_role = 'personal';
|
||||
}
|
||||
|
||||
$role = array('permissions_role' , t('Default permission role for new accounts'), $default_role, t('This role will be used for the first channel created after registration.'),$perm_roles);
|
||||
|
||||
|
||||
$homelogin = get_config('system','login_on_homepage');
|
||||
$enable_context_help = get_config('system','enable_context_help');
|
||||
|
||||
|
||||
@@ -1,138 +0,0 @@
|
||||
<?php
|
||||
namespace Zotlabs\Module;
|
||||
|
||||
require_once('include/channel.php');
|
||||
require_once('include/acl_selectors.php');
|
||||
require_once('include/conversation.php');
|
||||
|
||||
class Article_edit extends \Zotlabs\Web\Controller {
|
||||
|
||||
|
||||
function get() {
|
||||
|
||||
// Figure out which post we're editing
|
||||
$post_id = ((argc() > 1) ? intval(argv(1)) : 0);
|
||||
|
||||
if(! $post_id) {
|
||||
notice( t('Item not found') . EOL);
|
||||
return;
|
||||
}
|
||||
|
||||
$itm = q("SELECT * FROM item WHERE id = %d and item_type = %d LIMIT 1",
|
||||
intval($post_id),
|
||||
intval(ITEM_TYPE_ARTICLE)
|
||||
);
|
||||
if($itm) {
|
||||
$item_id = q("select * from iconfig where cat = 'system' and k = 'ARTICLE' and iid = %d limit 1",
|
||||
intval($itm[0]['id'])
|
||||
);
|
||||
if($item_id)
|
||||
$card_title = $item_id[0]['v'];
|
||||
}
|
||||
else {
|
||||
notice( t('Item not found') . EOL);
|
||||
return;
|
||||
}
|
||||
|
||||
$owner = $itm[0]['uid'];
|
||||
$uid = local_channel();
|
||||
|
||||
$observer = \App::get_observer();
|
||||
|
||||
$channel = channelx_by_n($owner);
|
||||
if(! $channel) {
|
||||
notice( t('Channel not found.') . EOL);
|
||||
return;
|
||||
}
|
||||
|
||||
$ob_hash = (($observer) ? $observer['xchan_hash'] : '');
|
||||
|
||||
if(! perm_is_allowed($owner,$ob_hash,'write_pages')) {
|
||||
notice( t('Permission denied.') . EOL);
|
||||
return;
|
||||
}
|
||||
|
||||
$is_owner = (($uid && $uid == $owner) ? true : false);
|
||||
|
||||
$o = '';
|
||||
|
||||
|
||||
|
||||
$category = '';
|
||||
$catsenabled = ((feature_enabled($owner,'categories')) ? 'categories' : '');
|
||||
|
||||
if ($catsenabled){
|
||||
$itm = fetch_post_tags($itm);
|
||||
|
||||
$cats = get_terms_oftype($itm[0]['term'], TERM_CATEGORY);
|
||||
|
||||
foreach ($cats as $cat) {
|
||||
if (strlen($category))
|
||||
$category .= ', ';
|
||||
$category .= $cat['term'];
|
||||
}
|
||||
}
|
||||
|
||||
if($itm[0]['attach']) {
|
||||
$j = json_decode($itm[0]['attach'],true);
|
||||
if($j) {
|
||||
foreach($j as $jj) {
|
||||
$itm[0]['body'] .= "\n" . '[attachment]' . basename($jj['href']) . ',' . $jj['revision'] . '[/attachment]' . "\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
$mimetype = $itm[0]['mimetype'];
|
||||
|
||||
$content = $itm[0]['body'];
|
||||
|
||||
$rp = 'articles/' . $channel['channel_address'];
|
||||
|
||||
$x = array(
|
||||
'nickname' => $channel['channel_address'],
|
||||
'bbco_autocomplete'=> 'bbcode',
|
||||
'return_path' => $rp,
|
||||
'webpage' => ITEM_TYPE_ARTICLE,
|
||||
'button' => t('Edit'),
|
||||
'writefiles' => perm_is_allowed($owner, get_observer_hash(), 'write_pages'),
|
||||
'weblink' => t('Insert web link'),
|
||||
'hide_voting' => false,
|
||||
'hide_future' => false,
|
||||
'hide_location' => false,
|
||||
'hide_expire' => false,
|
||||
'showacl' => true,
|
||||
'acl' => populate_acl($itm[0],false,\Zotlabs\Lib\PermissionDescription::fromGlobalPermission('view_pages')),
|
||||
'permissions' => $itm[0],
|
||||
'lockstate' => (($itm[0]['allow_cid'] || $itm[0]['allow_gid'] || $itm[0]['deny_cid'] || $itm[0]['deny_gid']) ? 'lock' : 'unlock'),
|
||||
'ptyp' => $itm[0]['type'],
|
||||
'mimeselect' => false,
|
||||
'mimetype' => $itm[0]['mimetype'],
|
||||
'body' => undo_post_tagging($content),
|
||||
'post_id' => $post_id,
|
||||
'visitor' => true,
|
||||
'title' => htmlspecialchars($itm[0]['title'],ENT_COMPAT,'UTF-8'),
|
||||
'summary' => htmlspecialchars($itm[0]['summary'],ENT_COMPAT,'UTF-8'),
|
||||
'placeholdertitle' => t('Title (optional)'),
|
||||
'pagetitle' => $card_title,
|
||||
'profile_uid' => (intval($channel['channel_id'])),
|
||||
'catsenabled' => $catsenabled,
|
||||
'category' => $category,
|
||||
'bbcode' => (($mimetype == 'text/bbcode') ? true : false)
|
||||
);
|
||||
|
||||
$editor = status_editor($a, $x, false, 'Article_edit');
|
||||
|
||||
$o .= replace_macros(get_markup_template('edpost_head.tpl'), array(
|
||||
'$title' => t('Edit Article'),
|
||||
'$delete' => ((($itm[0]['author_xchan'] === $ob_hash) || ($itm[0]['owner_xchan'] === $ob_hash)) ? t('Delete') : false),
|
||||
'$id' => $itm[0]['id'],
|
||||
'$cancel' => t('Cancel'),
|
||||
'$editor' => $editor
|
||||
));
|
||||
|
||||
return $o;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,232 +0,0 @@
|
||||
<?php
|
||||
namespace Zotlabs\Module;
|
||||
|
||||
use App;
|
||||
use Zotlabs\Lib\Apps;
|
||||
use Zotlabs\Web\Controller;
|
||||
use Zotlabs\Lib\PermissionDescription;
|
||||
|
||||
require_once('include/channel.php');
|
||||
require_once('include/conversation.php');
|
||||
require_once('include/acl_selectors.php');
|
||||
require_once('include/opengraph.php');
|
||||
|
||||
|
||||
class Articles extends Controller {
|
||||
|
||||
function init() {
|
||||
|
||||
if(argc() > 1)
|
||||
$which = argv(1);
|
||||
|
||||
if(! $which) {
|
||||
if(local_channel()) {
|
||||
$channel = App::get_channel();
|
||||
if($channel && $channel['channel_address'])
|
||||
$which = $channel['channel_address'];
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
profile_load($which);
|
||||
|
||||
}
|
||||
|
||||
function get($update = 0, $load = false) {
|
||||
|
||||
if(observer_prohibited(true)) {
|
||||
return login();
|
||||
}
|
||||
|
||||
if(! App::$profile) {
|
||||
notice( t('Requested profile is not available.') . EOL );
|
||||
App::$error = 404;
|
||||
return;
|
||||
}
|
||||
|
||||
if(! Apps::system_app_installed(App::$profile_uid, 'Articles')) {
|
||||
//Do not display any associated widgets at this point
|
||||
App::$pdl = '';
|
||||
$papp = Apps::get_papp('Articles');
|
||||
return Apps::app_render($papp, 'module');
|
||||
}
|
||||
|
||||
nav_set_selected('Articles');
|
||||
|
||||
head_add_link([
|
||||
'rel' => 'alternate',
|
||||
'type' => 'application/json+oembed',
|
||||
'href' => z_root() . '/oep?f=&url=' . urlencode(z_root() . '/' . App::$query_string),
|
||||
'title' => 'oembed'
|
||||
]);
|
||||
|
||||
|
||||
$category = (($_REQUEST['cat']) ? escape_tags(trim($_REQUEST['cat'])) : '');
|
||||
|
||||
if($category) {
|
||||
$sql_extra2 .= protect_sprintf(term_item_parent_query(App::$profile['profile_uid'],'item', $category, TERM_CATEGORY));
|
||||
}
|
||||
|
||||
$datequery = ((x($_GET,'dend') && is_a_date_arg($_GET['dend'])) ? notags($_GET['dend']) : '');
|
||||
$datequery2 = ((x($_GET,'dbegin') && is_a_date_arg($_GET['dbegin'])) ? notags($_GET['dbegin']) : '');
|
||||
|
||||
$which = argv(1);
|
||||
|
||||
$selected_card = ((argc() > 2) ? argv(2) : '');
|
||||
|
||||
$_SESSION['return_url'] = App::$query_string;
|
||||
|
||||
$uid = local_channel();
|
||||
$owner = App::$profile_uid;
|
||||
$observer = App::get_observer();
|
||||
|
||||
$ob_hash = (($observer) ? $observer['xchan_hash'] : '');
|
||||
|
||||
if(! perm_is_allowed($owner,$ob_hash,'view_pages')) {
|
||||
notice( t('Permission denied.') . EOL);
|
||||
return;
|
||||
}
|
||||
|
||||
$is_owner = ($uid && $uid == $owner);
|
||||
|
||||
$channel = channelx_by_n($owner);
|
||||
|
||||
if($channel) {
|
||||
$channel_acl = array(
|
||||
'allow_cid' => $channel['channel_allow_cid'],
|
||||
'allow_gid' => $channel['channel_allow_gid'],
|
||||
'deny_cid' => $channel['channel_deny_cid'],
|
||||
'deny_gid' => $channel['channel_deny_gid']
|
||||
);
|
||||
}
|
||||
else {
|
||||
$channel_acl = [ 'allow_cid' => '', 'allow_gid' => '', 'deny_cid' => '', 'deny_gid' => '' ];
|
||||
}
|
||||
|
||||
|
||||
|
||||
if(perm_is_allowed($owner,$ob_hash,'write_pages')) {
|
||||
|
||||
$x = [
|
||||
'webpage' => ITEM_TYPE_ARTICLE,
|
||||
'is_owner' => true,
|
||||
'content_label' => t('Add Article'),
|
||||
'button' => t('Save'),
|
||||
'nickname' => $channel['channel_address'],
|
||||
'lockstate' => (($channel['channel_allow_cid'] || $channel['channel_allow_gid']
|
||||
|| $channel['channel_deny_cid'] || $channel['channel_deny_gid']) ? 'lock' : 'unlock'),
|
||||
'acl' => (($is_owner) ? populate_acl($channel_acl, false,
|
||||
PermissionDescription::fromGlobalPermission('view_pages')) : ''),
|
||||
'permissions' => $channel_acl,
|
||||
'showacl' => (($is_owner) ? true : false),
|
||||
'visitor' => true,
|
||||
'hide_location' => false,
|
||||
'hide_voting' => false,
|
||||
'profile_uid' => intval($owner),
|
||||
'mimetype' => 'text/bbcode',
|
||||
'mimeselect' => false,
|
||||
'layoutselect' => false,
|
||||
'expanded' => false,
|
||||
'novoting' => false,
|
||||
'catsenabled' => feature_enabled($owner,'categories'),
|
||||
'bbco_autocomplete' => 'bbcode',
|
||||
'bbcode' => true
|
||||
];
|
||||
|
||||
if($_REQUEST['title'])
|
||||
$x['title'] = $_REQUEST['title'];
|
||||
if($_REQUEST['body'])
|
||||
$x['body'] = $_REQUEST['body'];
|
||||
$editor = status_editor($a,$x,false,'Articles');
|
||||
|
||||
}
|
||||
else {
|
||||
$editor = '';
|
||||
}
|
||||
|
||||
$itemspage = get_pconfig(local_channel(),'system','itemspage');
|
||||
App::set_pager_itemspage(((intval($itemspage)) ? $itemspage : 10));
|
||||
$pager_sql = sprintf(" LIMIT %d OFFSET %d ", intval(App::$pager['itemspage']), intval(App::$pager['start']));
|
||||
|
||||
|
||||
$sql_extra = item_permissions_sql($owner);
|
||||
$sql_item = '';
|
||||
|
||||
if($selected_card) {
|
||||
$r = q("select * from iconfig where iconfig.cat = 'system' and iconfig.k = 'ARTICLE' and iconfig.v = '%s' limit 1",
|
||||
dbesc($selected_card)
|
||||
);
|
||||
if($r) {
|
||||
$sql_item = "and item.id = " . intval($r[0]['iid']) . " ";
|
||||
}
|
||||
}
|
||||
if($datequery) {
|
||||
$sql_extra2 .= protect_sprintf(sprintf(" AND item.created <= '%s' ", dbesc(datetime_convert(date_default_timezone_get(),'',$datequery))));
|
||||
$order = 'post';
|
||||
}
|
||||
if($datequery2) {
|
||||
$sql_extra2 .= protect_sprintf(sprintf(" AND item.created >= '%s' ", dbesc(datetime_convert(date_default_timezone_get(),'',$datequery2))));
|
||||
}
|
||||
|
||||
if($datequery || $datequery2) {
|
||||
$sql_extra2 .= " and item.item_thread_top != 0 ";
|
||||
}
|
||||
|
||||
$r = q("select * from item
|
||||
where item.uid = %d and item_type = %d
|
||||
$sql_extra $sql_extra2 $sql_item order by item.created desc $pager_sql",
|
||||
intval($owner),
|
||||
intval(ITEM_TYPE_ARTICLE)
|
||||
);
|
||||
|
||||
$item_normal = " and item.item_hidden = 0 and item.item_type in (0,7) and item.item_deleted = 0
|
||||
and item.item_unpublished = 0 and item.item_delayed = 0 and item.item_pending_remove = 0
|
||||
and item.item_blocked = 0 ";
|
||||
|
||||
if($r) {
|
||||
|
||||
$pager_total = count($r);
|
||||
|
||||
$parents_str = ids_to_querystr($r,'id');
|
||||
|
||||
$r = q("SELECT item.*, item.id AS item_id
|
||||
FROM item
|
||||
WHERE item.uid = %d $item_normal
|
||||
AND item.parent IN ( %s )
|
||||
$sql_extra $sql_extra2 ",
|
||||
intval(App::$profile['profile_uid']),
|
||||
dbesc($parents_str)
|
||||
);
|
||||
if($r) {
|
||||
xchan_query($r);
|
||||
$items = fetch_post_tags($r, true);
|
||||
$items = conv_sort($items,'updated');
|
||||
}
|
||||
else
|
||||
$items = [];
|
||||
}
|
||||
|
||||
// Add Opengraph markup
|
||||
opengraph_add_meta((! empty($items) ? $r[0] : []), $channel);
|
||||
|
||||
$mode = 'articles';
|
||||
|
||||
if(get_pconfig(local_channel(),'system','articles_list_mode') && (! $selected_card))
|
||||
$page_mode = 'pager_list';
|
||||
else
|
||||
$page_mode = 'traditional';
|
||||
|
||||
$content = conversation($items,$mode,false,$page_mode);
|
||||
|
||||
$o = replace_macros(get_markup_template('cards.tpl'), [
|
||||
'$title' => t('Articles'),
|
||||
'$editor' => $editor,
|
||||
'$content' => $content,
|
||||
'$pager' => alt_pager($pager_total)
|
||||
]);
|
||||
|
||||
return $o;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,140 +0,0 @@
|
||||
<?php
|
||||
namespace Zotlabs\Module;
|
||||
|
||||
require_once('include/channel.php');
|
||||
require_once('include/acl_selectors.php');
|
||||
require_once('include/conversation.php');
|
||||
|
||||
class Card_edit extends \Zotlabs\Web\Controller {
|
||||
|
||||
|
||||
function get() {
|
||||
|
||||
// Figure out which post we're editing
|
||||
$post_id = ((argc() > 1) ? intval(argv(1)) : 0);
|
||||
|
||||
if(! $post_id) {
|
||||
notice( t('Item not found') . EOL);
|
||||
return;
|
||||
}
|
||||
|
||||
$itm = q("SELECT * FROM item WHERE id = %d and item_type = %d LIMIT 1",
|
||||
intval($post_id),
|
||||
intval(ITEM_TYPE_CARD)
|
||||
);
|
||||
if($itm) {
|
||||
$item_id = q("select * from iconfig where cat = 'system' and k = 'CARD' and iid = %d limit 1",
|
||||
intval($itm[0]['id'])
|
||||
);
|
||||
if($item_id)
|
||||
$card_title = $item_id[0]['v'];
|
||||
}
|
||||
else {
|
||||
notice( t('Item not found') . EOL);
|
||||
return;
|
||||
}
|
||||
|
||||
$owner = $itm[0]['uid'];
|
||||
$uid = local_channel();
|
||||
|
||||
$observer = \App::get_observer();
|
||||
|
||||
$channel = channelx_by_n($owner);
|
||||
if(! $channel) {
|
||||
notice( t('Channel not found.') . EOL);
|
||||
return;
|
||||
}
|
||||
|
||||
$ob_hash = (($observer) ? $observer['xchan_hash'] : '');
|
||||
|
||||
if(! perm_is_allowed($owner,$ob_hash,'write_pages')) {
|
||||
notice( t('Permission denied.') . EOL);
|
||||
return;
|
||||
}
|
||||
|
||||
$is_owner = (($uid && $uid == $owner) ? true : false);
|
||||
|
||||
$o = '';
|
||||
|
||||
|
||||
|
||||
$category = '';
|
||||
$catsenabled = ((feature_enabled($owner,'categories')) ? 'categories' : '');
|
||||
|
||||
if ($catsenabled){
|
||||
$itm = fetch_post_tags($itm);
|
||||
|
||||
$cats = get_terms_oftype($itm[0]['term'], TERM_CATEGORY);
|
||||
|
||||
foreach ($cats as $cat) {
|
||||
if (strlen($category))
|
||||
$category .= ', ';
|
||||
$category .= $cat['term'];
|
||||
}
|
||||
}
|
||||
|
||||
if($itm[0]['attach']) {
|
||||
$j = json_decode($itm[0]['attach'],true);
|
||||
if($j) {
|
||||
foreach($j as $jj) {
|
||||
$itm[0]['body'] .= "\n" . '[attachment]' . basename($jj['href']) . ',' . $jj['revision'] . '[/attachment]' . "\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
$mimetype = $itm[0]['mimetype'];
|
||||
|
||||
$content = $itm[0]['body'];
|
||||
|
||||
|
||||
|
||||
$rp = 'cards/' . $channel['channel_address'];
|
||||
|
||||
$x = array(
|
||||
'nickname' => $channel['channel_address'],
|
||||
'bbco_autocomplete'=> 'bbcode',
|
||||
'return_path' => $rp,
|
||||
'webpage' => ITEM_TYPE_CARD,
|
||||
'button' => t('Edit'),
|
||||
'writefiles' => perm_is_allowed($owner, get_observer_hash(), 'write_pages'),
|
||||
'weblink' => t('Insert web link'),
|
||||
'hide_voting' => false,
|
||||
'hide_future' => false,
|
||||
'hide_location' => false,
|
||||
'hide_expire' => false,
|
||||
'showacl' => true,
|
||||
'acl' => populate_acl($itm[0],false,\Zotlabs\Lib\PermissionDescription::fromGlobalPermission('view_pages')),
|
||||
'permissions' => $itm[0],
|
||||
'lockstate' => (($itm[0]['allow_cid'] || $itm[0]['allow_gid'] || $itm[0]['deny_cid'] || $itm[0]['deny_gid']) ? 'lock' : 'unlock'),
|
||||
'ptyp' => $itm[0]['type'],
|
||||
'mimeselect' => false,
|
||||
'mimetype' => $itm[0]['mimetype'],
|
||||
'body' => undo_post_tagging($content),
|
||||
'post_id' => $post_id,
|
||||
'visitor' => true,
|
||||
'title' => htmlspecialchars($itm[0]['title'],ENT_COMPAT,'UTF-8'),
|
||||
'summary' => htmlspecialchars($itm[0]['summary'],ENT_COMPAT,'UTF-8'),
|
||||
'placeholdertitle' => t('Title (optional)'),
|
||||
'pagetitle' => $card_title,
|
||||
'profile_uid' => (intval($channel['channel_id'])),
|
||||
'catsenabled' => $catsenabled,
|
||||
'category' => $category,
|
||||
'bbcode' => (($mimetype == 'text/bbcode') ? true : false)
|
||||
);
|
||||
|
||||
$editor = status_editor($a, $x, false, 'Card_edit');
|
||||
|
||||
$o .= replace_macros(get_markup_template('edpost_head.tpl'), array(
|
||||
'$title' => t('Edit Card'),
|
||||
'$delete' => ((($itm[0]['author_xchan'] === $ob_hash) || ($itm[0]['owner_xchan'] === $ob_hash)) ? t('Delete') : false),
|
||||
'$id' => $itm[0]['id'],
|
||||
'$cancel' => t('Cancel'),
|
||||
'$editor' => $editor
|
||||
));
|
||||
|
||||
return $o;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,214 +0,0 @@
|
||||
<?php
|
||||
namespace Zotlabs\Module;
|
||||
|
||||
use App;
|
||||
use Zotlabs\Lib\Apps;
|
||||
use Zotlabs\Web\Controller;
|
||||
use Zotlabs\Lib\PermissionDescription;
|
||||
|
||||
require_once('include/channel.php');
|
||||
require_once('include/conversation.php');
|
||||
require_once('include/acl_selectors.php');
|
||||
|
||||
/**
|
||||
* @brief Provides the Cards module.
|
||||
*
|
||||
*/
|
||||
class Cards extends Controller {
|
||||
|
||||
public function init() {
|
||||
|
||||
if(argc() > 1)
|
||||
$which = argv(1);
|
||||
else
|
||||
return;
|
||||
|
||||
profile_load($which);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
* @see \\Zotlabs\\Web\\Controller::get()
|
||||
*
|
||||
* @return string Parsed HTML from template 'cards.tpl'
|
||||
*/
|
||||
public function get($update = 0, $load = false) {
|
||||
|
||||
if(observer_prohibited(true)) {
|
||||
return login();
|
||||
}
|
||||
|
||||
if(! App::$profile) {
|
||||
notice( t('Requested profile is not available.') . EOL );
|
||||
App::$error = 404;
|
||||
return;
|
||||
}
|
||||
|
||||
if(! Apps::system_app_installed(App::$profile_uid, 'Cards')) {
|
||||
//Do not display any associated widgets at this point
|
||||
App::$pdl = '';
|
||||
$papp = Apps::get_papp('Cards');
|
||||
return Apps::app_render($papp, 'module');
|
||||
}
|
||||
|
||||
nav_set_selected('Cards');
|
||||
|
||||
head_add_link([
|
||||
'rel' => 'alternate',
|
||||
'type' => 'application/json+oembed',
|
||||
'href' => z_root() . '/oep?f=&url=' . urlencode(z_root() . '/' . App::$query_string),
|
||||
'title' => 'oembed'
|
||||
]);
|
||||
|
||||
|
||||
$category = (($_REQUEST['cat']) ? escape_tags(trim($_REQUEST['cat'])) : '');
|
||||
|
||||
if($category) {
|
||||
$sql_extra2 .= protect_sprintf(term_item_parent_query(App::$profile['profile_uid'], 'item', $category, TERM_CATEGORY));
|
||||
}
|
||||
|
||||
|
||||
$which = argv(1);
|
||||
|
||||
$selected_card = ((argc() > 2) ? argv(2) : '');
|
||||
|
||||
$_SESSION['return_url'] = App::$query_string;
|
||||
|
||||
$uid = local_channel();
|
||||
$owner = App::$profile_uid;
|
||||
$observer = App::get_observer();
|
||||
|
||||
$ob_hash = (($observer) ? $observer['xchan_hash'] : '');
|
||||
|
||||
if(! perm_is_allowed($owner, $ob_hash, 'view_pages')) {
|
||||
notice( t('Permission denied.') . EOL);
|
||||
return;
|
||||
}
|
||||
|
||||
$is_owner = ($uid && $uid == $owner);
|
||||
|
||||
$channel = channelx_by_n($owner);
|
||||
|
||||
if($channel) {
|
||||
$channel_acl = [
|
||||
'allow_cid' => $channel['channel_allow_cid'],
|
||||
'allow_gid' => $channel['channel_allow_gid'],
|
||||
'deny_cid' => $channel['channel_deny_cid'],
|
||||
'deny_gid' => $channel['channel_deny_gid']
|
||||
];
|
||||
}
|
||||
else {
|
||||
$channel_acl = [ 'allow_cid' => '', 'allow_gid' => '', 'deny_cid' => '', 'deny_gid' => '' ];
|
||||
}
|
||||
|
||||
|
||||
if(perm_is_allowed($owner, $ob_hash, 'write_pages')) {
|
||||
|
||||
$x = [
|
||||
'webpage' => ITEM_TYPE_CARD,
|
||||
'is_owner' => true,
|
||||
'content_label' => t('Add Card'),
|
||||
'button' => t('Save'),
|
||||
'nickname' => $channel['channel_address'],
|
||||
'lockstate' => (($channel['channel_allow_cid'] || $channel['channel_allow_gid']
|
||||
|| $channel['channel_deny_cid'] || $channel['channel_deny_gid']) ? 'lock' : 'unlock'),
|
||||
'acl' => (($is_owner) ? populate_acl($channel_acl, false,
|
||||
PermissionDescription::fromGlobalPermission('view_pages')) : ''),
|
||||
'permissions' => $channel_acl,
|
||||
'showacl' => (($is_owner) ? true : false),
|
||||
'visitor' => true,
|
||||
'hide_location' => false,
|
||||
'hide_voting' => false,
|
||||
'profile_uid' => intval($owner),
|
||||
'mimetype' => 'text/bbcode',
|
||||
'mimeselect' => false,
|
||||
'layoutselect' => false,
|
||||
'expanded' => false,
|
||||
'novoting' => false,
|
||||
'catsenabled' => feature_enabled($owner, 'categories'),
|
||||
'bbco_autocomplete' => 'bbcode',
|
||||
'bbcode' => true
|
||||
];
|
||||
|
||||
if($_REQUEST['title'])
|
||||
$x['title'] = $_REQUEST['title'];
|
||||
if($_REQUEST['body'])
|
||||
$x['body'] = $_REQUEST['body'];
|
||||
|
||||
$editor = status_editor($a, $x, false, 'Cards');
|
||||
}
|
||||
else {
|
||||
$editor = '';
|
||||
}
|
||||
|
||||
|
||||
$itemspage = get_pconfig(local_channel(),'system','itemspage');
|
||||
App::set_pager_itemspage(((intval($itemspage)) ? $itemspage : 10));
|
||||
$pager_sql = sprintf(" LIMIT %d OFFSET %d ", intval(App::$pager['itemspage']), intval(App::$pager['start']));
|
||||
|
||||
|
||||
$sql_extra = item_permissions_sql($owner);
|
||||
$sql_item = '';
|
||||
|
||||
if($selected_card) {
|
||||
$r = q("select * from iconfig where iconfig.cat = 'system' and iconfig.k = 'CARD' and iconfig.v = '%s' limit 1",
|
||||
dbesc($selected_card)
|
||||
);
|
||||
if($r) {
|
||||
$sql_item = "and item.id = " . intval($r[0]['iid']) . " ";
|
||||
}
|
||||
}
|
||||
|
||||
$r = q("select * from item
|
||||
where uid = %d and item_type = %d
|
||||
$sql_extra $sql_item order by item.created desc $pager_sql",
|
||||
intval($owner),
|
||||
intval(ITEM_TYPE_CARD)
|
||||
);
|
||||
|
||||
$item_normal = " and item.item_hidden = 0 and item.item_type in (0,6) and item.item_deleted = 0
|
||||
and item.item_unpublished = 0 and item.item_delayed = 0 and item.item_pending_remove = 0
|
||||
and item.item_blocked = 0 ";
|
||||
|
||||
$items_result = [];
|
||||
if($r) {
|
||||
|
||||
$pager_total = count($r);
|
||||
|
||||
$parents_str = ids_to_querystr($r, 'id');
|
||||
|
||||
$items = q("SELECT item.*, item.id AS item_id
|
||||
FROM item
|
||||
WHERE item.uid = %d $item_normal
|
||||
AND item.parent IN ( %s )
|
||||
$sql_extra $sql_extra2 ",
|
||||
intval(App::$profile['profile_uid']),
|
||||
dbesc($parents_str)
|
||||
);
|
||||
if($items) {
|
||||
xchan_query($items);
|
||||
$items = fetch_post_tags($items, true);
|
||||
$items_result = conv_sort($items, 'updated');
|
||||
}
|
||||
}
|
||||
|
||||
$mode = 'cards';
|
||||
|
||||
if(get_pconfig(local_channel(),'system','articles_list_mode') && (! $selected_card))
|
||||
$page_mode = 'pager_list';
|
||||
else
|
||||
$page_mode = 'traditional';
|
||||
|
||||
$content = conversation($items_result, $mode, false, $page_mode);
|
||||
|
||||
$o = replace_macros(get_markup_template('cards.tpl'), [
|
||||
'$title' => t('Cards'),
|
||||
'$editor' => $editor,
|
||||
'$content' => $content,
|
||||
'$pager' => alt_pager($pager_total)
|
||||
]);
|
||||
|
||||
return $o;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -67,7 +67,7 @@ class Channel extends Controller {
|
||||
|
||||
if ($sigdata && $sigdata['signer'] && $sigdata['header_valid']) {
|
||||
$data = json_encode(Libzot::zotinfo(['guid_hash' => $channel['channel_hash'], 'target_url' => $sigdata['signer']]));
|
||||
$s = q("select site_crypto, hubloc_sitekey from site left join hubloc on hubloc_url = site_url where hubloc_id_url = '%s' and hubloc_network = 'zot6' limit 1",
|
||||
$s = q("select site_crypto, hubloc_sitekey from site left join hubloc on hubloc_url = site_url where hubloc_id_url = '%s' and hubloc_network = 'zot6' order by hubloc_id desc limit 1",
|
||||
dbesc($sigdata['signer'])
|
||||
);
|
||||
|
||||
@@ -267,6 +267,7 @@ class Channel extends Controller {
|
||||
'reset' => t('Reset form')
|
||||
];
|
||||
|
||||
$a = '';
|
||||
$o .= status_editor($a, $x, false, 'Channel');
|
||||
}
|
||||
|
||||
|
||||
@@ -103,7 +103,7 @@ class Contactedit extends Controller {
|
||||
dbesc($profile_id),
|
||||
intval(local_channel())
|
||||
);
|
||||
if (!count($r)) {
|
||||
if (!$r) {
|
||||
notice(t('Could not locate selected profile.') . EOL);
|
||||
return;
|
||||
}
|
||||
@@ -452,8 +452,8 @@ class Contactedit extends Controller {
|
||||
|
||||
if (is_ajax()) {
|
||||
json_return_and_die([
|
||||
'success' => ((intval($_REQUEST['success'])) ? intval($_REQUEST['success']) : 1),
|
||||
'message' => (($_REQUEST['success']) ? t('Contact updated') : t('Contact update failed')),
|
||||
'success' => ((isset($_REQUEST['success'])) ? intval($_REQUEST['success']) : 1),
|
||||
'message' => ((isset($_REQUEST['success'])) ? t('Contact updated') : t('Contact update failed')),
|
||||
'id' => $contact_id,
|
||||
'title' => $header_html,
|
||||
'role' => ((intval($contact['abook_pending'])) ? '' : $roles_dict[$current_permcat]),
|
||||
|
||||
@@ -254,21 +254,21 @@ class Directory extends Controller {
|
||||
$connect_link = '';
|
||||
|
||||
$location = '';
|
||||
if(strlen($rr['locale']))
|
||||
if(isset($rr['locale']))
|
||||
$location .= $rr['locale'];
|
||||
if(strlen($rr['region'])) {
|
||||
if(strlen($rr['locale']))
|
||||
if(isset($rr['region'])) {
|
||||
if($location)
|
||||
$location .= ', ';
|
||||
$location .= $rr['region'];
|
||||
}
|
||||
if(strlen($rr['country'])) {
|
||||
if(strlen($location))
|
||||
if(isset($rr['country'])) {
|
||||
if($location)
|
||||
$location .= ', ';
|
||||
$location .= $rr['country'];
|
||||
}
|
||||
|
||||
$age = '';
|
||||
if(strlen($rr['birthday'])) {
|
||||
if(isset($rr['birthday'])) {
|
||||
if(($years = age($rr['birthday'],'UTC','')) > 0)
|
||||
$age = $years;
|
||||
}
|
||||
|
||||
@@ -143,48 +143,8 @@ class Display extends \Zotlabs\Web\Controller {
|
||||
return '';
|
||||
}
|
||||
}
|
||||
if($target_item['item_type'] == ITEM_TYPE_ARTICLE) {
|
||||
$x = q("select * from channel where channel_id = %d limit 1",
|
||||
intval($target_item['uid'])
|
||||
);
|
||||
$y = q("select * from iconfig left join item on iconfig.iid = item.id
|
||||
where item.uid = %d and iconfig.cat = 'system' and iconfig.k = 'ARTICLE' and item.id = %d limit 1",
|
||||
intval($target_item['uid']),
|
||||
intval($target_item['parent'])
|
||||
);
|
||||
if($x && $y) {
|
||||
goaway(z_root() . '/articles/' . $x[0]['channel_address'] . '/' . $y[0]['v']);
|
||||
}
|
||||
else {
|
||||
notice( t('Page not found.') . EOL);
|
||||
return '';
|
||||
}
|
||||
}
|
||||
if($target_item['item_type'] == ITEM_TYPE_CARD) {
|
||||
|
||||
$x = q("select * from channel where channel_id = %d limit 1",
|
||||
intval($target_item['uid'])
|
||||
);
|
||||
|
||||
$y = q("select * from iconfig left join item on iconfig.iid = item.id
|
||||
where item.uid = %d and iconfig.cat = 'system' and iconfig.k = 'CARD' and item.id = %d limit 1",
|
||||
intval($target_item['uid']),
|
||||
intval($target_item['parent'])
|
||||
);
|
||||
|
||||
if($x && $y) {
|
||||
goaway(z_root() . '/cards/' . $x[0]['channel_address'] . '/' . $y[0]['v']);
|
||||
}
|
||||
else {
|
||||
notice( t('Page not found.') . EOL);
|
||||
return '';
|
||||
}
|
||||
}
|
||||
if ($target_item['item_type'] == ITEM_TYPE_CUSTOM) {
|
||||
call_hooks('item_custom_display',$target_item);
|
||||
notice( t('Page not found.') . EOL);
|
||||
return '';
|
||||
}
|
||||
call_hooks('item_custom_display', $target_item);
|
||||
|
||||
$simple_update = '';
|
||||
if($update && $_SESSION['loadtime'])
|
||||
@@ -266,7 +226,7 @@ class Display extends \Zotlabs\Web\Controller {
|
||||
);
|
||||
}
|
||||
|
||||
if(!$r) {
|
||||
if($r === null) {
|
||||
$r = q("SELECT item.id AS item_id FROM item
|
||||
WHERE ((mid = '%s'
|
||||
AND (((( item.allow_cid = '' AND item.allow_gid = '' AND item.deny_cid = ''
|
||||
@@ -303,7 +263,7 @@ class Display extends \Zotlabs\Web\Controller {
|
||||
);
|
||||
}
|
||||
|
||||
if(! $r) {
|
||||
if($r === null) {
|
||||
$r = q("SELECT item.id as item_id from item
|
||||
WHERE ((parent_mid = '%s'
|
||||
AND (((( item.allow_cid = '' AND item.allow_gid = '' AND item.deny_cid = ''
|
||||
|
||||
@@ -56,9 +56,10 @@ class Dreport extends \Zotlabs\Web\Controller {
|
||||
return;
|
||||
}
|
||||
|
||||
$r = q("select * from dreport where dreport_xchan = '%s' and dreport_mid = '%s'",
|
||||
$r = q("select * from dreport where dreport_xchan = '%s' and (dreport_mid = '%s' or dreport_mid = '%s')",
|
||||
dbesc($channel['channel_hash']),
|
||||
dbesc($mid)
|
||||
dbesc($mid),
|
||||
dbesc(str_replace('/item/', '/activity/', $mid))
|
||||
);
|
||||
|
||||
if(! $r) {
|
||||
|
||||
@@ -5,7 +5,7 @@ namespace Zotlabs\Module;
|
||||
class Hcard extends \Zotlabs\Web\Controller {
|
||||
|
||||
function init() {
|
||||
|
||||
|
||||
if(argc() > 1)
|
||||
$which = argv(1);
|
||||
else {
|
||||
@@ -13,12 +13,12 @@ class Hcard extends \Zotlabs\Web\Controller {
|
||||
\App::$error = 404;
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
logger('hcard_request: ' . $which, LOGGER_DEBUG);
|
||||
|
||||
$profile = '';
|
||||
$channel = \App::get_channel();
|
||||
|
||||
|
||||
if((local_channel()) && (argc() > 2) && (argv(2) === 'view')) {
|
||||
$which = $channel['channel_address'];
|
||||
$profile = argv(1);
|
||||
@@ -30,22 +30,22 @@ class Hcard extends \Zotlabs\Web\Controller {
|
||||
$profile = '';
|
||||
$profile = $r[0]['profile_guid'];
|
||||
}
|
||||
|
||||
head_add_link( [
|
||||
'rel' => 'alternate',
|
||||
|
||||
head_add_link( [
|
||||
'rel' => 'alternate',
|
||||
'type' => 'application/atom+xml',
|
||||
'title' => t('Posts and comments'),
|
||||
'href' => z_root() . '/feed/' . $which
|
||||
]);
|
||||
|
||||
head_add_link( [
|
||||
'rel' => 'alternate',
|
||||
head_add_link( [
|
||||
'rel' => 'alternate',
|
||||
'type' => 'application/atom+xml',
|
||||
'title' => t('Only posts'),
|
||||
'href' => z_root() . '/feed/' . $which . '?f=&top=1'
|
||||
]);
|
||||
|
||||
|
||||
|
||||
if(! $profile) {
|
||||
$x = q("select channel_id as profile_uid from channel where channel_address = '%s' limit 1",
|
||||
dbesc(argv(1))
|
||||
@@ -54,20 +54,20 @@ class Hcard extends \Zotlabs\Web\Controller {
|
||||
\App::$profile = $x[0];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
profile_load($which,$profile);
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
function get() {
|
||||
|
||||
$x = new \Zotlabs\Widget\Profile();
|
||||
$x = new \Zotlabs\Widget\Fullprofile();
|
||||
return $x->widget(array());
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -36,7 +36,7 @@ class Home extends Controller {
|
||||
|
||||
$channel = App::get_channel();
|
||||
if (local_channel() && $channel && $channel['xchan_url'] && !$splash) {
|
||||
$dest = (($ret['startpage']) ? $ret['startpage'] : '');
|
||||
$dest = $ret['startpage'] ?? '';
|
||||
if (!$dest)
|
||||
$dest = get_config('system', 'startpage');
|
||||
if (!$dest)
|
||||
|
||||
@@ -27,6 +27,8 @@ class Hq extends \Zotlabs\Web\Controller {
|
||||
return;
|
||||
}
|
||||
|
||||
$item_hash = '';
|
||||
|
||||
if(argc() > 1 && argv(1) !== 'load') {
|
||||
$item_hash = unpack_link_id(argv(1));
|
||||
}
|
||||
@@ -45,24 +47,11 @@ class Hq extends \Zotlabs\Web\Controller {
|
||||
$sys = get_sys_channel();
|
||||
$sys_item = false;
|
||||
$sql_extra = '';
|
||||
|
||||
if(! $item_hash) {
|
||||
$r = q("SELECT mid FROM item
|
||||
WHERE uid = %d $item_normal
|
||||
AND mid = parent_mid
|
||||
AND item_private IN (0, 1)
|
||||
ORDER BY created DESC LIMIT 1",
|
||||
intval(local_channel())
|
||||
);
|
||||
if($r[0]['mid']) {
|
||||
$item_hash = $r[0]['mid'];
|
||||
}
|
||||
}
|
||||
$target_item = null;
|
||||
$o = '';
|
||||
|
||||
if($item_hash) {
|
||||
|
||||
$target_item = null;
|
||||
|
||||
$r = q("select id, uid, mid, parent_mid, thr_parent, verb, item_type, item_deleted, item_blocked from item where mid = '%s' limit 1",
|
||||
dbesc($item_hash)
|
||||
);
|
||||
@@ -97,7 +86,7 @@ class Hq extends \Zotlabs\Web\Controller {
|
||||
'allow_location' => ((intval(get_pconfig($channel['channel_id'],'system','use_browser_location'))) ? '1' : ''),
|
||||
'default_location' => $channel['channel_location'],
|
||||
'nickname' => $channel['channel_address'],
|
||||
'lockstate' => (($group || $cid || $channel['channel_allow_cid'] || $channel['channel_allow_gid'] || $channel['channel_deny_cid'] || $channel['channel_deny_gid']) ? 'lock' : 'unlock'),
|
||||
'lockstate' => (($channel['channel_allow_cid'] || $channel['channel_allow_gid'] || $channel['channel_deny_cid'] || $channel['channel_deny_gid']) ? 'lock' : 'unlock'),
|
||||
'acl' => populate_acl($channel_acl,true, \Zotlabs\Lib\PermissionDescription::fromGlobalPermission('view_stream'), get_post_aclDialogDescription(), 'acl_dialog_post'),
|
||||
'permissions' => $channel_acl,
|
||||
'bang' => '',
|
||||
@@ -112,7 +101,8 @@ class Hq extends \Zotlabs\Web\Controller {
|
||||
'reset' => t('Reset form')
|
||||
];
|
||||
|
||||
$o = status_editor($a, $x, true);
|
||||
$a = '';
|
||||
$o .= status_editor($a, $x, true);
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -49,11 +49,6 @@ class Import_progress extends \Zotlabs\Web\Controller {
|
||||
}
|
||||
|
||||
$ccompleted_str = t('Item sync completed but no items were found!');
|
||||
|
||||
if(argv(1) === 'resume_itemsync') {
|
||||
Master::Summon(["Content_importer","0","0001-01-01 00:00:00","2021-10-02 19:49:14","ct5","https%3A%2F%2Fhub.somaton.com"]);
|
||||
goaway('/import_progress');
|
||||
}
|
||||
}
|
||||
|
||||
$cprogress_str = ((intval($cprogress)) ? $cprogress . '%' : $cprogress);
|
||||
@@ -76,8 +71,6 @@ class Import_progress extends \Zotlabs\Web\Controller {
|
||||
Master::Summon($f['next_cmd']);
|
||||
goaway('/import_progress');
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
else {
|
||||
$fprogress = 'waiting to start...';
|
||||
|
||||
@@ -358,7 +358,7 @@ class Item extends Controller {
|
||||
$consensus = intval($_REQUEST['consensus']);
|
||||
$nocomment = intval($_REQUEST['nocomment']);
|
||||
|
||||
$is_poll = ((trim($_REQUEST['poll_answers'][0]) != '' && trim($_REQUEST['poll_answers'][1]) != '') ? true : false);
|
||||
$is_poll = ((trim((string)$_REQUEST['poll_answers'][0]) != '' && trim((string)$_REQUEST['poll_answers'][1]) != '') ? true : false);
|
||||
|
||||
// 'origin' (if non-zero) indicates that this network is where the message originated,
|
||||
// for the purpose of relaying comments to other conversation members.
|
||||
@@ -387,7 +387,7 @@ class Item extends Controller {
|
||||
$categories = ((x($_REQUEST, 'category')) ? escape_tags($_REQUEST['category']) : '');
|
||||
$webpage = ((x($_REQUEST, 'webpage')) ? intval($_REQUEST['webpage']) : 0);
|
||||
$item_obscured = ((x($_REQUEST, 'obscured')) ? intval($_REQUEST['obscured']) : 0);
|
||||
$pagetitle = ((x($_REQUEST, 'pagetitle')) ? escape_tags(urlencode($_REQUEST['pagetitle'])) : '');
|
||||
$pagetitle = ((x($_REQUEST, 'pagetitle')) ? escape_tags($_REQUEST['pagetitle']) : '');
|
||||
$layout_mid = ((x($_REQUEST, 'layout_mid')) ? escape_tags($_REQUEST['layout_mid']) : '');
|
||||
$plink = ((x($_REQUEST, 'permalink')) ? escape_tags($_REQUEST['permalink']) : '');
|
||||
$obj_type = ((x($_REQUEST, 'obj_type')) ? escape_tags($_REQUEST['obj_type']) : ACTIVITY_OBJ_NOTE);
|
||||
@@ -411,7 +411,7 @@ class Item extends Controller {
|
||||
}
|
||||
|
||||
if ($pagetitle) {
|
||||
$pagetitle = strtolower(URLify::transliterate($pagetitle));
|
||||
$pagetitle = str_replace('/', '-', strtolower(URLify::transliterate($pagetitle)));
|
||||
}
|
||||
|
||||
|
||||
@@ -695,6 +695,7 @@ class Item extends Controller {
|
||||
$expires = $orig_post['expires'];
|
||||
$comments_closed = $orig_post['comments_closed'];
|
||||
$mid = $orig_post['mid'];
|
||||
$thr_parent = $orig_post['thr_parent'];
|
||||
$parent_mid = $orig_post['parent_mid'];
|
||||
$plink = $orig_post['plink'];
|
||||
}
|
||||
@@ -719,13 +720,13 @@ class Item extends Controller {
|
||||
}
|
||||
|
||||
|
||||
$location = notags(trim($_REQUEST['location']));
|
||||
$coord = notags(trim($_REQUEST['coord']));
|
||||
$verb = notags(trim($_REQUEST['verb']));
|
||||
$title = escape_tags(trim($_REQUEST['title']));
|
||||
$summary = trim($_REQUEST['summary']);
|
||||
$body = trim($_REQUEST['body']);
|
||||
$body .= trim($_REQUEST['attachment']);
|
||||
$location = notags(trim((string)$_REQUEST['location']));
|
||||
$coord = notags(trim((string)$_REQUEST['coord']));
|
||||
$verb = notags(trim((string)$_REQUEST['verb']));
|
||||
$title = escape_tags(trim((string)$_REQUEST['title']));
|
||||
$summary = trim((string)$_REQUEST['summary']);
|
||||
$body = trim((string)$_REQUEST['body']);
|
||||
$body .= trim((string)$_REQUEST['attachment']);
|
||||
$postopts = '';
|
||||
|
||||
$allow_empty = ((array_key_exists('allow_empty', $_REQUEST)) ? intval($_REQUEST['allow_empty']) : 0);
|
||||
@@ -742,6 +743,8 @@ class Item extends Controller {
|
||||
$webpage = $parent_item['item_type'];
|
||||
}
|
||||
|
||||
|
||||
|
||||
if ((!$allow_empty) && (!strlen($body))) {
|
||||
if ($preview)
|
||||
killme();
|
||||
@@ -764,7 +767,7 @@ class Item extends Controller {
|
||||
}
|
||||
|
||||
|
||||
$mimetype = notags(trim($_REQUEST['mimetype']));
|
||||
$mimetype = notags(trim((string)$_REQUEST['mimetype']));
|
||||
if (!$mimetype)
|
||||
$mimetype = 'text/bbcode';
|
||||
|
||||
@@ -806,7 +809,6 @@ class Item extends Controller {
|
||||
|
||||
$post_tags = [];
|
||||
|
||||
|
||||
if ($mimetype === 'text/bbcode') {
|
||||
|
||||
require_once('include/text.php');
|
||||
@@ -918,15 +920,7 @@ class Item extends Controller {
|
||||
$cats = explode(',', $categories);
|
||||
foreach ($cats as $cat) {
|
||||
|
||||
if ($webpage == ITEM_TYPE_CARD) {
|
||||
$catlink = z_root() . '/cards/' . $channel['channel_address'] . '?f=&cat=' . urlencode(trim($cat));
|
||||
}
|
||||
elseif ($webpage == ITEM_TYPE_ARTICLE) {
|
||||
$catlink = z_root() . '/articles/' . $channel['channel_address'] . '?f=&cat=' . urlencode(trim($cat));
|
||||
}
|
||||
else {
|
||||
$catlink = $owner_xchan['xchan_url'] . '?f=&cat=' . urlencode(trim($cat));
|
||||
}
|
||||
$catlink = $owner_xchan['xchan_url'] . '?f=&cat=' . urlencode(trim($cat));
|
||||
|
||||
$post_tags[] = [
|
||||
'uid' => $profile_uid,
|
||||
@@ -1039,7 +1033,7 @@ class Item extends Controller {
|
||||
$parent_mid = $parent_item['mid'];
|
||||
|
||||
|
||||
// Fallback so that we alway have a thr_parent
|
||||
// Fallback so that we always have a thr_parent
|
||||
|
||||
if (!$thr_parent)
|
||||
$thr_parent = $mid;
|
||||
@@ -1047,36 +1041,7 @@ class Item extends Controller {
|
||||
|
||||
$item_thread_top = ((!$parent) ? 1 : 0);
|
||||
|
||||
|
||||
// fix permalinks for cards
|
||||
|
||||
if ($webpage == ITEM_TYPE_CARD) {
|
||||
$plink = z_root() . '/cards/' . $channel['channel_address'] . '/' . (($pagetitle) ? $pagetitle : $uuid);
|
||||
}
|
||||
if (($parent_item) && ($parent_item['item_type'] == ITEM_TYPE_CARD)) {
|
||||
$r = q("select v from iconfig where iconfig.cat = 'system' and iconfig.k = 'CARD' and iconfig.iid = %d limit 1",
|
||||
intval($parent_item['id'])
|
||||
);
|
||||
if ($r) {
|
||||
$plink = z_root() . '/cards/' . $channel['channel_address'] . '/' . $r[0]['v'];
|
||||
}
|
||||
}
|
||||
|
||||
if ($webpage == ITEM_TYPE_ARTICLE) {
|
||||
$plink = z_root() . '/articles/' . $channel['channel_address'] . '/' . (($pagetitle) ? $pagetitle : $uuid);
|
||||
}
|
||||
if (($parent_item) && ($parent_item['item_type'] == ITEM_TYPE_ARTICLE)) {
|
||||
$r = q("select v from iconfig where iconfig.cat = 'system' and iconfig.k = 'ARTICLE' and iconfig.iid = %d limit 1",
|
||||
intval($parent_item['id'])
|
||||
);
|
||||
if ($r) {
|
||||
$plink = z_root() . '/articles/' . $channel['channel_address'] . '/' . $r[0]['v'];
|
||||
}
|
||||
}
|
||||
|
||||
if ((!$plink) && ($item_thread_top)) {
|
||||
// $plink = z_root() . '/channel/' . $channel['channel_address'] . '/?f=&mid=' . gen_link_id($mid);
|
||||
// $plink = substr($plink,0,190);
|
||||
$plink = $mid;
|
||||
}
|
||||
|
||||
@@ -1092,7 +1057,7 @@ class Item extends Controller {
|
||||
$datarray['created'] = $created;
|
||||
$datarray['edited'] = (($orig_post) ? datetime_convert() : $created);
|
||||
$datarray['expires'] = $expires;
|
||||
$datarray['comments_closed'] = $comments_closed;
|
||||
$datarray['comments_closed'] = (($nocomment) ? $created : $comments_closed);
|
||||
$datarray['commented'] = (($orig_post) ? datetime_convert() : $created);
|
||||
$datarray['received'] = (($orig_post) ? datetime_convert() : $created);
|
||||
$datarray['changed'] = (($orig_post) ? datetime_convert() : $created);
|
||||
|
||||
@@ -129,6 +129,9 @@ class Network extends \Zotlabs\Web\Controller {
|
||||
$pf = ((x($_GET, 'pf')) ? $_GET['pf'] : '');
|
||||
$unseen = ((x($_GET, 'unseen')) ? $_GET['unseen'] : '');
|
||||
|
||||
$status_editor = '';
|
||||
|
||||
|
||||
if (Apps::system_app_installed(local_channel(), 'Affinity Tool')) {
|
||||
$affinity_locked = intval(get_pconfig(local_channel(), 'affinity', 'lock', 1));
|
||||
if ($affinity_locked) {
|
||||
@@ -208,6 +211,7 @@ class Network extends \Zotlabs\Web\Controller {
|
||||
'reset' => t('Reset form')
|
||||
);
|
||||
|
||||
$a = '';
|
||||
$status_editor = status_editor($a, $x, false, 'Network');
|
||||
$o .= $status_editor;
|
||||
|
||||
@@ -272,15 +276,17 @@ class Network extends \Zotlabs\Web\Controller {
|
||||
$likes_sql = " AND verb NOT IN ('" . dbesc(ACTIVITY_LIKE) . "', '" . dbesc(ACTIVITY_DISLIKE) . "') ";
|
||||
|
||||
// This is for nouveau view public forum cid queries (if a forum notification is clicked)
|
||||
$p = q("SELECT oid AS parent FROM term WHERE uid = %d AND ttype = %d AND term = '%s'",
|
||||
intval(local_channel()),
|
||||
intval(TERM_FORUM),
|
||||
dbesc($cid_r[0]['xchan_name'])
|
||||
);
|
||||
//$p = q("SELECT oid AS parent FROM term WHERE uid = %d AND ttype = %d AND term = '%s'",
|
||||
//intval(local_channel()),
|
||||
//intval(TERM_FORUM),
|
||||
//dbesc($cid_r[0]['xchan_name'])
|
||||
//);
|
||||
|
||||
$p_str = ids_to_querystr($p, 'parent');
|
||||
if($p_str)
|
||||
$p_sql = " OR item.parent IN ( $p_str ) ";
|
||||
//$p_str = ids_to_querystr($p, 'parent');
|
||||
|
||||
$p_sql = '';
|
||||
//if($p_str)
|
||||
//$p_sql = " OR item.parent IN ( $p_str ) ";
|
||||
|
||||
$sql_extra = " AND ( owner_xchan = '" . protect_sprintf(dbesc($cid_r[0]['abook_xchan'])) . "' OR owner_xchan = '" . protect_sprintf(dbesc($cid_r[0]['abook_xchan'])) . "' $p_sql ) AND item_unseen = 1 $likes_sql ";
|
||||
}
|
||||
@@ -368,9 +374,9 @@ class Network extends \Zotlabs\Web\Controller {
|
||||
// ActivityStreams specification.
|
||||
|
||||
if (substr($verb, 0, 1) === '.') {
|
||||
$verb = substr($verb, 1);
|
||||
$sql_verb = substr($verb, 1);
|
||||
$sql_extra .= sprintf(" AND item.obj_type like '%s' ",
|
||||
dbesc(protect_sprintf('%' . $verb . '%'))
|
||||
dbesc(protect_sprintf('%' . $sql_verb . '%'))
|
||||
);
|
||||
}
|
||||
else {
|
||||
|
||||
@@ -76,7 +76,7 @@ class Outbox extends Controller {
|
||||
App::set_pager_itemspage(30);
|
||||
}
|
||||
|
||||
if (App::$pager['unset'] && $total > 30) {
|
||||
if (isset(App::$pager['unset']) && $total > 30) {
|
||||
$ret = Activity::paged_collection_init($total, App::$query_string);
|
||||
}
|
||||
else {
|
||||
|
||||
@@ -32,14 +32,14 @@ class Owa extends Controller {
|
||||
$keyId = $sigblock['keyId'];
|
||||
if ($keyId) {
|
||||
$r = q("SELECT * FROM hubloc LEFT JOIN xchan ON hubloc_hash = xchan_hash
|
||||
WHERE hubloc_id_url = '%s' AND xchan_pubkey != '' ",
|
||||
WHERE hubloc_id_url = '%s' AND hubloc_deleted = 0 ORDER BY hubloc_id DESC",
|
||||
dbesc($keyId)
|
||||
);
|
||||
if (! $r) {
|
||||
$found = discover_by_webbie(str_replace('acct:','',$keyId));
|
||||
$found = discover_by_webbie($keyId);
|
||||
if ($found) {
|
||||
$r = q("SELECT * FROM hubloc LEFT JOIN xchan ON hubloc_hash = xchan_hash
|
||||
WHERE hubloc_id_url = '%s' AND xchan_pubkey != '' ",
|
||||
WHERE hubloc_id_url = '%s' AND hubloc_deleted = 0 ORDER BY hubloc_id DESC ",
|
||||
dbesc($keyId)
|
||||
);
|
||||
}
|
||||
@@ -61,10 +61,43 @@ class Owa extends Controller {
|
||||
logger('OWA fail: ' . $hubloc['hubloc_id'] . ' ' . $hubloc['hubloc_id_url']);
|
||||
}
|
||||
}
|
||||
|
||||
if (!$ret['success']) {
|
||||
|
||||
// Possible a reinstall?
|
||||
// In this case we probably already have an old hubloc
|
||||
// but not the new one yet.
|
||||
|
||||
$found = discover_by_webbie($keyId);
|
||||
|
||||
if ($found) {
|
||||
$r = q("SELECT * FROM hubloc LEFT JOIN xchan ON hubloc_hash = xchan_hash
|
||||
WHERE hubloc_id_url = '%s' AND hubloc_deleted = 0 ORDER BY hubloc_id DESC LIMIT 1",
|
||||
dbesc($keyId)
|
||||
);
|
||||
|
||||
if ($r) {
|
||||
$verified = HTTPSig::verify(file_get_contents('php://input'), $r[0]['xchan_pubkey']);
|
||||
if ($verified && $verified['header_signed'] && $verified['header_valid'] && ($verified['content_valid'] || (! $verified['content_signed']))) {
|
||||
logger('OWA header: ' . print_r($verified,true), LOGGER_DATA);
|
||||
logger('OWA success: ' . $r[0]['hubloc_id_url'], LOGGER_DATA);
|
||||
$ret['success'] = true;
|
||||
$token = random_string(32);
|
||||
Verify::create('owt', 0, $token, $r[0]['hubloc_id_url']);
|
||||
$result = '';
|
||||
openssl_public_encrypt($token, $result, $r[0]['xchan_pubkey']);
|
||||
$ret['encrypted_token'] = base64url_encode($result);
|
||||
} else {
|
||||
logger('OWA fail: ' . $hubloc['hubloc_id'] . ' ' . $hubloc['hubloc_id_url']);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
json_return_and_die($ret,'application/x-zot+json');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,42 +9,42 @@ class Page extends \Zotlabs\Web\Controller {
|
||||
|
||||
function init() {
|
||||
// We need this to make sure the channel theme is always loaded.
|
||||
|
||||
|
||||
$which = argv(1);
|
||||
$profile = 0;
|
||||
profile_load($which,$profile);
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
if(\App::$profile['profile_uid'])
|
||||
head_set_icon(\App::$profile['thumb']);
|
||||
|
||||
|
||||
// load the item here in the init function because we need to extract
|
||||
// the page layout and initialise the correct theme.
|
||||
|
||||
|
||||
|
||||
|
||||
$observer = \App::get_observer();
|
||||
$ob_hash = (($observer) ? $observer['xchan_hash'] : '');
|
||||
|
||||
|
||||
// perm_is_allowed is denied unconditionally when 'site blocked to unauthenticated members'.
|
||||
|
||||
|
||||
// perm_is_allowed is denied unconditionally when 'site blocked to unauthenticated members'.
|
||||
// This bypasses that restriction for sys channel (public) content
|
||||
|
||||
|
||||
if((! perm_is_allowed(\App::$profile['profile_uid'],$ob_hash,'view_pages')) && (! is_sys_channel(\App::$profile['profile_uid']))) {
|
||||
notice( t('Permission denied.') . EOL);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
if(argc() < 3) {
|
||||
notice( t('Invalid item.') . EOL);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
$channel_address = argv(1);
|
||||
|
||||
|
||||
// Always look first for the page name prefixed by the observer language; for instance page/nickname/de/foo
|
||||
// followed by page/nickname/foo if that is not found.
|
||||
// If your browser language is de and you want to access the default in this case,
|
||||
// If your browser language is de and you want to access the default in this case,
|
||||
// use page/nickname/-/foo to over-ride the language and access only the page with pagelink of 'foo'
|
||||
|
||||
$page_name = '';
|
||||
@@ -63,33 +63,33 @@ class Page extends \Zotlabs\Web\Controller {
|
||||
|
||||
// The page link title was stored in a urlencoded format
|
||||
// php or the browser may/will have decoded it, so re-encode it for our search
|
||||
|
||||
|
||||
$page_id = urlencode($page_name);
|
||||
$lang_page_id = urlencode(\App::$language . '/' . $page_name);
|
||||
|
||||
$u = q("select channel_id from channel where channel_address = '%s' limit 1",
|
||||
dbesc($channel_address)
|
||||
);
|
||||
|
||||
|
||||
if(! $u) {
|
||||
notice( t('Channel not found.') . EOL);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
if($_REQUEST['rev'])
|
||||
$revision = " and revision = " . intval($_REQUEST['rev']) . " ";
|
||||
else
|
||||
$revision = " order by revision desc ";
|
||||
|
||||
|
||||
require_once('include/security.php');
|
||||
$sql_options = item_permissions_sql($u[0]['channel_id']);
|
||||
|
||||
$r = null;
|
||||
$r = null;
|
||||
|
||||
if(! $ignore_language) {
|
||||
$r = q("select item.* from item left join iconfig on item.id = iconfig.iid
|
||||
where item.uid = %d and iconfig.cat = 'system' and iconfig.v = '%s' and item.item_delayed = 0
|
||||
and iconfig.k = 'WEBPAGE' and item_type = %d
|
||||
where item.uid = %d and iconfig.cat = 'system' and iconfig.v = '%s' and item.item_delayed = 0
|
||||
and iconfig.k = 'WEBPAGE' and item_type = %d
|
||||
$sql_options $revision limit 1",
|
||||
intval($u[0]['channel_id']),
|
||||
dbesc($lang_page_id),
|
||||
@@ -98,8 +98,8 @@ class Page extends \Zotlabs\Web\Controller {
|
||||
}
|
||||
if(! $r) {
|
||||
$r = q("select item.* from item left join iconfig on item.id = iconfig.iid
|
||||
where item.uid = %d and iconfig.cat = 'system' and iconfig.v = '%s' and item.item_delayed = 0
|
||||
and iconfig.k = 'WEBPAGE' and item_type = %d
|
||||
where item.uid = %d and iconfig.cat = 'system' and iconfig.v = '%s' and item.item_delayed = 0
|
||||
and iconfig.k = 'WEBPAGE' and item_type = %d
|
||||
$sql_options $revision limit 1",
|
||||
intval($u[0]['channel_id']),
|
||||
dbesc($page_id),
|
||||
@@ -109,7 +109,7 @@ class Page extends \Zotlabs\Web\Controller {
|
||||
if(! $r) {
|
||||
// no webpage by that name, but we do allow you to load/preview a layout using this module. Try that.
|
||||
$r = q("select item.* from item left join iconfig on item.id = iconfig.iid
|
||||
where item.uid = %d and iconfig.cat = 'system' and iconfig.v = '%s' and item.item_delayed = 0
|
||||
where item.uid = %d and iconfig.cat = 'system' and iconfig.v = '%s' and item.item_delayed = 0
|
||||
and iconfig.k = 'PDL' AND item_type = %d $sql_options $revision limit 1",
|
||||
intval($u[0]['channel_id']),
|
||||
dbesc($page_id),
|
||||
@@ -117,17 +117,17 @@ class Page extends \Zotlabs\Web\Controller {
|
||||
);
|
||||
}
|
||||
if(! $r) {
|
||||
|
||||
|
||||
// Check again with no permissions clause to see if it is a permissions issue
|
||||
|
||||
|
||||
$x = q("select item.* from item left join iconfig on item.id = iconfig.iid
|
||||
where item.uid = %d and iconfig.cat = 'system' and iconfig.v = '%s' and item.item_delayed = 0
|
||||
where item.uid = %d and iconfig.cat = 'system' and iconfig.v = '%s' and item.item_delayed = 0
|
||||
and iconfig.k = 'WEBPAGE' and item_type = %d $revision limit 1",
|
||||
intval($u[0]['channel_id']),
|
||||
dbesc($page_id),
|
||||
intval(ITEM_TYPE_WEBPAGE)
|
||||
);
|
||||
|
||||
|
||||
if($x) {
|
||||
// Yes, it's there. You just aren't allowed to see it.
|
||||
notice( t('Permission denied.') . EOL);
|
||||
@@ -140,7 +140,7 @@ class Page extends \Zotlabs\Web\Controller {
|
||||
|
||||
if($r[0]['title'])
|
||||
\App::$page['title'] = escape_tags($r[0]['title']);
|
||||
|
||||
|
||||
if($r[0]['item_type'] == ITEM_TYPE_PDL) {
|
||||
\App::$comanche = new \Zotlabs\Render\Comanche();
|
||||
\App::$comanche->parse($r[0]['body']);
|
||||
@@ -151,40 +151,41 @@ class Page extends \Zotlabs\Web\Controller {
|
||||
dbesc($r[0]['layout_mid']),
|
||||
intval($u[0]['channel_id'])
|
||||
);
|
||||
|
||||
|
||||
if($l) {
|
||||
\App::$comanche = new \Zotlabs\Render\Comanche();
|
||||
\App::$comanche->parse($l[0]['body']);
|
||||
\App::$pdl = $l[0]['body'];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
\App::$data['webpage'] = $r;
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
function get() {
|
||||
|
||||
|
||||
$r = \App::$data['webpage'];
|
||||
|
||||
if(! $r)
|
||||
return;
|
||||
|
||||
|
||||
if($r[0]['item_type'] == ITEM_TYPE_PDL) {
|
||||
$r[0]['body'] = t('Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.');
|
||||
$r[0]['mimetype'] = 'text/plain';
|
||||
$r[0]['title'] = '';
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
xchan_query($r);
|
||||
$r = fetch_post_tags($r,true);
|
||||
|
||||
|
||||
if($r[0]['mimetype'] === 'application/x-pdl')
|
||||
\App::$page['pdl_content'] = true;
|
||||
|
||||
|
||||
$o .= prepare_page($r[0]);
|
||||
return $o;
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
553
Zotlabs/Module/Pdledit_gui.php
Normal file
553
Zotlabs/Module/Pdledit_gui.php
Normal file
@@ -0,0 +1,553 @@
|
||||
<?php
|
||||
|
||||
namespace Zotlabs\Module;
|
||||
|
||||
use App;
|
||||
use Zotlabs\Web\Controller;
|
||||
use Zotlabs\Render\Comanche;
|
||||
use Zotlabs\Lib\Libsync;
|
||||
|
||||
class Pdledit_gui extends Controller {
|
||||
|
||||
function post() {
|
||||
|
||||
if (!local_channel()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!$_REQUEST['module']) {
|
||||
return;
|
||||
}
|
||||
|
||||
$module = $_REQUEST['module'];
|
||||
|
||||
$ret = [
|
||||
'success' => false,
|
||||
'module' => $module
|
||||
];
|
||||
|
||||
if ($_REQUEST['reset']) {
|
||||
del_pconfig(local_channel(), 'system', 'mod_' . $module . '.pdl');
|
||||
Libsync::build_sync_packet();
|
||||
$ret['success'] = true;
|
||||
json_return_and_die($ret);
|
||||
}
|
||||
|
||||
if ($_REQUEST['save']) {
|
||||
if (!$_REQUEST['data']) {
|
||||
return $ret;
|
||||
}
|
||||
|
||||
$data = json_decode($_REQUEST['data'],true);
|
||||
$stored_pdl_result = self::get_pdl($module);
|
||||
$pdl = $stored_pdl_result['pdl'];
|
||||
|
||||
foreach ($data as $region => $entries) {
|
||||
$region_pdl = '';
|
||||
foreach ($entries as $entry) {
|
||||
$region_pdl .= base64_decode($entry) . "\r\n";
|
||||
}
|
||||
$pdl = preg_replace('/\[region=' . $region . '\](.*?)\[\/region\]/ism', '[region=' . $region . ']' . "\r\n" . $region_pdl . "\r\n" . '[/region]', $pdl);
|
||||
}
|
||||
|
||||
set_pconfig(local_channel(), 'system', 'mod_' . $module . '.pdl', escape_tags($pdl));
|
||||
Libsync::build_sync_packet();
|
||||
|
||||
$ret['success'] = true;
|
||||
json_return_and_die($ret);
|
||||
}
|
||||
|
||||
if ($_REQUEST['save_src']) {
|
||||
set_pconfig(local_channel(), 'system', 'mod_' . $module . '.pdl', escape_tags($_REQUEST['src']));
|
||||
Libsync::build_sync_packet();
|
||||
|
||||
$ret['success'] = true;
|
||||
json_return_and_die($ret);
|
||||
}
|
||||
|
||||
if ($_REQUEST['save_template']) {
|
||||
if (!$_REQUEST['data']) {
|
||||
return $ret;
|
||||
}
|
||||
|
||||
$template = $_REQUEST['data'][0]['value'];
|
||||
$pdl_result = self::get_pdl($module);
|
||||
$stored_template = self::get_template($pdl_result['pdl']);
|
||||
|
||||
if ($template === $stored_template) {
|
||||
$ret['success'] = true;
|
||||
return $ret;
|
||||
}
|
||||
|
||||
$cnt = preg_match("/\[template\](.*?)\[\/template\]/ism", $pdl_result['pdl'], $matches);
|
||||
if ($cnt) {
|
||||
$pdl = str_replace('[template]' . $stored_template . '[/template]', '[template]' . $template . '[/template]', $pdl_result['pdl']);
|
||||
}
|
||||
else {
|
||||
$pdl = '[template]' . $template . '[/template]' . "\r\n";
|
||||
$pdl .= $pdl_result['pdl'];
|
||||
}
|
||||
|
||||
set_pconfig(local_channel(), 'system', 'mod_' . $module . '.pdl', escape_tags($pdl));
|
||||
Libsync::build_sync_packet();
|
||||
|
||||
$ret['success'] = true;
|
||||
json_return_and_die($ret);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function get() {
|
||||
|
||||
if(! local_channel()) {
|
||||
return EMPTY_STR;
|
||||
}
|
||||
|
||||
$module = argv(1);
|
||||
|
||||
if (!$module) {
|
||||
goaway(z_root() . '/pdledit_gui/hq');
|
||||
}
|
||||
|
||||
$pdl_result = self::get_pdl($module);
|
||||
|
||||
$pdl = $pdl_result['pdl'];
|
||||
$modified = $pdl_result['modified'];
|
||||
|
||||
if(!$pdl) {
|
||||
return t('Layout not found');
|
||||
}
|
||||
|
||||
$template = self::get_template($pdl);
|
||||
|
||||
$template_info = self::get_template_info($template);
|
||||
|
||||
if(empty($template_info['contentregion'])) {
|
||||
return t('This template does not support pdledi_gui (no content regions defined)');
|
||||
}
|
||||
|
||||
App::$page['template'] = $template;
|
||||
|
||||
$regions = self::get_regions($pdl);
|
||||
|
||||
foreach ($regions as $k => $v) {
|
||||
$region_str = '';
|
||||
if (is_array($v)) {
|
||||
ksort($v);
|
||||
foreach ($v as $entry) {
|
||||
// Get the info from the file and replace entry if we get anything useful
|
||||
$widget_info = get_widget_info($entry['name']);
|
||||
$entry['name'] = (($widget_info['name']) ? $widget_info['name'] : $entry['name']);
|
||||
$entry['desc'] = (($widget_info['description']) ? $widget_info['description'] : $entry['desc']);
|
||||
|
||||
$region_str .= replace_macros(get_markup_template('pdledit_gui_item.tpl'), [
|
||||
'$entry' => $entry
|
||||
]);
|
||||
}
|
||||
}
|
||||
App::$layout['region_' . $k] = $region_str;
|
||||
}
|
||||
|
||||
$templates = self::get_templates();
|
||||
$templates_html = replace_macros(get_markup_template('pdledit_gui_templates.tpl'), [
|
||||
'$templates' => $templates,
|
||||
'$active' => $template
|
||||
]);
|
||||
|
||||
$items_html = '';
|
||||
|
||||
//$items_html .= replace_macros(get_markup_template('pdledit_gui_item.tpl'), [
|
||||
//'$entry' => [
|
||||
//'type' => 'content',
|
||||
//'name' => t('Main page content'),
|
||||
//'src' => base64_encode('$content')
|
||||
//],
|
||||
//'$disable_controls' => true
|
||||
//]);
|
||||
|
||||
foreach (self::get_widgets($module) as $entry) {
|
||||
$items_html .= replace_macros(get_markup_template('pdledit_gui_item.tpl'), [
|
||||
'$entry' => $entry,
|
||||
'$disable_controls' => true
|
||||
]);
|
||||
}
|
||||
|
||||
foreach (self::get_menus() as $entry) {
|
||||
$items_html .= replace_macros(get_markup_template('pdledit_gui_item.tpl'), [
|
||||
'$entry' => $entry,
|
||||
'$disable_controls' => true
|
||||
]);
|
||||
}
|
||||
|
||||
foreach (self::get_blocks() as $entry) {
|
||||
$items_html .= replace_macros(get_markup_template('pdledit_gui_item.tpl'), [
|
||||
'$entry' => $entry,
|
||||
'$disable_controls' => true
|
||||
]);
|
||||
}
|
||||
|
||||
App::$layout['region_content'] .= replace_macros(get_markup_template('pdledit_gui.tpl'), [
|
||||
'$content_regions' => $template_info['contentregion'],
|
||||
'$page_src' => base64_encode($pdl),
|
||||
'$templates' => base64_encode($templates_html),
|
||||
'$modules' => base64_encode(self::get_modules()),
|
||||
'$items' => base64_encode($items_html),
|
||||
'$module_modified' => $modified,
|
||||
'$module' => $module
|
||||
]);
|
||||
|
||||
}
|
||||
|
||||
function get_templates() {
|
||||
$ret = [];
|
||||
|
||||
$files = glob('view/php/*.php');
|
||||
if($files) {
|
||||
foreach($files as $f) {
|
||||
$name = basename($f, '.php');
|
||||
$x = get_template_info($name);
|
||||
if(!empty($x['contentregion'])) {
|
||||
$ret[] = [
|
||||
'name' => $name,
|
||||
'desc' => $x['description']
|
||||
];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $ret;
|
||||
}
|
||||
|
||||
function get_modules() {
|
||||
$ret = '';
|
||||
|
||||
$files = glob('Zotlabs/Module/*.php');
|
||||
if($files) {
|
||||
foreach($files as $f) {
|
||||
$name = lcfirst(basename($f,'.php'));
|
||||
|
||||
if ($name === 'admin' && !is_site_admin()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$x = theme_include('mod_' . $name . '.pdl');
|
||||
if($x) {
|
||||
$ret .= '<div class="mb-2"><a href="pdledit_gui/' . $name . '">' . $name . '</a></div>';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $ret;
|
||||
}
|
||||
|
||||
function get_widgets($module) {
|
||||
$ret = [];
|
||||
|
||||
$checkpaths = [
|
||||
'Zotlabs/Widget/*.php'
|
||||
];
|
||||
|
||||
foreach ($checkpaths as $path) {
|
||||
$files = glob($path);
|
||||
if($files) {
|
||||
foreach($files as $f) {
|
||||
$name = lcfirst(basename($f, '.php'));
|
||||
|
||||
$widget_info = get_widget_info($name);
|
||||
if ($widget_info['requires'] && strpos($widget_info['requires'], 'admin') !== false && !is_site_admin()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if ($widget_info['requires'] && strpos($widget_info['requires'], $module) === false) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$ret[] = [
|
||||
'type' => 'widget',
|
||||
'name' => $widget_info['name'] ?? $name,
|
||||
'desc' => $widget_info['description'] ?? '',
|
||||
'src' => base64_encode('[widget=' . $name . '][/widget]')
|
||||
];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $ret;
|
||||
}
|
||||
|
||||
function get_menus() {
|
||||
$ret = [];
|
||||
|
||||
$r = q("select * from menu where menu_channel_id = %d and menu_flags = 0",
|
||||
intval(local_channel())
|
||||
);
|
||||
|
||||
foreach ($r as $rr) {
|
||||
$name = $rr['menu_name'];
|
||||
$desc = $rr['menu_desc'];
|
||||
$ret[] = [
|
||||
'type' => 'menu',
|
||||
'name' => $name,
|
||||
'desc' => $desc,
|
||||
'src' => base64_encode('[menu]' . $name . '[/menu]')
|
||||
];
|
||||
}
|
||||
|
||||
return $ret;
|
||||
}
|
||||
|
||||
function get_blocks() {
|
||||
$ret = [];
|
||||
|
||||
$r = q("select v, title, summary from item join iconfig on iconfig.iid = item.id and item.uid = %d
|
||||
and iconfig.cat = 'system' and iconfig.k = 'BUILDBLOCK'",
|
||||
intval(local_channel())
|
||||
);
|
||||
|
||||
foreach ($r as $rr) {
|
||||
$name = $rr['v'];
|
||||
$desc = (($rr['title']) ? $rr['title'] : $rr['summary']);
|
||||
$ret[] = [
|
||||
'type' => 'block',
|
||||
'name' => $name,
|
||||
'desc' => $desc,
|
||||
'src' => base64_encode('[block]' . $name . '[/block]')
|
||||
];
|
||||
}
|
||||
|
||||
return $ret;
|
||||
}
|
||||
|
||||
function get_template($pdl) {
|
||||
$ret = 'default';
|
||||
|
||||
$cnt = preg_match("/\[template\](.*?)\[\/template\]/ism", $pdl, $matches);
|
||||
if($cnt && isset($matches[1])) {
|
||||
$ret = trim($matches[1]);
|
||||
}
|
||||
|
||||
return $ret;
|
||||
}
|
||||
|
||||
function get_regions($pdl) {
|
||||
$ret = [];
|
||||
$supported_regions = ['aside', 'content', 'right_aside'];
|
||||
|
||||
$cnt = preg_match_all("/\[region=(.*?)\](.*?)\[\/region\]/ism", $pdl, $matches, PREG_SET_ORDER);
|
||||
if($cnt) {
|
||||
foreach($matches as $mtch) {
|
||||
if (!in_array($mtch[1], $supported_regions)) {
|
||||
continue;
|
||||
}
|
||||
$ret[$mtch[1]] = self::parse_region($mtch[2]);
|
||||
}
|
||||
}
|
||||
|
||||
return $ret;
|
||||
}
|
||||
|
||||
function parse_region($pdl) {
|
||||
$ret = [];
|
||||
|
||||
$cnt = preg_match_all('/\$content\b/ism', $pdl, $matches, PREG_SET_ORDER|PREG_OFFSET_CAPTURE);
|
||||
if($cnt) {
|
||||
foreach($matches as $mtch) {
|
||||
$offset = intval($mtch[0][1]);
|
||||
$name = trim($mtch[0][0]);
|
||||
//$src = base64url_encode(preg_replace(['/\s*\[/', '/\]\s*/'], ['[', ']'], $mtch[0][0]));
|
||||
$src = base64_encode($mtch[0][0]);
|
||||
$ret[$offset] = [
|
||||
'type' => 'content',
|
||||
'name' => t('Main page content'),
|
||||
'desc' => t('The main page content can not be edited!'),
|
||||
'src' => $src
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
$cnt = preg_match_all("/\[menu\](.*?)\[\/menu\]/ism", $pdl, $matches, PREG_SET_ORDER|PREG_OFFSET_CAPTURE);
|
||||
if($cnt) {
|
||||
foreach($matches as $mtch) {
|
||||
$offset = intval($mtch[1][1]);
|
||||
$name = trim($mtch[1][0]);
|
||||
//$src = base64url_encode(preg_replace(['/\s*\[/', '/\]\s*/'], ['[', ']'], $mtch[0][0]));
|
||||
$src = base64_encode($mtch[0][0]);
|
||||
|
||||
$ret[$offset] = [
|
||||
'type' => 'menu',
|
||||
'name' => $name,
|
||||
'desc' => '',
|
||||
'src' => $src
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
// menu class e.g. [menu=horizontal]my_menu[/menu] or [menu=tabbed]my_menu[/menu]
|
||||
// allows different menu renderings to be applied
|
||||
|
||||
//$cnt = preg_match_all("/\[menu=(.*?)\](.*?)\[\/menu\]/ism", $s, $matches, PREG_SET_ORDER);
|
||||
//if($cnt) {
|
||||
//foreach($matches as $mtch) {
|
||||
//$s = str_replace($mtch[0],$this->menu(trim($mtch[2]),$mtch[1]),$s);
|
||||
//}
|
||||
//}
|
||||
|
||||
|
||||
$cnt = preg_match_all("/\[block\](.*?)\[\/block\]/ism", $pdl, $matches, PREG_SET_ORDER|PREG_OFFSET_CAPTURE);
|
||||
if($cnt) {
|
||||
foreach($matches as $mtch) {
|
||||
$offset = intval($mtch[1][1]);
|
||||
$name = trim($mtch[1][0]);
|
||||
//$src = base64url_encode(preg_replace(['/\s*\[/', '/\]\s*/'], ['[', ']'], $mtch[0][0]));
|
||||
$src = base64_encode($mtch[0][0]);
|
||||
$ret[$offset] = [
|
||||
'type' => 'block',
|
||||
'name' => $name,
|
||||
'desc' => '',
|
||||
'src' => $src
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
//$cnt = preg_match_all("/\[block=(.*?)\](.*?)\[\/block\]/ism", $s, $matches, PREG_SET_ORDER);
|
||||
//if($cnt) {
|
||||
//foreach($matches as $mtch) {
|
||||
//$s = str_replace($mtch[0],$this->block(trim($mtch[2]),trim($mtch[1])),$s);
|
||||
//}
|
||||
//}
|
||||
|
||||
//$cnt = preg_match_all("/\[js\](.*?)\[\/js\]/ism", $s, $matches, PREG_SET_ORDER);
|
||||
//if($cnt) {
|
||||
//foreach($matches as $mtch) {
|
||||
//$s = str_replace($mtch[0],$this->js(trim($mtch[1])),$s);
|
||||
//}
|
||||
//}
|
||||
|
||||
//$cnt = preg_match_all("/\[css\](.*?)\[\/css\]/ism", $s, $matches, PREG_SET_ORDER);
|
||||
//if($cnt) {
|
||||
//foreach($matches as $mtch) {
|
||||
//$s = str_replace($mtch[0],$this->css(trim($mtch[1])),$s);
|
||||
//}
|
||||
//}
|
||||
|
||||
// need to modify this to accept parameters
|
||||
|
||||
$cnt = preg_match_all("/\[widget=(.*?)\](.*?)\[\/widget\]/ism", $pdl, $matches, PREG_SET_ORDER|PREG_OFFSET_CAPTURE);
|
||||
|
||||
if($cnt) {
|
||||
foreach($matches as $mtch) {
|
||||
$offset = intval($mtch[1][1]);
|
||||
$name = trim($mtch[1][0]);
|
||||
//$src = base64url_encode(preg_replace(['/\s*\[/', '/\]\s*/'], ['[', ']'], $mtch[0][0]));
|
||||
$src = base64_encode($mtch[0][0]);
|
||||
$ret[$offset] = [
|
||||
'type' => 'widget',
|
||||
'name' => $name,
|
||||
'desc' => '',
|
||||
'src' => $src
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
return $ret;
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief Parse template comment in search of template info.
|
||||
*
|
||||
* like
|
||||
* \code
|
||||
* * Name: MyWidget
|
||||
* * Description: A widget
|
||||
* * Version: 1.2.3
|
||||
* * Author: John <profile url>
|
||||
* * Author: Jane <email>
|
||||
* * ContentRegionID: some_id
|
||||
* * ContentRegionID: some_other_id
|
||||
* *
|
||||
*\endcode
|
||||
* @param string $template the name of the template
|
||||
* @return array with the information
|
||||
*/
|
||||
function get_template_info($template){
|
||||
$m = [];
|
||||
$info = [
|
||||
'name' => $template,
|
||||
'description' => '',
|
||||
'author' => [],
|
||||
'maintainer' => [],
|
||||
'version' => '',
|
||||
'contentregion' => []
|
||||
];
|
||||
|
||||
$checkpaths = [
|
||||
'view/php/' . $template . '.php',
|
||||
];
|
||||
|
||||
$template_found = false;
|
||||
|
||||
foreach ($checkpaths as $path) {
|
||||
if (is_file($path)) {
|
||||
$template_found = true;
|
||||
$f = file_get_contents($path);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(!($template_found && $f))
|
||||
return $info;
|
||||
|
||||
$f = escape_tags($f);
|
||||
$r = preg_match('|/\*.*\*/|msU', $f, $m);
|
||||
|
||||
if ($r) {
|
||||
$ll = explode("\n", $m[0]);
|
||||
foreach($ll as $l) {
|
||||
$l = trim($l, "\t\n\r */");
|
||||
if ($l != ''){
|
||||
list($k, $v) = array_map('trim', explode(':', $l, 2));
|
||||
$k = strtolower($k);
|
||||
if (in_array($k, ['author', 'maintainer'])){
|
||||
$r = preg_match('|([^<]+)<([^>]+)>|', $v, $m);
|
||||
if ($r) {
|
||||
$info[$k][] = array('name' => $m[1], 'link' => $m[2]);
|
||||
} else {
|
||||
$info[$k][] = array('name' => $v);
|
||||
}
|
||||
}
|
||||
elseif (in_array($k, ['contentregion'])){
|
||||
$info[$k][] = array_map('trim', explode(',', $v));
|
||||
}
|
||||
else {
|
||||
$info[$k] = $v;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $info;
|
||||
}
|
||||
|
||||
function get_pdl($module) {
|
||||
$ret = [
|
||||
'pdl' => null,
|
||||
'modified' => true
|
||||
];
|
||||
|
||||
$pdl_path = 'mod_' . $module . '.pdl';
|
||||
|
||||
$ret['pdl'] = get_pconfig(local_channel(), 'system', $pdl_path);
|
||||
|
||||
if(!$ret['pdl']) {
|
||||
$pdl_path = theme_include($pdl_path);
|
||||
if ($pdl_path) {
|
||||
$ret['pdl'] = file_get_contents($pdl_path);
|
||||
$ret['modified'] = false;
|
||||
}
|
||||
}
|
||||
|
||||
return $ret;
|
||||
}
|
||||
}
|
||||
@@ -3,35 +3,38 @@
|
||||
namespace Zotlabs\Module;
|
||||
|
||||
use App;
|
||||
use Zotlabs\Access\PermissionLimits;
|
||||
use Zotlabs\Access\Permissions;
|
||||
use Zotlabs\Web\Controller;
|
||||
use Zotlabs\Lib\Apps;
|
||||
use Zotlabs\Lib\Libsync;
|
||||
use Zotlabs\Lib\AccessList;
|
||||
use Zotlabs\Lib\Permcat;
|
||||
|
||||
class Permcats extends Controller {
|
||||
|
||||
function post() {
|
||||
|
||||
if(! local_channel())
|
||||
if (!local_channel())
|
||||
return;
|
||||
|
||||
$channel = App::get_channel();
|
||||
|
||||
check_form_security_token_redirectOnErr('/permcats', 'permcats');
|
||||
|
||||
$name = escape_tags(trim($_REQUEST['name']));
|
||||
$name = escape_tags(trim($_REQUEST['name']));
|
||||
$is_system_role = isset($_REQUEST['is_system_role']);
|
||||
$return_path = z_root() . '/permcats/' . $_REQUEST['return_path'];
|
||||
$group_hash = $_REQUEST['group_select'] ?? '';
|
||||
$deleted_role = $_REQUEST['deleted_role'] ?? '';
|
||||
$new_role = $_REQUEST['new_role'] ?? '';
|
||||
$contacts = [];
|
||||
$return_path = z_root() . '/permcats/' . $_REQUEST['return_path'];
|
||||
$group_hash = $_REQUEST['group_select'] ?? '';
|
||||
$deleted_role = $_REQUEST['deleted_role'] ?? '';
|
||||
$new_role = $_REQUEST['new_role'] ?? '';
|
||||
$contacts = [];
|
||||
|
||||
|
||||
if (argv(1) && hex2bin(argv(1)) !== $name) {
|
||||
$return_path = z_root() . '/permcats/' . bin2hex($name);
|
||||
}
|
||||
|
||||
if($deleted_role && $new_role) {
|
||||
if ($deleted_role && $new_role) {
|
||||
$r = q("SELECT abook_xchan FROM abook WHERE abook_channel = %d AND abook_role = '%s' AND abook_self = 0 AND abook_pending = 0",
|
||||
intval(local_channel()),
|
||||
dbesc($deleted_role)
|
||||
@@ -42,13 +45,13 @@ class Permcats extends Controller {
|
||||
}
|
||||
|
||||
if ($contacts) {
|
||||
\Zotlabs\Lib\Permcat::assign($channel, $new_role, $contacts);
|
||||
Permcat::assign($channel, $new_role, $contacts);
|
||||
}
|
||||
|
||||
\Zotlabs\Lib\Permcat::delete(local_channel(), $deleted_role);
|
||||
Permcat::delete(local_channel(), $deleted_role);
|
||||
|
||||
$default_role = get_pconfig(local_channel(), 'system', 'default_permcat', 'default');
|
||||
if($deleted_role === $default_role) {
|
||||
if ($deleted_role === $default_role) {
|
||||
set_pconfig(local_channel(), 'system', 'default_permcat', $new_role);
|
||||
}
|
||||
|
||||
@@ -70,6 +73,7 @@ class Permcats extends Controller {
|
||||
}
|
||||
}
|
||||
|
||||
$group = null;
|
||||
if (!$contacts && $group_hash) {
|
||||
$group = AccessList::by_hash(local_channel(), $group_hash);
|
||||
}
|
||||
@@ -78,8 +82,8 @@ class Permcats extends Controller {
|
||||
$contacts = AccessList::members_xchan(local_channel(), $group['id']);
|
||||
}
|
||||
|
||||
if(! $name ) {
|
||||
notice( t('Permission category name is required.') . EOL);
|
||||
if (!$name) {
|
||||
notice(t('Permission category name is required.') . EOL);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -92,35 +96,62 @@ class Permcats extends Controller {
|
||||
if ($is_system_role) {
|
||||
// if we have a system role just set the default and assign if aplicable and be done with it
|
||||
if ($contacts) {
|
||||
\Zotlabs\Lib\Permcat::assign($channel, $name, $contacts);
|
||||
Permcat::assign($channel, $name, $contacts);
|
||||
}
|
||||
|
||||
info( t('Contact role saved.') . EOL);
|
||||
info(t('Contact role saved.') . EOL);
|
||||
Libsync::build_sync_packet();
|
||||
goaway($return_path);
|
||||
return;
|
||||
}
|
||||
|
||||
$pcarr = [];
|
||||
$all_perms = \Zotlabs\Access\Permissions::Perms();
|
||||
$pcarr = [];
|
||||
$all_perms = Permissions::Perms();
|
||||
|
||||
if($all_perms) {
|
||||
foreach($all_perms as $perm => $desc) {
|
||||
if(array_key_exists('perms_' . $perm, $_POST)) {
|
||||
if ($all_perms) {
|
||||
foreach ($all_perms as $perm => $desc) {
|
||||
if (array_key_exists('perms_' . $perm, $_POST)) {
|
||||
$pcarr[] = $perm;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
\Zotlabs\Lib\Permcat::update(local_channel(), $name, $pcarr);
|
||||
$pcat = new Permcat(local_channel());
|
||||
$pcatlist = $pcat->listing();
|
||||
$existing_raw_perms = [];
|
||||
|
||||
if ($pcatlist) {
|
||||
foreach ($pcatlist as $pc) {
|
||||
if ($pc['name'] && ($pc['name'] === $name)) {
|
||||
$existing_raw_perms = $pc['raw_perms'];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!$contacts && array_diff_assoc($existing_raw_perms, Permissions::FilledPerms($pcarr))) {
|
||||
// If we don't have anyone to assign the role to and an existing role has changed,
|
||||
// we will re-assign the changed role to all its members if there are any.
|
||||
|
||||
$r = q("SELECT abook_xchan FROM abook WHERE abook_channel = %d AND abook_role = '%s' AND abook_self = 0 AND abook_pending = 0",
|
||||
intval(local_channel()),
|
||||
dbesc($name)
|
||||
);
|
||||
|
||||
if ($r) {
|
||||
$contacts = ids_to_array($r, 'abook_xchan');
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Permcat::update(local_channel(), $name, $pcarr);
|
||||
|
||||
if ($contacts) {
|
||||
\Zotlabs\Lib\Permcat::assign($channel, $name, $contacts);
|
||||
Permcat::assign($channel, $name, $contacts);
|
||||
}
|
||||
|
||||
Libsync::build_sync_packet();
|
||||
|
||||
info( t('Contact role saved.') . EOL);
|
||||
info(t('Contact role saved.') . EOL);
|
||||
goaway($return_path);
|
||||
|
||||
return;
|
||||
@@ -129,35 +160,34 @@ class Permcats extends Controller {
|
||||
|
||||
function get() {
|
||||
|
||||
if(! local_channel())
|
||||
return;
|
||||
if (!local_channel())
|
||||
return EMPTY_STR;
|
||||
|
||||
nav_set_selected('Contact Roles');
|
||||
|
||||
$channel = App::get_channel();
|
||||
|
||||
if(argc() > 1) {
|
||||
$name = '';
|
||||
if (argc() > 1) {
|
||||
$name = hex2bin(argv(1));
|
||||
}
|
||||
|
||||
$existing = [];
|
||||
|
||||
$pcat = new \Zotlabs\Lib\Permcat(local_channel());
|
||||
$pcatlist = $pcat->listing();
|
||||
|
||||
$is_system_role = false;
|
||||
$perms = [];
|
||||
$existing = [];
|
||||
$pcat = new Permcat(local_channel());
|
||||
$pcatlist = $pcat->listing();
|
||||
$is_system_role = false;
|
||||
$delete_role_select_options = [];
|
||||
$is_default_role = (get_pconfig(local_channel(),'system','default_permcat','default') === $name);
|
||||
$is_default_role = (get_pconfig(local_channel(), 'system', 'default_permcat', 'default') === $name);
|
||||
$localname = '';
|
||||
|
||||
if($pcatlist) {
|
||||
foreach($pcatlist as $pc) {
|
||||
if(($pc['name']) && ($name) && ($pc['name'] == $name)) {
|
||||
if ($pcatlist) {
|
||||
foreach ($pcatlist as $pc) {
|
||||
if ($pc['name'] && $name && ($pc['name'] === $name)) {
|
||||
$existing = $pc['perms'];
|
||||
if (isset($pc['system']) && intval($pc['system']))
|
||||
$is_system_role = $pc['name'];
|
||||
}
|
||||
|
||||
if($pc['name'] == $name) {
|
||||
if ($pc['name'] == $name) {
|
||||
$localname = $pc['localname'];
|
||||
}
|
||||
|
||||
@@ -177,13 +207,13 @@ class Permcats extends Controller {
|
||||
$delete_role_select_options
|
||||
];
|
||||
|
||||
$global_perms = \Zotlabs\Access\Permissions::Perms();
|
||||
$global_perms = Permissions::Perms();
|
||||
|
||||
foreach($global_perms as $k => $v) {
|
||||
$thisperm = \Zotlabs\Lib\Permcat::find_permcat($existing,$k);
|
||||
$checkinherited = \Zotlabs\Access\PermissionLimits::Get(local_channel(),$k);
|
||||
foreach ($global_perms as $k => $v) {
|
||||
$thisperm = Permcat::find_permcat($existing, $k);
|
||||
$checkinherited = PermissionLimits::Get(local_channel(), $k);
|
||||
|
||||
if($existing[$k])
|
||||
if ($existing[$k])
|
||||
$thisperm = 1;
|
||||
|
||||
$perms[] = [
|
||||
@@ -198,14 +228,13 @@ class Permcats extends Controller {
|
||||
];
|
||||
}
|
||||
|
||||
|
||||
$group_select_options = [
|
||||
'selected' => '',
|
||||
'form_id' => 'group_select',
|
||||
'label' => t('Assign this role to'),
|
||||
'after' => [
|
||||
'name' => t('All my contacts'),
|
||||
'id' => 'all_contacts',
|
||||
'form_id' => 'group_select',
|
||||
'label' => t('Assign this role to'),
|
||||
'after' => [
|
||||
'name' => t('All my contacts'),
|
||||
'id' => 'all_contacts',
|
||||
'selected' => false
|
||||
]
|
||||
];
|
||||
@@ -213,25 +242,25 @@ class Permcats extends Controller {
|
||||
$group_select = AccessList::select(local_channel(), $group_select_options);
|
||||
|
||||
$tpl = get_markup_template("permcats.tpl");
|
||||
$o .= replace_macros($tpl, array(
|
||||
$o = replace_macros($tpl, [
|
||||
'$form_security_token' => get_form_security_token("permcats"),
|
||||
'$default_role' => array('default_role', t('Automatically assign this role to new contacts'), intval($is_default_role), '', [t('No'), t('Yes')]),
|
||||
'$title' => t('Contact Roles'),
|
||||
'$name' => ['name', t('Role name') . ' <span class="required">*</span>', (($localname) ? $localname : ''), (($is_system_role) ? t('System role - not editable') : '') , '', (($is_system_role) ? 'disabled' : '')],
|
||||
'$delete_label' => t('Deleting') . ' ' . $localname,
|
||||
'$current_role' => $name,
|
||||
'$perms' => $perms,
|
||||
'$inherited' => t('inherited'),
|
||||
'$is_system_role' => $is_system_role,
|
||||
'$permlbl' => t('Role Permissions'),
|
||||
'$permnote' => t('Some permissions may be inherited from your <a href="settings">channel role</a>, which have higher priority than contact role settings.'),
|
||||
'$submit' => t('Submit'),
|
||||
'$return_path' => argv(1),
|
||||
'$group_select' => $group_select,
|
||||
'$delete_role_select' => $delete_role_select,
|
||||
'$delet_role_button' => t('Delete')
|
||||
'$default_role' => ['default_role', t('Automatically assign this role to new contacts'), intval($is_default_role), '', [t('No'), t('Yes')]],
|
||||
'$title' => t('Contact Roles'),
|
||||
'$name' => ['name', t('Role name') . ' <span class="required">*</span>', (($localname) ? $localname : ''), (($is_system_role) ? t('System role - not editable') : ''), '', (($is_system_role) ? 'disabled' : '')],
|
||||
'$delete_label' => t('Deleting') . ' ' . $localname,
|
||||
'$current_role' => $name,
|
||||
'$perms' => $perms,
|
||||
'$inherited' => t('inherited'),
|
||||
'$is_system_role' => $is_system_role,
|
||||
'$permlbl' => t('Role Permissions'),
|
||||
'$permnote' => t('Some permissions may be inherited from your <a href="settings">channel role</a>, which have higher priority than contact role settings.'),
|
||||
'$submit' => t('Submit'),
|
||||
'$return_path' => argv(1),
|
||||
'$group_select' => $group_select,
|
||||
'$delete_role_select' => $delete_role_select,
|
||||
'$delet_role_button' => t('Delete')
|
||||
]);
|
||||
|
||||
));
|
||||
return $o;
|
||||
}
|
||||
|
||||
|
||||
@@ -3,6 +3,7 @@ namespace Zotlabs\Module; /** @file */
|
||||
|
||||
use App;
|
||||
use Zotlabs\Lib\Apps;
|
||||
use Zotlabs\Lib\Activity;
|
||||
use Zotlabs\Web\Controller;
|
||||
|
||||
/**
|
||||
@@ -107,11 +108,6 @@ class Poke extends Controller {
|
||||
$deny_gid = (($item_private) ? '' : $channel['channel_deny_gid']);
|
||||
}
|
||||
|
||||
|
||||
$arr = array();
|
||||
|
||||
|
||||
|
||||
$arr['item_wall'] = 1;
|
||||
$arr['owner_xchan'] = (($parent_item) ? $parent_item['owner_xchan'] : $channel['channel_hash']);
|
||||
$arr['parent_mid'] = (($parent_mid) ? $parent_mid : '');
|
||||
@@ -122,26 +118,15 @@ class Poke extends Controller {
|
||||
$arr['deny_gid'] = $deny_gid;
|
||||
$arr['verb'] = $activity;
|
||||
$arr['item_private'] = $item_private;
|
||||
$arr['obj_type'] = ACTIVITY_OBJ_PERSON;
|
||||
$arr['obj_type'] = ACTIVITY_OBJ_NOTE;
|
||||
$arr['body'] = '[zrl=' . $channel['xchan_url'] . ']' . $channel['xchan_name'] . '[/zrl]' . ' ' . t($verbs[$verb][0]) . ' ' . '[zrl=' . $target['xchan_url'] . ']' . $target['xchan_name'] . '[/zrl]';
|
||||
|
||||
$obj = array(
|
||||
'type' => ACTIVITY_OBJ_PERSON,
|
||||
'title' => $target['xchan_name'],
|
||||
'id' => $target['xchan_hash'],
|
||||
'link' => array(
|
||||
array('rel' => 'alternate', 'type' => 'text/html', 'href' => $target['xchan_url']),
|
||||
array('rel' => 'photo', 'type' => $target['xchan_photo_mimetype'], 'href' => $target['xchan_photo_l'])
|
||||
),
|
||||
);
|
||||
|
||||
$arr['obj'] = json_encode($obj);
|
||||
|
||||
$arr['item_origin'] = 1;
|
||||
$arr['item_wall'] = 1;
|
||||
$arr['item_unseen'] = 1;
|
||||
if(! $parent_item)
|
||||
$item['item_thread_top'] = 1;
|
||||
$arr['item_thread_top'] = 1;
|
||||
|
||||
$arr['obj'] = Activity::encode_item($arr);
|
||||
|
||||
|
||||
post_activity_item($arr);
|
||||
@@ -198,8 +183,8 @@ class Poke extends Controller {
|
||||
$desc = t('Poke somebody');
|
||||
}
|
||||
else {
|
||||
$title = t('Poke/Prod');
|
||||
$desc = t('Poke, prod or do other things to somebody');
|
||||
$title = t('Poke');
|
||||
$desc = t('Poke or ping somebody');
|
||||
}
|
||||
|
||||
$o = replace_macros(get_markup_template('poke_content.tpl'),array(
|
||||
@@ -207,7 +192,7 @@ class Poke extends Controller {
|
||||
'$poke_basic' => $poke_basic,
|
||||
'$desc' => $desc,
|
||||
'$clabel' => t('Recipient'),
|
||||
'$choice' => t('Choose what you wish to do to recipient'),
|
||||
'$choice' => t('Choose action'),
|
||||
'$verbs' => $shortlist,
|
||||
'$parent' => $parent,
|
||||
'$prv_desc' => t('Make this post private'),
|
||||
|
||||
@@ -403,6 +403,10 @@ class Profile_photo extends Controller {
|
||||
foreach ($r as $rr) {
|
||||
if ($rr['is_default']) {
|
||||
$default_profile_id = intval($rr['id']);
|
||||
|
||||
if (!$profile_id) {
|
||||
$profile_id = $default_profile_id;
|
||||
}
|
||||
}
|
||||
|
||||
if ($profile_id === intval($rr['id'])) {
|
||||
|
||||
@@ -6,21 +6,21 @@ use Zotlabs\Lib\Libzot;
|
||||
class Rmagic extends \Zotlabs\Web\Controller {
|
||||
|
||||
function init() {
|
||||
|
||||
|
||||
if(local_channel())
|
||||
goaway(z_root());
|
||||
|
||||
|
||||
$me = get_my_address();
|
||||
if($me) {
|
||||
$r = q("select hubloc_url from hubloc where hubloc_addr = '%s'",
|
||||
$r = q("select hubloc_url, hubloc_network from hubloc where hubloc_addr = '%s' and hubloc_deleted = 0",
|
||||
dbesc($me)
|
||||
);
|
||||
);
|
||||
if(! $r) {
|
||||
$w = discover_by_webbie($me);
|
||||
if($w) {
|
||||
$r = q("select hubloc_url from hubloc where hubloc_addr = '%s'",
|
||||
$r = q("select hubloc_url, hubloc_network from hubloc where hubloc_addr = '%s' and hubloc_deleted = 0",
|
||||
dbesc($me)
|
||||
);
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -33,39 +33,39 @@ class Rmagic extends \Zotlabs\Web\Controller {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function post() {
|
||||
|
||||
|
||||
$address = trim($_REQUEST['address']);
|
||||
|
||||
|
||||
if(strpos($address,'@') === false) {
|
||||
$arr = array('address' => $address);
|
||||
call_hooks('reverse_magic_auth', $arr);
|
||||
|
||||
call_hooks('reverse_magic_auth', $arr);
|
||||
|
||||
// if they're still here...
|
||||
notice( t('Authentication failed.') . EOL);
|
||||
notice( t('Authentication failed.') . EOL);
|
||||
return;
|
||||
}
|
||||
else {
|
||||
|
||||
|
||||
// Presumed Red identity. Perform reverse magic auth
|
||||
|
||||
|
||||
if(strpos($address,'@') === false) {
|
||||
notice('Invalid address.');
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
$r = null;
|
||||
if($address) {
|
||||
$r = q("select hubloc_url from hubloc where hubloc_addr = '%s'",
|
||||
$r = q("select hubloc_url, hubloc_network from hubloc where hubloc_addr = '%s' and hubloc_deleted = 0",
|
||||
dbesc($address)
|
||||
);
|
||||
);
|
||||
if(! $r) {
|
||||
$w = discover_by_webbie($address);
|
||||
if($w) {
|
||||
$r = q("select hubloc_url from hubloc where hubloc_addr = '%s'",
|
||||
$r = q("select hubloc_url, hubloc_network from hubloc where hubloc_addr = '%s' and hubloc_deleted = 0",
|
||||
dbesc($address)
|
||||
);
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -76,20 +76,20 @@ class Rmagic extends \Zotlabs\Web\Controller {
|
||||
}
|
||||
else {
|
||||
$url = 'https://' . substr($address,strpos($address,'@')+1);
|
||||
}
|
||||
|
||||
if($url) {
|
||||
if($_SESSION['return_url'])
|
||||
}
|
||||
|
||||
if($url) {
|
||||
if($_SESSION['return_url'])
|
||||
$dest = bin2hex(z_root() . '/' . str_replace('zid=','zid_=',$_SESSION['return_url']));
|
||||
else
|
||||
$dest = bin2hex(z_root() . '/' . str_replace([ 'rmagic', 'zid=' ] ,[ '', 'zid_='],\App::$query_string));
|
||||
|
||||
|
||||
goaway($url . '/magic' . '?f=&owa=1&bdest=' . $dest);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
function get() {
|
||||
return replace_macros(get_markup_template('rmagic.tpl'),
|
||||
[
|
||||
@@ -97,6 +97,6 @@ class Rmagic extends \Zotlabs\Web\Controller {
|
||||
'$address' => [ 'address', t('Enter your channel address (e.g. channel@example.com)'), '', '' ],
|
||||
'$submit' => t('Authenticate')
|
||||
]
|
||||
);
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,6 +7,7 @@ use Zotlabs\Lib\Libzot;
|
||||
use Zotlabs\Lib\Activity;
|
||||
use Zotlabs\Lib\ActivityStreams;
|
||||
use Zotlabs\Web\Controller;
|
||||
use Zotlabs\Lib\Zotfinger;
|
||||
|
||||
class Search extends Controller {
|
||||
|
||||
@@ -58,15 +59,34 @@ class Search extends Controller {
|
||||
$o .= search($search, 'search-box', '/search', ((local_channel()) ? true : false));
|
||||
|
||||
if (local_channel() && strpos($search, 'https://') === 0 && !$update && !$load) {
|
||||
$f = Libzot::fetch_conversation(App::get_channel(), punify($search), true);
|
||||
|
||||
$url = htmlspecialchars_decode($search);
|
||||
|
||||
if (strpos($url, 'b64.') !== false) {
|
||||
if (strpos($url, '?') !== false) {
|
||||
$url = strtok($url, '?');
|
||||
}
|
||||
|
||||
$url = unpack_link_id(basename($url));
|
||||
}
|
||||
|
||||
$f = Libzot::fetch_conversation(App::get_channel(), punify($url), true);
|
||||
|
||||
if ($f) {
|
||||
goaway(z_root() . '/hq/' . gen_link_id($f['message_id']));
|
||||
$mid = $f[0]['message_id'];
|
||||
foreach ($f as $m) {
|
||||
if (strpos($search, $m['message_id']) === 0) {
|
||||
$mid = $m['message_id'];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
goaway(z_root() . '/hq/' . gen_link_id($mid));
|
||||
}
|
||||
else {
|
||||
// try other fetch providers (e.g. diaspora, pubcrawl)
|
||||
$hookdata = [
|
||||
'url' => punify($search)
|
||||
'url' => punify($url)
|
||||
];
|
||||
call_hooks('fetch_provider', $hookdata);
|
||||
}
|
||||
@@ -160,49 +180,46 @@ class Search extends Controller {
|
||||
|
||||
}
|
||||
|
||||
$item_normal = item_normal_search();
|
||||
$pub_sql = public_permissions_sql($observer_hash);
|
||||
|
||||
require_once('include/channel.php');
|
||||
|
||||
$sys = get_sys_channel();
|
||||
|
||||
if (($update) && ($load)) {
|
||||
$itemspage = get_pconfig(local_channel(), 'system', 'itemspage');
|
||||
App::set_pager_itemspage(((intval($itemspage)) ? $itemspage : 10));
|
||||
$pager_sql = sprintf(" LIMIT %d OFFSET %d ", intval(App::$pager['itemspage']), intval(App::$pager['start']));
|
||||
|
||||
// in case somebody turned off public access to sys channel content with permissions
|
||||
$item_normal = item_normal_search();
|
||||
$pub_sql = item_permissions_sql(0, $observer_hash);
|
||||
|
||||
if (!perm_is_allowed($sys['channel_id'], $observer_hash, 'view_stream'))
|
||||
$sys['xchan_hash'] .= 'disabled';
|
||||
$sys = get_sys_channel();
|
||||
|
||||
// in case somebody turned off public access to sys channel content using permissions
|
||||
// make that content unsearchable by ensuring the owner uid can't match
|
||||
$sys_id = perm_is_allowed($sys['channel_id'], $observer_hash, 'view_stream') ? $sys['channel_id'] : 0;
|
||||
|
||||
if ($load) {
|
||||
$r = null;
|
||||
|
||||
if (local_channel()) {
|
||||
$r = q("SELECT mid, MAX(id) as item_id from item
|
||||
WHERE ((( item.allow_cid = '' AND item.allow_gid = '' AND item.deny_cid = '' AND item.deny_gid = '' AND item_private = 0 )
|
||||
OR ( item.uid = %d )) OR item.owner_xchan = '%s' )
|
||||
$r = q("SELECT mid, MAX(id) AS item_id FROM item
|
||||
WHERE (( item.allow_cid = '' AND item.allow_gid = '' AND item.deny_cid = '' AND item.deny_gid = '' AND item.item_private = 0 )
|
||||
OR ( item.uid = %d ))
|
||||
$item_normal
|
||||
$sql_extra
|
||||
group by mid, created order by created desc $pager_sql ",
|
||||
intval(local_channel()),
|
||||
dbesc($sys['xchan_hash'])
|
||||
GROUP BY mid, created ORDER BY created DESC $pager_sql ",
|
||||
intval(local_channel())
|
||||
);
|
||||
}
|
||||
if ($r === null) {
|
||||
$r = q("SELECT mid, MAX(id) as item_id from item
|
||||
WHERE (((( item.allow_cid = '' AND item.allow_gid = '' AND item.deny_cid = ''
|
||||
AND item.deny_gid = '' AND item_private = 0 )
|
||||
and owner_xchan in ( " . stream_perms_xchans(($observer) ? (PERMS_NETWORK | PERMS_PUBLIC) : PERMS_PUBLIC) . " ))
|
||||
$pub_sql ) OR owner_xchan = '%s')
|
||||
|
||||
if (!$r) {
|
||||
$r = q("SELECT mid, MAX(id) AS item_id FROM item
|
||||
WHERE (((( item.allow_cid = '' AND item.allow_gid = '' AND item.deny_cid = '' AND item.deny_gid = '' AND item.item_private = 0 )
|
||||
AND item.uid IN ( " . stream_perms_api_uids(($observer_hash) ? (PERMS_NETWORK | PERMS_PUBLIC) : PERMS_PUBLIC) . " ))
|
||||
$pub_sql ) OR item.uid = %d)
|
||||
$item_normal
|
||||
$sql_extra
|
||||
group by mid, created order by created desc $pager_sql",
|
||||
dbesc($sys['xchan_hash'])
|
||||
GROUP BY mid, created ORDER BY created DESC $pager_sql",
|
||||
intval($sys_id)
|
||||
);
|
||||
}
|
||||
|
||||
if ($r) {
|
||||
$str = ids_to_querystr($r, 'item_id');
|
||||
$r = dbq("select *, id as item_id from item where id in ( " . $str . ") order by created desc");
|
||||
@@ -215,13 +232,12 @@ class Search extends Controller {
|
||||
|
||||
}
|
||||
|
||||
$items = [];
|
||||
|
||||
if ($r) {
|
||||
xchan_query($r);
|
||||
$items = fetch_post_tags($r, true);
|
||||
}
|
||||
else {
|
||||
$items = [];
|
||||
}
|
||||
|
||||
if ($format === 'json') {
|
||||
$result = [];
|
||||
|
||||
@@ -11,14 +11,14 @@ class Calendar {
|
||||
$module = substr(strrchr(strtolower(static::class), '\\'), 1);
|
||||
|
||||
check_form_security_token_redirectOnErr('/settings/' . $module, 'settings_' . $module);
|
||||
|
||||
|
||||
$features = get_module_features($module);
|
||||
|
||||
process_module_features_post(local_channel(), $features, $_POST);
|
||||
|
||||
|
||||
Libsync::build_sync_packet();
|
||||
|
||||
if($_POST['rpath'])
|
||||
if(isset($_POST['rpath']) && is_local_url($_POST['rpath']))
|
||||
goaway($_POST['rpath']);
|
||||
|
||||
return;
|
||||
@@ -34,14 +34,14 @@ class Calendar {
|
||||
$tpl = get_markup_template("settings_module.tpl");
|
||||
|
||||
$o .= replace_macros($tpl, array(
|
||||
'$rpath' => $rpath,
|
||||
'$rpath' => escape_url($rpath),
|
||||
'$action_url' => 'settings/' . $module,
|
||||
'$form_security_token' => get_form_security_token('settings_' . $module),
|
||||
'$title' => t('Calendar Settings'),
|
||||
'$features' => process_module_features_get(local_channel(), $features),
|
||||
'$submit' => t('Submit')
|
||||
));
|
||||
|
||||
|
||||
return $o;
|
||||
}
|
||||
|
||||
|
||||
@@ -35,6 +35,8 @@ class Channel {
|
||||
$pageflags = $channel['channel_pageflags'];
|
||||
$existing_adult = (($pageflags & PAGE_ADULT) ? 1 : 0);
|
||||
$expire = ((x($_POST, 'expire')) ? intval($_POST['expire']) : 0);
|
||||
$incl = ((x($_POST['message_filter_incl'])) ? htmlspecialchars_decode(trim($_POST['message_filter_incl']), ENT_QUOTES) : '');
|
||||
$excl = ((x($_POST['message_filter_excl'])) ? htmlspecialchars_decode(trim($_POST['message_filter_excl']), ENT_QUOTES) : '');
|
||||
|
||||
if ($adult != $existing_adult) {
|
||||
$pageflags = ($pageflags ^ PAGE_ADULT);
|
||||
@@ -131,6 +133,8 @@ class Channel {
|
||||
set_pconfig(local_channel(), 'system', 'photo_path', $photo_path);
|
||||
set_pconfig(local_channel(), 'system', 'attach_path', $attach_path);
|
||||
set_pconfig(local_channel(), 'system', 'email_notify_host', $mailhost);
|
||||
set_pconfig(local_channel(), 'system', 'message_filter_incl', $incl);
|
||||
set_pconfig(local_channel(), 'system', 'message_filter_excl', $excl);
|
||||
|
||||
$r = q("update channel set channel_pageflags = %d, channel_timezone = '%s',
|
||||
channel_location = '%s', channel_notifyflags = %d, channel_expire_days = %d
|
||||
@@ -277,6 +281,8 @@ class Channel {
|
||||
'$removeme' => t('Remove Channel'),
|
||||
'$removechannel' => t('Remove this channel.'),
|
||||
'$expire' => ['expire', t('Expire other channel content after this many days'), $expire, t('0 or blank to use the website limit.') . ' ' . ((intval($sys_expire)) ? sprintf(t('This website expires after %d days.'), intval($sys_expire)) : t('This website does not expire imported content.')) . ' ' . t('The website limit takes precedence if lower than your limit.')],
|
||||
'$message_filter_excl' => ['message_filter_excl', t('Do not import posts with this text'), get_pconfig(local_channel(), 'system', 'message_filter_excl', ''), t('Words one per line or #tags, $categories, /patterns/, lang=xx, lang!=xx - leave blank to import all posts')],
|
||||
'$message_filter_incl' => ['message_filter_incl', t('Only import posts with this text'), get_pconfig(local_channel(), 'system', 'message_filter_incl', ''), t('Words one per line or #tags, $categories, /patterns/, lang=xx, lang!=xx - leave blank to import all posts')]
|
||||
]);
|
||||
|
||||
call_hooks('settings_form', $o);
|
||||
|
||||
@@ -13,7 +13,7 @@ class Channel_home {
|
||||
$module = substr(strrchr(strtolower(static::class), '\\'), 1);
|
||||
|
||||
check_form_security_token_redirectOnErr('/settings/' . $module, 'settings_' . $module);
|
||||
|
||||
|
||||
$features = get_module_features($module);
|
||||
|
||||
process_module_features_post(local_channel(), $features, $_POST);
|
||||
@@ -25,10 +25,10 @@ class Channel_home {
|
||||
|
||||
$channel_menu = ((x($_POST['channel_menu'])) ? htmlspecialchars_decode(trim($_POST['channel_menu']),ENT_QUOTES) : '');
|
||||
set_pconfig(local_channel(),'system','channel_menu',$channel_menu);
|
||||
|
||||
|
||||
Libsync::build_sync_packet();
|
||||
|
||||
if($_POST['rpath'])
|
||||
if(isset($_POST['rpath']) && is_local_url($_POST['rpath']))
|
||||
goaway($_POST['rpath']);
|
||||
|
||||
return;
|
||||
@@ -82,7 +82,7 @@ class Channel_home {
|
||||
$tpl = get_markup_template("settings_module.tpl");
|
||||
|
||||
$o .= replace_macros($tpl, array(
|
||||
'$rpath' => $rpath,
|
||||
'$rpath' => escape_url($rpath),
|
||||
'$action_url' => 'settings/' . $module,
|
||||
'$form_security_token' => get_form_security_token('settings_' . $module),
|
||||
'$title' => t('Channel Home Settings'),
|
||||
@@ -90,7 +90,7 @@ class Channel_home {
|
||||
'$extra_settings_html' => $extra_settings_html,
|
||||
'$submit' => t('Submit')
|
||||
));
|
||||
|
||||
|
||||
return $o;
|
||||
}
|
||||
|
||||
|
||||
@@ -11,14 +11,14 @@ class Connections {
|
||||
$module = substr(strrchr(strtolower(static::class), '\\'), 1);
|
||||
|
||||
check_form_security_token_redirectOnErr('/settings/' . $module, 'settings_' . $module);
|
||||
|
||||
|
||||
$features = get_module_features($module);
|
||||
|
||||
process_module_features_post(local_channel(), $features, $_POST);
|
||||
|
||||
|
||||
Libsync::build_sync_packet();
|
||||
|
||||
if($_POST['rpath'])
|
||||
if(isset($_POST['rpath']) && is_local_url($_POST['rpath']))
|
||||
goaway($_POST['rpath']);
|
||||
|
||||
return;
|
||||
@@ -34,14 +34,14 @@ class Connections {
|
||||
$tpl = get_markup_template("settings_module.tpl");
|
||||
|
||||
$o .= replace_macros($tpl, array(
|
||||
'$rpath' => $rpath,
|
||||
'$rpath' => escape_url($rpath),
|
||||
'$action_url' => 'settings/' . $module,
|
||||
'$form_security_token' => get_form_security_token('settings_' . $module),
|
||||
'$title' => t('Connections Settings'),
|
||||
'$features' => process_module_features_get(local_channel(), $features),
|
||||
'$submit' => t('Submit')
|
||||
));
|
||||
|
||||
|
||||
return $o;
|
||||
}
|
||||
|
||||
|
||||
@@ -11,14 +11,14 @@ class Directory {
|
||||
$module = substr(strrchr(strtolower(static::class), '\\'), 1);
|
||||
|
||||
check_form_security_token_redirectOnErr('/settings/' . $module, 'settings_' . $module);
|
||||
|
||||
|
||||
$features = get_module_features($module);
|
||||
|
||||
process_module_features_post(local_channel(), $features, $_POST);
|
||||
|
||||
|
||||
Libsync::build_sync_packet();
|
||||
|
||||
if($_POST['rpath'])
|
||||
if(isset($_POST['rpath']) && is_local_url($_POST['rpath']))
|
||||
goaway($_POST['rpath']);
|
||||
|
||||
return;
|
||||
@@ -34,14 +34,14 @@ class Directory {
|
||||
$tpl = get_markup_template("settings_module.tpl");
|
||||
|
||||
$o .= replace_macros($tpl, array(
|
||||
'$rpath' => $rpath,
|
||||
'$rpath' => escape_url($rpath),
|
||||
'$action_url' => 'settings/' . $module,
|
||||
'$form_security_token' => get_form_security_token('settings_' . $module),
|
||||
'$title' => t('Directory Settings'),
|
||||
'$features' => process_module_features_get(local_channel(), $features),
|
||||
'$submit' => t('Submit')
|
||||
));
|
||||
|
||||
|
||||
return $o;
|
||||
}
|
||||
|
||||
|
||||
@@ -11,14 +11,14 @@ class Editor {
|
||||
$module = substr(strrchr(strtolower(static::class), '\\'), 1);
|
||||
|
||||
check_form_security_token_redirectOnErr('/settings/' . $module, 'settings_' . $module);
|
||||
|
||||
|
||||
$features = get_module_features($module);
|
||||
|
||||
process_module_features_post(local_channel(), $features, $_POST);
|
||||
|
||||
|
||||
Libsync::build_sync_packet();
|
||||
|
||||
if($_POST['rpath'])
|
||||
if(isset($_POST['rpath']) && is_local_url($_POST['rpath']))
|
||||
goaway($_POST['rpath']);
|
||||
|
||||
return;
|
||||
@@ -34,14 +34,14 @@ class Editor {
|
||||
$tpl = get_markup_template("settings_module.tpl");
|
||||
|
||||
$o .= replace_macros($tpl, array(
|
||||
'$rpath' => $rpath,
|
||||
'$rpath' => escape_url($rpath),
|
||||
'$action_url' => 'settings/' . $module,
|
||||
'$form_security_token' => get_form_security_token('settings_' . $module),
|
||||
'$title' => t('Editor Settings'),
|
||||
'$features' => process_module_features_get(local_channel(), $features),
|
||||
'$submit' => t('Submit')
|
||||
));
|
||||
|
||||
|
||||
return $o;
|
||||
}
|
||||
|
||||
|
||||
@@ -11,14 +11,14 @@ class Events {
|
||||
$module = substr(strrchr(strtolower(static::class), '\\'), 1);
|
||||
|
||||
check_form_security_token_redirectOnErr('/settings/' . $module, 'settings_' . $module);
|
||||
|
||||
|
||||
$features = get_module_features($module);
|
||||
|
||||
process_module_features_post(local_channel(), $features, $_POST);
|
||||
|
||||
|
||||
Libsync::build_sync_packet();
|
||||
|
||||
if($_POST['rpath'])
|
||||
if(isset($_POST['rpath']) && is_local_url($_POST['rpath']))
|
||||
goaway($_POST['rpath']);
|
||||
|
||||
return;
|
||||
@@ -34,14 +34,14 @@ class Events {
|
||||
$tpl = get_markup_template("settings_module.tpl");
|
||||
|
||||
$o .= replace_macros($tpl, array(
|
||||
'$rpath' => $rpath,
|
||||
'$rpath' => escape_url($rpath),
|
||||
'$action_url' => 'settings/' . $module,
|
||||
'$form_security_token' => get_form_security_token('settings_' . $module),
|
||||
'$title' => t('Events Settings'),
|
||||
'$features' => process_module_features_get(local_channel(), $features),
|
||||
'$submit' => t('Submit')
|
||||
));
|
||||
|
||||
|
||||
return $o;
|
||||
}
|
||||
|
||||
|
||||
@@ -12,14 +12,14 @@ class Manage {
|
||||
$module = substr(strrchr(strtolower(static::class), '\\'), 1);
|
||||
|
||||
check_form_security_token_redirectOnErr('/settings/' . $module, 'settings_' . $module);
|
||||
|
||||
|
||||
$features = get_module_features($module);
|
||||
|
||||
process_module_features_post(local_channel(), $features, $_POST);
|
||||
|
||||
|
||||
Libsync::build_sync_packet();
|
||||
|
||||
if($_POST['rpath'])
|
||||
if(isset($_POST['rpath']) && is_local_url($_POST['rpath']))
|
||||
goaway($_POST['rpath']);
|
||||
|
||||
return;
|
||||
@@ -35,14 +35,14 @@ class Manage {
|
||||
$tpl = get_markup_template("settings_module.tpl");
|
||||
|
||||
$o .= replace_macros($tpl, array(
|
||||
'$rpath' => $rpath,
|
||||
'$rpath' => escape_url($rpath),
|
||||
'$action_url' => 'settings/' . $module,
|
||||
'$form_security_token' => get_form_security_token('settings_' . $module),
|
||||
'$title' => t('Channel Manager Settings'),
|
||||
'$features' => process_module_features_get(local_channel(), $features),
|
||||
'$submit' => t('Submit')
|
||||
));
|
||||
|
||||
|
||||
return $o;
|
||||
}
|
||||
|
||||
|
||||
@@ -21,10 +21,10 @@ class Network {
|
||||
$network_divmore_height = 50;
|
||||
|
||||
set_pconfig(local_channel(),'system','network_divmore_height', $network_divmore_height);
|
||||
|
||||
|
||||
Libsync::build_sync_packet();
|
||||
|
||||
if($_POST['rpath'])
|
||||
if(isset($_POST['rpath']) && is_local_url($_POST['rpath']))
|
||||
goaway($_POST['rpath']);
|
||||
|
||||
return;
|
||||
@@ -53,7 +53,7 @@ class Network {
|
||||
$tpl = get_markup_template("settings_module.tpl");
|
||||
|
||||
$o .= replace_macros($tpl, array(
|
||||
'$rpath' => $rpath,
|
||||
'$rpath' => escape_url($rpath),
|
||||
'$action_url' => 'settings/' . $module,
|
||||
'$form_security_token' => get_form_security_token('settings_' . $module),
|
||||
'$title' => t('Stream Settings'),
|
||||
@@ -61,7 +61,7 @@ class Network {
|
||||
'$extra_settings_html' => $extra_settings_html,
|
||||
'$submit' => t('Submit')
|
||||
));
|
||||
|
||||
|
||||
return $o;
|
||||
}
|
||||
|
||||
|
||||
@@ -7,18 +7,18 @@ use Zotlabs\Lib\Libsync;
|
||||
class Photos {
|
||||
|
||||
function post() {
|
||||
|
||||
|
||||
$module = substr(strrchr(strtolower(static::class), '\\'), 1);
|
||||
|
||||
check_form_security_token_redirectOnErr('/settings/' . $module, 'settings_' . $module);
|
||||
|
||||
|
||||
$features = get_module_features($module);
|
||||
|
||||
process_module_features_post(local_channel(), $features, $_POST);
|
||||
|
||||
|
||||
Libsync::build_sync_packet();
|
||||
|
||||
if($_POST['rpath'])
|
||||
if(isset($_POST['rpath']) && is_local_url($_POST['rpath']))
|
||||
goaway($_POST['rpath']);
|
||||
|
||||
return;
|
||||
@@ -34,14 +34,14 @@ class Photos {
|
||||
$tpl = get_markup_template("settings_module.tpl");
|
||||
|
||||
$o .= replace_macros($tpl, array(
|
||||
'$rpath' => $rpath,
|
||||
'$rpath' => escape_url($rpath),
|
||||
'$action_url' => 'settings/' . $module,
|
||||
'$form_security_token' => get_form_security_token('settings_' . $module),
|
||||
'$title' => t('Photos Settings'),
|
||||
'$features' => process_module_features_get(local_channel(), $features),
|
||||
'$submit' => t('Submit')
|
||||
));
|
||||
|
||||
|
||||
return $o;
|
||||
}
|
||||
|
||||
|
||||
@@ -119,7 +119,7 @@ class Privacy {
|
||||
],
|
||||
'$autoperms' => ['autoperms', t('Automatically approve new contacts'), $autoperms, '', [t('No'), t('Yes')]],
|
||||
'$index_opt_out' => ['index_opt_out', t('Opt-out of search engine indexing'), $index_opt_out, '', [t('No'), t('Yes')]],
|
||||
'$group_actor' => ['group_actor', t('Group actor'), $group_actor, t('Allow this channel to act as a forum'), [t('No'), t('Yes')]],
|
||||
'$group_actor' => ['group_actor', t('Group actor'), $group_actor, t('Allow this channel to act as a forum'), [t('No'), t('Yes')]]
|
||||
]);
|
||||
|
||||
return $o;
|
||||
|
||||
@@ -23,7 +23,7 @@ class Profiles {
|
||||
|
||||
Libsync::build_sync_packet();
|
||||
|
||||
if($_POST['rpath'])
|
||||
if(isset($_POST['rpath']) && is_local_url($_POST['rpath']))
|
||||
goaway($_POST['rpath']);
|
||||
|
||||
return;
|
||||
@@ -43,7 +43,7 @@ class Profiles {
|
||||
$tpl = get_markup_template("settings_module.tpl");
|
||||
|
||||
$o .= replace_macros($tpl, array(
|
||||
'$rpath' => $rpath,
|
||||
'$rpath' => escape_url($rpath),
|
||||
'$action_url' => 'settings/' . $module,
|
||||
'$form_security_token' => get_form_security_token('settings_' . $module),
|
||||
'$title' => t('Profiles Settings'),
|
||||
|
||||
@@ -69,17 +69,22 @@ class Setup extends \Zotlabs\Web\Controller {
|
||||
$dbpass = ((isset($_POST['dbpass'])) ? trim($_POST['dbpass']) : '');
|
||||
$dbdata = ((isset($_POST['dbdata'])) ? trim($_POST['dbdata']) : '');
|
||||
$dbtype = ((isset($_POST['dbtype'])) ? intval(trim($_POST['dbtype'])) : 0);
|
||||
|
||||
$phpath = ((isset($_POST['phpath'])) ? trim($_POST['phpath']) : '');
|
||||
$adminmail = ((isset($_POST['adminmail'])) ? trim($_POST['adminmail']) : '');
|
||||
$siteurl = ((isset($_POST['siteurl'])) ? trim($_POST['siteurl']) : '');
|
||||
|
||||
if (empty($db_charset)) {
|
||||
$db_charset = ((intval($dbtype) === 0) ? 'utf8mb4' : 'UTF8');
|
||||
}
|
||||
|
||||
// $siteurl should not have a trailing slash
|
||||
|
||||
$siteurl = rtrim($siteurl,'/');
|
||||
|
||||
require_once('include/dba/dba_driver.php');
|
||||
|
||||
$db = \DBA::dba_factory($dbhost, $dbport, $dbuser, $dbpass, $dbdata, $dbtype, true);
|
||||
$db = \DBA::dba_factory($dbhost, $dbport, $dbuser, $dbpass, $dbdata, $dbtype, $db_charset, true);
|
||||
|
||||
if(! \DBA::$dba->connected) {
|
||||
echo 'Database Connect failed: ' . \DBA::$dba->error;
|
||||
@@ -94,11 +99,16 @@ class Setup extends \Zotlabs\Web\Controller {
|
||||
$dbpass = ((isset($_POST['dbpass'])) ? trim($_POST['dbpass']) : '');
|
||||
$dbdata = ((isset($_POST['dbdata'])) ? trim($_POST['dbdata']) : '');
|
||||
$dbtype = ((isset($_POST['dbtype'])) ? intval(trim($_POST['dbtype'])) : 0);
|
||||
|
||||
$phpath = ((isset($_POST['phpath'])) ? trim($_POST['phpath']) : '');
|
||||
$timezone = ((isset($_POST['timezone'])) ? trim($_POST['timezone']) : '');
|
||||
$adminmail = ((isset($_POST['adminmail'])) ? trim($_POST['adminmail']) : '');
|
||||
$siteurl = ((isset($_POST['siteurl'])) ? trim($_POST['siteurl']) : '');
|
||||
|
||||
if (empty($db_charset)) {
|
||||
$db_charset = ((intval($dbtype) === 0) ? 'utf8mb4' : 'UTF8');
|
||||
}
|
||||
|
||||
if($siteurl != z_root()) {
|
||||
$test = z_fetch_url($siteurl."/setup/testrewrite");
|
||||
if((! $test['success']) || ($test['body'] != 'ok')) {
|
||||
@@ -112,7 +122,7 @@ class Setup extends \Zotlabs\Web\Controller {
|
||||
|
||||
if(! isset(\DBA::$dba->connected)) {
|
||||
// connect to db
|
||||
$db = \DBA::dba_factory($dbhost, $dbport, $dbuser, $dbpass, $dbdata, $dbtype, true);
|
||||
$db = \DBA::dba_factory($dbhost, $dbport, $dbuser, $dbpass, $dbdata, $dbtype, $db_charset, true);
|
||||
}
|
||||
|
||||
if(! isset(\DBA::$dba->connected)) {
|
||||
@@ -377,8 +387,8 @@ class Setup extends \Zotlabs\Web\Controller {
|
||||
function check_php(&$phpath, &$checks) {
|
||||
$help = '';
|
||||
|
||||
if(version_compare(PHP_VERSION, '7.1') < 0) {
|
||||
$help .= t('PHP version 7.1 or greater is required.');
|
||||
if(version_compare(PHP_VERSION, '8.0') < 0) {
|
||||
$help .= t('PHP version 8.0 or greater is required.');
|
||||
$this->check_add($checks, t('PHP version'), false, true, $help);
|
||||
}
|
||||
|
||||
|
||||
@@ -10,14 +10,14 @@ class Siteinfo extends \Zotlabs\Web\Controller {
|
||||
json_return_and_die($data);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function get() {
|
||||
|
||||
$federated = [];
|
||||
call_hooks('federated_transports',$federated);
|
||||
|
||||
|
||||
$siteinfo = replace_macros(get_markup_template('siteinfo.tpl'),
|
||||
[
|
||||
[
|
||||
'$title' => t('About this site'),
|
||||
'$sitenametxt' => t('Site Name'),
|
||||
'$sitename' => \Zotlabs\Lib\System::get_site_name(),
|
||||
@@ -29,7 +29,7 @@ class Siteinfo extends \Zotlabs\Web\Controller {
|
||||
'$prj_header' => t('Software and Project information'),
|
||||
'$prj_name' => t('This site is powered by $Projectname'),
|
||||
'$prj_transport' => t('Federated and decentralised networking and identity services provided by Zot'),
|
||||
'$transport_link' => '<a href="https://zotlabs.com">https://zotlabs.com</a>',
|
||||
'$transport_link' => '<a href="https://zotlabs.org">https://zotlabs.org</a>',
|
||||
|
||||
'$additional_text' => t('Additional federated transport protocols:'),
|
||||
'$additional_fed' => implode(', ', $federated),
|
||||
@@ -41,11 +41,11 @@ class Siteinfo extends \Zotlabs\Web\Controller {
|
||||
]
|
||||
);
|
||||
|
||||
call_hooks('about_hook', $siteinfo);
|
||||
call_hooks('about_hook', $siteinfo);
|
||||
|
||||
return $siteinfo;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -41,7 +41,7 @@ class Sse_bs extends Controller {
|
||||
self::$offset = 0;
|
||||
self::$xchans = '';
|
||||
|
||||
if($_REQUEST['sse_rmids'])
|
||||
if(isset($_REQUEST['sse_rmids']))
|
||||
self::mark_read($_REQUEST['sse_rmids']);
|
||||
|
||||
if(!empty($_REQUEST['nquery']) && $_REQUEST['nquery'] !== '%') {
|
||||
@@ -160,8 +160,12 @@ class Sse_bs extends Controller {
|
||||
$offset = self::$offset;
|
||||
|
||||
$sql_extra = '';
|
||||
if(! (self::$vnotify & VNOTIFY_LIKE))
|
||||
if (!(self::$vnotify & VNOTIFY_LIKE)) {
|
||||
$sql_extra = " AND verb NOT IN ('" . dbesc(ACTIVITY_LIKE) . "', '" . dbesc(ACTIVITY_DISLIKE) . "') ";
|
||||
}
|
||||
elseif (!feature_enabled(self::$uid, 'dislike')) {
|
||||
$sql_extra = " AND verb NOT IN ('" . dbesc(ACTIVITY_DISLIKE) . "') ";
|
||||
}
|
||||
|
||||
$sql_extra2 = '';
|
||||
if(self::$xchans)
|
||||
@@ -236,8 +240,12 @@ class Sse_bs extends Controller {
|
||||
$offset = self::$offset;
|
||||
|
||||
$sql_extra = '';
|
||||
if(! (self::$vnotify & VNOTIFY_LIKE))
|
||||
if (!(self::$vnotify & VNOTIFY_LIKE)) {
|
||||
$sql_extra = " AND verb NOT IN ('" . dbesc(ACTIVITY_LIKE) . "', '" . dbesc(ACTIVITY_DISLIKE) . "') ";
|
||||
}
|
||||
elseif (!feature_enabled(self::$uid, 'dislike')) {
|
||||
$sql_extra = " AND verb NOT IN ('" . dbesc(ACTIVITY_DISLIKE) . "') ";
|
||||
}
|
||||
|
||||
$sql_extra2 = '';
|
||||
if(self::$xchans)
|
||||
@@ -311,8 +319,12 @@ class Sse_bs extends Controller {
|
||||
$offset = self::$offset;
|
||||
|
||||
$sql_extra = '';
|
||||
if(! (self::$vnotify & VNOTIFY_LIKE))
|
||||
if (!(self::$vnotify & VNOTIFY_LIKE)) {
|
||||
$sql_extra = " AND verb NOT IN ('" . dbesc(ACTIVITY_LIKE) . "', '" . dbesc(ACTIVITY_DISLIKE) . "') ";
|
||||
}
|
||||
elseif (!feature_enabled(self::$uid, 'dislike')) {
|
||||
$sql_extra = " AND verb NOT IN ('" . dbesc(ACTIVITY_DISLIKE) . "') ";
|
||||
}
|
||||
|
||||
$sql_extra2 = '';
|
||||
if(self::$xchans)
|
||||
@@ -398,8 +410,12 @@ class Sse_bs extends Controller {
|
||||
|
||||
$sys = get_sys_channel();
|
||||
$sql_extra = '';
|
||||
if(! (self::$vnotify & VNOTIFY_LIKE))
|
||||
if (!(self::$vnotify & VNOTIFY_LIKE)) {
|
||||
$sql_extra = " AND verb NOT IN ('" . dbesc(ACTIVITY_LIKE) . "', '" . dbesc(ACTIVITY_DISLIKE) . "') ";
|
||||
}
|
||||
elseif (!feature_enabled(self::$uid, 'dislike')) {
|
||||
$sql_extra = " AND verb NOT IN ('" . dbesc(ACTIVITY_DISLIKE) . "') ";
|
||||
}
|
||||
|
||||
$sql_extra2 = '';
|
||||
if(self::$xchans)
|
||||
@@ -564,12 +580,12 @@ class Sse_bs extends Controller {
|
||||
|
||||
$forums[$x]['notify_link'] = z_root() . '/network/?f=&pf=1&unseen=1&cid=' . $forums[$x]['abook_id'];
|
||||
$forums[$x]['name'] = $forums[$x]['xchan_name'];
|
||||
$forums[$x]['addr'] = $forums[$x]['xchan_addr'];
|
||||
$forums[$x]['addr'] = $forums[$x]['xchan_addr'] ?? $forums[$x]['xchan_url'];
|
||||
$forums[$x]['url'] = $forums[$x]['xchan_url'];
|
||||
$forums[$x]['photo'] = $forums[$x]['xchan_photo_s'];
|
||||
$forums[$x]['unseen'] = count($b64mids);
|
||||
$forums[$x]['private_forum'] = (($forums[$x]['private_forum']) ? 'lock' : '');
|
||||
$forums[$x]['message'] = (($forums[$x]['private_forum']) ? t('Private forum') : t('Public forum'));
|
||||
$forums[$x]['private_forum'] = ((isset($forums[$x]['private_forum']) && $forums[$x]['private_forum']) ? 'lock' : '');
|
||||
$forums[$x]['message'] = ((isset($forums[$x]['private_forum']) && $forums[$x]['private_forum']) ? t('Private forum') : t('Public forum'));
|
||||
$forums[$x]['mids'] = json_encode($b64mids);
|
||||
|
||||
unset($forums[$x]['abook_id']);
|
||||
|
||||
@@ -1,31 +1,46 @@
|
||||
<?php
|
||||
namespace Zotlabs\Module;
|
||||
|
||||
use App;
|
||||
use Zotlabs\Lib\Libsync;
|
||||
|
||||
|
||||
class Starred extends \Zotlabs\Web\Controller {
|
||||
|
||||
function init() {
|
||||
|
||||
|
||||
$starred = 0;
|
||||
|
||||
|
||||
if(! local_channel())
|
||||
killme();
|
||||
if(argc() > 1)
|
||||
$message_id = intval(argv(1));
|
||||
if(! $message_id)
|
||||
killme();
|
||||
|
||||
$r = q("SELECT item_starred FROM item WHERE uid = %d AND id = %d LIMIT 1",
|
||||
|
||||
$sys = get_sys_channel();
|
||||
|
||||
$r = q("SELECT * FROM item WHERE (uid = %d OR uid = %d) AND id = %d
|
||||
and item_type in (0,6,7) and item_deleted = 0 and item_unpublished = 0
|
||||
and item_delayed = 0 and item_pending_remove = 0 and item_blocked = 0 LIMIT 1",
|
||||
intval(local_channel()),
|
||||
intval($sys['channel_id']),
|
||||
intval($message_id)
|
||||
);
|
||||
if(! count($r))
|
||||
|
||||
if ($r) {
|
||||
if ($r[0]['uid'] === $sys['channel_id']) {
|
||||
$r = [ copy_of_pubitem(App::get_channel(), $r[0]['mid']) ];
|
||||
}
|
||||
}
|
||||
|
||||
if(!$r)
|
||||
killme();
|
||||
|
||||
|
||||
// reset $message_id to the fetched copy of message if applicable
|
||||
$message_id = $r[0]['id'];
|
||||
|
||||
$item_starred = (intval($r[0]['item_starred']) ? 0 : 1);
|
||||
|
||||
|
||||
$r = q("UPDATE item SET item_starred = %d WHERE uid = %d and id = %d",
|
||||
intval($item_starred),
|
||||
intval(local_channel()),
|
||||
@@ -38,8 +53,8 @@ class Starred extends \Zotlabs\Web\Controller {
|
||||
if($r) {
|
||||
xchan_query($r);
|
||||
$sync_item = fetch_post_tags($r);
|
||||
Libsync::build_sync_packet(local_channel(),[
|
||||
'item' => [
|
||||
Libsync::build_sync_packet(local_channel(),[
|
||||
'item' => [
|
||||
encode_item($sync_item[0],true)
|
||||
]
|
||||
]);
|
||||
@@ -49,5 +64,5 @@ class Starred extends \Zotlabs\Web\Controller {
|
||||
echo json_encode(array('result' => $item_starred));
|
||||
killme();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -21,7 +21,7 @@ class Wfinger extends \Zotlabs\Web\Controller {
|
||||
elseif(x($_SERVER,'HTTP_X_FORWARDED_PROTO') && ($_SERVER['HTTP_X_FORWARDED_PROTO'] == 'https'))
|
||||
$scheme = 'https';
|
||||
|
||||
$zot = intval($_REQUEST['zot']);
|
||||
$zot = $_REQUEST['zot'] ?? '';
|
||||
|
||||
if(($scheme !== 'https') && (! $zot)) {
|
||||
header($_SERVER["SERVER_PROTOCOL"] . ' ' . 500 . ' ' . 'Webfinger requires HTTPS');
|
||||
@@ -126,7 +126,7 @@ class Wfinger extends \Zotlabs\Web\Controller {
|
||||
'http://webfinger.net/ns/name' => $r['channel_name'],
|
||||
'http://xmlns.com/foaf/0.1/name' => $r['channel_name'],
|
||||
'https://w3id.org/security/v1#publicKeyPem' => $r['xchan_pubkey'],
|
||||
'http://purl.org/zot/federation' => 'zot6,zot'
|
||||
'http://purl.org/zot/federation' => 'zot6'
|
||||
];
|
||||
|
||||
foreach($aliases as $alias)
|
||||
@@ -183,12 +183,6 @@ class Wfinger extends \Zotlabs\Web\Controller {
|
||||
'href' => z_root() . '/profile/' . $r['channel_address'],
|
||||
],
|
||||
|
||||
[
|
||||
'rel' => 'http://schemas.google.com/g/2010#updates-from',
|
||||
'type' => 'application/atom+xml',
|
||||
'href' => z_root() . '/ofeed/' . $r['channel_address']
|
||||
],
|
||||
|
||||
[
|
||||
'rel' => 'http://webfinger.net/rel/blog',
|
||||
'href' => z_root() . '/channel/' . $r['channel_address'],
|
||||
@@ -205,11 +199,6 @@ class Wfinger extends \Zotlabs\Web\Controller {
|
||||
'href' => channel_url($r)
|
||||
],
|
||||
|
||||
[
|
||||
'rel' => 'http://purl.org/zot/protocol',
|
||||
'href' => z_root() . '/.well-known/zot-info' . '?address=' . $r['xchan_addr'],
|
||||
],
|
||||
|
||||
[
|
||||
'rel' => 'http://purl.org/openwebauth/v1',
|
||||
'type' => 'application/x-zot+json',
|
||||
|
||||
@@ -1,873 +0,0 @@
|
||||
<?php /** @file */
|
||||
|
||||
namespace Zotlabs\Module;
|
||||
|
||||
use App;
|
||||
use Zotlabs\Web\Controller;
|
||||
use Zotlabs\Lib\Apps;
|
||||
use Zotlabs\Lib\PermissionDescription;
|
||||
use Zotlabs\Lib\NativeWiki;
|
||||
use Zotlabs\Lib\NativeWikiPage;
|
||||
use Zotlabs\Lib\MarkdownSoap;
|
||||
use Michelf\MarkdownExtra;
|
||||
|
||||
require_once('include/acl_selectors.php');
|
||||
require_once('include/conversation.php');
|
||||
require_once('include/bbcode.php');
|
||||
|
||||
class Wiki extends Controller {
|
||||
|
||||
private $wiki = null;
|
||||
|
||||
function init() {
|
||||
// Determine which channel's wikis to display to the observer
|
||||
$nick = null;
|
||||
if (argc() > 1)
|
||||
$nick = argv(1); // if the channel name is in the URL, use that
|
||||
if (! $nick && local_channel()) { // if no channel name was provided, assume the current logged in channel
|
||||
$channel = \App::get_channel();
|
||||
if ($channel && $channel['channel_address']) {
|
||||
$nick = $channel['channel_address'];
|
||||
goaway(z_root() . '/wiki/' . $nick);
|
||||
}
|
||||
}
|
||||
if (! $nick) {
|
||||
notice( t('Profile Unavailable.') . EOL);
|
||||
goaway(z_root());
|
||||
}
|
||||
|
||||
profile_load($nick);
|
||||
}
|
||||
|
||||
function get() {
|
||||
|
||||
if(observer_prohibited(true)) {
|
||||
return login();
|
||||
}
|
||||
|
||||
if(! Apps::system_app_installed(App::$profile_uid, 'Wiki')) {
|
||||
//Do not display any associated widgets at this point
|
||||
App::$pdl = '';
|
||||
$papp = Apps::get_papp('Wiki');
|
||||
return Apps::app_render($papp, 'module');
|
||||
}
|
||||
|
||||
|
||||
if(! perm_is_allowed(\App::$profile_uid,get_observer_hash(),'view_wiki')) {
|
||||
notice( t('Permission denied.') . EOL);
|
||||
return;
|
||||
}
|
||||
|
||||
// TODO: Combine the interface configuration into a unified object
|
||||
// Something like $interface = array('new_page_button' => false, 'new_wiki_button' => false, ...)
|
||||
|
||||
$wiki_owner = false;
|
||||
$showNewWikiButton = false;
|
||||
$pageHistory = array();
|
||||
$local_observer = null;
|
||||
$resource_id = '';
|
||||
|
||||
// init() should have forced the URL to redirect to /wiki/channel so assume argc() > 1
|
||||
|
||||
$nick = argv(1);
|
||||
$owner = channelx_by_nick($nick); // The channel who owns the wikis being viewed
|
||||
if(! $owner) {
|
||||
notice( t('Invalid channel') . EOL);
|
||||
goaway('/' . argv(0));
|
||||
}
|
||||
|
||||
$observer_hash = get_observer_hash();
|
||||
|
||||
// Determine if the observer is the channel owner so the ACL dialog can be populated
|
||||
if (local_channel() === intval($owner['channel_id'])) {
|
||||
|
||||
$wiki_owner = true;
|
||||
|
||||
nav_set_selected('Wiki');
|
||||
|
||||
// Obtain the default permission settings of the channel
|
||||
$owner_acl = array(
|
||||
'allow_cid' => $owner['channel_allow_cid'],
|
||||
'allow_gid' => $owner['channel_allow_gid'],
|
||||
'deny_cid' => $owner['channel_deny_cid'],
|
||||
'deny_gid' => $owner['channel_deny_gid']
|
||||
);
|
||||
|
||||
// Initialize the ACL to the channel default permissions
|
||||
|
||||
$x = array(
|
||||
'lockstate' => (( $owner['channel_allow_cid'] ||
|
||||
$owner['channel_allow_gid'] ||
|
||||
$owner['channel_deny_cid'] ||
|
||||
$owner['channel_deny_gid'])
|
||||
? 'lock' : 'unlock'
|
||||
),
|
||||
'acl' => populate_acl($owner_acl, false, PermissionDescription::fromGlobalPermission('view_wiki')),
|
||||
'allow_cid' => acl2json($owner_acl['allow_cid']),
|
||||
'allow_gid' => acl2json($owner_acl['allow_gid']),
|
||||
'deny_cid' => acl2json($owner_acl['deny_cid']),
|
||||
'deny_gid' => acl2json($owner_acl['deny_gid']),
|
||||
'bang' => ''
|
||||
);
|
||||
}
|
||||
else {
|
||||
// Not the channel owner
|
||||
$owner_acl = $x = array();
|
||||
}
|
||||
|
||||
$is_owner = ((local_channel()) && (local_channel() == \App::$profile['profile_uid']) ? true : false);
|
||||
|
||||
$o = '';
|
||||
|
||||
// Download a wiki
|
||||
|
||||
if((argc() > 3) && (argv(2) === 'download') && (argv(3) === 'wiki')) {
|
||||
|
||||
$resource_id = argv(4);
|
||||
$w = NativeWiki::get_wiki($owner['channel_id'],$observer_hash,$resource_id);
|
||||
// $w = NativeWiki::get_wiki($owner,$observer_hash,$resource_id);
|
||||
if(! $w['htmlName']) {
|
||||
notice(t('Error retrieving wiki') . EOL);
|
||||
}
|
||||
|
||||
$zip_folder_name = random_string(10);
|
||||
$zip_folderpath = '/tmp/' . $zip_folder_name;
|
||||
if(!mkdir($zip_folderpath, 0770, false)) {
|
||||
logger('Error creating zip file export folder: ' . $zip_folderpath, LOGGER_NORMAL);
|
||||
notice(t('Error creating zip file export folder') . EOL);
|
||||
}
|
||||
|
||||
$zip_filename = $w['urlName'];
|
||||
$zip_filepath = '/tmp/' . $zip_folder_name . '/' . $zip_filename;
|
||||
|
||||
|
||||
// Generate the zip file
|
||||
|
||||
$zip = new \ZipArchive;
|
||||
$r = $zip->open($zip_filepath, \ZipArchive::CREATE);
|
||||
if($r === true) {
|
||||
$pages = [];
|
||||
$i = q("select * from item where resource_type = 'nwikipage' and resource_id = '%s' order by revision desc",
|
||||
dbesc($resource_id)
|
||||
);
|
||||
|
||||
if($i) {
|
||||
foreach($i as $iv) {
|
||||
if(in_array($iv['mid'],$pages))
|
||||
continue;
|
||||
|
||||
if($iv['mimetype'] === 'text/plain') {
|
||||
$content = html_entity_decode($iv['body'],ENT_COMPAT,'UTF-8');
|
||||
}
|
||||
elseif($iv['mimetype'] === 'text/bbcode') {
|
||||
$content = html_entity_decode($iv['body'],ENT_COMPAT,'UTF-8');
|
||||
}
|
||||
elseif($iv['mimetype'] === 'text/markdown') {
|
||||
$content = html_entity_decode(MarkdownSoap::unescape($iv['body']),ENT_COMPAT,'UTF-8');
|
||||
}
|
||||
$fname = get_iconfig($iv['id'],'nwikipage','pagetitle') . NativeWikiPage::get_file_ext($iv);
|
||||
$zip->addFromString($fname,$content);
|
||||
$pages[] = $iv['mid'];
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
$zip->close();
|
||||
|
||||
// Output the file for download
|
||||
|
||||
header('Content-disposition: attachment; filename="' . $zip_filename . '.zip"');
|
||||
header('Content-Type: application/zip');
|
||||
|
||||
$success = readfile($zip_filepath);
|
||||
|
||||
if(!$success) {
|
||||
logger('Error downloading wiki: ' . $resource_id);
|
||||
notice(t('Error downloading wiki: ' . $resource_id) . EOL);
|
||||
}
|
||||
|
||||
// delete temporary files
|
||||
rrmdir($zip_folderpath);
|
||||
killme();
|
||||
|
||||
}
|
||||
|
||||
switch(argc()) {
|
||||
case 2:
|
||||
$wikis = NativeWiki::listwikis($owner, get_observer_hash());
|
||||
|
||||
if($wikis) {
|
||||
$o .= replace_macros(get_markup_template('wikilist.tpl'), array(
|
||||
'$header' => t('Wikis'),
|
||||
'$channel' => $owner['channel_address'],
|
||||
'$wikis' => $wikis['wikis'],
|
||||
// If the observer is the local channel owner, show the wiki controls
|
||||
'$owner' => ((local_channel() && local_channel() === intval(\App::$profile['uid'])) ? true : false),
|
||||
'$edit' => t('Edit'),
|
||||
'$download' => t('Download'),
|
||||
'$view' => t('View'),
|
||||
'$create' => t('Create New'),
|
||||
'$submit' => t('Submit'),
|
||||
'$wikiName' => array('wikiName', t('Wiki name')),
|
||||
'$mimeType' => array('mimeType', t('Content type'), '', '', ['text/markdown' => t('Markdown'), 'text/bbcode' => t('BBcode'), 'text/plain' => t('Text') ]),
|
||||
'$name' => t('Name'),
|
||||
'$type' => t('Type'),
|
||||
'$unlocked' => t('Any type'),
|
||||
'$lockstate' => (x($x,'lockstate') ? $x['lockstate'] : ''),
|
||||
'$acl' => (x($x,'acl') ? $x['acl'] : ''),
|
||||
'$allow_cid' => (x($x,'allow_cid') ? $x['allow_cid'] : ''),
|
||||
'$allow_gid' => (x($x,'allow_gid') ? $x['allow_gid'] : ''),
|
||||
'$deny_cid' => (x($x,'deny_cid') ? $x['deny_cid'] : ''),
|
||||
'$deny_gid' => (x($x,'deny_gid') ? $x['deny_gid'] : ''),
|
||||
'$typelock' => array('typelock', t('Lock content type'), '', '', array(t('No'), t('Yes'))),
|
||||
'$notify' => array('postVisible', t('Create a status post for this wiki'), '', '', array(t('No'), t('Yes'))),
|
||||
'$edit_wiki_name' => t('Edit Wiki Name')
|
||||
));
|
||||
|
||||
return $o;
|
||||
}
|
||||
break;
|
||||
|
||||
case 3:
|
||||
|
||||
// /wiki/channel/wiki -> No page was specified, so redirect to Home.md
|
||||
|
||||
//$wikiUrlName = urlencode(argv(2));
|
||||
$wikiUrlName = NativeWiki::name_encode(argv(2));
|
||||
goaway(z_root() . '/' . argv(0) . '/' . argv(1) . '/' . $wikiUrlName . '/Home');
|
||||
|
||||
case 4:
|
||||
default:
|
||||
|
||||
// GET /wiki/channel/wiki/page
|
||||
// Fetch the wiki info and determine observer permissions
|
||||
|
||||
//$wikiUrlName = urldecode(argv(2));
|
||||
$wikiUrlName = NativeWiki::name_decode(argv(2));
|
||||
|
||||
$page_name = '';
|
||||
$ignore_language = false;
|
||||
|
||||
for($x = 3; $x < argc(); $x ++) {
|
||||
if($page_name === '' && argv($x) === '-') {
|
||||
$ignore_language = true;
|
||||
continue;
|
||||
}
|
||||
if($page_name) {
|
||||
$page_name .= '/';
|
||||
}
|
||||
$page_name .= argv($x);
|
||||
}
|
||||
|
||||
//$pageUrlName = urldecode($page_name);
|
||||
$pageUrlName = NativeWiki::name_decode($page_name);
|
||||
$langPageUrlName = \App::$language . '/' . $pageUrlName;
|
||||
|
||||
$w = NativeWiki::exists_by_name($owner['channel_id'], $wikiUrlName);
|
||||
|
||||
if(! $w['resource_id']) {
|
||||
notice(t('Wiki not found') . EOL);
|
||||
goaway(z_root() . '/' . argv(0) . '/' . argv(1));
|
||||
}
|
||||
|
||||
$resource_id = $w['resource_id'];
|
||||
|
||||
if(! $wiki_owner) {
|
||||
// Check for observer permissions
|
||||
$observer_hash = get_observer_hash();
|
||||
$perms = NativeWiki::get_permissions($resource_id, intval($owner['channel_id']), $observer_hash);
|
||||
if(! $perms['read']) {
|
||||
notice(t('Permission denied.') . EOL);
|
||||
goaway(z_root() . '/' . argv(0) . '/' . argv(1));
|
||||
return; //not reached
|
||||
}
|
||||
$wiki_editor = (($perms['write']) ? true : false);
|
||||
}
|
||||
else {
|
||||
$wiki_editor = true;
|
||||
}
|
||||
|
||||
//$wikiheaderName = urldecode($wikiUrlName);
|
||||
$wikiheaderName = escape_tags(NativeWiki::name_decode($wikiUrlName));
|
||||
//$wikiheaderPage = urldecode($pageUrlName);
|
||||
$wikiheaderPage = escape_tags(NativeWiki::name_decode($pageUrlName));
|
||||
|
||||
$renamePage = (($wikiheaderPage === 'Home') ? '' : t('Rename page'));
|
||||
$sharePage = t('Share');
|
||||
|
||||
$p = [];
|
||||
|
||||
if(! $ignore_language) {
|
||||
$p = NativeWikiPage::get_page_content(array('channel_id' => $owner['channel_id'], 'observer_hash' => $observer_hash, 'resource_id' => $resource_id, 'pageUrlName' => $langPageUrlName));
|
||||
}
|
||||
if(! ($p && $p['success'])) {
|
||||
$p = NativeWikiPage::get_page_content(array('channel_id' => $owner['channel_id'], 'observer_hash' => $observer_hash, 'resource_id' => $resource_id, 'pageUrlName' => $pageUrlName));
|
||||
}
|
||||
if(! ($p && $p['success'])) {
|
||||
$x = new \Zotlabs\Widget\Wiki_pages();
|
||||
|
||||
$html = $x->create_missing_page([
|
||||
'resource_id' => $resource_id,
|
||||
'channel_id' => $owner['channel_id'],
|
||||
'channel_address' => $owner['channel_address'],
|
||||
'refresh' => true
|
||||
]);
|
||||
//json_return_and_die(array('pages' => $page_list_html, 'message' => '', 'success' => true));
|
||||
notice( t('Error retrieving page content') . EOL);
|
||||
//goaway(z_root() . '/' . argv(0) . '/' . argv(1) );
|
||||
$renderedContent = NativeWikiPage::convert_links($html, argv(0) . '/' . argv(1) . '/' . NativeWiki::name_encode($wikiUrlName));
|
||||
$showPageControls = $wiki_editor;
|
||||
}
|
||||
else {
|
||||
$mimeType = $p['pageMimeType'];
|
||||
|
||||
$sampleContent = (($mimeType == 'text/bbcode') ? '[h3]' . t('New page') . '[/h3]' : '### ' . t('New page'));
|
||||
if($mimeType === 'text/plain')
|
||||
$sampleContent = t('New page');
|
||||
|
||||
$content = (($p['content'] == '') ? $sampleContent : $p['content']);
|
||||
|
||||
$hookinfo = ['content' => $content, 'mimetype' => $mimeType];
|
||||
call_hooks('wiki_preprocess',$hookinfo);
|
||||
$content = $hookinfo['content'];
|
||||
|
||||
// Render the Markdown-formatted page content in HTML
|
||||
if($mimeType == 'text/bbcode') {
|
||||
$renderedContent = zidify_links(smilies(bbcode($content)));
|
||||
$renderedContent = NativeWikiPage::convert_links($renderedContent,argv(0) . '/' . argv(1) . '/' . NativeWiki::name_encode($wikiUrlName));
|
||||
}
|
||||
elseif($mimeType === 'text/plain') {
|
||||
$renderedContent = str_replace(["\n",' ',"\t"],[EOL,' ',' '],htmlentities($content,ENT_COMPAT,'UTF-8',false));
|
||||
}
|
||||
elseif($mimeType === 'text/markdown') {
|
||||
$content = MarkdownSoap::unescape($content);
|
||||
//$html = NativeWikiPage::generate_toc(zidify_text(MarkdownExtra::defaultTransform(NativeWikiPage::bbcode($content))));
|
||||
//$renderedContent = NativeWikiPage::convert_links($html, argv(0) . '/' . argv(1) . '/' . $wikiUrlName);
|
||||
$html = NativeWikiPage::convert_links($content, argv(0) . '/' . argv(1) . '/' . NativeWiki::name_encode($wikiUrlName));
|
||||
$renderedContent = NativeWikiPage::generate_toc(zidify_text(MarkdownExtra::defaultTransform(NativeWikiPage::bbcode($html))));
|
||||
}
|
||||
$showPageControls = $wiki_editor;
|
||||
}
|
||||
break;
|
||||
// default: // Strip the extraneous URL components
|
||||
// goaway('/' . argv(0) . '/' . argv(1) . '/' . NativeWiki::name_encode($wikiUrlName) . '/' . $pageUrlName);
|
||||
}
|
||||
|
||||
|
||||
$wikiModalID = random_string(3);
|
||||
|
||||
$wikiModal = replace_macros(get_markup_template('generic_modal.tpl'), array(
|
||||
'$id' => $wikiModalID,
|
||||
'$title' => t('Revision Comparison'),
|
||||
'$ok' => (($showPageControls) ? t('Revert') : ''),
|
||||
'$cancel' => t('Cancel')
|
||||
));
|
||||
|
||||
$types = [ 'text/bbcode' => t('BBcode'), 'text/markdown' => t('Markdown'), 'text/plain' => 'Text' ];
|
||||
$currenttype = $types[$mimeType];
|
||||
|
||||
$placeholder = t('Short description of your changes (optional)');
|
||||
|
||||
$zrl = z_root() . '/wiki/' . argv(1) . '/' . NativeWiki::name_encode($wikiUrlName) . '/' . NativeWiki::name_encode($pageUrlName);
|
||||
$o .= replace_macros(get_markup_template('wiki.tpl'),array(
|
||||
'$wikiheaderName' => $wikiheaderName,
|
||||
'$wikiheaderPage' => $wikiheaderPage,
|
||||
'$renamePage' => $renamePage,
|
||||
'$sharePage' => $sharePage,
|
||||
'$shareLink' => urlencode('#^[zrl=' . $zrl . ']' . '[ ' . $owner['channel_name'] . ' ] ' . $wikiheaderName . ' - ' . $wikiheaderPage . '[/zrl]'),
|
||||
'$showPageControls' => $showPageControls,
|
||||
'$editOrSourceLabel' => (($showPageControls) ? t('Edit') : t('Source')),
|
||||
'$tools_label' => 'Page Tools',
|
||||
'$channel_address' => $owner['channel_address'],
|
||||
'$channel_id' => $owner['channel_id'],
|
||||
'$resource_id' => $resource_id,
|
||||
'$page' => $pageUrlName,
|
||||
'$mimeType' => $mimeType,
|
||||
'$typename' => $currenttype,
|
||||
'$content' => $content,
|
||||
'$renderedContent' => $renderedContent,
|
||||
'$pageRename' => array('pageRename', t('New page name'), '', ''),
|
||||
'$commitMsg' => array('commitMsg', '', '', '', '', 'placeholder="' . $placeholder . '"'),
|
||||
'$wikiModal' => $wikiModal,
|
||||
'$wikiModalID' => $wikiModalID,
|
||||
'$commit' => 'HEAD',
|
||||
'$embedPhotos' => t('Embed image from photo albums'),
|
||||
'$embedPhotosModalTitle' => t('Embed an image from your albums'),
|
||||
'$embedPhotosModalCancel' => t('Cancel'),
|
||||
'$embedPhotosModalOK' => t('OK'),
|
||||
'$modalchooseimages' => t('Choose images to embed'),
|
||||
'$modalchoosealbum' => t('Choose an album'),
|
||||
'$modaldiffalbum' => t('Choose a different album'),
|
||||
'$modalerrorlist' => t('Error getting album list'),
|
||||
'$modalerrorlink' => t('Error getting photo link'),
|
||||
'$modalerroralbum' => t('Error getting album'),
|
||||
'$view_lbl' => t('View'),
|
||||
'$history_lbl' => t('History')
|
||||
));
|
||||
|
||||
if($p['pageMimeType'] === 'text/markdown')
|
||||
head_add_js('/library/ace/ace.js'); // Ace Code Editor
|
||||
|
||||
return $o;
|
||||
}
|
||||
|
||||
function post() {
|
||||
|
||||
require_once('include/bbcode.php');
|
||||
|
||||
$nick = argv(1);
|
||||
$owner = channelx_by_nick($nick);
|
||||
$observer_hash = get_observer_hash();
|
||||
|
||||
if(! $owner) {
|
||||
notice( t('Permission denied.') . EOL);
|
||||
return;
|
||||
}
|
||||
|
||||
// /wiki/channel/preview
|
||||
// Render mardown-formatted text in HTML for preview
|
||||
if((argc() > 2) && (argv(2) === 'preview')) {
|
||||
$content = $_POST['content'];
|
||||
$resource_id = $_POST['resource_id'];
|
||||
|
||||
$w = NativeWiki::get_wiki($owner['channel_id'],$observer_hash,$resource_id);
|
||||
|
||||
$wikiURL = argv(0) . '/' . argv(1) . '/' . $w['urlName'];
|
||||
|
||||
$mimeType = $_POST['mimetype'];
|
||||
|
||||
if($mimeType === 'text/bbcode') {
|
||||
$html = zidify_links(smilies(bbcode($content)));
|
||||
$html = NativeWikiPage::convert_links($html,$wikiURL);
|
||||
}
|
||||
elseif($mimeType === 'text/markdown') {
|
||||
$linkconverted = NativeWikiPage::convert_links($content,$wikiURL);
|
||||
$bb = NativeWikiPage::bbcode($linkconverted);
|
||||
$x = new MarkdownSoap($bb);
|
||||
$md = $x->clean();
|
||||
$md = MarkdownSoap::unescape($md);
|
||||
$html = MarkdownExtra::defaultTransform($md);
|
||||
$html = NativeWikiPage::generate_toc(zidify_text($html));
|
||||
}
|
||||
elseif($mimeType === 'text/plain') {
|
||||
$html = str_replace(["\n",' ',"\t"],[EOL,' ',' '],htmlentities($content,ENT_COMPAT,'UTF-8',false));
|
||||
}
|
||||
json_return_and_die(array('html' => $html, 'success' => true));
|
||||
}
|
||||
|
||||
// Create a new wiki
|
||||
// /wiki/channel/create/wiki
|
||||
if ((argc() > 3) && (argv(2) === 'create') && (argv(3) === 'wiki')) {
|
||||
|
||||
// Only the channel owner can create a wiki, at least until we create a
|
||||
// more detail permissions framework
|
||||
|
||||
if (local_channel() !== intval($owner['channel_id'])) {
|
||||
goaway('/' . argv(0) . '/' . $nick . '/');
|
||||
}
|
||||
$wiki = array();
|
||||
|
||||
// backslashes won't work well in the javascript functions
|
||||
$name = str_replace('\\','',$_POST['wikiName']);
|
||||
|
||||
// Generate new wiki info from input name
|
||||
$wiki['postVisible'] = ((intval($_POST['postVisible'])) ? 1 : 0);
|
||||
$wiki['rawName'] = $name;
|
||||
$wiki['htmlName'] = escape_tags($name);
|
||||
//$wiki['urlName'] = urlencode(urlencode($name));
|
||||
$wiki['urlName'] = NativeWiki::name_encode($name);
|
||||
$wiki['mimeType'] = $_POST['mimeType'];
|
||||
$wiki['typelock'] = $_POST['typelock'];
|
||||
|
||||
if($wiki['urlName'] === '') {
|
||||
notice( t('Error creating wiki. Invalid name.') . EOL);
|
||||
goaway('/wiki');
|
||||
return; //not reached
|
||||
}
|
||||
|
||||
$exists = NativeWiki::exists_by_name($owner['channel_id'], $wiki['urlName']);
|
||||
if($exists['id']) {
|
||||
notice( t('A wiki with this name already exists.') . EOL);
|
||||
goaway('/wiki');
|
||||
return; //not reached
|
||||
}
|
||||
|
||||
// Get ACL for permissions
|
||||
$acl = new \Zotlabs\Access\AccessList($owner);
|
||||
$acl->set_from_array($_POST);
|
||||
$r = NativeWiki::create_wiki($owner, $observer_hash, $wiki, $acl);
|
||||
if($r['success']) {
|
||||
NativeWiki::sync_a_wiki_item($owner['channel_id'],$r['item_id'],$r['item']['resource_id']);
|
||||
$homePage = NativeWikiPage::create_page($owner, $observer_hash, 'Home', $r['item']['resource_id'], $wiki['mimeType']);
|
||||
if(! $homePage['success']) {
|
||||
notice( t('Wiki created, but error creating Home page.'));
|
||||
goaway(z_root() . '/wiki/' . $nick . '/' . NativeWiki::name_encode($wiki['urlName']));
|
||||
}
|
||||
NativeWiki::sync_a_wiki_item($owner['channel_id'], $homePage['item_id'], $r['item']['resource_id']);
|
||||
goaway(z_root() . '/wiki/' . $nick . '/' . NativeWiki::name_encode($wiki['urlName']) . '/' . NativeWiki::name_encode($homePage['page']['urlName']));
|
||||
}
|
||||
else {
|
||||
notice( t('Error creating wiki'));
|
||||
goaway(z_root() . '/wiki');
|
||||
}
|
||||
}
|
||||
|
||||
// Update a wiki
|
||||
// /wiki/channel/update/wiki
|
||||
if ((argc() > 3) && (argv(2) === 'update') && (argv(3) === 'wiki')) {
|
||||
// Only the channel owner can update a wiki, at least until we create a
|
||||
// more detail permissions framework
|
||||
|
||||
if (local_channel() !== intval($owner['channel_id'])) {
|
||||
goaway('/' . argv(0) . '/' . $nick . '/');
|
||||
}
|
||||
|
||||
$arr = [];
|
||||
|
||||
//$arr['urlName'] = urlencode(urlencode($_POST['origRawName']));
|
||||
$arr['urlName'] = NativeWiki::name_encode($_POST['origRawName']);
|
||||
|
||||
if($_POST['updateRawName'])
|
||||
$arr['updateRawName'] = $_POST['updateRawName'];
|
||||
|
||||
if(($arr['urlName'] || $arr['updateRawName']) === '') {
|
||||
notice( t('Error updating wiki. Invalid name.') . EOL);
|
||||
goaway('/wiki');
|
||||
return; //not reached
|
||||
}
|
||||
|
||||
$wiki = NativeWiki::exists_by_name($owner['channel_id'], $arr['urlName']);
|
||||
if($wiki['resource_id']) {
|
||||
|
||||
$arr['resource_id'] = $wiki['resource_id'];
|
||||
|
||||
$acl = new \Zotlabs\Access\AccessList($owner);
|
||||
$acl->set_from_array($_POST);
|
||||
|
||||
$r = NativeWiki::update_wiki($owner['channel_id'], $observer_hash, $arr, $acl);
|
||||
if($r['success']) {
|
||||
NativeWiki::sync_a_wiki_item($owner['channel_id'], $r['item_id'], $r['item']['resource_id']);
|
||||
goaway(z_root() . '/wiki/' . $nick);
|
||||
}
|
||||
else {
|
||||
notice( t('Error updating wiki'));
|
||||
goaway(z_root() . '/wiki');
|
||||
}
|
||||
|
||||
}
|
||||
goaway(z_root() . '/wiki');
|
||||
}
|
||||
|
||||
// Delete a wiki
|
||||
if ((argc() > 3) && (argv(2) === 'delete') && (argv(3) === 'wiki')) {
|
||||
|
||||
// Only the channel owner can delete a wiki, at least until we create a
|
||||
// more detail permissions framework
|
||||
if (local_channel() !== intval($owner['channel_id'])) {
|
||||
logger('Wiki delete permission denied.');
|
||||
json_return_and_die(array('message' => t('Wiki delete permission denied.'), 'success' => false));
|
||||
}
|
||||
$resource_id = $_POST['resource_id'];
|
||||
$deleted = NativeWiki::delete_wiki($owner['channel_id'],$observer_hash,$resource_id);
|
||||
if ($deleted['success']) {
|
||||
NativeWiki::sync_a_wiki_item($owner['channel_id'], 0, $resource_id);
|
||||
json_return_and_die(array('message' => '', 'success' => true));
|
||||
}
|
||||
else {
|
||||
logger('Error deleting wiki: ' . $resource_id . ' ' . $deleted['message']);
|
||||
json_return_and_die(array('message' => t('Error deleting wiki'), 'success' => false));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Create a page
|
||||
if ((argc() === 4) && (argv(2) === 'create') && (argv(3) === 'page')) {
|
||||
|
||||
$mimetype = $_POST['mimetype'];
|
||||
|
||||
$resource_id = $_POST['resource_id'];
|
||||
// Determine if observer has permission to create a page
|
||||
|
||||
|
||||
$perms = NativeWiki::get_permissions($resource_id, intval($owner['channel_id']), $observer_hash);
|
||||
if(! $perms['write']) {
|
||||
logger('Wiki write permission denied. ' . EOL);
|
||||
json_return_and_die(array('success' => false));
|
||||
}
|
||||
|
||||
$name = isset($_POST['pageName']) ? $_POST['pageName'] : $_POST['missingPageName']; //Get new page name
|
||||
|
||||
// backslashes won't work well in the javascript functions
|
||||
$name = str_replace('\\','',$name);
|
||||
|
||||
if(NativeWiki::name_encode(escape_tags($name)) === '') {
|
||||
json_return_and_die(array('message' => 'Error creating page. Invalid name (' . print_r($_POST,true) . ').', 'success' => false));
|
||||
}
|
||||
|
||||
$page = NativeWikiPage::create_page($owner, $observer_hash, $name, $resource_id, $mimetype);
|
||||
if($page['item_id']) {
|
||||
|
||||
$commit = NativeWikiPage::commit([
|
||||
'commit_msg' => t('New page created'),
|
||||
'resource_id' => $resource_id,
|
||||
'channel_id' => $owner['channel_id'],
|
||||
'observer_hash' => $observer_hash,
|
||||
'pageUrlName' => $name
|
||||
]);
|
||||
if($commit['success']) {
|
||||
NativeWiki::sync_a_wiki_item($owner['channel_id'], $commit['item_id'], $resource_id);
|
||||
//json_return_and_die(array('url' => '/' . argv(0) . '/' . argv(1) . '/' . urlencode($page['wiki']['urlName']) . '/' . urlencode($page['page']['urlName']), 'success' => true));
|
||||
json_return_and_die(array('url' => '/' . argv(0) . '/' . argv(1) . '/' . $page['wiki']['urlName'] . '/' . $page['page']['urlName'], 'success' => true));
|
||||
}
|
||||
else {
|
||||
json_return_and_die(array('message' => 'Error making git commit','url' => '/' . argv(0) . '/' . argv(1) . '/' . NativeWiki::name_encode($page['wiki']['urlName']) . '/' . NativeWiki::name_encode($page['page']['urlName']),'success' => false));
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
else {
|
||||
logger('Error creating page');
|
||||
json_return_and_die(array('message' => 'Error creating page.', 'success' => false));
|
||||
}
|
||||
}
|
||||
|
||||
// Fetch page list for a wiki
|
||||
if((argc() === 5) && (argv(2) === 'get') && (argv(3) === 'page') && (argv(4) === 'list')) {
|
||||
$resource_id = $_POST['resource_id']; // resource_id for wiki in db
|
||||
|
||||
$perms = NativeWiki::get_permissions($resource_id, intval($owner['channel_id']), $observer_hash);
|
||||
if(!$perms['read']) {
|
||||
logger('Wiki read permission denied.' . EOL);
|
||||
json_return_and_die(array('pages' => null, 'message' => 'Permission denied.', 'success' => false));
|
||||
}
|
||||
|
||||
// @FIXME - we shouldn't invoke this if it isn't in the PDL or has been over-ridden
|
||||
|
||||
$x = new \Zotlabs\Widget\Wiki_pages();
|
||||
|
||||
$page_list_html = $x->widget([
|
||||
'resource_id' => $resource_id,
|
||||
'channel_id' => $owner['channel_id'],
|
||||
'channel_address' => $owner['channel_address'],
|
||||
'refresh' => true
|
||||
]);
|
||||
json_return_and_die(array('pages' => $page_list_html, 'message' => '', 'success' => true));
|
||||
}
|
||||
|
||||
// Save a page
|
||||
if ((argc() === 4) && (argv(2) === 'save') && (argv(3) === 'page')) {
|
||||
|
||||
$resource_id = $_POST['resource_id'];
|
||||
$pageUrlName = $_POST['name'];
|
||||
$pageHtmlName = escape_tags($_POST['name']);
|
||||
$content = $_POST['content']; //Get new content
|
||||
$commitMsg = $_POST['commitMsg'];
|
||||
if ($commitMsg === '') {
|
||||
$commitMsg = 'Updated ' . $pageHtmlName;
|
||||
}
|
||||
|
||||
// Determine if observer has permission to save content
|
||||
$perms = NativeWiki::get_permissions($resource_id, intval($owner['channel_id']), $observer_hash);
|
||||
if(! $perms['write']) {
|
||||
logger('Wiki write permission denied. ' . EOL);
|
||||
json_return_and_die(array('success' => false));
|
||||
}
|
||||
|
||||
$saved = NativeWikiPage::save_page([
|
||||
'channel_id' => $owner['channel_id'],
|
||||
'observer_hash' => $observer_hash,
|
||||
'resource_id' => $resource_id,
|
||||
'pageUrlName' => $pageUrlName,
|
||||
'content' => $content
|
||||
]);
|
||||
if($saved['success']) {
|
||||
|
||||
$commit = NativeWikiPage::commit([
|
||||
'commit_msg' => $commitMsg,
|
||||
'pageUrlName' => $pageUrlName,
|
||||
'resource_id' => $resource_id,
|
||||
'channel_id' => $owner['channel_id'],
|
||||
'observer_hash' => $observer_hash,
|
||||
'revision' => (-1)
|
||||
]);
|
||||
if($commit['success']) {
|
||||
NativeWiki::sync_a_wiki_item($owner['channel_id'], $commit['item_id'], $resource_id);
|
||||
json_return_and_die(array('message' => 'Wiki git repo commit made', 'success' => true , 'content' => $content));
|
||||
}
|
||||
else {
|
||||
json_return_and_die(array('message' => 'Error making git commit','success' => false));
|
||||
}
|
||||
}
|
||||
else {
|
||||
json_return_and_die(array('message' => 'Error saving page', 'success' => false));
|
||||
}
|
||||
}
|
||||
|
||||
// Update page history
|
||||
// /wiki/channel/history/page
|
||||
if ((argc() === 4) && (argv(2) === 'history') && (argv(3) === 'page')) {
|
||||
|
||||
$resource_id = $_POST['resource_id'];
|
||||
$pageUrlName = $_POST['name'];
|
||||
|
||||
// Determine if observer has permission to read content
|
||||
|
||||
$perms = NativeWiki::get_permissions($resource_id, intval($owner['channel_id']), $observer_hash);
|
||||
if(! $perms['read']) {
|
||||
logger('Wiki read permission denied.' . EOL);
|
||||
json_return_and_die(array('historyHTML' => '', 'message' => 'Permission denied.', 'success' => false));
|
||||
}
|
||||
|
||||
$historyHTML = \Zotlabs\Lib\NativeWikiPage::render_page_history(array(
|
||||
'resource_id' => $resource_id,
|
||||
'pageUrlName' => $pageUrlName,
|
||||
'permsWrite' => $perms['write']
|
||||
));
|
||||
|
||||
json_return_and_die(array('historyHTML' => $historyHTML, 'message' => '', 'success' => true));
|
||||
}
|
||||
|
||||
// Delete a page
|
||||
if ((argc() === 4) && (argv(2) === 'delete') && (argv(3) === 'page')) {
|
||||
|
||||
$resource_id = $_POST['resource_id'];
|
||||
$pageUrlName = $_POST['name'];
|
||||
|
||||
if ($pageUrlName === 'Home') {
|
||||
json_return_and_die(array('message' => t('Cannot delete Home'),'success' => false));
|
||||
}
|
||||
|
||||
// Determine if observer has permission to delete pages
|
||||
// currently just allow page owner
|
||||
if((! local_channel()) || (local_channel() != $owner['channel_id'])) {
|
||||
logger('Wiki write permission denied. ' . EOL);
|
||||
json_return_and_die(array('success' => false));
|
||||
}
|
||||
|
||||
$perms = NativeWiki::get_permissions($resource_id, intval($owner['channel_id']), $observer_hash);
|
||||
if(! $perms['write']) {
|
||||
logger('Wiki write permission denied. ' . EOL);
|
||||
json_return_and_die(array('success' => false));
|
||||
}
|
||||
|
||||
$deleted = NativeWikiPage::delete_page([
|
||||
'channel_id' => $owner['channel_id'],
|
||||
'observer_hash' => $observer_hash,
|
||||
'resource_id' => $resource_id,
|
||||
'pageUrlName' => $pageUrlName
|
||||
]);
|
||||
if($deleted['success']) {
|
||||
NativeWiki::sync_a_wiki_item($owner['channel_id'], 0, $resource_id);
|
||||
json_return_and_die(array('message' => 'Wiki git repo commit made', 'success' => true));
|
||||
}
|
||||
else {
|
||||
json_return_and_die(array('message' => 'Error deleting page', 'success' => false));
|
||||
}
|
||||
}
|
||||
|
||||
// Revert a page
|
||||
if ((argc() === 4) && (argv(2) === 'revert') && (argv(3) === 'page')) {
|
||||
|
||||
$resource_id = $_POST['resource_id'];
|
||||
$pageUrlName = $_POST['name'];
|
||||
$commitHash = $_POST['commitHash'];
|
||||
|
||||
// Determine if observer has permission to revert pages
|
||||
$perms = NativeWiki::get_permissions($resource_id, intval($owner['channel_id']), $observer_hash);
|
||||
if(! $perms['write']) {
|
||||
logger('Wiki write permission denied.' . EOL);
|
||||
json_return_and_die(array('success' => false));
|
||||
}
|
||||
|
||||
$reverted = NativeWikiPage::revert_page([
|
||||
'channel_id' => $owner['channel_id'],
|
||||
'observer_hash' => $observer_hash,
|
||||
'commitHash' => $commitHash,
|
||||
'resource_id' => $resource_id,
|
||||
'pageUrlName' => $pageUrlName
|
||||
]);
|
||||
if($reverted['success']) {
|
||||
json_return_and_die(array('content' => $reverted['content'], 'message' => '', 'success' => true));
|
||||
}
|
||||
else {
|
||||
json_return_and_die(array('content' => '', 'message' => 'Error reverting page', 'success' => false));
|
||||
}
|
||||
}
|
||||
|
||||
// Compare page revisions
|
||||
if ((argc() === 4) && (argv(2) === 'compare') && (argv(3) === 'page')) {
|
||||
$resource_id = $_POST['resource_id'];
|
||||
$pageUrlName = $_POST['name'];
|
||||
$compareCommit = $_POST['compareCommit'];
|
||||
$currentCommit = $_POST['currentCommit'];
|
||||
// Determine if observer has permission to revert pages
|
||||
|
||||
$perms = NativeWiki::get_permissions($resource_id, intval($owner['channel_id']), $observer_hash);
|
||||
if(!$perms['read']) {
|
||||
logger('Wiki read permission denied.' . EOL);
|
||||
json_return_and_die(array('success' => false));
|
||||
}
|
||||
|
||||
$compare = NativeWikiPage::compare_page(array('channel_id' => $owner['channel_id'], 'observer_hash' => $observer_hash, 'currentCommit' => $currentCommit, 'compareCommit' => $compareCommit, 'resource_id' => $resource_id, 'pageUrlName' => $pageUrlName));
|
||||
if($compare['success']) {
|
||||
$diffHTML = '<table class="text-center" width="100%"><tr><td class="lead" width="50%">' . t('Current Revision') . '</td><td class="lead" width="50%">' . t('Selected Revision') . '</td></tr></table>' . $compare['diff'];
|
||||
json_return_and_die(array('diff' => $diffHTML, 'message' => '', 'success' => true));
|
||||
} else {
|
||||
json_return_and_die(array('diff' => '', 'message' => 'Error comparing page', 'success' => false));
|
||||
}
|
||||
}
|
||||
|
||||
// Rename a page
|
||||
if ((argc() === 4) && (argv(2) === 'rename') && (argv(3) === 'page')) {
|
||||
$resource_id = $_POST['resource_id'];
|
||||
$pageUrlName = $_POST['oldName'];
|
||||
$pageNewName = str_replace('\\','',$_POST['newName']);
|
||||
if ($pageUrlName === 'Home') {
|
||||
json_return_and_die(array('message' => 'Cannot rename Home','success' => false));
|
||||
}
|
||||
if(NativeWiki::name_encode(escape_tags($pageNewName)) === '') {
|
||||
json_return_and_die(array('message' => 'Error renaming page. Invalid name.', 'success' => false));
|
||||
}
|
||||
// Determine if observer has permission to rename pages
|
||||
|
||||
$perms = NativeWiki::get_permissions($resource_id, intval($owner['channel_id']), $observer_hash);
|
||||
if(! $perms['write']) {
|
||||
logger('Wiki write permission denied. ' . EOL);
|
||||
json_return_and_die(array('success' => false));
|
||||
}
|
||||
|
||||
$renamed = NativeWikiPage::rename_page([
|
||||
'channel_id' => $owner['channel_id'],
|
||||
'observer_hash' => $observer_hash,
|
||||
'resource_id' => $resource_id,
|
||||
'pageUrlName' => $pageUrlName,
|
||||
'pageNewName' => $pageNewName
|
||||
]);
|
||||
if($renamed['success']) {
|
||||
$commit = NativeWikiPage::commit([
|
||||
'channel_id' => $owner['channel_id'],
|
||||
'commit_msg' => 'Renamed ' . NativeWiki::name_decode($pageUrlName) . ' to ' . $renamed['page']['htmlName'],
|
||||
'resource_id' => $resource_id,
|
||||
'observer_hash' => $observer_hash,
|
||||
'pageUrlName' => $pageNewName
|
||||
]);
|
||||
if($commit['success']) {
|
||||
NativeWiki::sync_a_wiki_item($owner['channel_id'], $commit['item_id'], $resource_id);
|
||||
json_return_and_die(array('name' => $renamed['page'], 'message' => 'Wiki git repo commit made', 'success' => true));
|
||||
}
|
||||
else {
|
||||
json_return_and_die(array('message' => 'Error making git commit','success' => false));
|
||||
}
|
||||
}
|
||||
else {
|
||||
json_return_and_die(array('message' => 'Error renaming page', 'success' => false));
|
||||
}
|
||||
}
|
||||
|
||||
//notice( t('You must be authenticated.'));
|
||||
json_return_and_die(array('message' => t('You must be authenticated.'), 'success' => false));
|
||||
|
||||
}
|
||||
}
|
||||
@@ -8,21 +8,21 @@ use Zotlabs\Web\HTTPSig;
|
||||
class Zot_probe extends \Zotlabs\Web\Controller {
|
||||
|
||||
function get() {
|
||||
|
||||
|
||||
$o .= '<h3>Zot6 Probe Diagnostic</h3>';
|
||||
|
||||
|
||||
$o .= '<form action="zot_probe" method="get">';
|
||||
$o .= 'Lookup URI: <input type="text" style="width: 250px;" name="addr" value="' . $_GET['addr'] .'" /><br>';
|
||||
$o .= '<input type="submit" name="submit" value="Submit" /></form>';
|
||||
|
||||
$o .= '<input type="submit" name="submit" value="Submit" /></form>';
|
||||
|
||||
$o .= '<br /><br />';
|
||||
|
||||
|
||||
if(x($_GET,'addr')) {
|
||||
$addr = $_GET['addr'];
|
||||
|
||||
|
||||
$x = Zotfinger::exec($addr);
|
||||
|
||||
|
||||
$o .= '<pre>' . htmlspecialchars(print_array($x)) . '</pre>';
|
||||
|
||||
$headers = 'Accept: application/x-zot+json, application/jrd+json, application/json';
|
||||
@@ -38,10 +38,10 @@ class Zot_probe extends \Zotlabs\Web\Controller {
|
||||
|
||||
$o .= '<pre>' . htmlspecialchars(json_encode(json_decode($x['body']),JSON_PRETTY_PRINT|JSON_UNESCAPED_SLASHES)) . '</pre>' . EOL;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
return $o;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
namespace Zotlabs\Photo;
|
||||
|
||||
use Zotlabs\Lib\Hashpath;
|
||||
use Zotlabs\Lib\Hashpath;
|
||||
|
||||
/**
|
||||
* @brief Abstract photo driver class.
|
||||
@@ -344,19 +344,13 @@ abstract class PhotoDriver {
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
* PHP 7.2 allows you to use a stream resource, which should reduce/avoid
|
||||
* memory exhaustion on large images.
|
||||
*/
|
||||
|
||||
if(version_compare(PHP_VERSION, '7.2.0') >= 0) {
|
||||
$f = @fopen($filename, 'rb');
|
||||
} else {
|
||||
$f = $filename;
|
||||
}
|
||||
$f = @fopen($filename, 'rb');
|
||||
|
||||
if($f) {
|
||||
return @exif_read_data($f, null, true);
|
||||
// exif_read_data accepts a stream resource in php > 7.2
|
||||
$x = @exif_read_data($f, null, true);
|
||||
fclose($f);
|
||||
return $x;
|
||||
}
|
||||
|
||||
return false;
|
||||
@@ -427,30 +421,30 @@ abstract class PhotoDriver {
|
||||
|
||||
$p = [];
|
||||
|
||||
$p['aid'] = ((intval($arr['aid'])) ? intval($arr['aid']) : 0);
|
||||
$p['uid'] = ((intval($arr['uid'])) ? intval($arr['uid']) : 0);
|
||||
$p['xchan'] = (($arr['xchan']) ? $arr['xchan'] : '');
|
||||
$p['resource_id'] = (($arr['resource_id']) ? $arr['resource_id'] : '');
|
||||
$p['filename'] = (($arr['filename']) ? $arr['filename'] : '');
|
||||
$p['mimetype'] = (($arr['mimetype']) ? $arr['mimetype'] : $this->getType());
|
||||
$p['album'] = (($arr['album']) ? $arr['album'] : '');
|
||||
$p['imgscale'] = ((intval($arr['imgscale'])) ? intval($arr['imgscale']) : 0);
|
||||
$p['allow_cid'] = (($arr['allow_cid']) ? $arr['allow_cid'] : '');
|
||||
$p['allow_gid'] = (($arr['allow_gid']) ? $arr['allow_gid'] : '');
|
||||
$p['deny_cid'] = (($arr['deny_cid']) ? $arr['deny_cid'] : '');
|
||||
$p['deny_gid'] = (($arr['deny_gid']) ? $arr['deny_gid'] : '');
|
||||
$p['edited'] = (($arr['edited']) ? $arr['edited'] : datetime_convert());
|
||||
$p['title'] = (($arr['title']) ? $arr['title'] : '');
|
||||
$p['description'] = (($arr['description']) ? $arr['description'] : '');
|
||||
$p['photo_usage'] = intval($arr['photo_usage']);
|
||||
$p['os_storage'] = intval($arr['os_storage']);
|
||||
$p['os_path'] = $arr['os_path'];
|
||||
$p['os_syspath'] = ((array_key_exists('os_syspath', $arr)) ? $arr['os_syspath'] : '');
|
||||
$p['display_path'] = (($arr['display_path']) ? $arr['display_path'] : '');
|
||||
$p['width'] = (($arr['width']) ? $arr['width'] : $this->getWidth());
|
||||
$p['height'] = (($arr['height']) ? $arr['height'] : $this->getHeight());
|
||||
$p['expires'] = (($arr['expires']) ? $arr['expires'] : gmdate('Y-m-d H:i:s', time() + get_config('system', 'photo_cache_time', 86400)));
|
||||
$p['profile'] = ((array_key_exists('profile', $arr)) ? intval($arr['profile']) : 0);
|
||||
$p['aid'] = $arr['aid'] ?? 0;
|
||||
$p['uid'] = $arr['uid'] ?? 0;
|
||||
$p['xchan'] = $arr['xchan'] ?? '';
|
||||
$p['resource_id'] = $arr['resource_id'] ?? '';
|
||||
$p['filename'] = $arr['filename'] ?? '';
|
||||
$p['mimetype'] = $arr['mimetype'] ?? $this->getType();
|
||||
$p['album'] = $arr['album'] ?? '';
|
||||
$p['imgscale'] = $arr['imgscale'] ?? 0;
|
||||
$p['allow_cid'] = $arr['allow_cid'] ?? '';
|
||||
$p['allow_gid'] = $arr['allow_gid'] ?? '';
|
||||
$p['deny_cid'] = $arr['deny_cid'] ?? '';
|
||||
$p['deny_gid'] = $arr['deny_gid'] ?? '';
|
||||
$p['edited'] = $arr['edited'] ?? datetime_convert();
|
||||
$p['title'] = $arr['title'] ?? '';
|
||||
$p['description'] = $arr['description'] ?? '';
|
||||
$p['photo_usage'] = $arr['photo_usage'] ?? PHOTO_NORMAL;
|
||||
$p['os_storage'] = $arr['os_storage'] ?? 1;
|
||||
$p['os_path'] = $arr['os_path'] ?? '';
|
||||
$p['os_syspath'] = $arr['os_syspath'] ?? '';
|
||||
$p['display_path'] = $arr['display_path'] ?? '';
|
||||
$p['width'] = $arr['width'] ?? $this->getWidth();
|
||||
$p['height'] = $arr['height'] ?? $this->getHeight();
|
||||
$p['expires'] = $arr['expires'] ?? gmdate('Y-m-d H:i:s', time() + get_config('system', 'photo_cache_time', 86400));
|
||||
$p['profile'] = $arr['profile'] ?? 0;
|
||||
|
||||
if(! intval($p['imgscale']))
|
||||
logger('save: ' . print_r($arr, true), LOGGER_DATA);
|
||||
@@ -458,7 +452,7 @@ abstract class PhotoDriver {
|
||||
$x = q("select id, created from photo where resource_id = '%s' and uid = %d and xchan = '%s' and imgscale = %d limit 1", dbesc($p['resource_id']), intval($p['uid']), dbesc($p['xchan']), intval($p['imgscale']));
|
||||
|
||||
if($x) {
|
||||
$p['created'] = (($x['created']) ? $x['created'] : $p['edited']);
|
||||
$p['created'] = $x['created'] ?? $p['edited'];
|
||||
$r = q("UPDATE photo set
|
||||
aid = %d,
|
||||
uid = %d,
|
||||
@@ -489,16 +483,16 @@ abstract class PhotoDriver {
|
||||
where id = %d",
|
||||
intval($p['aid']), intval($p['uid']), dbesc($p['xchan']), dbesc($p['resource_id']), dbescdate($p['created']), dbescdate($p['edited']), dbesc(basename($p['filename'])), dbesc($p['mimetype']), dbesc($p['album']), intval($p['height']), intval($p['width']), (intval($p['os_storage']) ? dbescbin($p['os_syspath']) : dbescbin($this->imageString())), intval($p['os_storage']), (intval($p['os_storage']) ? @filesize($p['os_syspath']) : strlen($this->imageString())), intval($p['imgscale']), intval($p['photo_usage']), dbesc($p['title']), dbesc($p['description']), dbesc($p['os_path']), dbesc($p['display_path']), dbesc($p['allow_cid']), dbesc($p['allow_gid']), dbesc($p['deny_cid']), dbesc($p['deny_gid']), dbescdate($p['expires']), intval($p['profile']), intval($x[0]['id']));
|
||||
} else {
|
||||
$p['created'] = (($arr['created']) ? $arr['created'] : $p['edited']);
|
||||
$p['created'] = $arr['created'] ?? $p['edited'];
|
||||
$r = q("INSERT INTO photo
|
||||
( aid, uid, xchan, resource_id, created, edited, filename, mimetype, album, height, width, content, os_storage, filesize, imgscale, photo_usage, title, description, os_path, display_path, allow_cid, allow_gid, deny_cid, deny_gid, expires, profile )
|
||||
VALUES ( %d, %d, '%s', '%s', '%s', '%s', '%s', '%s', '%s', %d, %d, '%s', %d, %d, %d, %d, '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', %d)", intval($p['aid']), intval($p['uid']), dbesc($p['xchan']), dbesc($p['resource_id']), dbescdate($p['created']), dbescdate($p['edited']), dbesc(basename($p['filename'])), dbesc($p['mimetype']), dbesc($p['album']), intval($p['height']), intval($p['width']), (intval($p['os_storage']) ? dbescbin($p['os_syspath']) : dbescbin($this->imageString())), intval($p['os_storage']), (intval($p['os_storage']) ? @filesize($p['os_syspath']) : strlen($this->imageString())), intval($p['imgscale']), intval($p['photo_usage']), dbesc($p['title']), dbesc($p['description']), dbesc($p['os_path']), dbesc($p['display_path']), dbesc($p['allow_cid']), dbesc($p['allow_gid']), dbesc($p['deny_cid']), dbesc($p['deny_gid']), dbescdate($p['expires']), intval($p['profile']));
|
||||
}
|
||||
logger('Photo save imgscale ' . $p['imgscale'] . ' returned ' . intval($r));
|
||||
logger('Photo save imgscale ' . $p['imgscale'] . ' returned: ' . (($r) ? 1 : 0));
|
||||
|
||||
return $r;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief Stores thumbnail to database or filesystem.
|
||||
*
|
||||
@@ -530,13 +524,13 @@ abstract class PhotoDriver {
|
||||
}
|
||||
else
|
||||
$arr['os_storage'] = 0;
|
||||
|
||||
|
||||
if(! $this->save($arr)) {
|
||||
if(array_key_exists('os_syspath', $arr))
|
||||
@unlink($arr['os_syspath']);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -219,7 +219,8 @@ class Comanche {
|
||||
* - [if $config.system.foo {} baz] which will check if 'baz' is an array element in get_config('system','foo')
|
||||
* - [if $config.system.foo {*} baz] which will check if 'baz' is an array key in get_config('system','foo')
|
||||
* - [if $config.system.foo] which will check for a return of a true condition for get_config('system','foo');
|
||||
*
|
||||
* - [if !$config.system.foo] which will check for a return of a false condition for get_config('system','foo');
|
||||
*
|
||||
* The values 0, '', an empty array, and an unset value will all evaluate to false.
|
||||
*
|
||||
* @param int|string $s
|
||||
@@ -299,6 +300,15 @@ class Comanche {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Ordering of this check (for falsiness) with relation to the following one (check for truthiness) is important.
|
||||
if (preg_match('/[\!\$](.*?)$/', $s, $matches)) {
|
||||
$x = $this->get_condition_var($matches[1]);
|
||||
if (!$x) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
if(preg_match('/[\$](.*?)$/',$s,$matches)) {
|
||||
$x = $this->get_condition_var($matches[1]);
|
||||
if($x)
|
||||
@@ -572,7 +582,7 @@ class Comanche {
|
||||
require_once('widget/' . trim($name) . '.php');
|
||||
elseif(file_exists('widget/' . trim($name) . '/' . trim($name) . '.php'))
|
||||
require_once('widget/' . trim($name) . '/' . trim($name) . '.php');
|
||||
|
||||
|
||||
if(! function_exists($func)) {
|
||||
$theme_widget = $func . '.php';
|
||||
if(theme_include($theme_widget)) {
|
||||
@@ -640,7 +650,8 @@ class Comanche {
|
||||
$cnt = preg_match_all("/\[widget=(.*?)\](.*?)\[\/widget\]/ism", $s, $matches, PREG_SET_ORDER);
|
||||
if($cnt) {
|
||||
foreach($matches as $mtch) {
|
||||
$s = str_replace($mtch[0],$this->widget(trim($mtch[1]),$mtch[2]),$s);
|
||||
|
||||
$s = str_replace((string)$mtch[0], (string)$this->widget(trim((string)$mtch[1]), (string)$mtch[2]), $s);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
23
Zotlabs/Update/_1252.php
Normal file
23
Zotlabs/Update/_1252.php
Normal file
@@ -0,0 +1,23 @@
|
||||
<?php
|
||||
|
||||
namespace Zotlabs\Update;
|
||||
|
||||
class _1252 {
|
||||
|
||||
function run() {
|
||||
|
||||
dbq("START TRANSACTION");
|
||||
|
||||
$r = dbq("DELETE FROM app WHERE app_plugin = 'mail' AND app_system = 1");
|
||||
|
||||
if($r) {
|
||||
dbq("COMMIT");
|
||||
return UPDATE_SUCCESS;
|
||||
}
|
||||
|
||||
dbq("ROLLBACK");
|
||||
return UPDATE_FAILED;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
23
Zotlabs/Update/_1253.php
Normal file
23
Zotlabs/Update/_1253.php
Normal file
@@ -0,0 +1,23 @@
|
||||
<?php
|
||||
|
||||
namespace Zotlabs\Update;
|
||||
|
||||
class _1253 {
|
||||
|
||||
function run() {
|
||||
|
||||
dbq("START TRANSACTION");
|
||||
|
||||
$r = dbq("DELETE FROM app WHERE app_name IN ('Wiki', 'Cards', 'Articles') AND app_plugin = ''");
|
||||
|
||||
if($r) {
|
||||
dbq("COMMIT");
|
||||
return UPDATE_SUCCESS;
|
||||
}
|
||||
|
||||
dbq("ROLLBACK");
|
||||
return UPDATE_FAILED;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -20,7 +20,7 @@ class HTTPHeaders {
|
||||
}
|
||||
}
|
||||
else {
|
||||
if($this->in_progress['k']) {
|
||||
if(isset($this->in_progress['k'])) {
|
||||
$this->parsed[] = [ $this->in_progress['k'] => $this->in_progress['v'] ];
|
||||
$this->in_progress = [];
|
||||
}
|
||||
@@ -30,7 +30,7 @@ class HTTPHeaders {
|
||||
}
|
||||
|
||||
}
|
||||
if($this->in_progress['k']) {
|
||||
if(isset($this->in_progress['k'])) {
|
||||
$this->parsed[] = [ $this->in_progress['k'] => $this->in_progress['v'] ];
|
||||
$this->in_progress = [];
|
||||
}
|
||||
|
||||
@@ -127,6 +127,7 @@ class HTTPSig {
|
||||
if (array_key_exists($h, $headers)) {
|
||||
$signed_data .= $h . ': ' . $headers[$h] . "\n";
|
||||
}
|
||||
|
||||
if ($h === 'date') {
|
||||
$d = new DateTime($headers[$h]);
|
||||
$d->setTimeZone(new DateTimeZone('UTC'));
|
||||
@@ -142,20 +143,35 @@ class HTTPSig {
|
||||
$signed_data = rtrim($signed_data, "\n");
|
||||
|
||||
$algorithm = null;
|
||||
|
||||
if ($sig_block['algorithm'] === 'rsa-sha256') {
|
||||
$algorithm = 'sha256';
|
||||
}
|
||||
|
||||
if ($sig_block['algorithm'] === 'rsa-sha512') {
|
||||
$algorithm = 'sha512';
|
||||
}
|
||||
|
||||
if (!array_key_exists('keyId', $sig_block))
|
||||
if (!array_key_exists('keyId', $sig_block)) {
|
||||
return $result;
|
||||
}
|
||||
|
||||
$result['signer'] = $sig_block['keyId'];
|
||||
|
||||
$cached_key = self::get_key($key, $keytype, $result['signer']);
|
||||
|
||||
if ($sig_block['algorithm'] === 'hs2019') {
|
||||
if (isset($cached_key['algorithm'])) {
|
||||
if (strpos($cached_key['algorithm'], 'rsa-sha256') !== false) {
|
||||
$algorithm = 'sha256';
|
||||
}
|
||||
|
||||
if (strpos($cached_key['algorithm'], 'rsa-sha512') !== false) {
|
||||
$algorithm = 'sha512';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!($cached_key && $cached_key['public_key'])) {
|
||||
return $result;
|
||||
}
|
||||
@@ -243,7 +259,12 @@ class HTTPSig {
|
||||
}
|
||||
}
|
||||
|
||||
$key = self::get_activitystreams_key($id, $force);
|
||||
$delete = false;
|
||||
if ($keytype === 'delete') {
|
||||
$delete = true;
|
||||
}
|
||||
|
||||
$key = self::get_activitystreams_key($id, $force, $delete);
|
||||
|
||||
return $key;
|
||||
|
||||
@@ -274,10 +295,11 @@ class HTTPSig {
|
||||
* false if no pub key found, otherwise return an array with the pub key
|
||||
*/
|
||||
|
||||
static function get_activitystreams_key($id, $force = false) {
|
||||
static function get_activitystreams_key($id, $force = false, $delete = false) {
|
||||
|
||||
// Check the local cache first, but remove any fragments like #main-key since these won't be present in our cached data
|
||||
$url = ((strpos($id, '#')) ? substr($id, 0, strpos($id, '#')) : $id);
|
||||
$best = [];
|
||||
|
||||
// $force is used to ignore the local cache and only use the remote data; for instance the cached key might be stale
|
||||
if (!$force) {
|
||||
@@ -290,18 +312,50 @@ class HTTPSig {
|
||||
$best = Libzot::zot_record_preferred($x);
|
||||
}
|
||||
if ($best && $best['xchan_pubkey']) {
|
||||
return ['portable_id' => $best['xchan_hash'], 'public_key' => $best['xchan_pubkey'], 'hubloc' => $best];
|
||||
return ['portable_id' => $best['xchan_hash'], 'public_key' => $best['xchan_pubkey'], 'algorithm' => get_xconfig($best['xchan_hash'], 'system', 'signing_algorithm'), 'hubloc' => $best];
|
||||
}
|
||||
}
|
||||
|
||||
if ($delete) {
|
||||
// If we received a delete and we do not have the record cached,
|
||||
// we probably never saw this actor. Do not try to fetch it now.
|
||||
return false;
|
||||
}
|
||||
|
||||
// The record wasn't in cache. Fetch it now.
|
||||
$r = ActivityStreams::fetch($id);
|
||||
$signatureAlgorithm = EMPTY_STR;
|
||||
|
||||
if ($r) {
|
||||
if (array_key_exists('publicKey', $r) && array_key_exists('publicKeyPem', $r['publicKey']) && array_key_exists('id', $r['publicKey'])) {
|
||||
if ($r['publicKey']['id'] === $id || $r['id'] === $id) {
|
||||
$portable_id = ((array_key_exists('owner', $r['publicKey'])) ? $r['publicKey']['owner'] : EMPTY_STR);
|
||||
return ['public_key' => self::convertKey($r['publicKey']['publicKeyPem']), 'portable_id' => $portable_id, 'hubloc' => []];
|
||||
|
||||
// the w3c sec context has conflicting names and no defined values for this property except
|
||||
// "http://www.w3.org/2000/09/xmldsig#rsa-sha1"
|
||||
|
||||
// Since the names conflict, it could mess up LD-signatures but we will accept both, and at this
|
||||
// time we will only look for the substrings 'rsa-sha256' and 'rsa-sha512' within those properties.
|
||||
// We will also accept a toplevel 'sigAlgorithm' regardless of namespace with the same constraints.
|
||||
// Default to rsa-sha256 if we can't figure out. If they're sending 'hs2019' we have to
|
||||
// look for something.
|
||||
|
||||
if (isset($r['publicKey']['signingAlgorithm'])) {
|
||||
$signatureAlgorithm = $r['publicKey']['signingAlgorithm'];
|
||||
set_xconfig($portable_id, 'system', 'signing_algorithm', $signatureAlgorithm);
|
||||
}
|
||||
|
||||
if (isset($r['publicKey']['signatureAlgorithm'])) {
|
||||
$signatureAlgorithm = $r['publicKey']['signatureAlgorithm'];
|
||||
set_xconfig($portable_id, 'system', 'signing_algorithm', $signatureAlgorithm);
|
||||
}
|
||||
|
||||
if (isset($r['sigAlgorithm'])) {
|
||||
$signatureAlgorithm = $r['sigAlgorithm'];
|
||||
set_xconfig($portable_id, 'system', 'signing_algorithm', $signatureAlgorithm);
|
||||
}
|
||||
|
||||
return ['public_key' => self::convertKey($r['publicKey']['publicKeyPem']), 'portable_id' => $portable_id, 'algorithm' => (($signatureAlgorithm) ? $signatureAlgorithm : 'rsa-sha256'), 'hubloc' => []];
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -321,6 +375,8 @@ class HTTPSig {
|
||||
|
||||
static function get_webfinger_key($id, $force = false) {
|
||||
|
||||
$best = [];
|
||||
|
||||
if (!$force) {
|
||||
$x = q("select * from xchan left join hubloc on xchan_hash = hubloc_hash where hubloc_id_url = '%s' and hubloc_network in ('zot6', 'activitypub') order by hubloc_id desc",
|
||||
dbesc($id)
|
||||
@@ -331,7 +387,7 @@ class HTTPSig {
|
||||
}
|
||||
|
||||
if ($best && $best['xchan_pubkey']) {
|
||||
return ['portable_id' => $best['xchan_hash'], 'public_key' => $best['xchan_pubkey'], 'hubloc' => $best];
|
||||
return ['portable_id' => $best['xchan_hash'], 'public_key' => $best['xchan_pubkey'], 'algorithm' => get_xconfig($best['xchan_hash'], 'system', 'signing_algorithm'), 'hubloc' => $best];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -367,6 +423,9 @@ class HTTPSig {
|
||||
*/
|
||||
|
||||
static function get_zotfinger_key($id, $force = false) {
|
||||
|
||||
$best = [];
|
||||
|
||||
if (!$force) {
|
||||
$x = q("select * from xchan left join hubloc on xchan_hash = hubloc_hash where hubloc_id_url = '%s' and hubloc_network = 'zot6' order by hubloc_id desc",
|
||||
dbesc($id)
|
||||
@@ -377,7 +436,7 @@ class HTTPSig {
|
||||
}
|
||||
|
||||
if ($best && $best['xchan_pubkey']) {
|
||||
return ['portable_id' => $best['xchan_hash'], 'public_key' => $best['xchan_pubkey'], 'hubloc' => $best];
|
||||
return ['portable_id' => $best['xchan_hash'], 'public_key' => $best['xchan_pubkey'], 'algorithm' => get_xconfig($best['xchan_hash'], 'system', 'signing_algorithm'), 'hubloc' => $best];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -449,6 +508,12 @@ class HTTPSig {
|
||||
|
||||
$x = self::sign($head, $prvkey, $alg);
|
||||
|
||||
// TODO: should we default to hs2019? cavage-http-signatures-12 is not very wide spread yet
|
||||
|
||||
if (get_config('system', 'use_hs2019', false) && $algorithm === 'rsa-sha256') {
|
||||
$algorithm = 'hs2019';
|
||||
}
|
||||
|
||||
$headerval = 'keyId="' . $keyid . '",algorithm="' . $algorithm . '",headers="' . $x['headers'] . '",signature="' . $x['signature'] . '"';
|
||||
|
||||
if ($encryption) {
|
||||
@@ -516,11 +581,14 @@ class HTTPSig {
|
||||
|
||||
if ($head) {
|
||||
foreach ($head as $k => $v) {
|
||||
$headers .= strtolower($k) . ': ' . trim($v) . "\n";
|
||||
$k = strtolower($k);
|
||||
$v = (($v) ? trim($v) : '');
|
||||
|
||||
$headers .= $k . ': ' . $v . "\n";
|
||||
if ($fields)
|
||||
$fields .= ' ';
|
||||
|
||||
$fields .= strtolower($k);
|
||||
$fields .= $k;
|
||||
}
|
||||
// strip the trailing linefeed
|
||||
$headers = rtrim($headers, "\n");
|
||||
|
||||
@@ -6,7 +6,7 @@ namespace Zotlabs\Web;
|
||||
class SessionHandler implements \SessionHandlerInterface {
|
||||
|
||||
|
||||
function open ($s, $n) {
|
||||
function open ($s, $n) : bool {
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -15,7 +15,7 @@ class SessionHandler implements \SessionHandlerInterface {
|
||||
// some which call read explicitly and some that do not. So we call it explicitly
|
||||
// just after sid regeneration to force a record to exist.
|
||||
|
||||
function read ($id) {
|
||||
function read ($id) : string {
|
||||
|
||||
if($id) {
|
||||
$r = q("SELECT sess_data FROM session WHERE sid= '%s'", dbesc($id));
|
||||
@@ -36,7 +36,7 @@ class SessionHandler implements \SessionHandlerInterface {
|
||||
}
|
||||
|
||||
|
||||
function write ($id, $data) {
|
||||
function write ($id, $data) : bool {
|
||||
|
||||
// Pretend everything is hunky-dory, even though it isn't.
|
||||
// There probably isn't anything we can do about it in any event.
|
||||
@@ -49,9 +49,9 @@ class SessionHandler implements \SessionHandlerInterface {
|
||||
|
||||
// Unless we authenticate somehow, only keep a session for 5 minutes
|
||||
// The viewer can extend this by performing any web action using the
|
||||
// original cookie, but this allows us to cleanup the hundreds or
|
||||
// original cookie, but this allows us to cleanup the hundreds or
|
||||
// thousands of empty sessions left around from web crawlers which are
|
||||
// assigned cookies on each page that they never use.
|
||||
// assigned cookies on each page that they never use.
|
||||
|
||||
$expire = time() + 300;
|
||||
|
||||
@@ -74,19 +74,19 @@ class SessionHandler implements \SessionHandlerInterface {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
function close() {
|
||||
|
||||
function close() : bool {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
function destroy ($id) {
|
||||
function destroy ($id) : bool {
|
||||
q("DELETE FROM session WHERE sid = '%s'", dbesc($id));
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
function gc($expire) {
|
||||
function gc($expire) : int {
|
||||
q("DELETE FROM session WHERE expire < %d", dbesc(time()));
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -58,12 +58,13 @@ class WebServer {
|
||||
if((x($_GET,'zid')) && (! \App::$install)) {
|
||||
\App::$query_string = strip_zids(\App::$query_string);
|
||||
if(! local_channel()) {
|
||||
if ($_SESSION['my_address']!=$_GET['zid']) {
|
||||
if (!isset($_SESSION['my_address']) || $_SESSION['my_address'] != $_GET['zid']) {
|
||||
$_SESSION['my_address'] = $_GET['zid'];
|
||||
$_SESSION['authenticated'] = 0;
|
||||
}
|
||||
if(! $_SESSION['authenticated'])
|
||||
if(!$_SESSION['authenticated']) {
|
||||
zid_init();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -107,7 +108,8 @@ class WebServer {
|
||||
|
||||
$Router->Dispatch();
|
||||
|
||||
$this->set_homebase();
|
||||
// TODO: this is not used for anything atm and messes up comanche templates by adding some javascript
|
||||
//$this->set_homebase();
|
||||
|
||||
// now that we've been through the module content, see if the page reported
|
||||
// a permission problem and if so, a 403 response would seem to be in order.
|
||||
|
||||
@@ -1,5 +1,10 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* * Name: Activity
|
||||
* * Description: Shows the unseen activity count per contact
|
||||
*/
|
||||
|
||||
namespace Zotlabs\Widget;
|
||||
|
||||
class Activity {
|
||||
|
||||
@@ -1,5 +1,12 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* * Name: Activity filters
|
||||
* * Description: Filters for the network stream
|
||||
* * Requires: network
|
||||
*/
|
||||
|
||||
|
||||
namespace Zotlabs\Widget;
|
||||
|
||||
use App;
|
||||
|
||||
@@ -2,6 +2,12 @@
|
||||
|
||||
namespace Zotlabs\Widget;
|
||||
|
||||
/**
|
||||
* * Name: Activity order
|
||||
* * Description: Order the network stream by posted date, last commented or by date unthreaded
|
||||
* * Requires: network
|
||||
*/
|
||||
|
||||
class Activity_order {
|
||||
|
||||
function widget($arr) {
|
||||
@@ -22,7 +28,7 @@ class Activity_order {
|
||||
switch($_GET['order']){
|
||||
case 'post':
|
||||
$postord_active = 'active';
|
||||
set_pconfig(local_channel(), 'mod_network', 'order', 1);
|
||||
set_pconfig(local_channel(), 'mod_network', 'order', 1);
|
||||
break;
|
||||
case 'comment':
|
||||
$commentord_active = 'active';
|
||||
|
||||
@@ -1,5 +1,10 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* * Name: Admin menu
|
||||
* * Requires: admin
|
||||
*/
|
||||
|
||||
namespace Zotlabs\Widget;
|
||||
|
||||
class Admin {
|
||||
|
||||
@@ -1,5 +1,11 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* * Name: Affinity Tool
|
||||
* * Description: Filter the network stream by affinity, requires the Affinity Tool App
|
||||
* * Requires: network
|
||||
*/
|
||||
|
||||
namespace Zotlabs\Widget;
|
||||
|
||||
use Zotlabs\Lib\Apps;
|
||||
@@ -13,7 +19,7 @@ class Affinity {
|
||||
|
||||
if(! Apps::system_app_installed(local_channel(),'Affinity Tool'))
|
||||
return;
|
||||
|
||||
|
||||
$default_cmin = ((Apps::system_app_installed(local_channel(),'Affinity Tool')) ? get_pconfig(local_channel(),'affinity','cmin',0) : 0);
|
||||
$default_cmax = ((Apps::system_app_installed(local_channel(),'Affinity Tool')) ? get_pconfig(local_channel(),'affinity','cmax',99) : 99);
|
||||
|
||||
@@ -54,7 +60,7 @@ class Affinity {
|
||||
'$refresh' => t('Refresh'),
|
||||
'$labels' => $label_str,
|
||||
));
|
||||
|
||||
|
||||
$arr = array('html' => $x);
|
||||
call_hooks('main_slider',$arr);
|
||||
|
||||
@@ -63,4 +69,4 @@ class Affinity {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -1,5 +1,11 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* * Name: Album
|
||||
* * Description: Displays an album with a title which can be defined via the 'album' and 'title' variable
|
||||
* * Requires: channel, articles, cards, wiki
|
||||
*/
|
||||
|
||||
namespace Zotlabs\Widget;
|
||||
|
||||
require_once('include/attach.php');
|
||||
@@ -99,7 +105,7 @@ class Album {
|
||||
'$upload_form' => $upload_form,
|
||||
'$usage' => $usage_message
|
||||
));
|
||||
|
||||
|
||||
return $o;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,11 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* * Name: App categories
|
||||
* * Description: Shows a menu with various app categories
|
||||
* * Requires: apps
|
||||
*/
|
||||
|
||||
namespace Zotlabs\Widget;
|
||||
|
||||
class Appcategories {
|
||||
|
||||
@@ -1,5 +1,11 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* * Name: App cloud
|
||||
* * Description: Shows a cloud with various app categories
|
||||
* * Requires: apps
|
||||
*/
|
||||
|
||||
namespace Zotlabs\Widget;
|
||||
|
||||
class Appcloud {
|
||||
|
||||
@@ -1,5 +1,11 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* * Name: App store menu
|
||||
* * Description: Shows a menu with links to installed and available apps
|
||||
* * Requires: apps
|
||||
*/
|
||||
|
||||
namespace Zotlabs\Widget;
|
||||
|
||||
|
||||
|
||||
@@ -1,5 +1,11 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* * Name: Archive
|
||||
* * Description: A menu with links to content sorted by years and months
|
||||
* * Requires: channel, articles, cards
|
||||
*/
|
||||
|
||||
namespace Zotlabs\Widget;
|
||||
|
||||
|
||||
|
||||
@@ -1,14 +1,15 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* * Name: Bookmarked chats
|
||||
* * Description: A menu with bookmarked chats
|
||||
*/
|
||||
|
||||
namespace Zotlabs\Widget;
|
||||
|
||||
class Bookmarkedchats {
|
||||
|
||||
function widget($arr) {
|
||||
|
||||
if(! feature_enabled(\App::$profile['profile_uid'],'ajaxchat'))
|
||||
return '';
|
||||
|
||||
$h = get_observer_hash();
|
||||
if(! $h)
|
||||
return;
|
||||
|
||||
@@ -2,6 +2,13 @@
|
||||
|
||||
namespace Zotlabs\Widget;
|
||||
|
||||
/**
|
||||
* * Name: Category cloud
|
||||
* * Description: Display category links in a cloud
|
||||
* * Requires: channel, cards, articles
|
||||
*/
|
||||
|
||||
|
||||
class Catcloud {
|
||||
|
||||
function widget($arr) {
|
||||
@@ -22,7 +29,7 @@ class Catcloud {
|
||||
return card_catblock(\App::$profile['profile_uid'], $limit, '', \App::$profile['channel_hash']);
|
||||
|
||||
case 'articles':
|
||||
|
||||
|
||||
if(! perm_is_allowed(\App::$profile['profile_uid'], get_observer_hash(), 'view_pages'))
|
||||
return '';
|
||||
|
||||
|
||||
@@ -1,5 +1,11 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* * Name: Category cloud wall
|
||||
* * Description: Display category links in a cloud restricted to wall posts
|
||||
* * Requires: channel
|
||||
*/
|
||||
|
||||
namespace Zotlabs\Widget;
|
||||
|
||||
class Catcloud_wall {
|
||||
|
||||
@@ -1,5 +1,11 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* * Name: Categories
|
||||
* * Description: Display a menu with links to categories
|
||||
* * Requires: channel, articles, cards, cloud
|
||||
*/
|
||||
|
||||
namespace Zotlabs\Widget;
|
||||
|
||||
use App;
|
||||
@@ -11,36 +17,22 @@ class Categories {
|
||||
|
||||
function widget($arr) {
|
||||
|
||||
$cards = ((array_key_exists('cards',$arr) && $arr['cards']) ? true : false);
|
||||
|
||||
if(($cards) && (! Apps::system_app_installed(App::$profile['profile_uid'], 'Cards')))
|
||||
return '';
|
||||
|
||||
$articles = ((array_key_exists('articles',$arr) && $arr['articles']) ? true : false);
|
||||
|
||||
if(($articles) && (! Apps::system_app_installed(App::$profile['profile_uid'],'Articles')))
|
||||
return '';
|
||||
|
||||
$files = ((array_key_exists('files',$arr) && $arr['files']) ? true : false);
|
||||
|
||||
if((! App::$profile['profile_uid'])
|
||||
|| (! perm_is_allowed(App::$profile['profile_uid'],get_observer_hash(),(($cards || $articles) ? 'view_pages' : 'view_stream')))) {
|
||||
if(!App::$profile['profile_uid'] || !perm_is_allowed(App::$profile['profile_uid'], get_observer_hash(), 'view_stream')) {
|
||||
return '';
|
||||
}
|
||||
|
||||
$cat = ((x($_REQUEST,'cat')) ? htmlspecialchars($_REQUEST['cat'],ENT_COMPAT,'UTF-8') : '');
|
||||
$srchurl = (($cards) ? App::$argv[0] . '/' . App::$argv[1] : App::$query_string);
|
||||
$srchurl = rtrim(preg_replace('/cat\=[^\&].*?(\&|$)/is','',$srchurl),'&');
|
||||
$srchurl = str_replace(array('?f=','&f=', '/?'),array('', '', ''),$srchurl);
|
||||
$cat = ((x($_REQUEST, 'cat')) ? htmlspecialchars($_REQUEST['cat'], ENT_COMPAT, 'UTF-8') : '');
|
||||
$srchurl = App::$query_string;
|
||||
$srchurl = rtrim(preg_replace('/cat\=[^\&].*?(\&|$)/is', '', $srchurl), '&');
|
||||
$srchurl = str_replace(['?f=','&f=', '/?'], ['', '', ''], $srchurl);
|
||||
|
||||
if($cards)
|
||||
return cardcategories_widget($srchurl, $cat);
|
||||
elseif($articles)
|
||||
return articlecategories_widget($srchurl, $cat);
|
||||
elseif($files)
|
||||
if($files) {
|
||||
return filecategories_widget($srchurl, $cat);
|
||||
else
|
||||
return categories_widget($srchurl, $cat);
|
||||
}
|
||||
|
||||
return categories_widget($srchurl, $cat);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,9 +1,13 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* * Name: CalDAV/CardDAV tools
|
||||
* * Description: A widget with various CalDAV and CardDAV tools
|
||||
* * Requires: cdav
|
||||
*/
|
||||
|
||||
namespace Zotlabs\Widget;
|
||||
|
||||
|
||||
|
||||
class Cdav {
|
||||
|
||||
function widget() {
|
||||
@@ -164,7 +168,7 @@ class Cdav {
|
||||
'uri' => $sabreabook['uri'],
|
||||
'displayname' => $sabreabook['{DAV:}displayname'],
|
||||
'id' => $sabreabook['id']
|
||||
|
||||
|
||||
];
|
||||
}
|
||||
|
||||
|
||||
250
Zotlabs/Widget/Channel_activities.php
Normal file
250
Zotlabs/Widget/Channel_activities.php
Normal file
@@ -0,0 +1,250 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* * Name: Channel Activity
|
||||
* * Description: A widget that provides an overview of channels that require your attention and quick links to content that you have recently created or edited
|
||||
*/
|
||||
|
||||
namespace Zotlabs\Widget;
|
||||
|
||||
use App;
|
||||
use Zotlabs\Lib\Apps;
|
||||
|
||||
class Channel_activities {
|
||||
|
||||
public static $activities = [];
|
||||
public static $uid = null;
|
||||
public static $limit = 3;
|
||||
public static $channel = [];
|
||||
|
||||
public static function widget($arr) {
|
||||
if (!local_channel()) {
|
||||
return EMPTY_STR;
|
||||
}
|
||||
|
||||
self::$uid = local_channel();
|
||||
self::$channel = App::get_channel();
|
||||
|
||||
$o = '<div id="channel-activities" class="d-none overflow-hidden">';
|
||||
$o .= '<h2 class="mb-4">Welcome ' . self::$channel['channel_name'] . '!</h2>';
|
||||
//$o .= 'Last login date: ' . get_pconfig(self::$uid, 'system', 'stored_login_date') . ' from ' . get_pconfig(self::$uid, 'system', 'stored_login_addr');
|
||||
|
||||
self::get_photos_activity();
|
||||
self::get_files_activity();
|
||||
self::get_webpages_activity();
|
||||
self::get_channels_activity();
|
||||
|
||||
$hookdata = [
|
||||
'channel' => self::$channel,
|
||||
'activities' => self::$activities,
|
||||
'limit' => self::$limit
|
||||
];
|
||||
|
||||
call_hooks('channel_activities_widget', $hookdata);
|
||||
|
||||
if (!$hookdata['activities']) {
|
||||
$o .= '<h3>No recent activity to display</h3>';
|
||||
$o .= '</div>';
|
||||
return $o;
|
||||
}
|
||||
|
||||
$keys = array_column($hookdata['activities'], 'date');
|
||||
|
||||
array_multisort($keys, SORT_DESC, $hookdata['activities']);
|
||||
|
||||
foreach($hookdata['activities'] as $a) {
|
||||
$o .= replace_macros(get_markup_template($a['tpl']), [
|
||||
'$url' => $a['url'],
|
||||
'$icon' => $a['icon'],
|
||||
'$label' => $a['label'],
|
||||
'$items' => $a['items']
|
||||
]);
|
||||
}
|
||||
|
||||
$o .= '</div>';
|
||||
|
||||
return $o;
|
||||
}
|
||||
|
||||
private static function get_photos_activity() {
|
||||
|
||||
$r = q("SELECT edited, height, width, imgscale, description, filename, resource_id FROM photo WHERE uid = %d
|
||||
AND photo_usage = 0 AND is_nsfw = 0 AND imgscale = 3
|
||||
ORDER BY edited DESC LIMIT 6",
|
||||
intval(self::$uid)
|
||||
);
|
||||
|
||||
if (!$r) {
|
||||
return;
|
||||
}
|
||||
|
||||
foreach($r as $rr) {
|
||||
$i[] = [
|
||||
'url' => z_root() . '/photos/' . self::$channel['channel_address'] . '/image/' . $rr['resource_id'],
|
||||
'edited' => datetime_convert('UTC', date_default_timezone_get(), $rr['edited']),
|
||||
'width' => $rr['width'],
|
||||
'height' => $rr['height'],
|
||||
'alt' => (($rr['description']) ? $rr['description'] : $rr['filename']),
|
||||
'src' => z_root() . '/photo/' . $rr['resource_id'] . '-' . $rr['imgscale']
|
||||
];
|
||||
}
|
||||
|
||||
self::$activities['photos'] = [
|
||||
'label' => t('Photos'),
|
||||
'icon' => 'photo',
|
||||
'url' => z_root() . '/photos/' . self::$channel['channel_address'],
|
||||
'date' => $r[0]['edited'],
|
||||
'items' => $i,
|
||||
'tpl' => 'channel_activities_photos.tpl'
|
||||
];
|
||||
|
||||
}
|
||||
|
||||
private static function get_files_activity() {
|
||||
|
||||
$r = q("SELECT * FROM attach WHERE uid = %d
|
||||
AND is_dir = 0 AND is_photo = 0
|
||||
ORDER BY edited DESC LIMIT %d",
|
||||
intval(self::$uid),
|
||||
intval(self::$limit)
|
||||
);
|
||||
|
||||
if (!$r) {
|
||||
return;
|
||||
}
|
||||
|
||||
foreach($r as $rr) {
|
||||
$i[] = [
|
||||
'url' => z_root() . '/cloud/' . self::$channel['channel_address'] . '/' . rtrim($rr['display_path'], $rr['filename']) . '#' . $rr['id'],
|
||||
'summary' => $rr['filename'],
|
||||
'footer' => datetime_convert('UTC', date_default_timezone_get(), $rr['edited'])
|
||||
];
|
||||
}
|
||||
|
||||
self::$activities['files'] = [
|
||||
'label' => t('Files'),
|
||||
'icon' => 'folder-open',
|
||||
'url' => z_root() . '/cloud/' . self::$channel['channel_address'],
|
||||
'date' => $r[0]['edited'],
|
||||
'items' => $i,
|
||||
'tpl' => 'channel_activities.tpl'
|
||||
];
|
||||
|
||||
}
|
||||
|
||||
private static function get_webpages_activity() {
|
||||
|
||||
if(!Apps::system_app_installed(self::$uid, 'Webpages')) {
|
||||
return;
|
||||
}
|
||||
|
||||
$r = q("SELECT * FROM iconfig LEFT JOIN item ON iconfig.iid = item.id WHERE item.uid = %d
|
||||
AND iconfig.cat = 'system' AND iconfig.k = 'WEBPAGE' AND item_type = %d
|
||||
ORDER BY item.edited DESC LIMIT %d",
|
||||
intval(self::$uid),
|
||||
intval(ITEM_TYPE_WEBPAGE),
|
||||
intval(self::$limit)
|
||||
);
|
||||
|
||||
if (!$r) {
|
||||
return;
|
||||
}
|
||||
|
||||
foreach($r as $rr) {
|
||||
$summary = html2plain(purify_html(bbcode($rr['body'], ['drop_media' => true, 'tryoembed' => false])), 85, true);
|
||||
if ($summary) {
|
||||
$summary = substr_words(htmlentities($summary, ENT_QUOTES, 'UTF-8', false), 85);
|
||||
}
|
||||
|
||||
$i[] = [
|
||||
'url' => z_root() . '/page/' . self::$channel['channel_address'] . '/' . $rr['v'],
|
||||
'title' => $rr['title'],
|
||||
'summary' => $summary,
|
||||
'footer' => datetime_convert('UTC', date_default_timezone_get(), $rr['edited'])
|
||||
];
|
||||
}
|
||||
|
||||
self::$activities['webpages'] = [
|
||||
'label' => t('Webpages'),
|
||||
'icon' => 'newspaper-o',
|
||||
'url' => z_root() . '/webpages/' . self::$channel['channel_address'],
|
||||
'date' => $r[0]['edited'],
|
||||
'items' => $i,
|
||||
'tpl' => 'channel_activities.tpl'
|
||||
];
|
||||
|
||||
}
|
||||
|
||||
private static function get_channels_activity() {
|
||||
|
||||
$account = App::get_account();
|
||||
|
||||
$r = q("SELECT channel_id, channel_name, xchan_photo_s FROM channel
|
||||
LEFT JOIN xchan ON channel_hash = xchan_hash
|
||||
WHERE channel_account_id = %d
|
||||
AND channel_id != %d AND channel_removed = 0",
|
||||
intval($account['account_id']),
|
||||
intval(self::$uid)
|
||||
);
|
||||
|
||||
if (!$r) {
|
||||
return;
|
||||
}
|
||||
|
||||
$channels_activity = 0;
|
||||
|
||||
foreach($r as$rr) {
|
||||
|
||||
$intros = q("SELECT COUNT(abook_id) AS total FROM abook WHERE abook_channel = %d
|
||||
AND abook_pending = 1 AND abook_self = 0 AND abook_ignored = 0",
|
||||
intval($rr['channel_id'])
|
||||
);
|
||||
|
||||
$notices = q("SELECT COUNT(id) AS total FROM notify WHERE uid = %d AND seen = 0",
|
||||
intval($rr['channel_id'])
|
||||
);
|
||||
|
||||
if (!$intros[0]['total'] && !$notices[0]['total']) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$footer = '';
|
||||
|
||||
if ($intros[0]['total']) {
|
||||
$footer .= intval($intros[0]['total']) . ' ' . tt('new connection', 'new connections', intval($intros[0]['total']), 'noun');
|
||||
if ($notices[0]['total']) {
|
||||
$footer .= ', ';
|
||||
}
|
||||
}
|
||||
if ($notices[0]['total']) {
|
||||
$footer .= intval($notices[0]['total']) . ' ' . tt('notice', 'notices', intval($notices[0]['total']), 'noun');
|
||||
}
|
||||
|
||||
$i[] = [
|
||||
'url' => z_root() . '/manage/' . $rr['channel_id'],
|
||||
'title' => '',
|
||||
'summary' => '<img src="' . $rr['xchan_photo_s'] . '" class="menu-img-2">' . $rr['channel_name'],
|
||||
'footer' => $footer
|
||||
];
|
||||
|
||||
$channels_activity++;
|
||||
|
||||
}
|
||||
|
||||
if(!$channels_activity) {
|
||||
return;
|
||||
}
|
||||
|
||||
self::$activities['channels'] = [
|
||||
'label' => t('Channels'),
|
||||
'icon' => 'home',
|
||||
'url' => z_root() . '/manage',
|
||||
'date' => datetime_convert(),
|
||||
'items' => $i,
|
||||
'tpl' => 'channel_activities.tpl'
|
||||
];
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,5 +1,11 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* * Name: Chatroom list
|
||||
* * Description: A menu with links to your chatrooms
|
||||
* * Requires: chat, channel, articles, cards, wiki
|
||||
*/
|
||||
|
||||
namespace Zotlabs\Widget;
|
||||
|
||||
class Chatroom_list {
|
||||
|
||||
@@ -1,5 +1,11 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* * Name: Chatroom members
|
||||
* * Description: A widget that shows members of a chatroom
|
||||
* * Requires: chat
|
||||
*/
|
||||
|
||||
namespace Zotlabs\Widget;
|
||||
|
||||
class Chatroom_members {
|
||||
|
||||
@@ -1,5 +1,10 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* * Name: Clock
|
||||
* * Description: A simple widget that shows the current time
|
||||
*/
|
||||
|
||||
namespace Zotlabs\Widget;
|
||||
|
||||
class Clock {
|
||||
|
||||
@@ -1,54 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace Zotlabs\Widget;
|
||||
|
||||
use Zotlabs\Lib\AccessList;
|
||||
|
||||
class Collections {
|
||||
|
||||
function widget($args) {
|
||||
|
||||
if(argc() < 2)
|
||||
// return;
|
||||
|
||||
$mode = ((array_key_exists('mode',$args)) ? $args['mode'] : 'conversation');
|
||||
switch($mode) {
|
||||
case 'conversation':
|
||||
$every = argv(0);
|
||||
$each = argv(0);
|
||||
$edit = true;
|
||||
$current = $_REQUEST['gid'];
|
||||
$abook_id = 0;
|
||||
$wmode = 0;
|
||||
break;
|
||||
case 'connections':
|
||||
$every = 'connections';
|
||||
$each = 'group';
|
||||
$edit = true;
|
||||
$current = $_REQUEST['gid'];
|
||||
$abook_id = 0;
|
||||
$wmode = 0;
|
||||
case 'groups':
|
||||
$every = 'connections';
|
||||
$each = argv(0);
|
||||
$edit = false;
|
||||
$current = intval(argv(1));
|
||||
$abook_id = 0;
|
||||
$wmode = 1;
|
||||
break;
|
||||
case 'abook':
|
||||
$every = 'connections';
|
||||
$each = 'group';
|
||||
$edit = false;
|
||||
$current = 0;
|
||||
$abook_id = \App::$poi['abook_xchan'];
|
||||
$wmode = 1;
|
||||
break;
|
||||
default:
|
||||
return '';
|
||||
break;
|
||||
}
|
||||
|
||||
return AccessList::widget($every, $each, $edit, $current, $abook_id, $wmode);
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,11 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* * Name: Common friends
|
||||
* * Description: Display common friends to visitors
|
||||
* * Requires: channel, articles, cards, wiki
|
||||
*/
|
||||
|
||||
namespace Zotlabs\Widget;
|
||||
|
||||
require_once('include/contact_widgets.php');
|
||||
@@ -8,7 +14,7 @@ class Common_friends {
|
||||
|
||||
function widget($arr) {
|
||||
|
||||
if((! \App::$profile['profile_uid'])
|
||||
if((! \App::$profile['profile_uid'])
|
||||
|| (! perm_is_allowed(\App::$profile['profile_uid'],get_observer_hash(),'view_contacts'))) {
|
||||
return '';
|
||||
}
|
||||
|
||||
@@ -1,5 +1,11 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* * Name: Cover photo
|
||||
* * Description: Display a cover photo in the banner region
|
||||
* * Requires: disabled_for_pdledit_gui
|
||||
*/
|
||||
|
||||
namespace Zotlabs\Widget;
|
||||
|
||||
class Cover_photo {
|
||||
@@ -28,7 +34,10 @@ class Cover_photo {
|
||||
if(! array_key_exists('channels_visited',$_SESSION)) {
|
||||
$_SESSION['channels_visited'] = [];
|
||||
}
|
||||
$_SESSION['channels_visited'][] = $channel_id;
|
||||
|
||||
if (!in_array($channel_id, $_SESSION['channels_visited'])) {
|
||||
$_SESSION['channels_visited'][] = $channel_id;
|
||||
}
|
||||
|
||||
$channel = channelx_by_n($channel_id);
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user