mirror of
https://framagit.org/hubzilla/core.git
synced 2026-06-21 00:52:33 -04:00
Compare commits
107 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
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 |
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
|
||||
|
||||
39
CHANGELOG
39
CHANGELOG
@@ -1,3 +1,42 @@
|
||||
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
|
||||
|
||||
|
||||
@@ -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']);
|
||||
}
|
||||
|
||||
@@ -311,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 [];
|
||||
|
||||
@@ -501,7 +501,7 @@ class Activity {
|
||||
|
||||
$ret['attributedTo'] = $i['author']['xchan_url'];
|
||||
|
||||
if ($i['id'] != $i['parent']) {
|
||||
if ($i['mid'] !== $i['parent_mid']) {
|
||||
$ret['inReplyTo'] = ((strpos($i['thr_parent'], 'http') === 0) ? $i['thr_parent'] : z_root() . '/item/' . urlencode($i['thr_parent']));
|
||||
}
|
||||
|
||||
@@ -608,10 +608,10 @@ class Activity {
|
||||
$ptr = [$ptr];
|
||||
}
|
||||
foreach ($ptr as $t) {
|
||||
if (!array_key_exists('type', $t))
|
||||
if (is_array($t) && !array_key_exists('type', $t))
|
||||
$t['type'] = 'Hashtag';
|
||||
|
||||
if (array_key_exists('href', $t) && array_key_exists('name', $t)) {
|
||||
if (is_array($t) && array_key_exists('href', $t) && array_key_exists('name', $t)) {
|
||||
switch ($t['type']) {
|
||||
case 'Hashtag':
|
||||
$ret[] = ['ttype' => TERM_HASHTAG, 'url' => $t['href'], 'term' => escape_tags((substr($t['name'], 0, 1) === '#') ? substr($t['name'], 1) : $t['name'])];
|
||||
@@ -875,7 +875,7 @@ class Activity {
|
||||
}
|
||||
}
|
||||
|
||||
if ($i['id'] != $i['parent']) {
|
||||
if ($i['mid'] !== $i['parent_mid']) {
|
||||
$reply = true;
|
||||
|
||||
// inReplyTo needs to be set in the activity for followup actions (Like, Dislike, Announce, etc.),
|
||||
@@ -1154,9 +1154,10 @@ class Activity {
|
||||
$ret['url'] = $p['xchan_url'];
|
||||
|
||||
$ret['publicKey'] = [
|
||||
'id' => $p['xchan_url'],
|
||||
'owner' => $p['xchan_url'],
|
||||
'publicKeyPem' => $p['xchan_pubkey']
|
||||
'id' => $p['xchan_url'],
|
||||
'owner' => $p['xchan_url'],
|
||||
'signatureAlgorithm' => 'http://www.w3.org/2001/04/xmldsig-more#rsa-sha256',
|
||||
'publicKeyPem' => $p['xchan_pubkey']
|
||||
];
|
||||
|
||||
if ($c) {
|
||||
@@ -1599,6 +1600,25 @@ class Activity {
|
||||
return;
|
||||
}
|
||||
|
||||
public static function drop($channel, $observer, $act) {
|
||||
$r = q(
|
||||
"select * from item where mid = '%s' and uid = %d limit 1",
|
||||
dbesc((is_array($act->obj)) ? $act->obj['id'] : $act->obj),
|
||||
intval($channel['channel_id'])
|
||||
);
|
||||
|
||||
if (!$r) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (in_array($observer, [$r[0]['author_xchan'], $r[0]['owner_xchan']])) {
|
||||
drop_item($r[0]['id'], false);
|
||||
} elseif (in_array($act->actor['id'], [$r[0]['author_xchan'], $r[0]['owner_xchan']])) {
|
||||
drop_item($r[0]['id'], false);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static function actor_store($url, $person_obj, $force = false) {
|
||||
|
||||
if (!is_array($person_obj)) {
|
||||
@@ -1618,6 +1638,7 @@ class Activity {
|
||||
$ap_hubloc = null;
|
||||
|
||||
$hublocs = self::get_actor_hublocs($url);
|
||||
$has_zot_hubloc = false;
|
||||
|
||||
if ($hublocs) {
|
||||
foreach ($hublocs as $hub) {
|
||||
@@ -1625,6 +1646,7 @@ class Activity {
|
||||
$ap_hubloc = $hub;
|
||||
}
|
||||
if ($hub['hubloc_network'] === 'zot6') {
|
||||
$has_zot_hubloc = true;
|
||||
Libzot::update_cached_hubloc($hub);
|
||||
}
|
||||
}
|
||||
@@ -1648,16 +1670,18 @@ class Activity {
|
||||
return;
|
||||
}
|
||||
|
||||
$inbox = $person_obj['inbox'];
|
||||
$inbox = $person_obj['inbox'] ?? null;
|
||||
|
||||
// invalid identity
|
||||
// invalid AP identity
|
||||
|
||||
if (!$inbox || strpos($inbox, z_root()) !== false) {
|
||||
return;
|
||||
}
|
||||
|
||||
// store the actor record in XConfig
|
||||
XConfig::Set($url, 'system', 'actor_record', $person_obj);
|
||||
|
||||
// we already store this in Activity::fetch()
|
||||
// XConfig::Set($url, 'system', 'actor_record', $person_obj);
|
||||
|
||||
$name = $person_obj['name'];
|
||||
if (!$name) {
|
||||
@@ -1814,12 +1838,12 @@ class Activity {
|
||||
// Adding zot discovery urls to the actor record will cause federation to fail with the 20-30 projects which don't accept arrays in the url field.
|
||||
|
||||
$actor_protocols = self::get_actor_protocols($person_obj);
|
||||
if (in_array('zot6', $actor_protocols)) {
|
||||
if (!$has_zot_hubloc && in_array('zot6', $actor_protocols)) {
|
||||
$zx = q("select * from hubloc where hubloc_id_url = '%s' and hubloc_network = 'zot6'",
|
||||
dbesc($url)
|
||||
);
|
||||
if (!$zx && $webfinger_addr) {
|
||||
Master::Summon(['Gprobe', bin2hex($webfinger_addr)]);
|
||||
if (!$zx) {
|
||||
Master::Summon(['Gprobe', bin2hex($url)]);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1922,11 +1946,6 @@ class Activity {
|
||||
}
|
||||
}
|
||||
|
||||
$abook = q("select * from abook where abook_xchan = '%s' and abook_channel = %d limit 1",
|
||||
dbesc($observer_hash),
|
||||
intval($channel['channel_id'])
|
||||
);
|
||||
|
||||
$content = self::get_content($act->obj);
|
||||
|
||||
if (!$content) {
|
||||
@@ -2004,15 +2023,23 @@ class Activity {
|
||||
}
|
||||
|
||||
if ($channel['channel_system']) {
|
||||
if (!MessageFilter::evaluate($s, 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($s, $incl, $excl)) {
|
||||
logger('post is filtered');
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
$abook = q("select * from abook where (abook_xchan = '%s' OR abook_xchan = '%s') and abook_channel = %d ",
|
||||
dbesc($s['author_xchan']),
|
||||
dbesc($s['owner_xchan']),
|
||||
intval($channel['channel_id'])
|
||||
);
|
||||
|
||||
if ($abook) {
|
||||
if (!post_is_importable($s, $abook[0])) {
|
||||
if (!post_is_importable($channel['channel_id'], $s, $abook)) {
|
||||
logger('post is filtered');
|
||||
return;
|
||||
}
|
||||
@@ -2221,6 +2248,21 @@ class Activity {
|
||||
|
||||
static function decode_note($act) {
|
||||
|
||||
$response_activity = false;
|
||||
|
||||
$s = [];
|
||||
|
||||
// These activities should have been handled separately in the Inbox module and should not be turned into posts
|
||||
|
||||
if (
|
||||
in_array($act->type, ['Follow', 'Accept', 'Reject', 'Create', 'Update']) &&
|
||||
is_array($act->obj) &&
|
||||
array_key_exists('type', $act->obj) &&
|
||||
($act->obj['type'] === 'Follow' || ActivityStreams::is_an_actor($act->obj['type']))
|
||||
) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Within our family of projects, Follow/Unfollow of a thread is an internal activity which should not be transmitted,
|
||||
// hence if we receive it - ignore or reject it.
|
||||
// Unfollow is not defined by ActivityStreams, which prefers Undo->Follow.
|
||||
@@ -2230,22 +2272,31 @@ class Activity {
|
||||
return false;
|
||||
}
|
||||
|
||||
$response_activity = false;
|
||||
if (!isset($act->actor['id'])) {
|
||||
logger('No actor!');
|
||||
return false;
|
||||
}
|
||||
|
||||
$s = [];
|
||||
// ensure we store the original actor
|
||||
self::actor_store($act->actor['id'], $act->actor);
|
||||
|
||||
$s['owner_xchan'] = $act->actor['id'];
|
||||
$s['author_xchan'] = $act->actor['id'];
|
||||
|
||||
if (is_array($act->obj)) {
|
||||
$content = self::get_content($act->obj);
|
||||
}
|
||||
|
||||
$s['owner_xchan'] = $act->actor['id'];
|
||||
$s['author_xchan'] = $act->actor['id'];
|
||||
$s['mid'] = ((is_array($act->obj) && isset($act->obj['id'])) ? $act->obj['id'] : $act->obj);
|
||||
|
||||
// ensure we store the original actor
|
||||
self::actor_store($act->actor['id'], $act->actor);
|
||||
if (!$s['mid']) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Friendica sends the diaspora guid in a nonstandard field via AP
|
||||
// If no uuid is provided we will create an uuid v5 from the mid
|
||||
$s['uuid'] = ((is_array($act->obj) && isset($act->obj['diaspora:guid'])) ? $act->obj['diaspora:guid'] : uuid_from_url($s['mid']));
|
||||
|
||||
$s['mid'] = $act->obj['id'];
|
||||
$s['uuid'] = $act->obj['diaspora:guid'];
|
||||
$s['parent_mid'] = $act->parent_id;
|
||||
|
||||
if (array_key_exists('published', $act->data)) {
|
||||
@@ -2269,13 +2320,18 @@ class Activity {
|
||||
$s['expires'] = datetime_convert('UTC', 'UTC', $act->obj['expires']);
|
||||
}
|
||||
|
||||
if ($act->type === 'Invite' && is_array($act->obj) && array_key_exists('type', $act->obj) && $act->obj['type'] === 'Event') {
|
||||
$s['mid'] = $s['parent_mid'] = $act->id;
|
||||
}
|
||||
|
||||
if (ActivityStreams::is_response_activity($act->type)) {
|
||||
|
||||
$response_activity = true;
|
||||
|
||||
$s['mid'] = $act->id;
|
||||
// $s['parent_mid'] = $act->obj['id'];
|
||||
$s['uuid'] = $act->data['diaspora:guid'];
|
||||
$s['uuid'] = ((is_array($act->data) && isset($act->data['diaspora:guid'])) ? $act->data['diaspora:guid'] : uuid_from_url($s['mid']));
|
||||
|
||||
$s['parent_mid'] = ((is_array($act->obj) && isset($act->obj['id'])) ? $act->obj['id'] : $act->obj);
|
||||
|
||||
// over-ride the object timestamp with the activity
|
||||
|
||||
@@ -2288,8 +2344,8 @@ class Activity {
|
||||
}
|
||||
|
||||
$obj_actor = ((isset($act->obj['actor'])) ? $act->obj['actor'] : $act->get_actor('attributedTo', $act->obj));
|
||||
// ensure we store the original actor
|
||||
|
||||
// ensure we store the original actor
|
||||
self::actor_store($obj_actor['id'], $obj_actor);
|
||||
|
||||
$mention = self::get_actor_bbmention($obj_actor['id']);
|
||||
@@ -2318,13 +2374,41 @@ class Activity {
|
||||
}
|
||||
|
||||
if ($act->type === 'Announce') {
|
||||
$content['content'] = sprintf(t('🔁 Repeated %1$s\'s %2$s'), $mention, $act->obj['type']);
|
||||
$s['author_xchan'] = $obj_actor['id'];
|
||||
$s['mid'] = $act->obj['id'];
|
||||
$s['parent_mid'] = $act->obj['id'];
|
||||
}
|
||||
if ($act->type === 'emojiReaction') {
|
||||
$content['content'] = (($act->tgt && $act->tgt['type'] === 'Image') ? '[img=32x32]' . $act->tgt['url'] . '[/img]' : '&#x' . $act->tgt['name'] . ';');
|
||||
}
|
||||
}
|
||||
|
||||
$s['item_thread_top'] = 0;
|
||||
$s['comment_policy'] = 'authenticated';
|
||||
|
||||
if ($s['mid'] === $s['parent_mid']) {
|
||||
$s['item_thread_top'] = 1;
|
||||
|
||||
// it is a parent node - decode the comment policy info if present
|
||||
if (isset($act->obj['commentPolicy'])) {
|
||||
$until = strpos($act->obj['commentPolicy'], 'until=');
|
||||
if ($until !== false) {
|
||||
$s['comments_closed'] = datetime_convert('UTC', 'UTC', substr($act->obj['commentPolicy'], $until + 6));
|
||||
if ($s['comments_closed'] < datetime_convert()) {
|
||||
$s['nocomment'] = true;
|
||||
}
|
||||
}
|
||||
|
||||
$remainder = substr($act->obj['commentPolicy'], 0, (($until) ? $until : strlen($act->obj['commentPolicy'])));
|
||||
if ($remainder) {
|
||||
$s['comment_policy'] = $remainder;
|
||||
}
|
||||
if (!(isset($item['comment_policy']) && strlen($item['comment_policy']))) {
|
||||
$s['comment_policy'] = 'contacts';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!array_key_exists('created', $s))
|
||||
$s['created'] = datetime_convert();
|
||||
|
||||
@@ -2335,6 +2419,16 @@ class Activity {
|
||||
$s['summary'] = self::bb_content($content, 'summary');
|
||||
$s['body'] = ((self::bb_content($content, 'bbcode') && (!$response_activity)) ? self::bb_content($content, 'bbcode') : self::bb_content($content, 'content'));
|
||||
|
||||
if (isset($act->obj['quoteUrl'])) {
|
||||
$quote_bbcode = self::get_quote_bbcode($act->obj['quoteUrl']);
|
||||
|
||||
if ($s['body']) {
|
||||
$s['body'] .= "\r\n\r\n";
|
||||
}
|
||||
|
||||
$s['body'] .= $quote_bbcode;
|
||||
}
|
||||
|
||||
$s['verb'] = self::activity_decode_mapper($act->type);
|
||||
|
||||
// Mastodon does not provide update timestamps when updating poll tallies which means race conditions may occur here.
|
||||
@@ -2351,6 +2445,12 @@ class Activity {
|
||||
$s['obj_type'] = ACTIVITY_OBJ_COMMENT;
|
||||
}
|
||||
|
||||
$s['obj'] = $act->obj;
|
||||
if (is_array($s['obj']) && array_path_exists('actor/id', $s['obj'])) {
|
||||
$s['obj']['actor'] = $s['obj']['actor']['id'];
|
||||
}
|
||||
|
||||
/*
|
||||
$eventptr = null;
|
||||
|
||||
if ($act->obj['type'] === 'Invite' && array_path_exists('object/type', $act->obj) && $act->obj['object']['type'] === 'Event') {
|
||||
@@ -2371,19 +2471,19 @@ class Activity {
|
||||
$s['obj']['asld'] = $eventptr;
|
||||
$s['obj']['type'] = ACTIVITY_OBJ_EVENT;
|
||||
$s['obj']['id'] = $eventptr['id'];
|
||||
$s['obj']['title'] = $eventptr['name'];
|
||||
$s['obj']['title'] = html2plain($eventptr['name']);
|
||||
|
||||
if (strpos($act->obj['startTime'], 'Z'))
|
||||
$s['obj']['adjust'] = true;
|
||||
else
|
||||
$s['obj']['adjust'] = false;
|
||||
$s['obj']['adjust'] = true;
|
||||
|
||||
$s['obj']['dtstart'] = datetime_convert('UTC', 'UTC', $eventptr['startTime']);
|
||||
if ($act->obj['endTime'])
|
||||
$s['obj']['dtend'] = datetime_convert('UTC', 'UTC', $eventptr['endTime']);
|
||||
else
|
||||
$s['obj']['nofinish'] = true;
|
||||
$s['obj']['description'] = $eventptr['content'];
|
||||
$s['obj']['description'] = html2bbcode($eventptr['content']);
|
||||
|
||||
if (array_path_exists('location/content', $eventptr))
|
||||
$s['obj']['location'] = $eventptr['location']['content'];
|
||||
@@ -2392,6 +2492,7 @@ class Activity {
|
||||
else {
|
||||
$s['obj'] = $act->obj;
|
||||
}
|
||||
*/
|
||||
|
||||
$generator = $act->get_property_obj('generator');
|
||||
if ((!$generator) && (!$response_activity)) {
|
||||
@@ -2431,7 +2532,7 @@ class Activity {
|
||||
if (array_key_exists('type', $act->obj)) {
|
||||
|
||||
if ($act->obj['type'] === 'Note' && $s['attach']) {
|
||||
$s['body'] .= self::bb_attach($s['attach'], $s['body']);
|
||||
$s['body'] = self::bb_attach($s['attach'], $s['body']) . $s['body'];
|
||||
}
|
||||
|
||||
if ($act->obj['type'] === 'Question' && in_array($act->type, ['Create', 'Update'])) {
|
||||
@@ -2459,31 +2560,57 @@ class Activity {
|
||||
'video/webm'
|
||||
];
|
||||
|
||||
$mps = [];
|
||||
$mps = [];
|
||||
$poster = null;
|
||||
$ptr = null;
|
||||
|
||||
// try to find a poster to display on the video element
|
||||
|
||||
if (array_key_exists('icon',$act->obj)) {
|
||||
if (is_array($act->obj['icon'])) {
|
||||
if (array_key_exists(0,$act->obj['icon'])) {
|
||||
$ptr = $act->obj['icon'];
|
||||
}
|
||||
else {
|
||||
$ptr = [ $act->obj['icon'] ];
|
||||
}
|
||||
}
|
||||
if ($ptr) {
|
||||
foreach ($ptr as $foo) {
|
||||
if (is_array($foo) && array_key_exists('type',$foo) && $foo['type'] === 'Image' && is_string($foo['url'])) {
|
||||
$poster = $foo['url'];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$tag = (($poster) ? '[video poster="' . $poster . '"]' : '[video]' );
|
||||
$ptr = null;
|
||||
|
||||
if (array_key_exists('url', $act->obj)) {
|
||||
if (array_key_exists('url',$act->obj)) {
|
||||
if (is_array($act->obj['url'])) {
|
||||
if (array_key_exists(0, $act->obj['url'])) {
|
||||
if (array_key_exists(0,$act->obj['url'])) {
|
||||
$ptr = $act->obj['url'];
|
||||
}
|
||||
else {
|
||||
$ptr = [$act->obj['url']];
|
||||
$ptr = [ $act->obj['url'] ];
|
||||
}
|
||||
foreach ($ptr as $vurl) {
|
||||
// peertube uses the non-standard element name 'mimeType' here
|
||||
if (array_key_exists('mimeType', $vurl)) {
|
||||
if (in_array($vurl['mimeType'], $vtypes)) {
|
||||
if (!array_key_exists('width', $vurl)) {
|
||||
$vurl['width'] = 0;
|
||||
}
|
||||
$mps[] = $vurl;
|
||||
// handle peertube's weird url link tree if we find it here
|
||||
// 0 => html link, 1 => application/x-mpegURL with 'tag' set to an array of actual media links
|
||||
foreach ($ptr as $idex) {
|
||||
if (is_array($idex) && array_key_exists('mediaType',$idex)) {
|
||||
if ($idex['mediaType'] === 'application/x-mpegURL' && isset($idex['tag']) && is_array($idex['tag'])) {
|
||||
$ptr = $idex['tag'];
|
||||
break;
|
||||
}
|
||||
}
|
||||
elseif (array_key_exists('mediaType', $vurl)) {
|
||||
}
|
||||
|
||||
foreach ($ptr as $vurl) {
|
||||
if (array_key_exists('mediaType',$vurl)) {
|
||||
if (in_array($vurl['mediaType'], $vtypes)) {
|
||||
if (!array_key_exists('width', $vurl)) {
|
||||
$vurl['width'] = 0;
|
||||
if (! array_key_exists('height',$vurl)) {
|
||||
$vurl['height'] = 0;
|
||||
}
|
||||
$mps[] = $vurl;
|
||||
}
|
||||
@@ -2491,17 +2618,18 @@ class Activity {
|
||||
}
|
||||
}
|
||||
if ($mps) {
|
||||
usort($mps, [__CLASS__, 'vid_sort']);
|
||||
usort($mps,[ '\Zotlabs\Lib\Activity', 'vid_sort' ]);
|
||||
foreach ($mps as $m) {
|
||||
if (intval($m['width']) < 500 && self::media_not_in_body($m['href'], $s['body'])) {
|
||||
$s['body'] .= "\n\n" . '[video]' . $m['href'] . '[/video]';
|
||||
if (intval($m['height']) < 500 && Activity::media_not_in_body($m['href'],$s['body'])) {
|
||||
$s['body'] = $tag . $m['href'] . '[/video]' . "\n\n" . $s['body'];
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
elseif (is_string($act->obj['url']) && self::media_not_in_body($act->obj['url'], $s['body'])) {
|
||||
$s['body'] .= "\n\n" . '[video]' . $act->obj['url'] . '[/video]';
|
||||
elseif (is_string($act->obj['url']) && Activity::media_not_in_body($act->obj['url'],$s['body'])) {
|
||||
$s['body'] = $tag . $act->obj['url'] . '[/video]' . "\n\n" . $s['body'];
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2525,13 +2653,13 @@ class Activity {
|
||||
}
|
||||
foreach ($ptr as $vurl) {
|
||||
if (in_array($vurl['mediaType'], $atypes) && self::media_not_in_body($vurl['href'], $s['body'])) {
|
||||
$s['body'] .= "\n\n" . '[audio]' . $vurl['href'] . '[/audio]';
|
||||
$s['body'] = '[audio]' . $vurl['href'] . '[/audio]' . "\n\n" . $s['body'];
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
elseif (is_string($act->obj['url']) && self::media_not_in_body($act->obj['url'], $s['body'])) {
|
||||
$s['body'] .= "\n\n" . '[audio]' . $act->obj['url'] . '[/audio]';
|
||||
$s['body'] = '[audio]' . $act->obj['url'] . '[/audio]' . "\n\n" . $s['body'];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2606,7 +2734,6 @@ class Activity {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (in_array($act->obj['type'], ['Note', 'Article', 'Page'])) {
|
||||
$ptr = null;
|
||||
|
||||
@@ -2744,12 +2871,6 @@ class Activity {
|
||||
return;
|
||||
}*/
|
||||
|
||||
// TODO: this his handled in pubcrawl atm.
|
||||
// very unpleasant and imperfect way of determining a Mastodon DM
|
||||
/*if ($act->raw_recips && array_key_exists('to',$act->raw_recips) && is_array($act->raw_recips['to']) && count($act->raw_recips['to']) === 1 && $act->raw_recips['to'][0] === channel_url($channel) && ! $act->raw_recips['cc']) {
|
||||
$item['item_private'] = 2;
|
||||
}*/
|
||||
|
||||
if ($item['parent_mid'] && $item['parent_mid'] !== $item['mid']) {
|
||||
$is_child_node = true;
|
||||
}
|
||||
@@ -2914,19 +3035,23 @@ class Activity {
|
||||
return;
|
||||
|
||||
if ($channel['channel_system']) {
|
||||
if (!MessageFilter::evaluate($item, 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($item, $incl, $excl)) {
|
||||
logger('post is filtered');
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
$abook = q("select * from abook where abook_xchan = '%s' and abook_channel = %d limit 1",
|
||||
dbesc($observer_hash),
|
||||
$abook = q("select * from abook where ( abook_xchan = '%s' OR abook_xchan = '%s') and abook_channel = %d ",
|
||||
dbesc($item['author_xchan']),
|
||||
dbesc($item['owner_xchan']),
|
||||
intval($channel['channel_id'])
|
||||
);
|
||||
|
||||
if ($abook) {
|
||||
if (!post_is_importable($item, $abook[0])) {
|
||||
if (!post_is_importable($channel['channel_id'], $item, $abook)) {
|
||||
logger('post is filtered');
|
||||
return;
|
||||
}
|
||||
@@ -2996,6 +3121,19 @@ class Activity {
|
||||
$item['thr_parent'] = $parent[0]['parent_mid'];
|
||||
}
|
||||
$item['parent_mid'] = $parent[0]['parent_mid'];
|
||||
//$item['item_private'] = $parent[0]['item_private'];
|
||||
|
||||
}
|
||||
|
||||
// An ugly and imperfect way to recognise a mastodon direct message
|
||||
if (
|
||||
$item['item_private'] === 1 &&
|
||||
!isset($act->raw_recips['cc']) &&
|
||||
is_array($act->raw_recips['to']) &&
|
||||
in_array(channel_url($channel), $act->raw_recips['to']) &&
|
||||
!in_array($act->actor['followers'], $act->raw_recips['to'])
|
||||
) {
|
||||
$item['item_private'] = 2;
|
||||
}
|
||||
|
||||
// TODO: not implemented
|
||||
@@ -3006,6 +3144,12 @@ class Activity {
|
||||
intval($item['uid'])
|
||||
);
|
||||
if ($r) {
|
||||
|
||||
// If we already have the item, dismiss its announce
|
||||
if ($act->type === 'Announce') {
|
||||
return;
|
||||
}
|
||||
|
||||
if ($item['edited'] > $r[0]['edited']) {
|
||||
$item['id'] = $r[0]['id'];
|
||||
$x = item_store_update($item);
|
||||
@@ -3022,12 +3166,12 @@ class Activity {
|
||||
logger('topfetch', LOGGER_DEBUG);
|
||||
// if the thread owner is a connnection, we will already receive any additional comments to their posts
|
||||
// but if they are not we can try to fetch others in the background
|
||||
$x = q("SELECT abook.*, xchan.* FROM abook left join xchan on abook_xchan = xchan_hash
|
||||
$connected = q("SELECT abook.*, xchan.* FROM abook left join xchan on abook_xchan = xchan_hash
|
||||
WHERE abook_channel = %d and abook_xchan = '%s' LIMIT 1",
|
||||
intval($channel['channel_id']),
|
||||
dbesc($parent[0]['owner_xchan'])
|
||||
);
|
||||
if (!$x) {
|
||||
if (!$connected) {
|
||||
// determine if the top-level post provides a replies collection
|
||||
if ($parent[0]['obj']) {
|
||||
$parent[0]['obj'] = json_decode($parent[0]['obj'], true);
|
||||
@@ -3279,6 +3423,7 @@ class Activity {
|
||||
|
||||
}
|
||||
|
||||
/* this is deprecated and not used anymore
|
||||
static function announce_note($channel, $observer_hash, $act) {
|
||||
|
||||
$s = [];
|
||||
@@ -3409,6 +3554,7 @@ class Activity {
|
||||
}
|
||||
|
||||
}
|
||||
*/
|
||||
|
||||
static function like_note($channel, $observer_hash, $act) {
|
||||
|
||||
@@ -3629,7 +3775,49 @@ class Activity {
|
||||
$event['nofinish'] = true;
|
||||
}
|
||||
}
|
||||
/*
|
||||
$eventptr = null;
|
||||
|
||||
if ($act->obj['type'] === 'Invite' && array_path_exists('object/type', $act->obj) && $act->obj['object']['type'] === 'Event') {
|
||||
$eventptr = $act->obj['object'];
|
||||
$s['mid'] = $s['parent_mid'] = $act->obj['id'];
|
||||
}
|
||||
|
||||
if ($act->obj['type'] === 'Event') {
|
||||
if ($act->type === 'Invite') {
|
||||
$s['mid'] = $s['parent_mid'] = $act->id;
|
||||
}
|
||||
$eventptr = $act->obj;
|
||||
}
|
||||
|
||||
if ($eventptr) {
|
||||
|
||||
$s['obj'] = [];
|
||||
$s['obj']['asld'] = $eventptr;
|
||||
$s['obj']['type'] = ACTIVITY_OBJ_EVENT;
|
||||
$s['obj']['id'] = $eventptr['id'];
|
||||
$s['obj']['title'] = html2plain($eventptr['name']);
|
||||
|
||||
if (strpos($act->obj['startTime'], 'Z'))
|
||||
$s['obj']['adjust'] = true;
|
||||
else
|
||||
$s['obj']['adjust'] = true;
|
||||
|
||||
$s['obj']['dtstart'] = datetime_convert('UTC', 'UTC', $eventptr['startTime']);
|
||||
if ($act->obj['endTime'])
|
||||
$s['obj']['dtend'] = datetime_convert('UTC', 'UTC', $eventptr['endTime']);
|
||||
else
|
||||
$s['obj']['nofinish'] = true;
|
||||
$s['obj']['description'] = html2bbcode($eventptr['content']);
|
||||
|
||||
if (array_path_exists('location/content', $eventptr))
|
||||
$s['obj']['location'] = $eventptr['location']['content'];
|
||||
|
||||
}
|
||||
else {
|
||||
$s['obj'] = $act->obj;
|
||||
}
|
||||
*/
|
||||
foreach (['name', 'summary', 'content'] as $a) {
|
||||
if (($x = self::get_textfield($act, $a)) !== false) {
|
||||
$content[$a] = $x;
|
||||
@@ -3786,7 +3974,7 @@ class Activity {
|
||||
return $ret;
|
||||
}
|
||||
|
||||
foreach ($tag as $t) {
|
||||
foreach ($actor['tag'] as $t) {
|
||||
if ((isset($t['type']) && $t['type'] === 'PropertyValue') &&
|
||||
(isset($t['name']) && $t['name'] === 'Protocol') &&
|
||||
(isset($t['value']) && in_array($t['value'], ['zot6', 'activitypub', 'diaspora']))
|
||||
@@ -3797,4 +3985,32 @@ class Activity {
|
||||
|
||||
return $ret;
|
||||
}
|
||||
|
||||
static function get_quote_bbcode($url) {
|
||||
|
||||
$ret = '';
|
||||
|
||||
$a = self::fetch($url);
|
||||
if ($a) {
|
||||
$act = new ActivityStreams($a);
|
||||
|
||||
if ($act->is_valid()) {
|
||||
$content = self::get_content($act->obj);
|
||||
|
||||
$ret .= "[share author='" . urlencode($act->actor['name']) .
|
||||
"' profile='" . $act->actor['id'] .
|
||||
"' avatar='" . $act->actor['icon']['url'] .
|
||||
"' link='" . $act->obj['id'] .
|
||||
"' auth='" . ((is_matrix_url($act->actor['id'])) ? 'true' : 'false') .
|
||||
"' posted='" . $act->obj['published'] .
|
||||
"' message_id='" . $act->obj['id'] .
|
||||
"']";
|
||||
$ret .= self::bb_content($content, 'content');
|
||||
$ret .= '[/share]';
|
||||
}
|
||||
}
|
||||
|
||||
return $ret;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -422,15 +422,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;
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -87,6 +87,10 @@ class Crypto {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!$alg) {
|
||||
$alg = 'sha256';
|
||||
}
|
||||
|
||||
try {
|
||||
$verify = openssl_verify($data, $sig, $key, $alg);
|
||||
} catch (Exception $e) {
|
||||
|
||||
@@ -845,6 +845,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']), 75, true);
|
||||
if ($body) {
|
||||
$body = htmlentities($body, ENT_QUOTES, 'UTF-8', false);
|
||||
}
|
||||
|
||||
$x = array(
|
||||
'notify_link' => $item['llink'],
|
||||
@@ -858,7 +862,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) {
|
||||
|
||||
@@ -676,6 +676,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)
|
||||
);
|
||||
@@ -1003,7 +1007,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);
|
||||
}
|
||||
|
||||
@@ -1227,6 +1231,16 @@ class Libzot {
|
||||
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'",
|
||||
dbesc($AS->actor['id'])
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
if ($r) {
|
||||
$r = self::zot_record_preferred($r);
|
||||
$arr['author_xchan'] = $r['hubloc_hash'];
|
||||
@@ -1280,22 +1294,12 @@ class Libzot {
|
||||
|
||||
if ($AS->data['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 (!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);
|
||||
}
|
||||
@@ -1568,7 +1572,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;
|
||||
}
|
||||
@@ -1743,11 +1751,13 @@ 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'])) {
|
||||
|
||||
@@ -1798,17 +1808,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');
|
||||
@@ -1838,20 +1849,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.
|
||||
@@ -1861,13 +1881,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
|
||||
@@ -2845,6 +2871,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'];
|
||||
|
||||
@@ -2,85 +2,104 @@
|
||||
|
||||
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/x-multicode'));
|
||||
$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) === '*')))
|
||||
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;
|
||||
}
|
||||
}
|
||||
} 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) {
|
||||
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)
|
||||
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) === '*')))
|
||||
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;
|
||||
}
|
||||
}
|
||||
} 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) {
|
||||
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)
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -88,4 +107,113 @@ 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;
|
||||
*
|
||||
* 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;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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));
|
||||
}
|
||||
@@ -97,7 +99,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,6 +114,7 @@ class Hq extends \Zotlabs\Web\Controller {
|
||||
'reset' => t('Reset form')
|
||||
];
|
||||
|
||||
$a = '';
|
||||
$o = status_editor($a, $x, true);
|
||||
|
||||
}
|
||||
|
||||
@@ -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'];
|
||||
}
|
||||
@@ -1092,7 +1093,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);
|
||||
|
||||
@@ -272,15 +272,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 ";
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
@@ -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'),
|
||||
|
||||
@@ -75,7 +75,7 @@ class Setup extends \Zotlabs\Web\Controller {
|
||||
$siteurl = ((isset($_POST['siteurl'])) ? trim($_POST['siteurl']) : '');
|
||||
|
||||
if (empty($db_charset)) {
|
||||
$db_charset = ((intval($db_type) === 0) ? 'utf8mb4' : 'UTF8');
|
||||
$db_charset = ((intval($dbtype) === 0) ? 'utf8mb4' : 'UTF8');
|
||||
}
|
||||
|
||||
// $siteurl should not have a trailing slash
|
||||
@@ -106,7 +106,7 @@ class Setup extends \Zotlabs\Web\Controller {
|
||||
$siteurl = ((isset($_POST['siteurl'])) ? trim($_POST['siteurl']) : '');
|
||||
|
||||
if (empty($db_charset)) {
|
||||
$db_charset = ((intval($db_type) === 0) ? 'utf8mb4' : 'UTF8');
|
||||
$db_charset = ((intval($dbtype) === 0) ? 'utf8mb4' : 'UTF8');
|
||||
}
|
||||
|
||||
if($siteurl != z_root()) {
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
namespace Zotlabs\Photo;
|
||||
|
||||
use Zotlabs\Lib\Hashpath;
|
||||
use Zotlabs\Lib\Hashpath;
|
||||
|
||||
/**
|
||||
* @brief Abstract photo driver class.
|
||||
@@ -494,11 +494,11 @@ abstract class PhotoDriver {
|
||||
( 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 +530,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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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,34 @@ 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;
|
||||
@@ -296,7 +311,7 @@ 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];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -308,12 +323,38 @@ class HTTPSig {
|
||||
|
||||
// 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' => []];
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -343,7 +384,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];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -389,7 +430,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];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -461,6 +502,9 @@ class HTTPSig {
|
||||
|
||||
$x = self::sign($head, $prvkey, $alg);
|
||||
|
||||
// TODO: should we default to hs2019?
|
||||
// $headerval = 'keyId="' . $keyid . '",algorithm="' . (($algorithm === 'rsa-sha256') ? 'hs2019' : $algorithm) . '",headers="' . $x['headers'] . '",signature="' . $x['signature'] . '"';
|
||||
|
||||
$headerval = 'keyId="' . $keyid . '",algorithm="' . $algorithm . '",headers="' . $x['headers'] . '",signature="' . $x['signature'] . '"';
|
||||
|
||||
if ($encryption) {
|
||||
@@ -528,11 +572,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");
|
||||
|
||||
@@ -107,7 +107,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;
|
||||
|
||||
@@ -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']
|
||||
|
||||
|
||||
];
|
||||
}
|
||||
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -1,5 +1,11 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* * Name: Design tools
|
||||
* * Description: Links to useful tools for webpages
|
||||
* * Requires: webpages
|
||||
*/
|
||||
|
||||
namespace Zotlabs\Widget;
|
||||
|
||||
class Design_tools {
|
||||
@@ -11,4 +17,4 @@ class Design_tools {
|
||||
|
||||
return EMPTY_STR;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,11 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* * Name: Dirsort
|
||||
* * Description: Various options to provide different vies of the directory
|
||||
* * Requires: directory
|
||||
*/
|
||||
|
||||
namespace Zotlabs\Widget;
|
||||
|
||||
use Zotlabs\Lib\Libzotdir;
|
||||
|
||||
@@ -1,5 +1,11 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* * Name: Directory tags
|
||||
* * Description: Show directory tags in a cloud
|
||||
* * Requires: directory
|
||||
*/
|
||||
|
||||
namespace Zotlabs\Widget;
|
||||
|
||||
class Dirtags {
|
||||
|
||||
@@ -1,19 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace Zotlabs\Widget;
|
||||
|
||||
class Eventstools {
|
||||
|
||||
function widget($arr) {
|
||||
|
||||
if(! local_channel())
|
||||
return;
|
||||
|
||||
return replace_macros(get_markup_template('events_tools_side.tpl'), array(
|
||||
'$title' => t('Events Tools'),
|
||||
'$export' => t('Export Calendar'),
|
||||
'$import' => t('Import Calendar'),
|
||||
'$submit' => t('Submit')
|
||||
));
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,11 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* * Name: Saved folders
|
||||
* * Description: A menu containing saved folders
|
||||
* * Requires: network
|
||||
*/
|
||||
|
||||
namespace Zotlabs\Widget;
|
||||
|
||||
require_once('include/contact_widgets.php');
|
||||
@@ -10,7 +16,6 @@ class Filer {
|
||||
if(! local_channel())
|
||||
return '';
|
||||
|
||||
|
||||
$selected = ((x($_REQUEST,'file')) ? $_REQUEST['file'] : '');
|
||||
|
||||
$terms = array();
|
||||
|
||||
@@ -1,5 +1,10 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* * Name: Find channels
|
||||
* * Description: A simple form to search for channels in the directory
|
||||
*/
|
||||
|
||||
namespace Zotlabs\Widget;
|
||||
|
||||
require_once('include/contact_widgets.php');
|
||||
|
||||
@@ -1,5 +1,10 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* * Name: Follow
|
||||
* * Description: A simple form which allows you to enter an address and send a follow request
|
||||
*/
|
||||
|
||||
namespace Zotlabs\Widget;
|
||||
|
||||
|
||||
@@ -24,7 +29,7 @@ class Follow {
|
||||
else {
|
||||
$abook_usage_message = '';
|
||||
}
|
||||
|
||||
|
||||
return replace_macros(get_markup_template('follow.tpl'),array(
|
||||
'$connect' => t('Add New Connection'),
|
||||
'$desc' => t('Enter channel address'),
|
||||
|
||||
@@ -1,5 +1,10 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* * Name: Forums
|
||||
* * Description: A list of forum channels with unseen item counts
|
||||
*/
|
||||
|
||||
namespace Zotlabs\Widget;
|
||||
|
||||
class Forums {
|
||||
@@ -21,35 +26,7 @@ class Forums {
|
||||
$unseen = 1;
|
||||
|
||||
$perms_sql = item_permissions_sql(local_channel()) . item_normal();
|
||||
|
||||
$xf = false;
|
||||
|
||||
$x1 = q("select xchan from abconfig where chan = %d and cat = 'their_perms' and k = 'send_stream' and v = '0'",
|
||||
intval(local_channel())
|
||||
);
|
||||
if($x1) {
|
||||
$xc = ids_to_querystr($x1,'xchan',true);
|
||||
|
||||
$x2 = q("select xchan from abconfig where chan = %d and cat = 'their_perms' and k = 'tag_deliver' and v = '1' and xchan in (" . $xc . ") ",
|
||||
intval(local_channel())
|
||||
);
|
||||
|
||||
if($x2) {
|
||||
$xf = ids_to_querystr($x2,'xchan',true);
|
||||
|
||||
// private forums
|
||||
$x3 = q("select xchan from abconfig where chan = %d and cat = 'their_perms' and k = 'post_wall' and v = '1' and xchan in (" . $xc . ") and not xchan in (" . $xf . ") ",
|
||||
intval(local_channel())
|
||||
);
|
||||
if($x3) {
|
||||
$xf = ids_to_querystr(array_merge($x2,$x3),'xchan',true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$sql_extra = (($xf) ? " and ( xchan_hash in (" . $xf . ") or xchan_pubforum = 1 ) " : " and xchan_pubforum = 1 ");
|
||||
|
||||
|
||||
$sql_extra = " and xchan_pubforum = 1 ";
|
||||
|
||||
$r1 = q("select abook_id, xchan_hash, xchan_name, xchan_url, xchan_photo_s from abook left join xchan on abook_xchan = xchan_hash where xchan_deleted = 0 and abook_channel = %d and abook_pending = 0 and abook_ignored = 0 and abook_blocked = 0 and abook_archived = 0 $sql_extra order by xchan_name $limit ",
|
||||
intval(local_channel())
|
||||
|
||||
@@ -1,5 +1,11 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* * Name: Full profile
|
||||
* * Description: Profile card with extended profile info
|
||||
* * Requires: channel, articles, cards, wiki, cloud, photos
|
||||
*/
|
||||
|
||||
namespace Zotlabs\Widget;
|
||||
|
||||
class Fullprofile {
|
||||
|
||||
@@ -1,11 +1,18 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* * Name: Help index
|
||||
* * Description: Help pages index
|
||||
*/
|
||||
|
||||
namespace Zotlabs\Widget;
|
||||
|
||||
class Helpindex {
|
||||
|
||||
function widget($arr) {
|
||||
|
||||
require_once('include/help.php');
|
||||
|
||||
$o .= '<div class="widget">';
|
||||
|
||||
$level_0 = get_help_content('sitetoc');
|
||||
|
||||
@@ -1,5 +1,12 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* * Name: HQ Controls
|
||||
* * Description: Control buttons for the HQ module
|
||||
* * Author: Mario Vavti
|
||||
* * Requires: hq
|
||||
*/
|
||||
|
||||
namespace Zotlabs\Widget;
|
||||
|
||||
use Zotlabs\Lib\Apps;
|
||||
|
||||
@@ -1,5 +1,11 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* * Name: Item
|
||||
* * Description: Display a webpage by title or mid,
|
||||
* * Requires: channel, articles, cards, wiki
|
||||
*/
|
||||
|
||||
namespace Zotlabs\Widget;
|
||||
|
||||
require_once('include/security.php');
|
||||
@@ -35,7 +41,7 @@ class Item {
|
||||
);
|
||||
}
|
||||
else {
|
||||
$r = q("select * from item where mid = '%s' and uid = %d and item_type = "
|
||||
$r = q("select * from item where mid = '%s' and uid = %d and item_type = "
|
||||
. intval(ITEM_TYPE_WEBPAGE) . " $sql_extra limit 1",
|
||||
dbesc($arr['mid']),
|
||||
intval($channel_id)
|
||||
|
||||
@@ -1,5 +1,11 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* * Name: Menu preview
|
||||
* * Description: Shows a preview of the current menu
|
||||
* * Requires: mitem
|
||||
*/
|
||||
|
||||
namespace Zotlabs\Widget;
|
||||
|
||||
require_once('include/menu.php');
|
||||
|
||||
@@ -1,5 +1,13 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* * Name: HQ Messages
|
||||
* * Description: Quick access to messages, direct messages, starred messages (if enabled) and notifications
|
||||
* * Author: Mario Vavti
|
||||
* * Requires: hq
|
||||
*/
|
||||
|
||||
|
||||
namespace Zotlabs\Widget;
|
||||
|
||||
use App;
|
||||
@@ -17,8 +25,8 @@ class Messages {
|
||||
|
||||
$tpl = get_markup_template('messages_widget.tpl');
|
||||
$o = replace_macros($tpl, [
|
||||
'$entries' => $page['entries'],
|
||||
'$offset' => $page['offset'],
|
||||
'$entries' => $page['entries'] ?? [],
|
||||
'$offset' => $page['offset'] ?? 0,
|
||||
'$feature_star' => feature_enabled(local_channel(), 'star_posts'),
|
||||
'$strings' => [
|
||||
'messages_title' => t('Public and restricted messages'),
|
||||
@@ -37,11 +45,11 @@ class Messages {
|
||||
if (!local_channel())
|
||||
return;
|
||||
|
||||
if ($options['offset'] == -1) {
|
||||
if (isset($options['offset']) && $options['offset'] == -1) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ($options['type'] == 'notification') {
|
||||
if (isset($options['type']) && $options['type'] == 'notification') {
|
||||
return self::get_notices_page($options);
|
||||
}
|
||||
|
||||
@@ -103,13 +111,20 @@ class Messages {
|
||||
if (!$summary) {
|
||||
$summary = $item['summary'];
|
||||
}
|
||||
|
||||
if (!$summary) {
|
||||
$summary = htmlentities(html2plain(bbcode($item['body'], ['drop_media' => true]), 75, true), ENT_QUOTES, 'UTF-8', false);
|
||||
$summary = html2plain(bbcode($item['body'], ['drop_media' => true]), 75, true);
|
||||
if ($summary) {
|
||||
$summary = htmlentities($summary, ENT_QUOTES, 'UTF-8', false);
|
||||
}
|
||||
}
|
||||
|
||||
if (!$summary) {
|
||||
$summary = '...';
|
||||
}
|
||||
$summary = substr_words($summary, 68);
|
||||
else {
|
||||
$summary = substr_words($summary, 68);
|
||||
}
|
||||
|
||||
switch(intval($item['item_private'])) {
|
||||
case 1:
|
||||
|
||||
@@ -1,5 +1,10 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* * Name: New member
|
||||
* * Description: Display useful links for new members to help them get started
|
||||
*/
|
||||
|
||||
namespace Zotlabs\Widget;
|
||||
|
||||
class Newmember {
|
||||
@@ -29,7 +34,7 @@ class Newmember {
|
||||
|
||||
$options = [
|
||||
t('Profile Creation'),
|
||||
[
|
||||
[
|
||||
'profile_photo' => t('Upload profile photo'),
|
||||
'cover_photo' => t('Upload cover photo'),
|
||||
'profiles' => t('Edit your profile'),
|
||||
@@ -84,4 +89,4 @@ class Newmember {
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -1,5 +1,13 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* * Name: Notes
|
||||
* * Description: A simple notes widget, requires the Notes App
|
||||
* * Author: Mike Macgirvin
|
||||
* * Author: Mario Vavti
|
||||
* * Maintainer: Mario Vavti
|
||||
*/
|
||||
|
||||
namespace Zotlabs\Widget;
|
||||
|
||||
use Zotlabs\Lib\Apps;
|
||||
@@ -33,9 +41,6 @@ class Notes {
|
||||
]
|
||||
));
|
||||
|
||||
|
||||
|
||||
|
||||
return $o;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,11 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* * Name: Notifications
|
||||
* * Description: Shows all kind of notifications
|
||||
* * Author: Mario Vavti
|
||||
*/
|
||||
|
||||
namespace Zotlabs\Widget;
|
||||
|
||||
class Notifications {
|
||||
|
||||
@@ -1,5 +1,12 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* * Name: Contact roles
|
||||
* * Description: Display a menu with all defined contact roles and contacts which are assigned to the selected role
|
||||
* * Author: Mario Vavti
|
||||
* * Requires: permcats
|
||||
*/
|
||||
|
||||
namespace Zotlabs\Widget;
|
||||
|
||||
use Zotlabs\Lib\Permcat;
|
||||
|
||||
@@ -1,5 +1,11 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* * Name: Photo
|
||||
* * Description: Displays a single photo
|
||||
*/
|
||||
|
||||
|
||||
namespace Zotlabs\Widget;
|
||||
|
||||
|
||||
|
||||
@@ -1,5 +1,11 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* * Name: Photo albums
|
||||
* * Description: Displays a menu with links to existing photo albums
|
||||
* * Requires: photos
|
||||
*/
|
||||
|
||||
namespace Zotlabs\Widget;
|
||||
|
||||
require_once('include/photos.php');
|
||||
|
||||
@@ -1,5 +1,10 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* * Name: Random photo
|
||||
* * Description: Display a random photo
|
||||
*/
|
||||
|
||||
namespace Zotlabs\Widget;
|
||||
|
||||
require_once('include/photos.php');
|
||||
@@ -40,15 +45,15 @@ class Photo_rand {
|
||||
|
||||
if(strpos($url, 'http') !== 0)
|
||||
return '';
|
||||
|
||||
|
||||
if(array_key_exists('style', $arr) && isset($arr['style']))
|
||||
$style = $arr['style'];
|
||||
|
||||
|
||||
// ensure they can't sneak in an eval(js) function
|
||||
|
||||
if(strpos($style,'(') !== false)
|
||||
return '';
|
||||
|
||||
|
||||
$url = zid($url);
|
||||
|
||||
$o = '<div class="widget">';
|
||||
|
||||
@@ -1,11 +1,14 @@
|
||||
<?php
|
||||
namespace Zotlabs\Widget;
|
||||
|
||||
/*
|
||||
* Show pinned content
|
||||
*
|
||||
/**
|
||||
* * Name: Pinned items
|
||||
* * Description: Display pinned items
|
||||
* * Author: Max Kostikov
|
||||
* * Requires: disabled_for_pdledit_gui
|
||||
*/
|
||||
|
||||
|
||||
class Pinned {
|
||||
|
||||
private $allowed_types = 0;
|
||||
|
||||
@@ -1,5 +1,11 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* * Name: Portfolio
|
||||
* * Description: Display a photo album in a portfolio style
|
||||
* * Requires: channel, articles, cards, wiki
|
||||
*/
|
||||
|
||||
namespace Zotlabs\Widget;
|
||||
|
||||
require_once('include/attach.php');
|
||||
@@ -8,11 +14,9 @@ class Portfolio {
|
||||
|
||||
function widget($args) {
|
||||
|
||||
|
||||
$owner_uid = \App::$profile_uid;
|
||||
$sql_extra = permissions_sql($owner_uid);
|
||||
|
||||
|
||||
if(! perm_is_allowed($owner_uid,get_observer_hash(),'view_storage'))
|
||||
return '';
|
||||
|
||||
@@ -112,7 +116,7 @@ class Portfolio {
|
||||
'$upload_form' => $upload_form,
|
||||
'$usage' => $usage_message
|
||||
));
|
||||
|
||||
|
||||
return $o;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,12 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* * Name: Privacy Groups
|
||||
* * Description: Display a menu with links to existing privacy groups
|
||||
* * Requires: group
|
||||
*/
|
||||
|
||||
|
||||
namespace Zotlabs\Widget;
|
||||
|
||||
use Zotlabs\Lib\AccessList;
|
||||
|
||||
@@ -1,5 +1,12 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* * Name: Profile
|
||||
* * Description: Your profile card
|
||||
* * Requires: channel, articles, cards, wiki, cloud, photos
|
||||
*/
|
||||
|
||||
|
||||
namespace Zotlabs\Widget;
|
||||
|
||||
use App;
|
||||
|
||||
@@ -1,16 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace Zotlabs\Widget;
|
||||
|
||||
class Pubsites {
|
||||
|
||||
// used by site ratings pages to provide a return link
|
||||
|
||||
function widget($arr) {
|
||||
if(\App::$poi)
|
||||
return;
|
||||
return '<div class="widget"><ul class="nav nav-pills"><li><a href="pubsites">' . t('Public Hubs') . '</a></li></ul></div>';
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,10 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* * Name: Public stream tags
|
||||
* * Description: Display public stream tags in a cloud
|
||||
*/
|
||||
|
||||
namespace Zotlabs\Widget;
|
||||
|
||||
class Pubtagcloud {
|
||||
|
||||
@@ -1,5 +1,10 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* * Name: Random block
|
||||
* * Description: Display a random block item
|
||||
*/
|
||||
|
||||
namespace Zotlabs\Widget;
|
||||
|
||||
class Random_block {
|
||||
|
||||
@@ -1,5 +1,11 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* * Name: Rating
|
||||
* * Description: Deprecated rating tool
|
||||
* * Requires: disabled_for_pdledit_gui
|
||||
*/
|
||||
|
||||
namespace Zotlabs\Widget;
|
||||
|
||||
class Rating {
|
||||
|
||||
@@ -1,5 +1,11 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* * Name: Saved searches
|
||||
* * Description: A search form which also displays saved searches if the feature is enabled
|
||||
* * Requires: network
|
||||
*/
|
||||
|
||||
namespace Zotlabs\Widget;
|
||||
|
||||
class Savedsearch {
|
||||
|
||||
@@ -1,5 +1,10 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* * Name: Settings menu
|
||||
* * Description: Display the channel settings menu
|
||||
*/
|
||||
|
||||
namespace Zotlabs\Widget;
|
||||
|
||||
class Settings_menu {
|
||||
|
||||
@@ -1,18 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace Zotlabs\Widget;
|
||||
|
||||
class Shortprofile {
|
||||
|
||||
function widget($arr) {
|
||||
|
||||
if(! \App::$profile['profile_uid'])
|
||||
return;
|
||||
|
||||
$block = observer_prohibited();
|
||||
|
||||
return profile_sidebar(\App::$profile, $block, true, true);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,5 +1,11 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* * Name: Search
|
||||
* * Description: A search form
|
||||
* * Requires: search, network, channel
|
||||
*/
|
||||
|
||||
namespace Zotlabs\Widget;
|
||||
|
||||
|
||||
|
||||
@@ -1,14 +1,18 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* * Name: Suggested chats
|
||||
* * Description: A menu with chatroom suggestions
|
||||
* * Requires: disabled_due_to_reasons
|
||||
*/
|
||||
|
||||
|
||||
namespace Zotlabs\Widget;
|
||||
|
||||
class Suggestedchats {
|
||||
|
||||
function widget($arr) {
|
||||
|
||||
if(! feature_enabled(\App::$profile['profile_uid'],'ajaxchat'))
|
||||
return '';
|
||||
|
||||
// There are reports that this tool does not ever remove chatrooms on dead sites,
|
||||
// and also will happily link to private chats which you cannot enter.
|
||||
// For those reasons, it will be disabled until somebody decides it's worth
|
||||
|
||||
@@ -1,5 +1,10 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* * Name: Suggestions
|
||||
* * Description: Display suggestions for new contacts
|
||||
*/
|
||||
|
||||
namespace Zotlabs\Widget;
|
||||
|
||||
use Zotlabs\Lib\Apps;
|
||||
@@ -12,7 +17,7 @@ class Suggestions {
|
||||
function widget($arr) {
|
||||
|
||||
|
||||
if((! local_channel()) || (! Apps::system_app_installed(local_channel(), 'Suggest Channels')))
|
||||
if(! local_channel())
|
||||
return EMPTY_STR;
|
||||
|
||||
$r = suggestion_query(local_channel(),get_observer_hash(),0,20);
|
||||
@@ -23,14 +28,14 @@ class Suggestions {
|
||||
|
||||
$arr = array();
|
||||
|
||||
// Get two random entries from the top 20 returned.
|
||||
// Get four random entries from the top 20 returned.
|
||||
// We'll grab the first one and the one immediately following.
|
||||
// This will throw some entropy intot he situation so you won't
|
||||
// be looking at the same two mug shots every time the widget runs
|
||||
|
||||
$index = ((count($r) > 2) ? mt_rand(0,count($r) - 2) : 0);
|
||||
$index = ((count($r) > 4) ? mt_rand(0,count($r) - 4) : 0);
|
||||
|
||||
for($x = $index; $x <= ($index+1); $x ++) {
|
||||
for($x = $index; $x <= ($index+3); $x ++) {
|
||||
$rr = $r[$x];
|
||||
if(! $rr['xchan_url'])
|
||||
break;
|
||||
|
||||
@@ -2,6 +2,11 @@
|
||||
|
||||
namespace Zotlabs\Widget;
|
||||
|
||||
/**
|
||||
* * Name: Tag cloud
|
||||
* * Description: Display hashtags of your network items in a cloud
|
||||
* * Requires: network, hq
|
||||
*/
|
||||
|
||||
class Tagcloud {
|
||||
|
||||
|
||||
@@ -1,5 +1,11 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* * Name: Tag cloud wall
|
||||
* * Description: Display hashtags of your channel wall items in a cloud if the feature is enabled
|
||||
* * Requires: channel
|
||||
*/
|
||||
|
||||
namespace Zotlabs\Widget;
|
||||
|
||||
class Tagcloud_wall {
|
||||
|
||||
@@ -1,8 +1,11 @@
|
||||
<?php
|
||||
|
||||
namespace Zotlabs\Widget;
|
||||
/**
|
||||
* * Name: Task list
|
||||
* * Description: Simple task list mangager
|
||||
*/
|
||||
|
||||
require_once('include/event.php');
|
||||
namespace Zotlabs\Widget;
|
||||
|
||||
class Tasklist {
|
||||
|
||||
@@ -20,7 +23,7 @@ class Tasklist {
|
||||
}
|
||||
</script>';
|
||||
|
||||
$o .= '<div class="widget">' . '<h3>' . t('Tasks') . '</h3><div class="tasklist-tasks">';
|
||||
$o .= '<div class="widget">' . '<h3>' . t('Tasks') . '</h3><div class="tasklist-tasks mb-1">';
|
||||
$o .= '</div><form id="tasklist-new-form" action="" ><input class="form-control" id="tasklist-new-summary" type="text" name="summary" value="" /></form>';
|
||||
$o .= '</div>';
|
||||
return $o;
|
||||
|
||||
@@ -1,5 +1,11 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* * Name: Tokens
|
||||
* * Description: Display a menu with links to existing guest access tokens
|
||||
* * Requires: tokens
|
||||
*/
|
||||
|
||||
namespace Zotlabs\Widget;
|
||||
|
||||
class Tokens {
|
||||
|
||||
@@ -1,5 +1,10 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* * Name: Vcard
|
||||
* * Description: Your default profile card
|
||||
*/
|
||||
|
||||
namespace Zotlabs\Widget;
|
||||
|
||||
class Vcard {
|
||||
|
||||
@@ -1,7 +1,12 @@
|
||||
<?php
|
||||
|
||||
namespace Zotlabs\Widget;
|
||||
/**
|
||||
* * Name: Website import/export
|
||||
* * Description: Tools to import and export websites
|
||||
* * Requires: website
|
||||
*/
|
||||
|
||||
namespace Zotlabs\Widget;
|
||||
|
||||
class Website_portation_tools {
|
||||
|
||||
|
||||
@@ -1,5 +1,10 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* * Name: Wiki list
|
||||
* * Description: A list of existing wikis
|
||||
*/
|
||||
|
||||
namespace Zotlabs\Widget;
|
||||
|
||||
class Wiki_list {
|
||||
|
||||
@@ -1,5 +1,11 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* * Name: Wiki page history
|
||||
* * Description: History of an existing wiki page
|
||||
* * Requires: wiki
|
||||
*/
|
||||
|
||||
namespace Zotlabs\Widget;
|
||||
|
||||
class Wiki_page_history {
|
||||
@@ -10,7 +16,7 @@ class Wiki_page_history {
|
||||
$resource_id = ((array_key_exists('resource_id', $arr)) ? $arr['resource_id'] : '');
|
||||
|
||||
$pageHistory = \Zotlabs\Lib\NativeWikiPage::page_history([
|
||||
'channel_id' => \App::$profile_uid,
|
||||
'channel_id' => \App::$profile_uid,
|
||||
'observer_hash' => get_observer_hash(),
|
||||
'resource_id' => $resource_id,
|
||||
'pageUrlName' => $pageUrlName
|
||||
|
||||
@@ -1,5 +1,11 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* * Name: Wiki pages
|
||||
* * Description: A list of existing pages of a wiki
|
||||
* * Requires: wiki
|
||||
*/
|
||||
|
||||
namespace Zotlabs\Widget;
|
||||
|
||||
use Zotlabs\Lib\NativeWiki;
|
||||
@@ -34,7 +40,7 @@ class Wiki_pages {
|
||||
'$addnew' => t('Add new page'),
|
||||
'$typelock' => $typelock,
|
||||
'$lockedtype' => $w['mimeType'],
|
||||
'$mimetype' => mimetype_select(0,$w['mimeType'],
|
||||
'$mimetype' => mimetype_select(0,$w['mimeType'],
|
||||
[ 'text/markdown' => t('Markdown'), 'text/bbcode' => t('BBcode'), 'text/plain' => t('Text') ]),
|
||||
'$pageName' => array('missingPageName', 'Create Page' , $pageName),
|
||||
'$refresh' => $arr['refresh'],
|
||||
@@ -91,7 +97,7 @@ class Wiki_pages {
|
||||
'$addnew' => t('Add new page'),
|
||||
'$typelock' => $typelock,
|
||||
'$lockedtype' => $w['mimeType'],
|
||||
'$mimetype' => mimetype_select(0,$w['mimeType'],
|
||||
'$mimetype' => mimetype_select(0,$w['mimeType'],
|
||||
[ 'text/markdown' => t('Markdown'), 'text/bbcode' => t('BBcode'), 'text/plain' => t('Text') ]),
|
||||
'$pageName' => array('pageName', t('Page name')),
|
||||
'$refresh' => $arr['refresh'],
|
||||
|
||||
@@ -1,5 +1,10 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* * Name: Zcard
|
||||
* * Description: Your default profile card including your cover photo
|
||||
*/
|
||||
|
||||
namespace Zotlabs\Widget;
|
||||
|
||||
class Zcard {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
version: 3
|
||||
url: $baseurl/pdledit
|
||||
version: 1
|
||||
url: $baseurl/pdledit_gui
|
||||
requires: local_channel
|
||||
name: PDL Editor
|
||||
photo: icon:object-group
|
||||
15
boot.php
15
boot.php
@@ -60,7 +60,7 @@ require_once('include/bbcode.php');
|
||||
require_once('include/items.php');
|
||||
|
||||
define('PLATFORM_NAME', 'hubzilla');
|
||||
define('STD_VERSION', '7.0.3');
|
||||
define('STD_VERSION', '7.2');
|
||||
define('ZOT_REVISION', '6.0');
|
||||
|
||||
define('DB_UPDATE_VERSION', 1252);
|
||||
@@ -915,9 +915,14 @@ class App {
|
||||
|
||||
if ((x($_SERVER, 'QUERY_STRING')) && substr($_SERVER['QUERY_STRING'], 0, 2) === "q=") {
|
||||
self::$query_string = str_replace(['<', '>'], ['<', '>'], substr($_SERVER['QUERY_STRING'], 2));
|
||||
|
||||
// removing trailing / - maybe a nginx problem
|
||||
if (substr(self::$query_string, 0, 1) == "/")
|
||||
self::$query_string = substr(self::$query_string, 1);
|
||||
|
||||
// trim trailing '&' if no extra args are present
|
||||
self::$query_string = rtrim(self::$query_string, '&');
|
||||
|
||||
// change the first & to ?
|
||||
self::$query_string = preg_replace('/&/', '?', self::$query_string, 1);
|
||||
}
|
||||
@@ -1687,7 +1692,7 @@ function fix_system_urls($oldurl, $newurl) {
|
||||
* @param boolean $login_page (optional) default true
|
||||
* @return string Parsed HTML code.
|
||||
*/
|
||||
function login($register = false, $form_id = 'main-login', $hiddens = false, $login_page = true) {
|
||||
function login($register = false, $form_id = 'main_login', $hiddens = false, $login_page = true) {
|
||||
|
||||
$o = '';
|
||||
$reg = null;
|
||||
@@ -1747,9 +1752,9 @@ function login($register = false, $form_id = 'main-login', $hiddens = false, $lo
|
||||
'$login' => t('Login'),
|
||||
'$remote_login' => t('Remote Authentication'),
|
||||
'$form_id' => $form_id,
|
||||
'$lname' => ['username', $lname_label],
|
||||
'$lpassword' => ['password', t('Password')],
|
||||
'$remember_me' => [(($login_page) ? 'remember' : 'remember_me'), t('Remember me'), '', '', [t('No'), t('Yes')]],
|
||||
'$lname' => [$form_id . '_username', $lname_label],
|
||||
'$lpassword' => [$form_id . '_password', t('Password')],
|
||||
'$remember_me' => [$form_id . '_remember', t('Remember me'), '', '', [t('No'), t('Yes')]],
|
||||
'$hiddens' => $hiddens,
|
||||
'$register' => $reg,
|
||||
'$lostpass' => t('Forgot your password?'),
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user