aboutsummaryrefslogtreecommitdiffstats
path: root/Zotlabs
diff options
context:
space:
mode:
authorMario Vavti <mario@mariovavti.com>2017-03-08 09:39:46 +0100
committerMario Vavti <mario@mariovavti.com>2017-03-08 09:39:46 +0100
commitbc2b948f1f6e62b1c277a4042200bb6678956f3f (patch)
tree8586c30e495607eee23f16c0aad40974f0711275 /Zotlabs
parent23e3e2c50499fab52769929a448e73012fd915af (diff)
parentff9442474d07cce24c8f66db39ec34471c3874a2 (diff)
downloadvolse-hubzilla-bc2b948f1f6e62b1c277a4042200bb6678956f3f.tar.gz
volse-hubzilla-bc2b948f1f6e62b1c277a4042200bb6678956f3f.tar.bz2
volse-hubzilla-bc2b948f1f6e62b1c277a4042200bb6678956f3f.zip
Merge branch 2.2RC2.2
Diffstat (limited to 'Zotlabs')
-rw-r--r--Zotlabs/Access/PermissionRoles.php53
-rw-r--r--Zotlabs/Access/Permissions.php95
-rw-r--r--Zotlabs/Daemon/Addon.php14
-rw-r--r--Zotlabs/Daemon/Checksites.php1
-rw-r--r--Zotlabs/Daemon/Cron_daily.php1
-rw-r--r--Zotlabs/Daemon/Cron_weekly.php1
-rw-r--r--Zotlabs/Daemon/Queue.php23
-rw-r--r--Zotlabs/Lib/Apps.php144
-rw-r--r--Zotlabs/Lib/NativeWiki.php210
-rw-r--r--Zotlabs/Lib/NativeWikiPage.php664
-rw-r--r--Zotlabs/Lib/Permcat.php146
-rw-r--r--Zotlabs/Lib/ThreadItem.php10
-rw-r--r--Zotlabs/Module/Acl.php53
-rw-r--r--Zotlabs/Module/Admin/Plugins.php19
-rw-r--r--Zotlabs/Module/Admin/Queue.php1
-rw-r--r--Zotlabs/Module/Admin/Site.php10
-rw-r--r--Zotlabs/Module/Admin/Themes.php2
-rw-r--r--Zotlabs/Module/Appman.php18
-rw-r--r--Zotlabs/Module/Apps.php14
-rw-r--r--Zotlabs/Module/Cal.php4
-rw-r--r--Zotlabs/Module/Channel.php18
-rw-r--r--Zotlabs/Module/Chat.php4
-rw-r--r--Zotlabs/Module/Chatsvc.php22
-rw-r--r--Zotlabs/Module/Cloud.php4
-rw-r--r--Zotlabs/Module/Connections.php16
-rw-r--r--Zotlabs/Module/Connedit.php124
-rw-r--r--Zotlabs/Module/Directory.php2
-rw-r--r--Zotlabs/Module/Display.php61
-rw-r--r--Zotlabs/Module/Editpost.php1
-rw-r--r--Zotlabs/Module/Events.php25
-rw-r--r--Zotlabs/Module/Ffsapi.php71
-rw-r--r--Zotlabs/Module/Fhublocs.php28
-rw-r--r--Zotlabs/Module/Hcard.php15
-rw-r--r--Zotlabs/Module/Hostxrd.php1
-rw-r--r--Zotlabs/Module/Import.php500
-rw-r--r--Zotlabs/Module/Item.php69
-rw-r--r--Zotlabs/Module/Like.php2
-rw-r--r--Zotlabs/Module/Lockview.php39
-rw-r--r--Zotlabs/Module/Mail.php37
-rw-r--r--Zotlabs/Module/Match.php84
-rw-r--r--Zotlabs/Module/Message.php2
-rw-r--r--Zotlabs/Module/Mood.php2
-rw-r--r--Zotlabs/Module/Notifications.php5
-rw-r--r--Zotlabs/Module/Oexchange.php2
-rw-r--r--Zotlabs/Module/Opensearch.php24
-rw-r--r--Zotlabs/Module/Permcat.php25
-rw-r--r--Zotlabs/Module/Photos.php32
-rw-r--r--Zotlabs/Module/Profile.php30
-rw-r--r--Zotlabs/Module/Profile_photo.php19
-rw-r--r--Zotlabs/Module/Profiles.php63
-rw-r--r--Zotlabs/Module/Profperm.php10
-rw-r--r--Zotlabs/Module/Rmagic.php15
-rw-r--r--Zotlabs/Module/Rsd_xml.php17
-rw-r--r--Zotlabs/Module/Search.php2
-rw-r--r--Zotlabs/Module/Settings/Channel.php48
-rw-r--r--Zotlabs/Module/Settings/Display.php17
-rw-r--r--Zotlabs/Module/Settings/Featured.php29
-rw-r--r--Zotlabs/Module/Settings/Permcats.php117
-rw-r--r--Zotlabs/Module/Settings/Tokens.php3
-rw-r--r--Zotlabs/Module/Setup.php9
-rw-r--r--Zotlabs/Module/Subthread.php2
-rw-r--r--Zotlabs/Module/Tagger.php7
-rw-r--r--Zotlabs/Module/Uexport.php17
-rw-r--r--Zotlabs/Module/Update_display.php18
-rw-r--r--Zotlabs/Module/Viewconnections.php2
-rw-r--r--Zotlabs/Module/Viewsrc.php4
-rw-r--r--Zotlabs/Module/Webpages.php6
-rw-r--r--Zotlabs/Module/Wfinger.php2
-rw-r--r--Zotlabs/Module/Wiki.php348
-rw-r--r--Zotlabs/Render/Comanche.php57
-rw-r--r--Zotlabs/Render/Theme.php12
-rw-r--r--Zotlabs/Storage/Browser.php8
-rw-r--r--Zotlabs/Web/HTTPHeaders.php46
-rw-r--r--Zotlabs/Web/Router.php25
74 files changed, 2621 insertions, 1010 deletions
diff --git a/Zotlabs/Access/PermissionRoles.php b/Zotlabs/Access/PermissionRoles.php
index 94c49c44f..49d478c5c 100644
--- a/Zotlabs/Access/PermissionRoles.php
+++ b/Zotlabs/Access/PermissionRoles.php
@@ -8,7 +8,7 @@ use Zotlabs\Lib as Zlib;
class PermissionRoles {
static public function version() {
- return 1;
+ return 2;
}
static function role_perms($role) {
@@ -25,7 +25,7 @@ class PermissionRoles {
$ret['online'] = true;
$ret['perms_connect'] = [
'view_stream', 'view_profile', 'view_contacts', 'view_storage',
- 'view_pages', 'send_stream', 'post_wall', 'post_comments',
+ 'view_pages', 'view_wiki', 'send_stream', 'post_wall', 'post_comments',
'post_mail', 'chat', 'post_like', 'republish' ];
$ret['limits'] = PermissionLimits::Std_Limits();
@@ -38,7 +38,7 @@ class PermissionRoles {
$ret['online'] = true;
$ret['perms_connect'] = [
'view_stream', 'view_profile', 'view_contacts', 'view_storage',
- 'view_pages', 'send_stream', 'post_wall', 'post_comments',
+ 'view_pages', 'view_wiki', 'send_stream', 'post_wall', 'post_comments',
'post_mail', 'chat', 'post_like' ];
$ret['limits'] = PermissionLimits::Std_Limits();
@@ -52,7 +52,7 @@ class PermissionRoles {
$ret['online'] = false;
$ret['perms_connect'] = [
'view_stream', 'view_profile', 'view_contacts', 'view_storage',
- 'view_pages', 'send_stream', 'post_wall', 'post_comments',
+ 'view_pages', 'view_wiki', 'send_stream', 'post_wall', 'post_comments',
'post_mail', 'post_like' ];
$ret['limits'] = PermissionLimits::Std_Limits();
$ret['limits']['view_contacts'] = PERMS_SPECIFIC;
@@ -67,7 +67,7 @@ class PermissionRoles {
$ret['online'] = false;
$ret['perms_connect'] = [
'view_stream', 'view_profile', 'view_contacts', 'view_storage',
- 'view_pages', 'post_wall', 'post_comments', 'tag_deliver',
+ 'view_pages', 'view_wiki', 'post_wall', 'post_comments', 'tag_deliver',
'post_mail', 'post_like' , 'republish', 'chat' ];
$ret['limits'] = PermissionLimits::Std_Limits();
@@ -80,7 +80,7 @@ class PermissionRoles {
$ret['online'] = false;
$ret['perms_connect'] = [
'view_stream', 'view_profile', 'view_contacts', 'view_storage',
- 'view_pages', 'post_wall', 'post_comments', 'tag_deliver',
+ 'view_pages', 'view_wiki', 'post_wall', 'post_comments', 'tag_deliver',
'post_mail', 'post_like' , 'chat' ];
$ret['limits'] = PermissionLimits::Std_Limits();
@@ -95,7 +95,7 @@ class PermissionRoles {
$ret['perms_connect'] = [
'view_stream', 'view_profile', 'view_contacts', 'view_storage',
- 'view_pages', 'post_wall', 'post_comments',
+ 'view_pages', 'view_wiki', 'post_wall', 'post_comments',
'post_mail', 'post_like' , 'chat' ];
$ret['limits'] = PermissionLimits::Std_Limits();
@@ -103,6 +103,7 @@ class PermissionRoles {
$ret['limits']['view_contacts'] = PERMS_SPECIFIC;
$ret['limits']['view_storage'] = PERMS_SPECIFIC;
$ret['limits']['view_pages'] = PERMS_SPECIFIC;
+ $ret['limits']['view_wiki'] = PERMS_SPECIFIC;
break;
@@ -114,7 +115,7 @@ class PermissionRoles {
$ret['perms_connect'] = [
'view_stream', 'view_profile', 'view_contacts', 'view_storage',
- 'view_pages', 'send_stream', 'post_wall', 'post_comments',
+ 'view_pages', 'view_wiki', 'send_stream', 'post_wall', 'post_comments',
'post_mail', 'post_like' , 'republish' ];
$ret['limits'] = PermissionLimits::Std_Limits();
@@ -128,7 +129,7 @@ class PermissionRoles {
$ret['online'] = false;
$ret['perms_connect'] = [
'view_stream', 'view_profile', 'view_contacts', 'view_storage',
- 'view_pages', 'send_stream', 'post_wall', 'post_comments',
+ 'view_pages', 'view_wiki', 'send_stream', 'post_wall', 'post_comments',
'post_mail', 'post_like' , 'republish' ];
$ret['limits'] = PermissionLimits::Std_Limits();
@@ -143,7 +144,7 @@ class PermissionRoles {
$ret['perms_connect'] = [
'view_stream', 'view_profile', 'view_contacts', 'view_storage',
- 'view_pages', 'post_like' , 'republish' ];
+ 'view_pages', 'view_wiki', 'post_like' , 'republish' ];
$ret['limits'] = PermissionLimits::Std_Limits();
@@ -157,8 +158,8 @@ class PermissionRoles {
$ret['perms_connect'] = [
'view_stream', 'view_profile', 'view_contacts', 'view_storage',
- 'view_pages', 'write_storage', 'write_pages', 'post_wall', 'post_comments', 'tag_deliver',
- 'post_mail', 'post_like' , 'republish', 'chat' ];
+ 'view_pages', 'view_wiki', 'write_storage', 'write_pages', 'post_wall', 'post_comments', 'tag_deliver',
+ 'post_mail', 'post_like' , 'republish', 'chat', 'write_wiki' ];
$ret['limits'] = PermissionLimits::Std_Limits();
break;
@@ -185,6 +186,12 @@ class PermissionRoles {
// if($perm === 'mynewperm')
// \Zotlabs\Access\PermissionLimits::Set($uid,$perm,1);
+ if($perm === 'view_wiki')
+ \Zotlabs\Access\PermissionLimits::Set($uid,$perm,PERMS_PUBLIC);
+
+ if($perm === 'write_wiki')
+ \Zotlabs\Access\PermissionLimits::Set($uid,$perm,PERMS_SPECIFIC);
+
// set autoperms here if applicable
// choices are to set to 0, 1, or the value of an existing perm
@@ -195,7 +202,13 @@ class PermissionRoles {
$value = 0;
// if($perm === 'mynewperm')
- // $value = get_abconfig($uid,$c['channel_hash'],'autoperms','someexistingperm'));
+ // $value = get_abconfig($uid,$c['channel_hash'],'autoperms','someexistingperm');
+
+ if($perm === 'view_wiki')
+ $value = get_abconfig($uid,$c['channel_hash'],'autoperms','view_pages');
+
+ if($perm === 'write_wiki')
+ $value = get_abconfig($uid,$c['channel_hash'],'autoperms','write_pages');
if($c) {
set_abconfig($uid,$c['channel_hash'],'autoperms',$perm,$value);
@@ -212,8 +225,16 @@ class PermissionRoles {
// case 'mynewperm':
// choices are to set to 1, set to 0, or clone an existing perm
// set_abconfig($uid,$ab['abook_xchan'],'my_perms',$perm,
- // get_abconfig($uid,$ab['abook_xchan'],'my_perms','someexistingperm'));
-
+ // intval(get_abconfig($uid,$ab['abook_xchan'],'my_perms','someexistingperm')));
+
+ case 'view_wiki':
+ set_abconfig($uid,$ab['abook_xchan'],'my_perms',$perm,
+ intval(get_abconfig($uid,$ab['abook_xchan'],'my_perms','view_pages')));
+
+ case 'write_wiki':
+ set_abconfig($uid,$ab['abook_xchan'],'my_perms',$perm,
+ intval(get_abconfig($uid,$ab['abook_xchan'],'my_perms','write_pages')));
+
default:
break;
}
@@ -255,6 +276,4 @@ class PermissionRoles {
return $roles;
}
-
-
} \ No newline at end of file
diff --git a/Zotlabs/Access/Permissions.php b/Zotlabs/Access/Permissions.php
index 43baa6cf7..d51e4d0ea 100644
--- a/Zotlabs/Access/Permissions.php
+++ b/Zotlabs/Access/Permissions.php
@@ -18,7 +18,7 @@ class Permissions {
* permission roles. You will want to set a default PermissionLimit for each channel and also
* provide a sane default for any existing connections. You may or may not wish to provide a
* default auto permission. If in doubt, leave this alone as custom permissions by definition
- * are the responsbility of the channel owner to manage. You just don't want to create any
+ * are the responsibility of the channel owner to manage. You just don't want to create any
* suprises or break things so you have an opportunity to provide sane settings.
*
* Update the version here and in PermissionRoles
@@ -36,7 +36,7 @@ class Permissions {
static public function version() {
// This must match the version in PermissionRoles.php before permission updates can run.
- return 1;
+ return 2;
}
@@ -50,7 +50,9 @@ class Permissions {
'view_storage' => t('Can view my file storage and photos'),
'write_storage' => t('Can upload/modify my file storage and photos'),
'view_pages' => t('Can view my channel webpages'),
+ 'view_wiki' => t('Can view my wiki pages'),
'write_pages' => t('Can create/edit my channel webpages'),
+ 'write_wiki' => t('Can write to my wiki pages'),
'post_wall' => t('Can post on my channel (wall) page'),
'post_comments' => t('Can comment on or like my posts'),
'post_mail' => t('Can send me private mail messages'),
@@ -92,6 +94,10 @@ class Permissions {
// Undeclared permissions are set to 0
static public function FilledPerms($arr) {
+ if(is_null($arr)) {
+ btlogger('FilledPerms: null');
+ }
+
$everything = self::Perms();
$ret = [];
foreach($everything as $k => $v) {
@@ -104,6 +110,17 @@ class Permissions {
}
+ static public function OPerms($arr) {
+ $ret = [];
+ if($arr) {
+ foreach($arr as $k => $v) {
+ $ret[] = [ 'name' => $k, 'value' => $v ];
+ }
+ }
+ return $ret;
+ }
+
+
static public function FilledAutoperms($channel_id) {
if(! intval(get_pconfig($channel_id,'system','autoperms')))
return false;
@@ -114,7 +131,7 @@ class Permissions {
);
if($r) {
foreach($r as $rr) {
- $arr[$rr['k']] = $arr[$rr['v']];
+ $arr[$rr['k']] = intval($rr['v']);
}
}
return $arr;
@@ -129,4 +146,76 @@ class Permissions {
}
return true;
}
+
+ static public function connect_perms($channel_id) {
+
+ $my_perms = [];
+ $permcat = null;
+ $automatic = 0;
+
+ // If a default permcat exists, use that
+
+ $pc = ((feature_enabled($channel_id,'permcats')) ? get_pconfig($channel_id,'system','default_permcat') : 'default');
+ if(! in_array($pc, [ '','default' ])) {
+ $pcp = new Zlib\Permcat($channel_id);
+ $permcat = $pcp->fetch($pc);
+ if($permcat && $permcat['perms']) {
+ foreach($permcat['perms'] as $p) {
+ $my_perms[$p['name']] = $p['value'];
+ }
+ }
+ }
+
+ // look up the permission role to see if it specified auto-connect
+ // and if there was no permcat or a default permcat, set the perms
+ // from the role
+
+ $role = get_pconfig($channel_id,'system','permissions_role');
+ if($role) {
+ $xx = PermissionRoles::role_perms($role);
+ if($xx['perms_auto'])
+ $automatic = 1;
+
+ if((! $my_perms) && ($xx['perms_connect'])) {
+ $default_perms = $xx['perms_connect'];
+ $my_perms = Permissions::FilledPerms($default_perms);
+ }
+ }
+
+ // If we reached this point without having any permission information,
+ // it is likely a custom permissions role. First see if there are any
+ // automatic permissions.
+
+ if(! $my_perms) {
+ $m = Permissions::FilledAutoperms($channel_id);
+ if($m) {
+ $automatic = 1;
+ $my_perms = $m;
+ }
+ }
+
+ // If we reached this point with no permissions, the channel is using
+ // custom perms but they are not automatic. They will be stored in abconfig with
+ // the channel's channel_hash (the 'self' connection).
+
+ if(! $my_perms) {
+ $r = q("select channel_hash from channel where channel_id = %d",
+ intval($channel_id)
+ );
+ if($r) {
+ $x = q("select * from abconfig where chan = %d and xchan = '%s' and cat = 'my_perms'",
+ intval($channel_id),
+ dbesc($r[0]['channel_hash'])
+ );
+ if($x) {
+ foreach($x as $xv) {
+ $my_perms[$xv['k']] = intval($xv['v']);
+ }
+ }
+ }
+ }
+
+ return ( [ 'perms' => $my_perms, 'automatic' => $automatic ] );
+ }
+
} \ No newline at end of file
diff --git a/Zotlabs/Daemon/Addon.php b/Zotlabs/Daemon/Addon.php
new file mode 100644
index 000000000..c2889e596
--- /dev/null
+++ b/Zotlabs/Daemon/Addon.php
@@ -0,0 +1,14 @@
+<?php
+
+namespace Zotlabs\Daemon;
+
+require_once('include/zot.php');
+
+class Addon {
+
+ static public function run($argc,$argv) {
+
+ call_hooks('daemon_addon',$argv);
+
+ }
+}
diff --git a/Zotlabs/Daemon/Checksites.php b/Zotlabs/Daemon/Checksites.php
index 991456319..a2081967a 100644
--- a/Zotlabs/Daemon/Checksites.php
+++ b/Zotlabs/Daemon/Checksites.php
@@ -3,7 +3,6 @@
namespace Zotlabs\Daemon;
require_once('include/zot.php');
-require_once('include/hubloc.php');
class Checksites {
diff --git a/Zotlabs/Daemon/Cron_daily.php b/Zotlabs/Daemon/Cron_daily.php
index a16d49853..0f0001890 100644
--- a/Zotlabs/Daemon/Cron_daily.php
+++ b/Zotlabs/Daemon/Cron_daily.php
@@ -76,7 +76,6 @@ class Cron_daily {
Master::Summon(array('Expire'));
Master::Summon(array('Cli_suggest'));
- require_once('include/hubloc.php');
remove_obsolete_hublocs();
call_hooks('cron_daily',datetime_convert());
diff --git a/Zotlabs/Daemon/Cron_weekly.php b/Zotlabs/Daemon/Cron_weekly.php
index ba4b67ff5..5b185f475 100644
--- a/Zotlabs/Daemon/Cron_weekly.php
+++ b/Zotlabs/Daemon/Cron_weekly.php
@@ -17,7 +17,6 @@ class Cron_weekly {
z_check_cert();
- require_once('include/hubloc.php');
prune_hub_reinstalls();
mark_orphan_hubsxchans();
diff --git a/Zotlabs/Daemon/Queue.php b/Zotlabs/Daemon/Queue.php
index 27306589d..11cbe4494 100644
--- a/Zotlabs/Daemon/Queue.php
+++ b/Zotlabs/Daemon/Queue.php
@@ -61,30 +61,15 @@ class Queue {
// the site is permanently down, there's no reason to attempt delivery at all, or at most not more than once
// or twice a day.
- // FIXME: can we sort postgres on outq_priority and maintain the 'distinct' ?
- // The order by max(outq_priority) might be a dodgy query because of the group by.
- // The desired result is to return a sequence in the order most likely to be delivered in this run.
- // If a hub has already been sitting in the queue for a few days, they should be delivered last;
- // hence every failure should drop them further down the priority list.
-
- if(ACTIVE_DBTYPE == DBTYPE_POSTGRES) {
- $prefix = 'DISTINCT ON (outq_posturl)';
- $suffix = 'ORDER BY outq_posturl';
- } else {
- $prefix = '';
- $suffix = 'GROUP BY outq_posturl ORDER BY max(outq_priority)';
- }
- $r = q("SELECT $prefix * FROM outq WHERE outq_delivered = 0 and (( outq_created > %s - INTERVAL %s and outq_updated < %s - INTERVAL %s ) OR ( outq_updated < %s - INTERVAL %s )) $suffix",
- db_utcnow(), db_quoteinterval('12 HOUR'),
- db_utcnow(), db_quoteinterval('15 MINUTE'),
- db_utcnow(), db_quoteinterval('1 HOUR')
+ $r = q("SELECT * FROM outq WHERE outq_delivered = 0 and outq_scheduled < %s ",
+ db_utcnow()
);
}
if(! $r)
return;
- foreach($r as $rr) {
- queue_deliver($rr);
+ foreach($r as $rv) {
+ queue_deliver($rv);
}
}
}
diff --git a/Zotlabs/Lib/Apps.php b/Zotlabs/Lib/Apps.php
index ac03e11e1..0ca2f7a99 100644
--- a/Zotlabs/Lib/Apps.php
+++ b/Zotlabs/Lib/Apps.php
@@ -38,6 +38,7 @@ class Apps {
if(plugin_is_installed($plugin)) {
$x = self::parse_app_description($f,$translate);
if($x) {
+ $x['plugin'] = $plugin;
$ret[] = $x;
}
}
@@ -54,7 +55,6 @@ class Apps {
return;
$apps = self::get_system_apps(false);
-
self::$installed_system_apps = q("select * from app where app_system = 1 and app_channel = %d",
intval(local_channel())
);
@@ -102,11 +102,13 @@ class Apps {
foreach(self::$installed_system_apps as $iapp) {
if($iapp['app_id'] == hash('whirlpool',$app['name'])) {
$notfound = false;
- if($iapp['app_version'] != $app['version']) {
+ if(($iapp['app_version'] != $app['version'])
+ || ($app['plugin'] && (! $iapp['app_plugin']))) {
return intval($iapp['app_id']);
}
}
}
+
return $notfound;
}
@@ -144,8 +146,11 @@ class Apps {
$ret['type'] = 'system';
foreach($ret as $k => $v) {
- if(strpos($v,'http') === 0)
- $ret[$k] = zid($v);
+ if(strpos($v,'http') === 0) {
+ if(! (local_channel() && strpos($v,z_root()) === 0)) {
+ $ret[$k] = zid($v);
+ }
+ }
}
if(array_key_exists('desc',$ret))
@@ -157,6 +162,8 @@ class Apps {
if(array_key_exists('version',$ret))
$ret['version'] = str_replace(array('\'','"'),array('&#39;','&dquot;'),$ret['version']);
+ if(array_key_exists('categories',$ret))
+ $ret['categories'] = str_replace(array('\'','"'),array('&#39;','&dquot;'),$ret['categories']);
if(array_key_exists('requires',$ret)) {
$requires = explode(',',$ret['requires']);
@@ -238,9 +245,9 @@ class Apps {
'Profile Photo' => t('Profile Photo')
);
- if(array_key_exists($arr['name'],$apps))
+ if(array_key_exists($arr['name'],$apps)) {
$arr['name'] = $apps[$arr['name']];
-
+ }
}
@@ -255,6 +262,7 @@ class Apps {
* list: normal mode for viewing an app on the app page
* no buttons are shown
* edit: viewing the app page in editing mode provides a delete button
+ * nav: render apps for app-bin
*/
$installed = false;
@@ -267,14 +275,20 @@ class Apps {
self::translate_system_apps($papp);
+ if(($papp['plugin']) && (! plugin_is_installed($papp['plugin'])))
+ return '';
+
$papp['papp'] = self::papp_encode($papp);
if(! strstr($papp['url'],'://'))
$papp['url'] = z_root() . ((strpos($papp['url'],'/') === 0) ? '' : '/') . $papp['url'];
foreach($papp as $k => $v) {
- if(strpos($v,'http') === 0 && $k != 'papp')
- $papp[$k] = zid($v);
+ if(strpos($v,'http') === 0 && $k != 'papp') {
+ if(! (local_channel() && strpos($v,z_root()) === 0)) {
+ $papp[$k] = zid($v);
+ }
+ }
if($k === 'desc')
$papp['desc'] = str_replace(array('\'','"'),array('&#39;','&dquot;'),$papp['desc']);
@@ -332,14 +346,23 @@ class Apps {
}
$install_action = (($installed) ? t('Update') : t('Install'));
+ $icon = ((strpos($papp['photo'],'icon:') === 0) ? substr($papp['photo'],5) : '');
return replace_macros(get_markup_template('app.tpl'),array(
'$app' => $papp,
+ '$icon' => $icon,
'$hosturl' => $hosturl,
'$purchase' => (($papp['page'] && (! $installed)) ? t('Purchase') : ''),
'$install' => (($hosturl && $mode == 'view') ? $install_action : ''),
'$edit' => ((local_channel() && $installed && $mode == 'edit') ? t('Edit') : ''),
- '$delete' => ((local_channel() && $installed && $mode == 'edit') ? t('Delete') : '')
+ '$delete' => ((local_channel() && $installed && $mode == 'edit') ? t('Delete') : ''),
+ '$undelete' => ((local_channel() && $installed && $mode == 'edit') ? t('Undelete') : ''),
+ '$deleted' => $papp['deleted'],
+ '$feature' => (($papp['embed']) ? false : true),
+ '$featured' => ((strpos($papp['categories'], 'nav_featured_app') === false) ? false : true),
+ '$navapps' => (($mode == 'nav') ? true : false),
+ '$add' => t('Add to app-tray'),
+ '$remove' => t('Remove from app-tray')
));
}
@@ -382,36 +405,82 @@ class Apps {
intval($uid)
);
if($x) {
- $x[0]['app_deleted'] = 1;
- q("delete from term where otype = %d and oid = %d",
- intval(TERM_OBJ_APP),
- intval($x[0]['id'])
- );
- if($x[0]['app_system']) {
- $r = q("update app set app_deleted = 1 where app_id = '%s' and app_channel = %d",
- dbesc($app['guid']),
- intval($uid)
+ if(! intval($x[0]['app_deleted'])) {
+ $x[0]['app_deleted'] = 1;
+ q("delete from term where otype = %d and oid = %d",
+ intval(TERM_OBJ_APP),
+ intval($x[0]['id'])
);
+ if($x[0]['app_system']) {
+ $r = q("update app set app_deleted = 1 where app_id = '%s' and app_channel = %d",
+ dbesc($app['guid']),
+ intval($uid)
+ );
+ }
+ else {
+ $r = q("delete from app where app_id = '%s' and app_channel = %d",
+ dbesc($app['guid']),
+ intval($uid)
+ );
+
+ // we don't sync system apps - they may be completely different on the other system
+ build_sync_packet($uid,array('app' => $x));
+ }
}
else {
- $r = q("delete from app where app_id = '%s' and app_channel = %d",
+ self::app_undestroy($uid,$app);
+ }
+ }
+ }
+ }
+
+ static public function app_undestroy($uid,$app) {
+
+ // undelete a system app
+
+ if($uid && $app['guid']) {
+
+ $x = q("select * from app where app_id = '%s' and app_channel = %d limit 1",
+ dbesc($app['guid']),
+ intval($uid)
+ );
+ if($x) {
+ if($x[0]['app_system']) {
+ $r = q("update app set app_deleted = 0 where app_id = '%s' and app_channel = %d",
dbesc($app['guid']),
intval($uid)
);
-
- // we don't sync system apps - they may be completely different on the other system
- build_sync_packet($uid,array('app' => $x));
}
}
}
}
+ static public function app_feature($uid,$app) {
+ $r = q("select id from app where app_id = '%s' and app_channel = %d limit 1",
+ dbesc($app['guid']),
+ intval($uid)
+ );
+
+ $x = q("select * from term where otype = %d and oid = %d and term = 'nav_featured_app' limit 1",
+ intval(TERM_OBJ_APP),
+ intval($r[0]['id'])
+ );
+
+ if($x) {
+ q("delete from term where otype = %d and oid = %d and term = 'nav_featured_app'",
+ intval(TERM_OBJ_APP),
+ intval($x[0]['oid'])
+ );
+ }
+ else {
+ store_item_tag($uid,$r[0]['id'],TERM_OBJ_APP,TERM_CATEGORY,'nav_featured_app',escape_tags(z_root() . '/apps/?f=&cat=nav_featured_app'));
+ }
+ }
static public function app_installed($uid,$app) {
- $r = q("select id from app where app_id = '%s' and app_version = '%s' and app_channel = %d limit 1",
+ $r = q("select id from app where app_id = '%s' and app_channel = %d limit 1",
dbesc((array_key_exists('guid',$app)) ? $app['guid'] : ''),
- dbesc((array_key_exists('version',$app)) ? $app['version'] : ''),
intval($uid)
);
return(($r) ? true : false);
@@ -421,7 +490,7 @@ class Apps {
static public function app_list($uid, $deleted = false, $cat = '') {
if($deleted)
- $sql_extra = " and app_deleted = 1 ";
+ $sql_extra = "";
else
$sql_extra = " and app_deleted = 0 ";
@@ -445,6 +514,7 @@ class Apps {
$r = q("select * from app where app_channel = %d $sql_extra order by app_name asc",
intval($uid)
);
+
if($r) {
for($x = 0; $x < count($r); $x ++) {
if(! $r[$x]['app_system'])
@@ -455,6 +525,7 @@ class Apps {
);
}
}
+
return($r);
}
@@ -467,7 +538,7 @@ class Apps {
static public function app_store($arr) {
- // logger('app_store: ' . print_r($arr,true));
+ //logger('app_store: ' . print_r($arr,true));
$darray = array();
$ret = array('success' => false);
@@ -478,7 +549,7 @@ class Apps {
if((! $darray['app_url']) || (! $darray['app_channel']))
return $ret;
- if($arr['photo'] && ! strstr($arr['photo'],z_root())) {
+ if($arr['photo'] && (strpos($arr['photo'],'icon:') !== 0) && (! strstr($arr['photo'],z_root()))) {
$x = import_xchan_photo($arr['photo'],get_observer_hash(),true);
$arr['photo'] = $x[1];
}
@@ -494,13 +565,14 @@ class Apps {
$darray['app_addr'] = ((x($arr,'addr')) ? escape_tags($arr['addr']) : '');
$darray['app_price'] = ((x($arr,'price')) ? escape_tags($arr['price']) : '');
$darray['app_page'] = ((x($arr,'page')) ? escape_tags($arr['page']) : '');
+ $darray['app_plugin'] = ((x($arr,'plugin')) ? escape_tags($arr['plugin']) : '');
$darray['app_requires'] = ((x($arr,'requires')) ? escape_tags($arr['requires']) : '');
$darray['app_system'] = ((x($arr,'system')) ? intval($arr['system']) : 0);
$darray['app_deleted'] = ((x($arr,'deleted')) ? intval($arr['deleted']) : 0);
$created = datetime_convert();
- $r = q("insert into app ( app_id, app_sig, app_author, app_name, app_desc, app_url, app_photo, app_version, app_channel, app_addr, app_price, app_page, app_requires, app_created, app_edited, app_system, app_deleted ) values ( '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', %d, '%s', '%s', '%s', '%s', '%s', '%s', %d, %d )",
+ $r = q("insert into app ( app_id, app_sig, app_author, app_name, app_desc, app_url, app_photo, app_version, app_channel, app_addr, app_price, app_page, app_requires, app_created, app_edited, app_system, app_plugin, app_deleted ) values ( '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', %d, '%s', '%s', '%s', '%s', '%s', '%s', %d, '%s', %d )",
dbesc($darray['app_id']),
dbesc($darray['app_sig']),
dbesc($darray['app_author']),
@@ -517,6 +589,7 @@ class Apps {
dbesc($created),
dbesc($created),
intval($darray['app_system']),
+ dbesc($darray['app_plugin']),
intval($darray['app_deleted'])
);
if($r) {
@@ -545,6 +618,7 @@ class Apps {
static public function app_update($arr) {
+ //logger('app_update: ' . print_r($arr,true));
$darray = array();
$ret = array('success' => false);
@@ -555,7 +629,7 @@ class Apps {
if((! $darray['app_url']) || (! $darray['app_channel']) || (! $darray['app_id']))
return $ret;
- if($arr['photo'] && ! strstr($arr['photo'],z_root())) {
+ if($arr['photo'] && (strpos($arr['photo'],'icon:') !== 0) && (! strstr($arr['photo'],z_root()))) {
$x = import_xchan_photo($arr['photo'],get_observer_hash(),true);
$arr['photo'] = $x[1];
}
@@ -569,13 +643,14 @@ class Apps {
$darray['app_addr'] = ((x($arr,'addr')) ? escape_tags($arr['addr']) : '');
$darray['app_price'] = ((x($arr,'price')) ? escape_tags($arr['price']) : '');
$darray['app_page'] = ((x($arr,'page')) ? escape_tags($arr['page']) : '');
+ $darray['app_plugin'] = ((x($arr,'plugin')) ? escape_tags($arr['plugin']) : '');
$darray['app_requires'] = ((x($arr,'requires')) ? escape_tags($arr['requires']) : '');
$darray['app_system'] = ((x($arr,'system')) ? intval($arr['system']) : 0);
$darray['app_deleted'] = ((x($arr,'deleted')) ? intval($arr['deleted']) : 0);
$edited = datetime_convert();
- $r = q("update app set app_sig = '%s', app_author = '%s', app_name = '%s', app_desc = '%s', app_url = '%s', app_photo = '%s', app_version = '%s', app_addr = '%s', app_price = '%s', app_page = '%s', app_requires = '%s', app_edited = '%s', app_system = %d, app_deleted = %d where app_id = '%s' and app_channel = %d",
+ $r = q("update app set app_sig = '%s', app_author = '%s', app_name = '%s', app_desc = '%s', app_url = '%s', app_photo = '%s', app_version = '%s', app_addr = '%s', app_price = '%s', app_page = '%s', app_requires = '%s', app_edited = '%s', app_system = %d, app_plugin = '%s', app_deleted = %d where app_id = '%s' and app_channel = %d",
dbesc($darray['app_sig']),
dbesc($darray['app_author']),
dbesc($darray['app_name']),
@@ -589,6 +664,7 @@ class Apps {
dbesc($darray['app_requires']),
dbesc($edited),
intval($darray['app_system']),
+ dbesc($darray['app_plugin']),
intval($darray['app_deleted']),
dbesc($darray['app_id']),
intval($darray['app_channel'])
@@ -655,6 +731,9 @@ class Apps {
if($app['app_photo'])
$ret['photo'] = $app['app_photo'];
+ if($app['app_icon'])
+ $ret['icon'] = $app['app_icon'];
+
if($app['app_version'])
$ret['version'] = $app['app_version'];
@@ -673,6 +752,9 @@ class Apps {
if($app['app_system'])
$ret['system'] = $app['app_system'];
+ if($app['app_plugin'])
+ $ret['plugin'] = $app['app_plugin'];
+
if($app['app_deleted'])
$ret['deleted'] = $app['app_deleted'];
@@ -690,6 +772,8 @@ class Apps {
if(! $embed)
return $ret;
+ $ret['embed'] = true;
+
if(array_key_exists('categories',$ret))
unset($ret['categories']);
diff --git a/Zotlabs/Lib/NativeWiki.php b/Zotlabs/Lib/NativeWiki.php
new file mode 100644
index 000000000..7786ec25a
--- /dev/null
+++ b/Zotlabs/Lib/NativeWiki.php
@@ -0,0 +1,210 @@
+<?php
+
+namespace Zotlabs\Lib;
+
+define ( 'NWIKI_ITEM_RESOURCE_TYPE', 'nwiki' );
+
+class NativeWiki {
+
+
+ static public function listwikis($channel, $observer_hash) {
+
+ $sql_extra = item_permissions_sql($channel['channel_id'], $observer_hash);
+ $wikis = q("SELECT * FROM item
+ WHERE resource_type = '%s' AND mid = parent_mid AND uid = %d AND item_deleted = 0 $sql_extra",
+ dbesc(NWIKI_ITEM_RESOURCE_TYPE),
+ intval($channel['channel_id'])
+ );
+
+ if($wikis) {
+ foreach($wikis as &$w) {
+ $w['rawName'] = get_iconfig($w, 'wiki', 'rawName');
+ $w['htmlName'] = escape_tags($w['rawName']);
+ $w['urlName'] = urlencode(urlencode($w['rawName']));
+ $w['mimeType'] = get_iconfig($w, 'wiki', 'mimeType');
+ $w['lock'] = (($w['item_private'] || $w['allow_cid'] || $w['allow_gid'] || $w['deny_cid'] || $w['deny_gid']) ? true : false);
+ }
+ }
+ // TODO: query db for wikis the observer can access. Return with two lists, for read and write access
+ return array('wikis' => $wikis);
+ }
+
+
+ function create_wiki($channel, $observer_hash, $wiki, $acl) {
+
+ // Generate unique resource_id using the same method as item_message_id()
+ do {
+ $dups = false;
+ $resource_id = random_string();
+ $r = q("SELECT mid FROM item WHERE resource_id = '%s' AND resource_type = '%s' AND uid = %d LIMIT 1",
+ dbesc($resource_id),
+ dbesc(NWIKI_ITEM_RESOURCE_TYPE),
+ intval($channel['channel_id'])
+ );
+ if($r)
+ $dups = true;
+ } while($dups == true);
+
+ $ac = $acl->get();
+ $mid = item_message_id();
+
+ $arr = array(); // Initialize the array of parameters for the post
+ $item_hidden = ((intval($wiki['postVisible']) === 0) ? 1 : 0);
+ $wiki_url = z_root() . '/wiki/' . $channel['channel_address'] . '/' . $wiki['urlName'];
+ $arr['aid'] = $channel['channel_account_id'];
+ $arr['uid'] = $channel['channel_id'];
+ $arr['mid'] = $mid;
+ $arr['parent_mid'] = $mid;
+ $arr['item_hidden'] = $item_hidden;
+ $arr['resource_type'] = NWIKI_ITEM_RESOURCE_TYPE;
+ $arr['resource_id'] = $resource_id;
+ $arr['owner_xchan'] = $channel['channel_hash'];
+ $arr['author_xchan'] = $observer_hash;
+ $arr['plink'] = z_root() . '/channel/' . $channel['channel_address'] . '/?f=&mid=' . urlencode($arr['mid']);
+ $arr['llink'] = $arr['plink'];
+ $arr['title'] = $wiki['htmlName']; // name of new wiki;
+ $arr['allow_cid'] = $ac['allow_cid'];
+ $arr['allow_gid'] = $ac['allow_gid'];
+ $arr['deny_cid'] = $ac['deny_cid'];
+ $arr['deny_gid'] = $ac['deny_gid'];
+ $arr['item_wall'] = 1;
+ $arr['item_origin'] = 1;
+ $arr['item_thread_top'] = 1;
+ $arr['item_private'] = intval($acl->is_private());
+ $arr['verb'] = ACTIVITY_CREATE;
+ $arr['obj_type'] = ACTIVITY_OBJ_WIKI;
+ $arr['body'] = '[table][tr][td][h1]New Wiki[/h1][/td][/tr][tr][td][zrl=' . $wiki_url . ']' . $wiki['htmlName'] . '[/zrl][/td][/tr][/table]';
+
+ $arr['public_policy'] = map_scope(\Zotlabs\Access\PermissionLimits::Get($channel['channel_id'],'view_wiki'),true);
+
+ // Save the wiki name information using iconfig. This is shareable.
+ if(! set_iconfig($arr, 'wiki', 'rawName', $wiki['rawName'], true)) {
+ return array('item' => null, 'success' => false);
+ }
+ if(! set_iconfig($arr, 'wiki', 'mimeType', $wiki['mimeType'], true)) {
+ return array('item' => null, 'success' => false);
+ }
+
+ $post = item_store($arr);
+
+ $item_id = $post['item_id'];
+
+ if($item_id) {
+ \Zotlabs\Daemon\Master::Summon(array('Notifier', 'activity', $item_id));
+ return array('item' => $post['item'], 'item_id' => $item_id, 'success' => true);
+ }
+ else {
+ return array('item' => null, 'success' => false);
+ }
+ }
+
+ static public function sync_a_wiki_item($uid,$id,$resource_id) {
+
+
+ $r = q("SELECT * from item WHERE uid = %d AND ( id = %d OR ( resource_type = '%s' and resource_id = %d )) ",
+ intval($uid),
+ intval($id),
+ dbesc(NWIKI_ITEM_RESOURCE_TYPE),
+ intval($resource_id)
+ );
+ if($r) {
+ xchan_query($r);
+ $sync_item = fetch_post_tags($r);
+ build_sync_packet($uid,array('wiki' => array(encode_item($sync_item[0],true))));
+ }
+ }
+
+ function delete_wiki($channel_id,$observer_hash,$resource_id) {
+
+ $w = self::get_wiki($channel_id,$observer_hash,$resource_id);
+ $item = $w['wiki'];
+ if(! $item) {
+ return array('item' => null, 'success' => false);
+ }
+ else {
+ $drop = drop_item($item['id'], false, DROPITEM_NORMAL, true);
+ }
+
+ info( t('Wiki files deleted successfully'));
+
+ return array('item' => $item, 'item_id' => $item['id'], 'success' => (($drop === 1) ? true : false));
+ }
+
+
+ static public function get_wiki($channel_id, $observer_hash, $resource_id) {
+
+ $sql_extra = item_permissions_sql($channel_id,$observer_hash);
+
+ $item = q("SELECT * FROM item WHERE uid = %d AND resource_type = '%s' AND resource_id = '%s' AND item_deleted = 0
+ $sql_extra limit 1",
+ intval($channel_id),
+ dbesc(NWIKI_ITEM_RESOURCE_TYPE),
+ dbesc($resource_id)
+ );
+ if(! $item) {
+ return array('wiki' => null);
+ }
+ else {
+
+ $w = $item[0]; // wiki item table record
+ // Get wiki metadata
+ $rawName = get_iconfig($w, 'wiki', 'rawName');
+ $mimeType = get_iconfig($w, 'wiki', 'mimeType');
+
+ return array(
+ 'wiki' => $w,
+ 'rawName' => $rawName,
+ 'htmlName' => escape_tags($rawName),
+ 'urlName' => urlencode(urlencode($rawName)),
+ 'mimeType' => $mimeType
+ );
+ }
+ }
+
+
+ static public function exists_by_name($uid, $urlName) {
+
+ $sql_extra = item_permissions_sql($uid);
+
+ $item = q("SELECT item.id, resource_id FROM item left join iconfig on iconfig.iid = item.id
+ WHERE resource_type = '%s' AND iconfig.v = '%s' AND uid = %d
+ AND item_deleted = 0 $sql_extra limit 1",
+ dbesc(NWIKI_ITEM_RESOURCE_TYPE),
+ dbesc(urldecode($urlName)),
+ intval($uid)
+ );
+
+ if($item) {
+ return array('id' => $item[0]['id'], 'resource_id' => $item[0]['resource_id']);
+ }
+ else {
+ return array('id' => null, 'resource_id' => null);
+ }
+ }
+
+
+ static public function get_permissions($resource_id, $owner_id, $observer_hash) {
+ // TODO: For now, only the owner can edit
+ $sql_extra = item_permissions_sql($owner_id, $observer_hash);
+
+ if(local_channel() && local_channel() == $owner_id) {
+ return [ 'read' => true, 'write' => true, 'success' => true ];
+ }
+
+ $r = q("SELECT * FROM item WHERE uid = %d and resource_type = '%s' AND resource_id = '%s' $sql_extra LIMIT 1",
+ intval($owner_id),
+ dbesc(NWIKI_ITEM_RESOURCE_TYPE),
+ dbesc($resource_id)
+ );
+
+ if(! $r) {
+ return array('read' => false, 'write' => false, 'success' => true);
+ }
+ else {
+ // TODO: Create a new permission setting for wiki analogous to webpages. Until
+ // then, use webpage permissions
+ $write = perm_is_allowed($owner_id, $observer_hash,'write_wiki');
+ return array('read' => true, 'write' => $write, 'success' => true);
+ }
+ }
+}
diff --git a/Zotlabs/Lib/NativeWikiPage.php b/Zotlabs/Lib/NativeWikiPage.php
new file mode 100644
index 000000000..4086a023e
--- /dev/null
+++ b/Zotlabs/Lib/NativeWikiPage.php
@@ -0,0 +1,664 @@
+<?php
+
+namespace Zotlabs\Lib;
+
+use \Zotlabs\Lib as Zlib;
+
+class NativeWikiPage {
+
+ static public function page_list($channel_id,$observer_hash, $resource_id) {
+
+ // TODO: Create item table records for pages so that metadata like title can be applied
+ $w = Zlib\NativeWiki::get_wiki($channel_id,$observer_hash,$resource_id);
+
+ $pages[] = [
+ 'resource_id' => '',
+ 'title' => 'Home',
+ 'url' => 'Home',
+ 'link_id' => 'id_wiki_home_0'
+ ];
+
+ $sql_extra = item_permissions_sql($channel_id,$observer_hash);
+
+ $r = q("select * from item where resource_type = 'nwikipage' and resource_id = '%s' and uid = %d and item_deleted = 0
+ $sql_extra group by mid",
+ dbesc($resource_id),
+ intval($channel_id)
+ );
+ if($r) {
+ $items = fetch_post_tags($r,true);
+ foreach($items as $page_item) {
+ $title = get_iconfig($page_item['id'],'nwikipage','pagetitle',t('(No Title)'));
+ if(urldecode($title) !== 'Home') {
+ $pages[] = [
+ 'resource_id' => $resource_id,
+ 'title' => escape_tags($title),
+ 'url' => urlencode(urlencode($title)),
+ 'link_id' => 'id_' . substr($resource_id, 0, 10) . '_' . $page_item['id']
+ ];
+ }
+ }
+ }
+
+ return array('pages' => $pages, 'wiki' => $w);
+ }
+
+
+ static public function create_page($channel_id, $observer_hash, $name, $resource_id) {
+
+ $w = Zlib\NativeWiki::get_wiki($channel_id, $observer_hash, $resource_id);
+
+ if (! $w['wiki']) {
+ return array('content' => null, 'message' => 'Error reading wiki', 'success' => false);
+ }
+
+ // create an empty activity
+
+ $arr = [];
+ $arr['uid'] = $channel_id;
+ $arr['author_xchan'] = $observer_hash;
+ $arr['resource_type'] = 'nwikipage';
+ $arr['resource_id'] = $resource_id;
+ $arr['allow_cid'] = $w['wiki']['allow_cid'];
+ $arr['allow_gid'] = $w['wiki']['allow_gid'];
+ $arr['deny_cid'] = $w['wiki']['deny_cid'];
+ $arr['deny_gid'] = $w['wiki']['deny_gid'];
+
+ $arr['public_policy'] = map_scope(\Zotlabs\Access\PermissionLimits::Get($channel_id,'view_wiki'),true);
+
+ // We may wish to change this some day.
+ $arr['item_unpublished'] = 1;
+
+ set_iconfig($arr,'nwikipage','pagetitle',(($name) ? $name : t('(No Title)')),true);
+
+ $p = post_activity_item($arr, false, false);
+
+ if($p['item_id']) {
+ $page = [
+ 'rawName' => $name,
+ 'htmlName' => escape_tags($name),
+ 'urlName' => urlencode($name),
+
+ ];
+
+ return array('page' => $page, 'item_id' => $p['item_id'], 'item' => $p['activity'], 'wiki' => $w, 'message' => '', 'success' => true);
+ }
+ return [ 'success' => false, 'message' => t('Wiki page create failed.') ];
+ }
+
+ static public function rename_page($arr) {
+
+ $pageUrlName = ((array_key_exists('pageUrlName',$arr)) ? $arr['pageUrlName'] : '');
+ $pageNewName = ((array_key_exists('pageNewName',$arr)) ? $arr['pageNewName'] : '');
+ $resource_id = ((array_key_exists('resource_id',$arr)) ? $arr['resource_id'] : '');
+ $observer_hash = ((array_key_exists('observer_hash',$arr)) ? $arr['observer_hash'] : '');
+ $channel_id = ((array_key_exists('channel_id',$arr)) ? $arr['channel_id'] : 0);
+
+ $w = Zlib\NativeWiki::get_wiki($channel_id, $observer_hash, $resource_id);
+ if(! $w['wiki']) {
+ return array('message' => t('Wiki not found.'), 'success' => false);
+ }
+
+
+ $ic = q("select * from iconfig left join item on iconfig.iid = item.id
+ where uid = %d and cat = 'nwikipage' and k = 'pagetitle' and v = '%s'",
+ intval($channel_id),
+ dbesc($pageNewName)
+ );
+
+ if($ic) {
+ return [ 'success' => false, 'message' => t('Destination name already exists') ];
+ }
+
+
+ $ids = [];
+
+ $ic = q("select *, item.id as item_id from iconfig left join item on iconfig.iid = item.id
+ where uid = %d and cat = 'nwikipage' and k = 'pagetitle' and v = '%s'",
+ intval($channel_id),
+ dbesc($pageUrlName)
+ );
+
+ if($ic) {
+ foreach($ic as $c) {
+ set_iconfig($c['item_id'],'nwikipage','pagetitle',$pageNewName);
+ }
+
+ $page = [
+ 'rawName' => $pageNewName,
+ 'htmlName' => escape_tags($pageNewName),
+ 'urlName' => urlencode(escape_tags($pageNewName))
+ ];
+
+ return [ 'success' => true, 'page' => $page ];
+ }
+
+ return [ 'success' => false, 'item_id' => $c['item_id'], 'message' => t('Page not found') ];
+
+ }
+
+ static public function get_page_content($arr) {
+ $pageUrlName = ((array_key_exists('pageUrlName',$arr)) ? $arr['pageUrlName'] : '');
+ $resource_id = ((array_key_exists('resource_id',$arr)) ? $arr['resource_id'] : '');
+ $observer_hash = ((array_key_exists('observer_hash',$arr)) ? $arr['observer_hash'] : '');
+ $channel_id = ((array_key_exists('channel_id',$arr)) ? intval($arr['channel_id']) : 0);
+ $revision = ((array_key_exists('revision',$arr)) ? intval($arr['revision']) : (-1));
+
+
+ $w = Zlib\NativeWiki::get_wiki($channel_id, $observer_hash, $resource_id);
+ if (! $w['wiki']) {
+ return array('content' => null, 'message' => 'Error reading wiki', 'success' => false);
+ }
+
+ $item = self::load_page($arr);
+
+ if($item) {
+ $content = $item['body'];
+
+ return [
+ 'content' => json_encode($content),
+ 'mimeType' => $w['mimeType'],
+ 'message' => '',
+ 'success' => true
+ ];
+ }
+
+ return array('content' => null, 'message' => t('Error reading page content'), 'success' => false);
+
+ }
+
+ static public function page_history($arr) {
+ $pageUrlName = ((array_key_exists('pageUrlName',$arr)) ? $arr['pageUrlName'] : '');
+ $resource_id = ((array_key_exists('resource_id',$arr)) ? $arr['resource_id'] : '');
+ $observer_hash = ((array_key_exists('observer_hash',$arr)) ? $arr['observer_hash'] : '');
+ $channel_id = ((array_key_exists('channel_id',$arr)) ? $arr['channel_id'] : 0);
+
+ $w = Zlib\NativeWiki::get_wiki($channel_id, $observer_hash, $resource_id);
+ if (!$w['wiki']) {
+ return array('history' => null, 'message' => 'Error reading wiki', 'success' => false);
+ }
+
+ $items = self::load_page_history($arr);
+
+ $history = [];
+
+ if($items) {
+ $processed = 0;
+ foreach($items as $item) {
+ if($processed > 1000)
+ break;
+ $processed ++;
+ $history[] = [
+ 'revision' => $item['revision'],
+ 'date' => datetime_convert('UTC',date_default_timezone_get(),$item['edited']),
+ 'name' => $item['author']['xchan_name'],
+ 'title' => get_iconfig($item,'nwikipage','commit_msg')
+ ];
+
+ }
+
+ return [ 'success' => true, 'history' => $history ];
+ }
+
+ return [ 'success' => false ];
+
+ }
+
+
+ static public function load_page($arr) {
+
+ $pageUrlName = ((array_key_exists('pageUrlName',$arr)) ? $arr['pageUrlName'] : '');
+ $resource_id = ((array_key_exists('resource_id',$arr)) ? $arr['resource_id'] : '');
+ $observer_hash = ((array_key_exists('observer_hash',$arr)) ? $arr['observer_hash'] : '');
+ $channel_id = ((array_key_exists('channel_id',$arr)) ? $arr['channel_id'] : 0);
+ $revision = ((array_key_exists('revision',$arr)) ? $arr['revision'] : (-1));
+
+ $w = Zlib\NativeWiki::get_wiki($channel_id, $observer_hash, $resource_id);
+
+ if (! $w['wiki']) {
+ return array('content' => null, 'message' => 'Error reading wiki', 'success' => false);
+ }
+
+ $ids = '';
+
+ $ic = q("select * from iconfig left join item on iconfig.iid = item.id where uid = %d and cat = 'nwikipage' and k = 'pagetitle' and v = '%s'",
+ intval($channel_id),
+ dbesc($pageUrlName)
+ );
+
+ if($ic) {
+ foreach($ic as $c) {
+ if($ids)
+ $ids .= ',';
+ $ids .= intval($c['iid']);
+ }
+ }
+
+ $sql_extra = item_permissions_sql($channel_id,$observer_hash);
+
+ if($revision == (-1))
+ $sql_extra .= " order by revision desc ";
+ elseif($revision)
+ $sql_extra .= " and revision = " . intval($revision) . " ";
+
+ $r = null;
+
+
+ if($ids) {
+ $r = q("select * from item where resource_type = 'nwikipage' and resource_id = '%s' and uid = %d and id in ( $ids ) $sql_extra limit 1",
+ dbesc($resource_id),
+ intval($channel_id)
+ );
+
+ if($r) {
+ $items = fetch_post_tags($r,true);
+ return $items[0];
+ }
+ }
+
+ return null;
+ }
+
+ static public function load_page_history($arr) {
+
+ $pageUrlName = ((array_key_exists('pageUrlName',$arr)) ? $arr['pageUrlName'] : '');
+ $resource_id = ((array_key_exists('resource_id',$arr)) ? $arr['resource_id'] : '');
+ $observer_hash = ((array_key_exists('observer_hash',$arr)) ? $arr['observer_hash'] : '');
+ $channel_id = ((array_key_exists('channel_id',$arr)) ? $arr['channel_id'] : 0);
+ $revision = ((array_key_exists('revision',$arr)) ? $arr['revision'] : (-1));
+
+ $w = Zlib\NativeWiki::get_wiki($channel_id, $observer_hash, $resource_id);
+ if (! $w['wiki']) {
+ return array('content' => null, 'message' => 'Error reading wiki', 'success' => false);
+ }
+
+ $ids = '';
+
+ $ic = q("select * from iconfig left join item on iconfig.iid = item.id where uid = %d and cat = 'nwikipage' and k = 'pagetitle' and v = '%s'",
+ intval($channel_id),
+ dbesc($pageUrlName)
+ );
+
+ if($ic) {
+ foreach($ic as $c) {
+ if($ids)
+ $ids .= ',';
+ $ids .= intval($c['iid']);
+ }
+ }
+
+ $sql_extra = item_permissions_sql($channel_id,$observer_hash);
+
+ $sql_extra .= " order by revision desc ";
+
+ $r = null;
+ if($ids) {
+ $r = q("select * from item where resource_type = 'nwikipage' and resource_id = '%s' and uid = %d and id in ( $ids ) and item_deleted = 0 $sql_extra",
+ dbesc($resource_id),
+ intval($channel_id)
+ );
+ if($r) {
+ xchan_query($r);
+ $items = fetch_post_tags($r,true);
+ return $items;
+ }
+ }
+
+ return null;
+ }
+
+
+
+ static public function prepare_content($s) {
+
+ $text = preg_replace_callback('{
+ (?:\n\n|\A\n?)
+ ( # $1 = the code block -- one or more lines, starting with a space/tab
+ (?>
+ [ ]{'.'4'.'} # Lines must start with a tab or a tab-width of spaces
+ .*\n+
+ )+
+ )
+ ((?=^[ ]{0,'.'4'.'}\S)|\Z) # Lookahead for non-space at line-start, or end of doc
+ }xm',
+ 'self::nwiki_prepare_content_callback', $s);
+
+ return $text;
+ }
+
+ static public function nwiki_prepare_content_callback($matches) {
+ $codeblock = $matches[1];
+
+ $codeblock = htmlspecialchars($codeblock, ENT_NOQUOTES, UTF8, false);
+ return "\n\n" . $codeblock ;
+ }
+
+
+
+ static public function save_page($arr) {
+
+ $pageUrlName = ((array_key_exists('pageUrlName',$arr)) ? $arr['pageUrlName'] : '');
+ $content = ((array_key_exists('content',$arr)) ? purify_html(Zlib\NativeWikiPage::prepare_content($arr['content'])) : '');
+ $resource_id = ((array_key_exists('resource_id',$arr)) ? $arr['resource_id'] : '');
+ $observer_hash = ((array_key_exists('observer_hash',$arr)) ? $arr['observer_hash'] : '');
+ $channel_id = ((array_key_exists('channel_id',$arr)) ? $arr['channel_id'] : 0);
+ $revision = ((array_key_exists('revision',$arr)) ? $arr['revision'] : 0);
+
+ $w = Zlib\NativeWiki::get_wiki($channel_id, $observer_hash, $resource_id);
+
+ if (!$w['wiki']) {
+ return array('message' => t('Error reading wiki'), 'success' => false);
+ }
+
+ // fetch the most recently saved revision.
+
+ $item = self::load_page($arr);
+ if(! $item) {
+ return array('message' => t('Page not found'), 'success' => false);
+ }
+
+ // change just the fields we need to change to create a revision;
+
+ unset($item['id']);
+ unset($item['author']);
+
+ $item['parent'] = 0;
+ $item['body'] = $content;
+ $item['author_xchan'] = $observer_hash;
+ $item['revision'] = (($arr['revision']) ? intval($arr['revision']) + 1 : intval($item['revision']) + 1);
+ $item['edited'] = datetime_convert();
+
+ if($item['iconfig'] && is_array($item['iconfig']) && count($item['iconfig'])) {
+ for($x = 0; $x < count($item['iconfig']); $x ++) {
+ unset($item['iconfig'][$x]['id']);
+ unset($item['iconfig'][$x]['iid']);
+ }
+ }
+
+ $ret = item_store($item, false, false);
+
+ if($ret['item_id'])
+ return array('message' => '', 'item_id' => $ret['item_id'], 'filename' => $filename, 'success' => true);
+ else
+ return array('message' => t('Page update failed.'), 'success' => false);
+ }
+
+ static public function delete_page($arr) {
+ $pageUrlName = ((array_key_exists('pageUrlName',$arr)) ? $arr['pageUrlName'] : '');
+ $resource_id = ((array_key_exists('resource_id',$arr)) ? $arr['resource_id'] : '');
+ $observer_hash = ((array_key_exists('observer_hash',$arr)) ? $arr['observer_hash'] : '');
+ $channel_id = ((array_key_exists('channel_id',$arr)) ? $arr['channel_id'] : 0);
+
+ $w = Zlib\NativeWiki::get_wiki($channel_id, $observer_hash, $resource_id);
+
+ if(! $w['wiki']) {
+ return [ 'success' => false, 'message' => t('Error reading wiki') ];
+ }
+
+ $ids = [];
+
+ $ic = q("select * from iconfig left join item on iconfig.iid = item.id
+ where uid = %d and cat = 'nwikipage' and k = 'pagetitle' and v = '%s'",
+ intval($channel_id),
+ dbesc($pageUrlName)
+ );
+
+ if($ic) {
+ foreach($ic as $c) {
+ $ids[] = intval($c['iid']);
+ }
+ }
+
+ if($ids) {
+ drop_items($ids);
+ return [ 'success' => true ];
+ }
+
+ return [ 'success' => false, 'message' => t('Nothing deleted') ];
+ }
+
+ static public function revert_page($arr) {
+ $pageUrlName = ((array_key_exists('pageUrlName',$arr)) ? $arr['pageUrlName'] : '');
+ $resource_id = ((array_key_exists('resource_id',$arr)) ? $arr['resource_id'] : '');
+ $commitHash = ((array_key_exists('commitHash',$arr)) ? $arr['commitHash'] : null);
+ $observer_hash = ((array_key_exists('observer_hash',$arr)) ? $arr['observer_hash'] : '');
+ $channel_id = ((array_key_exists('channel_id',$arr)) ? $arr['channel_id'] : 0);
+
+ if (! $commitHash) {
+ return array('content' => $content, 'message' => 'No commit was provided', 'success' => false);
+ }
+
+ $w = Zlib\NativeWiki::get_wiki($channel_id, $observer_hash, $resource_id);
+ if (!$w['wiki']) {
+ return array('content' => $content, 'message' => 'Error reading wiki', 'success' => false);
+ }
+
+ $x = $arr;
+
+ if(intval($commitHash) > 0) {
+ unset($x['commitHash']);
+ $x['revision'] = intval($commitHash) - 1;
+ $loaded = self::load_page($x);
+
+ if($loaded) {
+ $content = $loaded['body'];
+ return [ 'content' => $content, 'success' => true ];
+ }
+ return [ 'content' => $content, 'success' => false ];
+ }
+ }
+
+ static public function compare_page($arr) {
+ $pageUrlName = ((array_key_exists('pageUrlName',$arr)) ? $arr['pageUrlName'] : '');
+ $resource_id = ((array_key_exists('resource_id',$arr)) ? $arr['resource_id'] : '');
+ $currentCommit = ((array_key_exists('currentCommit',$arr)) ? $arr['currentCommit'] : (-1));
+ $compareCommit = ((array_key_exists('compareCommit',$arr)) ? $arr['compareCommit'] : 0);
+ $observer_hash = ((array_key_exists('observer_hash',$arr)) ? $arr['observer_hash'] : '');
+ $channel_id = ((array_key_exists('channel_id',$arr)) ? $arr['channel_id'] : 0);
+
+ $w = Zlib\NativeWiki::get_wiki($channel_id, $observer_hash, $resource_id);
+
+ if (!$w['wiki']) {
+ return array('message' => t('Error reading wiki'), 'success' => false);
+ }
+
+ $x = $arr;
+ $x['revision'] = (-1);
+
+ $currpage = self::load_page($x);
+ if($currpage)
+ $currentContent = $currpage['body'];
+
+ $x['revision'] = $compareCommit;
+ $comppage = self::load_page($x);
+ if($comppage)
+ $compareContent = $comppage['body'];
+
+ if($currpage && $comppage) {
+ require_once('library/class.Diff.php');
+ $diff = \Diff::toTable(\Diff::compare($currentContent, $compareContent));
+
+ return [ 'success' => true, 'diff' => $diff ];
+ }
+ return [ 'success' => false, 'message' => t('Compare: object not found.') ];
+
+ }
+
+ static public function commit($arr) {
+
+ $commit_msg = ((array_key_exists('commit_msg', $arr)) ? $arr['commit_msg'] : t('Page updated'));
+ $observer_hash = ((array_key_exists('observer_hash',$arr)) ? $arr['observer_hash'] : '');
+ $channel_id = ((array_key_exists('channel_id',$arr)) ? $arr['channel_id'] : 0);
+ $pageUrlName = ((array_key_exists('pageUrlName',$arr)) ? $arr['pageUrlName'] : t('Untitled'));
+
+ if(array_key_exists('resource_id', $arr)) {
+ $resource_id = $arr['resource_id'];
+ }
+ else {
+ return array('message' => t('Wiki resource_id required for git commit'), 'success' => false);
+ }
+
+ $w = Zlib\NativeWiki::get_wiki($channel_id, $observer_hash, $resource_id);
+ if (! $w['wiki']) {
+ return array('message' => t('Error reading wiki'), 'success' => false);
+ }
+
+
+ $page = self::load_page($arr);
+
+ if($page) {
+ set_iconfig($page['id'],'nwikipage','commit_msg',escape_tags($commit_msg),true);
+ return [ 'success' => true, 'item_id' => $page['id'], 'page' => $page ];
+ }
+
+ return [ 'success' => false, 'message' => t('Page not found.') ];
+
+ }
+
+ static public function convert_links($s, $wikiURL) {
+
+ if (strpos($s,'[[') !== false) {
+ preg_match_all("/\[\[(.*?)\]\]/", $s, $match);
+ $pages = $pageURLs = array();
+ foreach ($match[1] as $m) {
+ // TODO: Why do we need to double urlencode for this to work?
+ $pageURLs[] = urlencode(urlencode(escape_tags($m)));
+ $pages[] = $m;
+ }
+ $idx = 0;
+ while(strpos($s,'[[') !== false) {
+ $replace = '<a href="'.$wikiURL.'/'.$pageURLs[$idx].'">'.$pages[$idx].'</a>';
+ $s = preg_replace("/\[\[(.*?)\]\]/", $replace, $s, 1);
+ $idx++;
+ }
+ }
+ return $s;
+ }
+
+ /**
+ * Replace the instances of the string [toc] with a list element that will be populated by
+ * a table of contents by the JavaScript library
+ * @param string $s
+ * @return string
+ */
+ static public function generate_toc($s) {
+ if (strpos($s,'[toc]') !== false) {
+ //$toc_md = wiki_toc($s); // Generate Markdown-formatted list prior to HTML render
+ $toc_md = '<ul id="wiki-toc"></ul>'; // use the available jQuery plugin http://ndabas.github.io/toc/
+ $s = preg_replace("/\[toc\]/", $toc_md, $s, -1);
+ }
+ return $s;
+ }
+
+ /**
+ * Converts a select set of bbcode tags. Much of the code is copied from include/bbcode.php
+ * @param string $s
+ * @return string
+ */
+ static public function bbcode($s) {
+
+ $s = str_replace(array('[baseurl]', '[sitename]'), array(z_root(), get_config('system', 'sitename')), $s);
+
+ $s = preg_replace_callback("/\[observer\.language\=(.*?)\](.*?)\[\/observer\]/ism",'oblanguage_callback', $s);
+
+ $s = preg_replace_callback("/\[observer\.language\!\=(.*?)\](.*?)\[\/observer\]/ism",'oblanguage_necallback', $s);
+
+
+ $observer = \App::get_observer();
+ if ($observer) {
+ $s1 = '<span class="bb_observer" title="' . t('Different viewers will see this text differently') . '">';
+ $s2 = '</span>';
+ $obsBaseURL = $observer['xchan_connurl'];
+ $obsBaseURL = preg_replace("/\/poco\/.*$/", '', $obsBaseURL);
+ $s = str_replace('[observer.baseurl]', $obsBaseURL, $s);
+ $s = str_replace('[observer.url]', $observer['xchan_url'], $s);
+ $s = str_replace('[observer.name]', $s1 . $observer['xchan_name'] . $s2, $s);
+ $s = str_replace('[observer.address]', $s1 . $observer['xchan_addr'] . $s2, $s);
+ $s = str_replace('[observer.webname]', substr($observer['xchan_addr'], 0, strpos($observer['xchan_addr'], '@')), $s);
+ $s = str_replace('[observer.photo]', '', $s);
+ }
+ else {
+ $s = str_replace('[observer.baseurl]', '', $s);
+ $s = str_replace('[observer.url]', '', $s);
+ $s = str_replace('[observer.name]', '', $s);
+ $s = str_replace('[observer.address]', '', $s);
+ $s = str_replace('[observer.webname]', '', $s);
+ $s = str_replace('[observer.photo]', '', $s);
+ }
+
+ return $s;
+ }
+
+ static public function get_file_ext($arr) {
+ if($arr['mimeType'] == 'text/bbcode')
+ return '.bb';
+ else
+ return '.md';
+ }
+
+ // This function is derived from
+ // http://stackoverflow.com/questions/32068537/generate-table-of-contents-from-markdown-in-php
+ static public function toc($content) {
+ // ensure using only "\n" as line-break
+ $source = str_replace(["\r\n", "\r"], "\n", $content);
+
+ // look for markdown TOC items
+ preg_match_all(
+ '/^(?:=|-|#).*$/m',
+ $source,
+ $matches,
+ PREG_PATTERN_ORDER | PREG_OFFSET_CAPTURE
+ );
+
+ // preprocess: iterate matched lines to create an array of items
+ // where each item is an array(level, text)
+ $file_size = strlen($source);
+ foreach ($matches[0] as $item) {
+ $found_mark = substr($item[0], 0, 1);
+ if ($found_mark == '#') {
+ // text is the found item
+ $item_text = $item[0];
+ $item_level = strrpos($item_text, '#') + 1;
+ $item_text = substr($item_text, $item_level);
+ } else {
+ // text is the previous line (empty if <hr>)
+ $item_offset = $item[1];
+ $prev_line_offset = strrpos($source, "\n", -($file_size - $item_offset + 2));
+ $item_text =
+ substr($source, $prev_line_offset, $item_offset - $prev_line_offset - 1);
+ $item_text = trim($item_text);
+ $item_level = $found_mark == '=' ? 1 : 2;
+ }
+ if (!trim($item_text) OR strpos($item_text, '|') !== FALSE) {
+ // item is an horizontal separator or a table header, don't mind
+ continue;
+ }
+ $raw_toc[] = ['level' => $item_level, 'text' => trim($item_text)];
+ }
+ $o = '';
+ foreach($raw_toc as $t) {
+ $level = intval($t['level']);
+ $text = $t['text'];
+ switch ($level) {
+ case 1:
+ $li = '* ';
+ break;
+ case 2:
+ $li = ' * ';
+ break;
+ case 3:
+ $li = ' * ';
+ break;
+ case 4:
+ $li = ' * ';
+ break;
+ default:
+ $li = '* ';
+ break;
+ }
+ $o .= $li . $text . "\n";
+ }
+ return $o;
+ }
+
+}
diff --git a/Zotlabs/Lib/Permcat.php b/Zotlabs/Lib/Permcat.php
new file mode 100644
index 000000000..505ee2cfc
--- /dev/null
+++ b/Zotlabs/Lib/Permcat.php
@@ -0,0 +1,146 @@
+<?php
+
+namespace Zotlabs\Lib;
+
+use \Zotlabs\Access as Zaccess;
+
+class Permcat {
+
+ private $permcats = [];
+
+ public function __construct($channel_id) {
+
+ $perms = [];
+
+ // first check role perms for a perms_connect setting
+
+ $role = get_pconfig($channel_id,'system','permissions_role');
+ if($role) {
+ $x = Zaccess\PermissionRoles::role_perms($role);
+ if($x['perms_connect']) {
+ $perms = Zaccess\Permissions::FilledPerms($x['perms_connect']);
+ }
+ }
+
+ // if no role perms it may be a custom role, see if there any autoperms
+
+ if(! $perms) {
+ $perms = Zaccess\Permissions::FilledAutoPerms($channel_id);
+ }
+
+ // if no autoperms it may be a custom role with manual perms
+
+ if(! $perms) {
+ $r = q("select channel_hash from channel where channel_id = %d",
+ intval($channel_id)
+ );
+ if($r) {
+ $x = q("select * from abconfig where chan = %d and xchan = '%s' and cat = 'my_perms'",
+ intval($channel_id),
+ dbesc($r[0]['channel_hash'])
+ );
+ if($x) {
+ foreach($x as $xv) {
+ $perms[$xv['k']] = intval($xv['v']);
+ }
+ }
+ }
+ }
+
+ // nothing was found - create a filled permission array where all permissions are 0
+
+ if(! $perms) {
+ $perms = Zaccess\Permissions::FilledPerms([]);
+ }
+
+ $this->permcats[] = [
+ 'name' => 'default',
+ 'localname' => t('default','permcat'),
+ 'perms' => Zaccess\Permissions::Operms($perms),
+ 'system' => 1
+ ];
+
+
+ $p = $this->load_permcats($channel_id);
+ if($p) {
+ for($x = 0; $x < count($p); $x++) {
+ $this->permcats[] = [
+ 'name' => $p[$x][0],
+ 'localname' => $p[$x][1],
+ 'perms' => Zaccess\Permissions::Operms(Zaccess\Permissions::FilledPerms($p[$x][2])),
+ 'system' => intval($p[$x][3])
+ ];
+ }
+ }
+ }
+
+
+ public function listing() {
+ return $this->permcats;
+ }
+
+ public function fetch($name) {
+ if($name && $this->permcats) {
+ foreach($this->permcats as $permcat) {
+ if(strcasecmp($permcat['name'],$name) === 0) {
+ return $permcat;
+ }
+ }
+ }
+ return ['error' => true];
+ }
+
+ public function load_permcats($uid) {
+
+ $permcats = [
+ [ 'follower', t('follower','permcat'),
+ [ 'view_stream','view_profile','view_contacts','view_storage','view_pages','view_wiki',
+ 'post_like' ], 1
+ ],
+ [ 'contributor', t('contributor','permcat'),
+ [ 'view_stream','view_profile','view_contacts','view_storage','view_pages','view_wiki',
+ 'post_wall','post_comments','write_wiki','post_like','tag_deliver','chat' ], 1
+ ],
+ [ 'publisher', t('publisher','permcat'),
+ [ 'view_stream','view_profile','view_contacts','view_storage','view_pages',
+ 'write_storage','post_wall','write_pages','write_wiki','post_comments','post_like','tag_deliver',
+ 'chat', 'republish' ], 1
+ ]
+ ];
+
+ if($uid) {
+ $x = q("select * from pconfig where uid = %d and cat = 'permcat'",
+ intval($uid)
+ );
+ if($x) {
+ foreach($x as $xv) {
+ $value = ((preg_match('|^a:[0-9]+:{.*}$|s', $xv['v'])) ? unserialize($xv['v']) : $xv['v']);
+ $permcats[] = [ $xv['k'], $xv['k'], $value, 0 ];
+ }
+ }
+ }
+
+ call_hooks('permcats',$permcats);
+
+ return $permcats;
+
+ }
+
+ static public function find_permcat($arr,$name) {
+ if((! $arr) || (! $name))
+ return false;
+ foreach($arr as $p)
+ if($p['name'] == $name)
+ return $p['value'];
+ }
+
+ static public function update($channel_id, $name,$permarr) {
+ PConfig::Set($channel_id,'permcat',$name,$permarr);
+ }
+
+ static public function delete($channel_id,$name) {
+ PConfig::Delete($channel_id,'permcat',$name);
+ }
+
+
+} \ No newline at end of file
diff --git a/Zotlabs/Lib/ThreadItem.php b/Zotlabs/Lib/ThreadItem.php
index a1666e148..07b782309 100644
--- a/Zotlabs/Lib/ThreadItem.php
+++ b/Zotlabs/Lib/ThreadItem.php
@@ -136,7 +136,7 @@ class ThreadItem {
$filer = ((($conv->get_profile_owner() == local_channel()) && (! array_key_exists('real_uid',$item))) ? t("Save to Folder") : false);
$profile_avatar = $item['author']['xchan_photo_m'];
- $profile_link = chanlink_url($item['author']['xchan_url']);
+ $profile_link = chanlink_hash($item['author_xchan']);
$profile_name = $item['author']['xchan_name'];
$location = format_location($item);
@@ -295,7 +295,7 @@ class ThreadItem {
$owner_address = substr($item['owner']['xchan_addr'],0,strpos($item['owner']['xchan_addr'],'@'));
$viewthread = $item['llink'];
if($conv->get_mode() === 'channel')
- $viewthread = z_root() . '/channel/' . $owner_address . '?f=&mid=' . $item['mid'];
+ $viewthread = z_root() . '/channel/' . $owner_address . '?f=&mid=' . urlencode($item['mid']);
$comment_count_txt = sprintf( tt('%d comment','%d comments',$total_children),$total_children );
$list_unseen_txt = (($unseen_comments) ? sprintf('%d unseen',$unseen_comments) : '');
@@ -335,6 +335,8 @@ class ThreadItem {
'wall' => t('Wall-to-Wall'),
'vwall' => t('via Wall-To-Wall:'),
'profile_url' => $profile_link,
+ 'thread_action_menu' => thread_action_menu($item,$conv->get_mode()),
+ 'thread_author_menu' => thread_author_menu($item,$conv->get_mode()),
'item_photo_menu' => item_photo_menu($item),
'dreport' => $dreport,
'name' => $profile_name,
@@ -407,7 +409,7 @@ class ThreadItem {
'comment' => $this->get_comment_box($indent),
'previewing' => ($conv->is_preview() ? ' preview ' : ''),
'wait' => t('Please wait'),
- 'submid' => substr($item['mid'],0,32),
+ 'submid' => str_replace(['+','='], ['',''], base64_encode(substr($item['mid'],0,32))),
'thread_level' => $thread_level
);
@@ -765,7 +767,7 @@ class ThreadItem {
return;
if($this->is_toplevel() && ($this->get_data_value('author_xchan') != $this->get_data_value('owner_xchan'))) {
- $this->owner_url = chanlink_url($this->data['owner']['xchan_url']);
+ $this->owner_url = chanlink_hash($this->data['owner']['xchan_hash']);
$this->owner_photo = $this->data['owner']['xchan_photo_m'];
$this->owner_name = $this->data['owner']['xchan_name'];
$this->wall_to_wall = true;
diff --git a/Zotlabs/Module/Acl.php b/Zotlabs/Module/Acl.php
index 29c1e5280..c3c50cac2 100644
--- a/Zotlabs/Module/Acl.php
+++ b/Zotlabs/Module/Acl.php
@@ -19,7 +19,7 @@ require_once("include/group.php");
class Acl extends \Zotlabs\Web\Controller {
- function init(){
+ function init() {
// logger('mod_acl: ' . print_r($_REQUEST,true));
@@ -49,7 +49,7 @@ class Acl extends \Zotlabs\Web\Controller {
$extra_channels = (x($_REQUEST,'extra_channels') ? $_REQUEST['extra_channels'] : array());
// The different autocomplete libraries use different names for the search text
- // parameter. Internaly we'll use $search to represent the search text no matter
+ // parameter. Internally we'll use $search to represent the search text no matter
// what request variable it was attached to.
if(array_key_exists('query',$_REQUEST)) {
@@ -87,8 +87,8 @@ class Acl extends \Zotlabs\Web\Controller {
$order_extra2 = "CASE WHEN xchan_name LIKE "
. protect_sprintf( "'%" . dbesc($search) . "%'" )
- . " then POSITION('" . dbesc($search)
- . "' IN xchan_name) else position('" . dbesc($search) . "' IN xchan_addr) end, ";
+ . " then POSITION('" . protect_sprintf(dbesc($search))
+ . "' IN xchan_name) else position('" . protect_sprintf(dbesc($search)) . "' IN xchan_addr) end, ";
$col = ((strpos($search,'@') !== false) ? 'xchan_addr' : 'xchan_name' );
$sql_extra3 = "AND $col like " . protect_sprintf( "'%" . dbesc($search) . "%'" ) . " ";
@@ -103,7 +103,28 @@ class Acl extends \Zotlabs\Web\Controller {
$contacts = array();
if($type == '' || $type == 'g') {
-
+
+ // virtual groups based on private profile viewing ability
+
+ $r = q("select id, profile_guid, profile_name from profile where is_default = 0 and uid = %d",
+ intval(local_channel())
+ );
+ if($r) {
+ foreach($r as $rv) {
+ $groups[] = array(
+ "type" => "g",
+ "photo" => "images/twopeople.png",
+ "name" => t('Profile','acl') . ' ' . $rv['profile_name'],
+ "id" => 'vp' . $rv['id'],
+ "xid" => 'vp.' . $rv['profile_guid'],
+ "uids" => group_get_profile_members_xchan(local_channel(), $rv['id']),
+ "link" => ''
+ );
+ }
+ }
+
+ // Normal privacy groups
+
$r = q("SELECT groups.id, groups.hash, groups.gname
FROM groups, group_member
WHERE groups.deleted = 0 AND groups.uid = %d
@@ -134,25 +155,34 @@ class Acl extends \Zotlabs\Web\Controller {
}
if($type == '' || $type == 'c') {
+
$extra_channels_sql = '';
- // Only include channels who allow the observer to view their permissions
- foreach($extra_channels as $channel) {
- if(perm_is_allowed(intval($channel), get_observer_hash(),'view_contacts'))
- $extra_channels_sql .= "," . intval($channel);
+
+ // Only include channels who allow the observer to view their connections
+ if($extra_channels) {
+ foreach($extra_channels as $channel) {
+ if(perm_is_allowed(intval($channel), get_observer_hash(),'view_contacts')) {
+ if($extra_channel_sql)
+ $extra_channels_sql .= ',';
+ $extra_channels_sql .= intval($channel);
+ }
+ }
}
- $extra_channels_sql = substr($extra_channels_sql,1); // Remove initial comma
-
// Getting info from the abook is better for local users because it contains info about permissions
if(local_channel()) {
if($extra_channels_sql != '')
$extra_channels_sql = " OR (abook_channel IN ($extra_channels_sql)) and abook_hidden = 0 ";
+
+ // Add atokens belonging to the local channel @TODO restrict by search
+
$r2 = null;
$r1 = q("select * from atoken where atoken_uid = %d",
intval(local_channel())
);
+
if($r1) {
require_once('include/security.php');
$r2 = array();
@@ -172,6 +202,7 @@ class Acl extends \Zotlabs\Web\Controller {
}
}
+ // add connections
$r = q("SELECT abook_id as id, xchan_hash as hash, xchan_name as name, xchan_photo_s as micro, xchan_url as url, xchan_addr as nick, abook_their_perms, xchan_pubforum, abook_flags, abook_self
FROM abook left join xchan on abook_xchan = xchan_hash
diff --git a/Zotlabs/Module/Admin/Plugins.php b/Zotlabs/Module/Admin/Plugins.php
index 9e48b4b86..527e96496 100644
--- a/Zotlabs/Module/Admin/Plugins.php
+++ b/Zotlabs/Module/Admin/Plugins.php
@@ -36,7 +36,7 @@ class Plugins {
json_return_and_die(array('message' => 'Error creating extend folder: ' . $extendDir, 'success' => false));
}
else {
- if (!symlink('extend/addon', $addonDir)) {
+ if (!symlink(realpath('extend/addon'), $addonDir)) {
logger('Error creating symlink to addon folder: ' . $addonDir);
json_return_and_die(array('message' => 'Error creating symlink to addon folder: ' . $addonDir, 'success' => false));
}
@@ -57,7 +57,7 @@ class Plugins {
$files = array_diff(scandir($repoDir), array('.', '..'));
foreach ($files as $file) {
if (is_dir($repoDir . '/' . $file) && $file !== '.git') {
- $source = 'extend/addon/' . $repoName . '/' . $file;
+ $source = '../extend/addon/' . $repoName . '/' . $file;
$target = realpath('addon/') . '/' . $file;
unlink($target);
if (!symlink($source, $target)) {
@@ -86,7 +86,7 @@ class Plugins {
logger('Error creating extend folder: ' . $extendDir);
json_return_and_die(array('message' => 'Error creating extend folder: ' . $extendDir, 'success' => false));
} else {
- if (!symlink('extend/addon', $addonDir)) {
+ if (!symlink(realpath('extend/addon'), $addonDir)) {
logger('Error creating symlink to addon folder: ' . $addonDir);
json_return_and_die(array('message' => 'Error creating symlink to addon folder: ' . $addonDir, 'success' => false));
}
@@ -119,7 +119,7 @@ class Plugins {
logger('Error creating extend folder: ' . $extendDir);
json_return_and_die(array('message' => 'Error creating extend folder: ' . $extendDir, 'success' => false));
} else {
- if (!symlink('extend/addon', $addonDir)) {
+ if (!symlink(realpath('extend/addon'), $addonDir)) {
logger('Error creating symlink to addon folder: ' . $addonDir);
json_return_and_die(array('message' => 'Error creating symlink to addon folder: ' . $addonDir, 'success' => false));
}
@@ -156,7 +156,7 @@ class Plugins {
$files = array_diff(scandir($repoDir), array('.', '..'));
foreach ($files as $file) {
if (is_dir($repoDir . '/' . $file) && $file !== '.git') {
- $source = 'extend/addon/' . $repoName . '/' . $file;
+ $source = '../extend/addon/' . $repoName . '/' . $file;
$target = realpath('addon/') . '/' . $file;
unlink($target);
if (!symlink($source, $target)) {
@@ -176,13 +176,13 @@ class Plugins {
$repoURL = $_REQUEST['repoURL'];
$extendDir = 'store/[data]/git/sys/extend';
$addonDir = $extendDir . '/addon';
- $tempAddonDir = 'store/[data]/git/sys/temp';
+ $tempAddonDir = realpath('store/[data]') . '/git/sys/temp';
if (!file_exists($extendDir)) {
if (!mkdir($extendDir, 0770, true)) {
logger('Error creating extend folder: ' . $extendDir);
json_return_and_die(array('message' => 'Error creating extend folder: ' . $extendDir, 'success' => false));
} else {
- if (!symlink('extend/addon', $addonDir)) {
+ if (!symlink(realpath('extend/addon'), $addonDir)) {
logger('Error creating symlink to addon folder: ' . $addonDir);
json_return_and_die(array('message' => 'Error creating symlink to addon folder: ' . $addonDir, 'success' => false));
}
@@ -395,6 +395,10 @@ class Plugins {
usort($plugins,'self::plugin_sort');
+ $allowManageRepos = false;
+ if(is_writable('extend/addon') && is_writable('store/[data]')) {
+ $allowManageRepos = true;
+ }
$admin_plugins_add_repo_form= replace_macros(
get_markup_template('admin_plugins_addrepo.tpl'), array(
@@ -432,6 +436,7 @@ class Plugins {
'$plugins' => $plugins,
'$disabled' => t('Disabled - version incompatibility'),
'$form_security_token' => get_form_security_token('admin_plugins'),
+ '$allowManageRepos' => $allowManageRepos,
'$managerepos' => t('Manage Repos'),
'$installedtitle' => t('Installed Plugin Repositories'),
'$addnewrepotitle' => t('Install a New Plugin Repository'),
diff --git a/Zotlabs/Module/Admin/Queue.php b/Zotlabs/Module/Admin/Queue.php
index 4986de925..5a47413ee 100644
--- a/Zotlabs/Module/Admin/Queue.php
+++ b/Zotlabs/Module/Admin/Queue.php
@@ -15,7 +15,6 @@ class Queue {
$expert = ((array_key_exists('expert',$_REQUEST)) ? intval($_REQUEST['expert']) : 0);
if($_REQUEST['drophub']) {
- require_once('hubloc.php');
hubloc_mark_as_down($_REQUEST['drophub']);
remove_queue_by_posturl($_REQUEST['drophub']);
}
diff --git a/Zotlabs/Module/Admin/Site.php b/Zotlabs/Module/Admin/Site.php
index 829ca71e4..b71e63030 100644
--- a/Zotlabs/Module/Admin/Site.php
+++ b/Zotlabs/Module/Admin/Site.php
@@ -163,6 +163,14 @@ class Site {
foreach($files as $file) {
$vars = '';
$f = basename($file);
+
+ $info = get_theme_info($f);
+ $compatible = check_plugin_versions($info);
+ if(!$compatible) {
+ $theme_choices[$f] = $theme_choices_mobile[$f] = sprintf(t('%s - (Incompatible)'), $f);
+ continue;
+ }
+
if (file_exists($file . '/library'))
continue;
if (file_exists($file . '/mobile'))
@@ -310,4 +318,4 @@ class Site {
));
}
-} \ No newline at end of file
+}
diff --git a/Zotlabs/Module/Admin/Themes.php b/Zotlabs/Module/Admin/Themes.php
index 63a9a1670..fc908ec8b 100644
--- a/Zotlabs/Module/Admin/Themes.php
+++ b/Zotlabs/Module/Admin/Themes.php
@@ -230,4 +230,4 @@ class Themes {
-} \ No newline at end of file
+}
diff --git a/Zotlabs/Module/Appman.php b/Zotlabs/Module/Appman.php
index a200e986a..70cc7e44b 100644
--- a/Zotlabs/Module/Appman.php
+++ b/Zotlabs/Module/Appman.php
@@ -27,6 +27,7 @@ class Appman extends \Zotlabs\Web\Controller {
'price' => escape_tags($_REQUEST['price']),
'requires' => escape_tags($_REQUEST['requires']),
'system' => intval($_REQUEST['system']),
+ 'plugin' => escape_tags($_REQUEST['plugin']),
'sig' => escape_tags($_REQUEST['sig']),
'categories' => escape_tags($_REQUEST['categories'])
);
@@ -35,8 +36,9 @@ class Appman extends \Zotlabs\Web\Controller {
if(Zlib\Apps::app_installed(local_channel(),$arr))
info( t('App installed.') . EOL);
-
- return;
+
+ goaway(z_root() . '/apps');
+ return; //not reached
}
@@ -56,13 +58,18 @@ class Appman extends \Zotlabs\Web\Controller {
if($_POST['delete']) {
Zlib\Apps::app_destroy(local_channel(),$papp);
}
-
+
if($_POST['edit']) {
return;
}
-
+
+ if($_POST['feature']) {
+ Zlib\Apps::app_feature(local_channel(),$papp);
+ }
+
if($_SESSION['return_url'])
goaway(z_root() . '/' . $_SESSION['return_url']);
+
goaway(z_root() . '/apps');
@@ -75,7 +82,7 @@ class Appman extends \Zotlabs\Web\Controller {
notice( t('Permission denied.') . EOL);
return;
}
-
+
$channel = \App::get_channel();
$app = null;
$embed = null;
@@ -121,6 +128,7 @@ class Appman extends \Zotlabs\Web\Controller {
'$price' => array('price', t('Price of app'),(($app) ? $app['app_price'] : ''), ''),
'$page' => array('page', t('Location (URL) to purchase app'),(($app) ? $app['app_page'] : ''), ''),
'$system' => (($app) ? intval($app['app_system']) : 0),
+ '$plugin' => (($app) ? $app['app_plugin'] : ''),
'$requires' => (($app) ? $app['app_requires'] : ''),
'$embed' => $embed,
'$submit' => t('Submit')
diff --git a/Zotlabs/Module/Apps.php b/Zotlabs/Module/Apps.php
index 4dab621b2..261615997 100644
--- a/Zotlabs/Module/Apps.php
+++ b/Zotlabs/Module/Apps.php
@@ -12,16 +12,15 @@ class Apps extends \Zotlabs\Web\Controller {
$mode = 'edit';
else
$mode = 'list';
-
- $_SESSION['return_url'] = \App::$cmd;
+
+ $_SESSION['return_url'] = \App::$query_string;
$apps = array();
-
if(local_channel()) {
Zlib\Apps::import_system_apps();
$syslist = array();
- $list = Zlib\Apps::app_list(local_channel(), false, $_GET['cat']);
+ $list = Zlib\Apps::app_list(local_channel(), (($mode == 'edit') ? true : false), $_GET['cat']);
if($list) {
foreach($list as $x) {
$syslist[] = Zlib\Apps::app_encode($x);
@@ -39,12 +38,15 @@ class Apps extends \Zotlabs\Web\Controller {
foreach($syslist as $app) {
$apps[] = Zlib\Apps::app_render($app,$mode);
}
-
+
return replace_macros(get_markup_template('myapps.tpl'), array(
'$sitename' => get_config('system','sitename'),
- '$cat' => ((array_key_exists('cat',$_GET) && $_GET['cat']) ? ' - ' . escape_tags($_GET['cat']) : ''),
+ '$cat' => ((array_key_exists('cat',$_GET) && $_GET['cat']) ? escape_tags($_GET['cat']) : ''),
'$title' => t('Apps'),
'$apps' => $apps,
+ '$authed' => ((local_channel()) ? true : false),
+ '$manage' => t('Manage apps'),
+ '$create' => (($mode == 'edit') ? t('Create new app') : '')
));
}
diff --git a/Zotlabs/Module/Cal.php b/Zotlabs/Module/Cal.php
index 1279a51b1..b982d19a8 100644
--- a/Zotlabs/Module/Cal.php
+++ b/Zotlabs/Module/Cal.php
@@ -292,8 +292,8 @@ class Cal extends \Zotlabs\Web\Controller {
$title = strip_tags(html_entity_decode($title,ENT_QUOTES,'UTF-8'));
}
$html = format_event_html($rr);
- $rr['desc'] = bbcode($rr['desc']);
- $rr['location'] = bbcode($rr['location']);
+ $rr['desc'] = zidify_links(smilies(bbcode($rr['desc'])));
+ $rr['location'] = zidify_links(smilies(bbcode($rr['location'])));
$events[] = array(
'id'=>$rr['id'],
'hash' => $rr['event_hash'],
diff --git a/Zotlabs/Module/Channel.php b/Zotlabs/Module/Channel.php
index 45da92184..0d20e0080 100644
--- a/Zotlabs/Module/Channel.php
+++ b/Zotlabs/Module/Channel.php
@@ -41,12 +41,20 @@ class Channel extends \Zotlabs\Web\Controller {
$profile = argv(1);
}
- \App::$page['htmlhead'] .= '<link rel="alternate" type="application/atom+xml" title="' . t('Posts and comments') . '" href="' . z_root() . '/feed/' . $which . '" />' . "\r\n" ;
- \App::$page['htmlhead'] .= '<link rel="alternate" type="application/atom+xml" title="' . t('Only posts') . '" href="' . z_root() . '/feed/' . $which . '?top=1" />' . "\r\n" ;
+ head_add_link( [
+ 'rel' => 'alternate',
+ 'type' => 'application/atom+xml',
+ 'title' => t('Posts and comments'),
+ 'href' => z_root() . '/feed/' . $which
+ ]);
+
+ head_add_link( [
+ 'rel' => 'alternate',
+ 'type' => 'application/atom+xml',
+ 'title' => t('Only posts'),
+ 'href' => z_root() . '/feed/' . $which . '?f=&top=1'
+ ]);
- // Not yet ready for prime time
- // \App::$page['htmlhead'] .= '<link rel="openid.server" href="' . z_root() . '/id/' . $which .'?f=" />' . "\r\n" ;
- // \App::$page['htmlhead'] .= '<link rel="openid.delegate" href="' . z_root() . '/channel/' . $which .'" />' . "\r\n" ;
// Run profile_load() here to make sure the theme is set before
// we start loading content
diff --git a/Zotlabs/Module/Chat.php b/Zotlabs/Module/Chat.php
index 2c0e7a155..febfd51e5 100644
--- a/Zotlabs/Module/Chat.php
+++ b/Zotlabs/Module/Chat.php
@@ -33,9 +33,7 @@ class Chat extends \Zotlabs\Web\Controller {
$which = $channel['channel_address'];
$profile = argv(1);
}
-
- \App::$page['htmlhead'] .= '<link rel="alternate" type="application/atom+xml" href="' . z_root() . '/feed/' . $which .'" />' . "\r\n" ;
-
+
// Run profile_load() here to make sure the theme is set before
// we start loading content
diff --git a/Zotlabs/Module/Chatsvc.php b/Zotlabs/Module/Chatsvc.php
index 6a28a7c4d..0f79e3b4c 100644
--- a/Zotlabs/Module/Chatsvc.php
+++ b/Zotlabs/Module/Chatsvc.php
@@ -111,8 +111,22 @@ class Chatsvc extends \Zotlabs\Web\Controller {
intval(\App::$data['chat']['room_id'])
);
if($r) {
- foreach($r as $rr) {
- switch($rr['cp_status']) {
+ foreach($r as $rv) {
+ if(! $rv['xchan_name']) {
+ $rv['xchan_hash'] = $rv['cp_xchan'];
+ $rv['xchan_name'] = substr($rv['cp_xchan'],strrpos($rv['cp_xchan'],'.')+1);
+ $rv['xchan_addr'] = '';
+ $rv['xchan_network'] = 'unknown';
+ $rv['xchan_url'] = z_root();
+ $rv['xchan_hidden'] = 1;
+ $rv['xchan_photo_mimetype'] = 'image/jpeg';
+ $rv['xchan_photo_l'] = get_default_profile_photo(300);
+ $rv['xchan_photo_m'] = get_default_profile_photo(80);
+ $rv['xchan_photo_s'] = get_default_profile_photo(48);
+
+ }
+
+ switch($rv['cp_status']) {
case 'away':
$status = t('Away');
$status_class = 'away';
@@ -124,7 +138,7 @@ class Chatsvc extends \Zotlabs\Web\Controller {
break;
}
- $inroom[] = array('img' => zid($rr['xchan_photo_m']), 'img_type' => $rr['xchan_photo_mimetype'],'name' => $rr['xchan_name'], 'status' => $status, 'status_class' => $status_class);
+ $inroom[] = array('img' => zid($rv['xchan_photo_m']), 'img_type' => $rv['xchan_photo_mimetype'],'name' => $rv['xchan_name'], 'status' => $status, 'status_class' => $status_class);
}
}
@@ -143,7 +157,7 @@ class Chatsvc extends \Zotlabs\Web\Controller {
'name' => $rr['xchan_name'],
'isotime' => datetime_convert('UTC', date_default_timezone_get(), $rr['created'], 'c'),
'localtime' => datetime_convert('UTC', date_default_timezone_get(), $rr['created'], 'r'),
- 'text' => smilies(bbcode($rr['chat_text'])),
+ 'text' => zidify_links(smilies(bbcode($rr['chat_text']))),
'self' => ((get_observer_hash() == $rr['chat_xchan']) ? 'self' : '')
);
}
diff --git a/Zotlabs/Module/Cloud.php b/Zotlabs/Module/Cloud.php
index 1fda8e32b..2b6d7bcbe 100644
--- a/Zotlabs/Module/Cloud.php
+++ b/Zotlabs/Module/Cloud.php
@@ -37,8 +37,6 @@ class Cloud extends \Zotlabs\Web\Controller {
$profile = 0;
- \App::$page['htmlhead'] .= '<link rel="alternate" type="application/atom+xml" href="' . z_root() . '/feed/' . $which . '" />' . "\r\n";
-
if ($which)
profile_load( $which, $profile);
@@ -59,8 +57,6 @@ class Cloud extends \Zotlabs\Web\Controller {
$auth->observer = $ob_hash;
}
- if ($_GET['davguest'])
- $_SESSION['davguest'] = true;
$_SERVER['QUERY_STRING'] = str_replace(array('?f=', '&f='), array('', ''), $_SERVER['QUERY_STRING']);
$_SERVER['QUERY_STRING'] = strip_zids($_SERVER['QUERY_STRING']);
diff --git a/Zotlabs/Module/Connections.php b/Zotlabs/Module/Connections.php
index a412d16ae..e8a92e8b7 100644
--- a/Zotlabs/Module/Connections.php
+++ b/Zotlabs/Module/Connections.php
@@ -228,10 +228,18 @@ class Connections extends \Zotlabs\Web\Controller {
$contacts = array();
- if(count($r)) {
-
+ if($r) {
+
+ vcard_query($r);
+
+
foreach($r as $rr) {
if($rr['xchan_url']) {
+
+ if(($rr['vcard']) && is_array($rr['vcard']['tels']) && $rr['vcard']['tels'][0]['nr'])
+ $phone = ((\App::$is_mobile || \App::$is_tablet) ? $rr['vcard']['tels'][0]['nr'] : '');
+ else
+ $phone = '';
$status_str = '';
$status = array(
@@ -261,12 +269,14 @@ class Connections extends \Zotlabs\Web\Controller {
'link' => z_root() . '/connedit/' . $rr['abook_id'],
'deletelink' => z_root() . '/connedit/' . intval($rr['abook_id']) . '/drop',
'delete' => t('Delete'),
- 'url' => chanlink_url($rr['xchan_url']),
+ 'url' => chanlink_hash($rr['xchan_hash']),
'webbie_label' => t('Channel address'),
'webbie' => $rr['xchan_addr'],
'network_label' => t('Network'),
'network' => network_to_name($rr['xchan_network']),
'public_forum' => ((intval($rr['xchan_pubforum'])) ? true : false),
+ 'call' => t('Call'),
+ 'phone' => $phone,
'status_label' => t('Status'),
'status' => $status_str,
'connected_label' => t('Connected'),
diff --git a/Zotlabs/Module/Connedit.php b/Zotlabs/Module/Connedit.php
index 5968ccde6..7a753c286 100644
--- a/Zotlabs/Module/Connedit.php
+++ b/Zotlabs/Module/Connedit.php
@@ -37,7 +37,7 @@ class Connedit extends \Zotlabs\Web\Controller {
intval(argv(1))
);
if($r) {
- \App::$poi = $r[0];
+ \App::$poi = array_shift($r);
}
}
@@ -86,6 +86,12 @@ class Connedit extends \Zotlabs\Web\Controller {
call_hooks('contact_edit_post', $_POST);
+ $vc = get_abconfig(local_channel(),$orig_record['abook_xchan'],'system','vcard');
+ $vcard = (($vc) ? \Sabre\VObject\Reader::read($vc) : null);
+ $serialised_vcard = update_vcard($_REQUEST,$vcard);
+ if($serialised_vcard)
+ set_abconfig(local_channel(),$orig_record[0]['abook_xchan'],'system','vcard',$serialised_vcard);
+
if(intval($orig_record[0]['abook_self'])) {
$autoperms = intval($_POST['autoperms']);
$is_self = true;
@@ -206,6 +212,7 @@ class Connedit extends \Zotlabs\Web\Controller {
}
if(($_REQUEST['pending']) && intval($orig_record[0]['abook_pending'])) {
+
$new_friend = true;
// @fixme it won't be common, but when you accept a new connection request
@@ -215,21 +222,13 @@ class Connedit extends \Zotlabs\Web\Controller {
// request. The workaround is to approve the connection, then go back and
// adjust permissions as desired.
- $abook_my_perms = get_channel_default_perms(local_channel());
-
- $role = get_pconfig(local_channel(),'system','permissions_role');
- if($role) {
- $x = \Zotlabs\Access\PermissionRoles::role_perms($role);
- if($x['perms_connect']) {
- $abook_my_perms = $x['perms_connect'];
+ $p = \Zotlabs\Access\Permissions::connect_perms(local_channel());
+ $my_perms = $p['perms'];
+ if($my_perms) {
+ foreach($my_perms as $k => $v) {
+ set_abconfig($channel['channel_id'],$orig_record[0]['abook_xchan'],'my_perms',$k,$v);
}
}
-
- $filled_perms = \Zotlabs\Access\Permissions::FilledPerms($abook_my_perms);
- foreach($filled_perms as $k => $v) {
- set_abconfig($channel['channel_id'],$orig_record[0]['abook_xchan'],'my_perms',$k,$v);
- }
-
}
$abook_pending = (($new_friend) ? 0 : $orig_record[0]['abook_pending']);
@@ -246,14 +245,6 @@ class Connedit extends \Zotlabs\Web\Controller {
intval(local_channel())
);
- if($orig_record[0]['abook_profile'] != $profile_id) {
- //Update profile photo permissions
-
- logger('A new profile was assigned - updating profile photos');
- profile_photo_set_profile_perms(local_channel(),$profile_id);
-
- }
-
if($r)
info( t('Connection updated.') . EOL);
else
@@ -367,7 +358,7 @@ class Connedit extends \Zotlabs\Web\Controller {
intval(\App::$poi['abook_id'])
);
if($r) {
- \App::$poi = $r[0];
+ \App::$poi = array_shift($r);
}
$clone = \App::$poi;
@@ -639,6 +630,15 @@ class Connedit extends \Zotlabs\Web\Controller {
),
);
+
+ $sections = [];
+
+ $sections['perms'] = [
+ 'label' => t('Permissions'),
+ 'url' => z_root() . '/connedit/' . $contact['abook_id'] . '/?f=&section=perms',
+ 'sel' => '',
+ 'title' => t('Open Individual Permissions section by default'),
+ ];
$self = false;
@@ -647,17 +647,32 @@ class Connedit extends \Zotlabs\Web\Controller {
$abook_prev = $abook_next = 0;
}
+ $vc = get_abconfig(local_channel(),$contact['abook_xchan'],'system','vcard');
+
+ $vctmp = (($vc) ? \Sabre\VObject\Reader::read($vc) : null);
+ $vcard = (($vctmp) ? get_vcard_array($vctmp,$contact['abook_id']) : [] );
+ if(! $vcard)
+ $vcard['fn'] = $contact['xchan_name'];
+
+
$tpl = get_markup_template("abook_edit.tpl");
if(feature_enabled(local_channel(),'affinity')) {
+
+ $sections['affinity'] = [
+ 'label' => t('Affinity'),
+ 'url' => z_root() . '/connedit/' . $contact['abook_id'] . '/?f=&section=affinity',
+ 'sel' => '',
+ 'title' => t('Open Set Affinity section by default'),
+ ];
- $labels = array(
+ $labels = [
t('Me'),
t('Family'),
t('Friends'),
t('Acquaintances'),
t('All')
- );
+ ];
call_hooks('affinity_labels',$labels);
$label_str = '';
@@ -679,6 +694,15 @@ class Connedit extends \Zotlabs\Web\Controller {
'$labels' => $label_str,
));
}
+
+ if(feature_enabled(local_channel(),'connfilter')) {
+ $sections['filter'] = [
+ 'label' => t('Filter'),
+ 'url' => z_root() . '/connedit/' . $contact['abook_id'] . '/?f=&section=filter',
+ 'sel' => '',
+ 'title' => t('Open Custom Filter section by default'),
+ ];
+ }
$rating_val = 0;
$rating_text = '';
@@ -754,6 +778,15 @@ class Connedit extends \Zotlabs\Web\Controller {
$perms[] = array('perms_' . $k, $v, ((array_key_exists($k,$their_perms)) ? intval($their_perms[$k]) : ''),$thisperm, 1, (($checkinherited & PERMS_SPECIFIC) ? '' : '1'), '', $checkinherited);
}
+ $pcat = new \Zotlabs\Lib\Permcat(local_channel());
+ $pcatlist = $pcat->listing();
+ $permcats = [];
+ if($pcatlist) {
+ foreach($pcatlist as $pc) {
+ $permcats[$pc['name']] = $pc['localname'];
+ }
+ }
+
$locstr = '';
$locs = q("select hubloc_addr as location from hubloc left join site on hubloc_url = site_url where hubloc_hash = '%s'
@@ -775,12 +808,16 @@ class Connedit extends \Zotlabs\Web\Controller {
else
$locstr = t('none');
- $o .= replace_macros($tpl,array(
-
+ $o .= replace_macros($tpl, [
'$header' => (($self) ? t('Connection Default Permissions') : sprintf( t('Connection: %s'),$contact['xchan_name'])),
'$autoperms' => array('autoperms',t('Apply these permissions automatically'), ((get_pconfig(local_channel(),'system','autoperms')) ? 1 : 0), t('Connection requests will be approved without your interaction'), $yes_no),
+ '$permcat' => [ 'permcat', t('Permission role'), '', '',$permcats ],
+ '$permcat_new' => t('Add permission role'),
+ '$permcat_enable' => feature_enabled(local_channel(),'permcats'),
'$addr' => $contact['xchan_addr'],
'$section' => $section,
+ '$sections' => $sections,
+ '$vcard' => $vcard,
'$addr_text' => t('This connection\'s primary address is'),
'$loc_text' => t('Available locations:'),
'$locstr' => $locstr,
@@ -818,13 +855,42 @@ class Connedit extends \Zotlabs\Web\Controller {
'$permnote_self' => t('Some permissions may be inherited from your channel\'s <a href="settings"><strong>privacy settings</strong></a>, which have higher priority than individual settings. You can change those settings here but they wont have any impact unless the inherited setting changes.'),
'$lastupdtext' => t('Last update:'),
'$last_update' => relative_date($contact['abook_connected']),
+ '$is_mobile' => ((\App::$is_mobile || \App::$is_tablet) ? true : false),
'$profile_select' => contact_profile_assign($contact['abook_profile']),
'$multiprofs' => $multiprofs,
'$contact_id' => $contact['abook_id'],
'$name' => $contact['xchan_name'],
'$abook_prev' => $abook_prev,
- '$abook_next' => $abook_next
- ));
+ '$abook_next' => $abook_next,
+ '$vcard_label' => t('Details'),
+ '$displayname' => $displayname,
+ '$name_label' => t('Name'),
+ '$org_label' => t('Organisation'),
+ '$title_label' => t('Title'),
+ '$tel_label' => t('Phone'),
+ '$email_label' => t('Email'),
+ '$impp_label' => t('Instant messenger'),
+ '$url_label' => t('Website'),
+ '$adr_label' => t('Address'),
+ '$note_label' => t('Note'),
+ '$mobile' => t('Mobile'),
+ '$home' => t('Home'),
+ '$work' => t('Work'),
+ '$other' => t('Other'),
+ '$add_card' => t('Add Contact'),
+ '$add_field' => t('Add Field'),
+ '$create' => t('Create'),
+ '$update' => t('Update'),
+ '$delete' => t('Delete'),
+ '$cancel' => t('Cancel'),
+ '$po_box' => t('P.O. Box'),
+ '$extra' => t('Additional'),
+ '$street' => t('Street'),
+ '$locality' => t('Locality'),
+ '$region' => t('Region'),
+ '$zip_code' => t('ZIP Code'),
+ '$country' => t('Country')
+ ]);
$arr = array('contact' => $contact,'output' => $o);
diff --git a/Zotlabs/Module/Directory.php b/Zotlabs/Module/Directory.php
index ceeeda933..59ae88857 100644
--- a/Zotlabs/Module/Directory.php
+++ b/Zotlabs/Module/Directory.php
@@ -263,7 +263,7 @@ class Directory extends \Zotlabs\Web\Controller {
$hometown = ((x($profile,'hometown') == 1) ? $profile['hometown'] : False);
- $about = ((x($profile,'about') == 1) ? bbcode($profile['about']) : False);
+ $about = ((x($profile,'about') == 1) ? zidify_links(bbcode($profile['about'])) : False);
$keywords = ((x($profile,'keywords')) ? $profile['keywords'] : '');
diff --git a/Zotlabs/Module/Display.php b/Zotlabs/Module/Display.php
index 42f6dd4ac..a4d59a1b6 100644
--- a/Zotlabs/Module/Display.php
+++ b/Zotlabs/Module/Display.php
@@ -1,12 +1,17 @@
<?php
namespace Zotlabs\Module;
+require_once("include/bbcode.php");
+require_once('include/security.php');
+require_once('include/conversation.php');
+require_once('include/acl_selectors.php');
+require_once('include/items.php');
class Display extends \Zotlabs\Web\Controller {
function get($update = 0, $load = false) {
-
+
$checkjs = new \Zotlabs\Web\CheckJS(1);
if($load)
@@ -18,30 +23,21 @@ class Display extends \Zotlabs\Web\Controller {
return;
}
- require_once("include/bbcode.php");
- require_once('include/security.php');
- require_once('include/conversation.php');
- require_once('include/acl_selectors.php');
- require_once('include/items.php');
-
-
- \App::$page['htmlhead'] .= replace_macros(get_markup_template('display-head.tpl'), array());
-
+
if(argc() > 1 && argv(1) !== 'load')
$item_hash = argv(1);
-
if($_REQUEST['mid'])
$item_hash = $_REQUEST['mid'];
-
-
- if(! $item_hash) {
+
+ if(! $item_hash) {
\App::$error = 404;
notice( t('Item not found.') . EOL);
return;
}
$observer_is_owner = false;
+ $updateable = false;
if(local_channel() && (! $update)) {
@@ -93,9 +89,15 @@ class Display extends \Zotlabs\Web\Controller {
// find a copy of the item somewhere
$target_item = null;
-
+
+ if(strpos($item_hash,'b64.') === 0)
+ $decoded = @base64url_decode(substr($item_hash,4));
+ if($decoded)
+ $item_hash = $decoded;
+
$r = q("select id, uid, mid, parent_mid, item_type, item_deleted from item where mid like '%s' limit 1",
- dbesc($item_hash . '%')
+ dbesc($item_hash . '%'),
+ dbesc($decoded . '%')
);
if($r) {
@@ -180,10 +182,9 @@ class Display extends \Zotlabs\Web\Controller {
$item_normal = item_normal();
$sql_extra = public_permissions_sql($observer_hash);
-
+
if(($update && $load) || ($checkjs->disabled())) {
- $updateable = false;
$pager_sql = sprintf(" LIMIT %d OFFSET %d ", intval(\App::$pager['itemspage']),intval(\App::$pager['start']));
@@ -193,9 +194,9 @@ class Display extends \Zotlabs\Web\Controller {
require_once('include/channel.php');
$sys = get_sys_channel();
$sysid = $sys['channel_id'];
-
+
if(local_channel()) {
- $r = q("SELECT * from item
+ $r = q("SELECT item.id as item_id from item
WHERE uid = %d
and mid = '%s'
$item_normal
@@ -209,6 +210,7 @@ class Display extends \Zotlabs\Web\Controller {
}
}
+
if($r === null) {
// in case somebody turned off public access to sys channel content using permissions
@@ -218,7 +220,7 @@ class Display extends \Zotlabs\Web\Controller {
$sysid = 0;
- $r = q("SELECT * from item
+ $r = q("SELECT item.id as item_id from item
WHERE mid = '%s'
AND (((( item.allow_cid = '' AND item.allow_gid = '' AND item.deny_cid = ''
AND item.deny_gid = '' AND item_private = 0 )
@@ -241,11 +243,11 @@ class Display extends \Zotlabs\Web\Controller {
require_once('include/channel.php');
$sys = get_sys_channel();
$sysid = $sys['channel_id'];
-
+
if(local_channel()) {
- $r = q("SELECT * from item
+ $r = q("SELECT item.parent AS item_id from item
WHERE uid = %d
- and mid = '%s'
+ and parent_mid = '%s'
$item_normal
$simple_update
limit 1",
@@ -256,14 +258,15 @@ class Display extends \Zotlabs\Web\Controller {
$updateable = true;
}
}
+
if($r === null) {
// in case somebody turned off public access to sys channel content using permissions
// make that content unsearchable by ensuring the owner_xchan can't match
if(! perm_is_allowed($sysid,$observer_hash,'view_stream'))
$sysid = 0;
- $r = q("SELECT * from item
- WHERE mid = '%s'
+ $r = q("SELECT item.parent AS item_id from item
+ WHERE parent_mid = '%s'
AND (((( item.allow_cid = '' AND item.allow_gid = '' AND item.deny_cid = ''
AND item.deny_gid = '' AND item_private = 0 )
and owner_xchan in ( " . stream_perms_xchans(($observer_hash) ? (PERMS_NETWORK|PERMS_PUBLIC) : PERMS_PUBLIC) . " ))
@@ -285,7 +288,7 @@ class Display extends \Zotlabs\Web\Controller {
if($r) {
- $parents_str = ids_to_querystr($r,'id');
+ $parents_str = ids_to_querystr($r,'item_id');
if($parents_str) {
$items = q("SELECT item.*, item.id AS item_id
@@ -315,10 +318,10 @@ class Display extends \Zotlabs\Web\Controller {
if($updateable) {
$x = q("UPDATE item SET item_unseen = 0 where item_unseen = 1 AND uid = %d and parent = %d ",
intval(local_channel()),
- intval($r[0]['parent'])
+ intval($r[0]['item_id'])
);
}
-
+
$o .= '<div id="content-complete"></div>';
return $o;
diff --git a/Zotlabs/Module/Editpost.php b/Zotlabs/Module/Editpost.php
index 5c04653b8..d7612b165 100644
--- a/Zotlabs/Module/Editpost.php
+++ b/Zotlabs/Module/Editpost.php
@@ -78,6 +78,7 @@ class Editpost extends \Zotlabs\Web\Controller {
$x = array(
'nickname' => $channel['channel_address'],
+ 'item' => $itm[0],
'editor_autocomplete'=> true,
'bbco_autocomplete'=> 'bbcode',
'return_path' => $_SESSION['return_url'],
diff --git a/Zotlabs/Module/Events.php b/Zotlabs/Module/Events.php
index b8910b644..edc6dd3f0 100644
--- a/Zotlabs/Module/Events.php
+++ b/Zotlabs/Module/Events.php
@@ -43,6 +43,10 @@ class Events extends \Zotlabs\Web\Controller {
$adjust = intval($_POST['adjust']);
$nofinish = intval($_POST['nofinish']);
+ $timezone = ((x($_POST,'timezone_select')) ? notags(trim($_POST['timezone_select'])) : '');
+
+ $tz = (($timezone) ? $timezone : date_default_timezone_get());
+
$categories = escape_tags(trim($_POST['category']));
// only allow editing your own events.
@@ -71,9 +75,9 @@ class Events extends \Zotlabs\Web\Controller {
if($adjust) {
- $start = datetime_convert(date_default_timezone_get(),'UTC',$start);
+ $start = datetime_convert($tz,'UTC',$start);
if(! $nofinish)
- $finish = datetime_convert(date_default_timezone_get(),'UTC',$finish);
+ $finish = datetime_convert($tz,'UTC',$finish);
}
else {
$start = datetime_convert('UTC','UTC',$start);
@@ -374,11 +378,14 @@ class Events extends \Zotlabs\Web\Controller {
$event_xchan = ((x($orig_event)) ? $orig_event['event_xchan'] : $channel['channel_hash']);
$mid = ((x($orig_event)) ? $orig_event['mid'] : '');
- if(! x($orig_event))
+ if(! x($orig_event)) {
$sh_checked = '';
- else
+ $a_checked = ' checked="checked" ';
+ }
+ else {
$sh_checked = ((($orig_event['allow_cid'] === '<' . $channel['channel_hash'] . '>' || (! $orig_event['allow_cid'])) && (! $orig_event['allow_gid']) && (! $orig_event['deny_cid']) && (! $orig_event['deny_gid'])) ? '' : ' checked="checked" ' );
-
+ }
+
if($orig_event['event_xchan'])
$sh_checked .= ' disabled="disabled" ';
@@ -478,6 +485,8 @@ class Events extends \Zotlabs\Web\Controller {
'$allow_gid' => acl2json($permissions['allow_gid']),
'$deny_cid' => acl2json($permissions['deny_cid']),
'$deny_gid' => acl2json($permissions['deny_gid']),
+ '$tz_choose' => feature_enabled(local_channel(),'event_tz_select'),
+ '$timezone' => array('timezone_select' , t('Timezone:'), date_default_timezone_get(), '', get_timezones()),
'$lockstate' => (($acl->is_private()) ? 'lock' : 'unlock'),
@@ -625,14 +634,14 @@ class Events extends \Zotlabs\Web\Controller {
$drop = array(z_root().'/events/drop/'.$rr['event_hash'],t('Delete event'),'','');
- $title = strip_tags(html_entity_decode(bbcode($rr['summary']),ENT_QUOTES,'UTF-8'));
+ $title = strip_tags(html_entity_decode(zidify_links(bbcode($rr['summary'])),ENT_QUOTES,'UTF-8'));
if(! $title) {
list($title, $_trash) = explode("<br",bbcode($rr['desc']),2);
$title = strip_tags(html_entity_decode($title,ENT_QUOTES,'UTF-8'));
}
$html = format_event_html($rr);
- $rr['desc'] = bbcode($rr['desc']);
- $rr['location'] = bbcode($rr['location']);
+ $rr['desc'] = zidify_links(smilies(bbcode($rr['desc'])));
+ $rr['location'] = zidify_links(smilies(bbcode($rr['location'])));
$events[] = array(
'id'=>$rr['id'],
'hash' => $rr['event_hash'],
diff --git a/Zotlabs/Module/Ffsapi.php b/Zotlabs/Module/Ffsapi.php
deleted file mode 100644
index f3ade73c2..000000000
--- a/Zotlabs/Module/Ffsapi.php
+++ /dev/null
@@ -1,71 +0,0 @@
-<?php
-namespace Zotlabs\Module;
-
-
-
-class Ffsapi extends \Zotlabs\Web\Controller {
-
- function get() {
-
- $baseurl = z_root();
- $name = get_config('system','sitename');
- $description = t('Share content from Firefox to $Projectname');
- $author = 'Mike Macgirvin';
- $homepage = 'http://hubzilla.org';
- $activate = t('Activate the Firefox $Projectname provider');
-
- $s = <<< EOT
-
- <script>
-
- var baseurl = '$baseurl';
-
- var data = {
- "origin": baseurl,
- // currently required
- "name": '$name',
- "iconURL": baseurl+"/images/hz-16.png",
- "icon32URL": baseurl+"/images/hz-32.png",
- "icon64URL": baseurl+"/images/hz-64.png",
-
- // at least one of these must be defined
- // "workerURL": baseurl+"/worker.js",
- // "sidebarURL": baseurl+"/sidebar.htm",
- "shareURL": baseurl+"/rpost?f=&url=%{url}",
-
- // status buttons are scheduled for Firefox 26 or 27
- //"statusURL": baseurl+"/statusPanel.html",
-
- // social bookmarks are available in Firefox 26
- "markURL": baseurl+"/rbmark?f=&url=%{url}&title=%{title}",
- // icons should be 32x32 pixels
- // "markedIcon": baseurl+"/images/checkbox-checked-32.png",
- // "unmarkedIcon": baseurl+"/images/checkbox-unchecked-32.png",
- "unmarkedIcon": baseurl+"/images/hz-bookmark-32.png",
-
- // should be available for display purposes
- "description": "$description",
- "author": "$author",
- "homepageURL": "$homepage",
-
- // optional
- "version": "1.0"
- }
-
- function activate(node) {
- var event = new CustomEvent("ActivateSocialFeature");
- var jdata = JSON.stringify(data);
- node.setAttribute("data-service", JSON.stringify(data));
- node.dispatchEvent(event);
- }
- </script>
-
- <button onclick="activate(this)" title="$activate" class="btn btn-primary">$activate</button>
-
-EOT;
-
- return $s;
-
- }
-
-}
diff --git a/Zotlabs/Module/Fhublocs.php b/Zotlabs/Module/Fhublocs.php
index cdf323a41..42c119da3 100644
--- a/Zotlabs/Module/Fhublocs.php
+++ b/Zotlabs/Module/Fhublocs.php
@@ -56,19 +56,21 @@ class Fhublocs extends \Zotlabs\Web\Controller {
// Create a verified hub location pointing to this site.
- $h = q("insert into hubloc ( hubloc_guid, hubloc_guid_sig, hubloc_hash, hubloc_addr, hubloc_primary, hubloc_url, hubloc_url_sig, hubloc_host, hubloc_callback, hubloc_sitekey, hubloc_network )
- values ( '%s', '%s', '%s', '%s', %d, '%s', '%s', '%s', '%s', '%s', '%s' )",
- dbesc($rr['channel_guid']),
- dbesc($rr['channel_guid_sig']),
- dbesc($rr['channel_hash']),
- dbesc(channel_reddress($rr)),
- intval($primary),
- dbesc(z_root()),
- dbesc(base64url_encode(rsa_sign(z_root(),$rr['channel_prvkey']))),
- dbesc(\App::get_hostname()),
- dbesc(z_root() . '/post'),
- dbesc($sitekey),
- dbesc('zot')
+
+ $h = hubloc_store_lowlevel(
+ [
+ 'hubloc_guid' => $rr['channel_guid'],
+ 'hubloc_guid_sig' => $rr['channel_guid_sig'],
+ 'hubloc_hash' => $rr['channel_hash'],
+ 'hubloc_addr' => channel_reddress($rr),
+ 'hubloc_network' => 'zot',
+ 'hubloc_primary' => $primary,
+ 'hubloc_url' => z_root(),
+ 'hubloc_url_sig' => base64url_encode(rsa_sign(z_root(),$rr['channel_prvkey'])),
+ 'hubloc_host' => \App::get_hostname(),
+ 'hubloc_callback' => z_root() . '/post',
+ 'hubloc_sitekey' => $sitekey
+ ]
);
if($h)
diff --git a/Zotlabs/Module/Hcard.php b/Zotlabs/Module/Hcard.php
index 93c8d3ece..ec9181f6a 100644
--- a/Zotlabs/Module/Hcard.php
+++ b/Zotlabs/Module/Hcard.php
@@ -29,7 +29,20 @@ class Hcard extends \Zotlabs\Web\Controller {
$profile = $r[0]['profile_guid'];
}
- \App::$page['htmlhead'] .= '<link rel="alternate" type="application/atom+xml" href="' . z_root() . '/feed/' . $which .'" />' . "\r\n" ;
+ head_add_link( [
+ 'rel' => 'alternate',
+ 'type' => 'application/atom+xml',
+ 'title' => t('Posts and comments'),
+ 'href' => z_root() . '/feed/' . $which
+ ]);
+
+ head_add_link( [
+ 'rel' => 'alternate',
+ 'type' => 'application/atom+xml',
+ 'title' => t('Only posts'),
+ 'href' => z_root() . '/feed/' . $which . '?f=&top=1'
+ ]);
+
if(! $profile) {
$x = q("select channel_id as profile_uid from channel where channel_address = '%s' limit 1",
diff --git a/Zotlabs/Module/Hostxrd.php b/Zotlabs/Module/Hostxrd.php
index 1aae8da9e..c1d5cf0e9 100644
--- a/Zotlabs/Module/Hostxrd.php
+++ b/Zotlabs/Module/Hostxrd.php
@@ -5,6 +5,7 @@ namespace Zotlabs\Module;
class Hostxrd extends \Zotlabs\Web\Controller {
function init() {
+ session_write_close();
header('Access-Control-Allow-Origin: *');
header("Content-type: application/xrd+xml");
logger('hostxrd',LOGGER_DEBUG);
diff --git a/Zotlabs/Module/Import.php b/Zotlabs/Module/Import.php
index 451effaca..3969f25e0 100644
--- a/Zotlabs/Module/Import.php
+++ b/Zotlabs/Module/Import.php
@@ -1,4 +1,5 @@
<?php
+
namespace Zotlabs\Module;
// Import a channel, either by direct file upload or via
@@ -21,33 +22,18 @@ class Import extends \Zotlabs\Web\Controller {
return;
}
- $max_identities = account_service_class_fetch($account_id,'total_identities');
- $max_friends = account_service_class_fetch($account_id,'total_channels');
- $max_feeds = account_service_class_fetch($account_id,'total_feeds');
-
- if($max_identities !== false) {
- $r = q("select channel_id from channel where channel_account_id = %d",
- intval($account_id)
- );
- if($r && count($r) > $max_identities) {
- notice( sprintf( t('Your service plan only allows %d channels.'), $max_identities) . EOL);
- return;
- }
- }
-
-
- $data = null;
- $seize = ((x($_REQUEST,'make_primary')) ? intval($_REQUEST['make_primary']) : 0);
- $import_posts = ((x($_REQUEST,'import_posts')) ? intval($_REQUEST['import_posts']) : 0);
- $src = $_FILES['filename']['tmp_name'];
- $filename = basename($_FILES['filename']['name']);
- $filesize = intval($_FILES['filename']['size']);
- $filetype = $_FILES['filename']['type'];
-
- $completed = ((array_key_exists('import_step',$_SESSION)) ? intval($_SESSION['import_step']) : 0);
- if($completed)
- logger('saved import step: ' . $_SESSION['import_step']);
+ $max_friends = account_service_class_fetch($account_id,'total_channels');
+ $max_feeds = account_service_class_fetch($account_id,'total_feeds');
+ $data = null;
+ $seize = ((x($_REQUEST,'make_primary')) ? intval($_REQUEST['make_primary']) : 0);
+ $import_posts = ((x($_REQUEST,'import_posts')) ? intval($_REQUEST['import_posts']) : 0);
+ $moving = intval($_REQUEST['moving']);
+ $src = $_FILES['filename']['tmp_name'];
+ $filename = basename($_FILES['filename']['name']);
+ $filesize = intval($_FILES['filename']['size']);
+ $filetype = $_FILES['filename']['type'];
+
if($src) {
// This is OS specific and could also fail if your tmpdir isn't very large
@@ -112,14 +98,12 @@ class Import extends \Zotlabs\Web\Controller {
// print_r($data);
- if(array_key_exists('user',$data) && array_key_exists('version',$data)) {
- require_once('include/Import/import_diaspora.php');
- import_diaspora($data);
- return;
+ if(! array_key_exists('compatibility',$data)) {
+ call_hooks('import_foreign_channel_data',$data);
+ if($data['handled'])
+ return;
}
-
- $moving = false;
-
+
if(array_key_exists('compatibility',$data) && array_key_exists('database',$data['compatibility'])) {
$v1 = substr($data['compatibility']['database'],-4);
$v2 = substr(DB_UPDATE_VERSION,-4);
@@ -140,28 +124,26 @@ class Import extends \Zotlabs\Web\Controller {
if(array_key_exists('channel',$data)) {
- if($completed < 1) {
- $channel = import_channel($data['channel'], $account_id, $seize);
+ $max_identities = account_service_class_fetch($account_id,'total_identities');
- }
- else {
- $r = q("select * from channel where channel_account_id = %d and channel_guid = '%s' limit 1",
- intval($account_id),
- dbesc($channel['channel_guid'])
+ if($max_identities !== false) {
+ $r = q("select channel_id from channel where channel_account_id = %d",
+ intval($account_id)
);
- if($r)
- $channel = $r[0];
- }
- if(! $channel) {
- logger('mod_import: channel not found. ', print_r($channel,true));
- notice( t('Cloned channel not found. Import failed.') . EOL);
- return;
+ if($r && count($r) > $max_identities) {
+ notice( sprintf( t('Your service plan only allows %d channels.'), $max_identities) . EOL);
+ return;
+ }
}
- }
+
+ $channel = import_channel($data['channel'], $account_id, $seize);
- if(! $channel)
+ }
+ else {
+ $moving = false;
$channel = \App::get_channel();
-
+ }
+
if(! $channel) {
logger('mod_import: channel not found. ', print_r($channel,true));
notice( t('No channel. Import failed.') . EOL);
@@ -169,18 +151,17 @@ class Import extends \Zotlabs\Web\Controller {
}
- if($completed < 2) {
- if(is_array($data['config'])) {
- import_config($channel,$data['config']);
- }
-
- logger('import step 2');
- $_SESSION['import_step'] = 2;
+
+ if(is_array($data['config'])) {
+ import_config($channel,$data['config']);
}
+ logger('import step 2');
- if($completed < 3) {
+
+
+ if(array_key_exists('channel',$data)) {
if($data['photo']) {
require_once('include/photo/photo_driver.php');
import_channel_photo(base64url_decode($data['photo']['data']),$data['photo']['type'],$account_id,$channel['channel_id']);
@@ -188,41 +169,36 @@ class Import extends \Zotlabs\Web\Controller {
if(is_array($data['profile']))
import_profiles($channel,$data['profile']);
-
- logger('import step 3');
- $_SESSION['import_step'] = 3;
}
+
+ logger('import step 3');
-
- if($completed < 4) {
-
- if(is_array($data['hubloc']) && (! $moving)) {
- import_hublocs($channel,$data['hubloc'],$seize);
-
- }
- logger('import step 4');
- $_SESSION['import_step'] = 4;
+ if(is_array($data['hubloc'])) {
+ import_hublocs($channel,$data['hubloc'],$seize,$moving);
}
-
- if($completed < 5) {
- // create new hubloc for the new channel at this site
-
- $r = q("insert into hubloc ( hubloc_guid, hubloc_guid_sig, hubloc_hash, hubloc_addr, hubloc_network, hubloc_primary,
- hubloc_url, hubloc_url_sig, hubloc_host, hubloc_callback, hubloc_sitekey )
- values ( '%s', '%s', '%s', '%s', '%s', %d, '%s', '%s', '%s', '%s', '%s' )",
- dbesc($channel['channel_guid']),
- dbesc($channel['channel_guid_sig']),
- dbesc($channel['channel_hash']),
- dbesc(channel_reddress($channel)),
- dbesc('zot'),
- intval(($seize) ? 1 : 0),
- dbesc(z_root()),
- dbesc(base64url_encode(rsa_sign(z_root(),$channel['channel_prvkey']))),
- dbesc(\App::get_hostname()),
- dbesc(z_root() . '/post'),
- dbesc(get_config('system','pubkey'))
+
+ logger('import step 4');
+
+ // create new hubloc for the new channel at this site
+
+ if(array_key_exists('channel',$data)) {
+ $r = hubloc_store_lowlevel(
+ [
+ 'hubloc_guid' => $channel['channel_guid'],
+ 'hubloc_guid_sig' => $channel['channel_guid_sig'],
+ 'hubloc_hash' => $channel['channel_hash'],
+ 'hubloc_addr' => channel_reddress($channel),
+ 'hubloc_network' => 'zot',
+ 'hubloc_primary' => (($seize) ? 1 : 0),
+ 'hubloc_url' => z_root(),
+ 'hubloc_url_sig' => base64url_encode(rsa_sign(z_root(),$channel['channel_prvkey'])),
+ 'hubloc_host' => \App::get_hostname(),
+ 'hubloc_callback' => z_root() . '/post',
+ 'hubloc_sitekey' => get_config('system','pubkey'),
+ 'hubloc_updated' => datetime_convert()
+ ]
);
-
+
// reset the original primary hubloc if it is being seized
if($seize) {
@@ -231,220 +207,205 @@ class Import extends \Zotlabs\Web\Controller {
dbesc(z_root())
);
}
- logger('import step 5');
- $_SESSION['import_step'] = 5;
}
+
+ logger('import step 5');
- if($completed < 6) {
- // import xchans and contact photos
+ // import xchans and contact photos
- if($seize) {
+ if(array_key_exists('channel',$data) && $seize) {
- // replace any existing xchan we may have on this site if we're seizing control
+ // replace any existing xchan we may have on this site if we're seizing control
- $r = q("delete from xchan where xchan_hash = '%s'",
- dbesc($channel['channel_hash'])
- );
-
- $r = q("insert into xchan ( xchan_hash, xchan_guid, xchan_guid_sig, xchan_pubkey, xchan_photo_l, xchan_photo_m, xchan_photo_s, xchan_addr, xchan_url, xchan_follow, xchan_connurl, xchan_name, xchan_network, xchan_photo_date, xchan_name_date, xchan_hidden, xchan_orphan, xchan_censored, xchan_selfcensored, xchan_system, xchan_pubforum, xchan_deleted ) values ('%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', %d, %d, %d, %d, %d, %d, %d )",
- dbesc($channel['channel_hash']),
- dbesc($channel['channel_guid']),
- dbesc($channel['channel_guid_sig']),
- dbesc($channel['channel_pubkey']),
- dbesc(z_root() . "/photo/profile/l/" . $channel['channel_id']),
- dbesc(z_root() . "/photo/profile/m/" . $channel['channel_id']),
- dbesc(z_root() . "/photo/profile/s/" . $channel['channel_id']),
- dbesc(channel_reddress($channel)),
- dbesc(z_root() . '/channel/' . $channel['channel_address']),
- dbesc(z_root() . '/follow?f=&url=%s'),
- dbesc(z_root() . '/poco/' . $channel['channel_address']),
- dbesc($channel['channel_name']),
- dbesc('zot'),
- dbesc(datetime_convert()),
- dbesc(datetime_convert()),
- 0,0,0,0,0,0,0
- );
- }
- logger('import step 6');
- $_SESSION['import_step'] = 6;
+ $r = q("delete from xchan where xchan_hash = '%s'",
+ dbesc($channel['channel_hash'])
+ );
+
+
+ $r = xchan_store_lowlevel(
+ [
+ 'xchan_hash' => $channel['channel_hash'],
+ 'xchan_guid' => $channel['channel_guid'],
+ 'xchan_guid_sig' => $channel['channel_guid_sig'],
+ 'xchan_pubkey' => $channel['channel_pubkey'],
+ 'xchan_photo_l' => z_root() . "/photo/profile/l/" . $channel['channel_id'],
+ 'xchan_photo_m' => z_root() . "/photo/profile/m/" . $channel['channel_id'],
+ 'xchan_photo_s' => z_root() . "/photo/profile/s/" . $channel['channel_id'],
+ 'xchan_addr' => channel_reddress($channel),
+ 'xchan_url' => z_root() . '/channel/' . $channel['channel_address'],
+ 'xchan_connurl' => z_root() . '/poco/' . $channel['channel_address'],
+ 'xchan_follow' => z_root() . '/follow?f=&url=%s',
+ 'xchan_name' => $channel['channel_name'],
+ 'xchan_network' => 'zot',
+ 'xchan_photo_date' => datetime_convert(),
+ 'xchan_name_date' => datetime_convert()
+ ]
+ );
}
- if($completed < 7) {
+ logger('import step 6');
+
- $xchans = $data['xchan'];
- if($xchans) {
- foreach($xchans as $xchan) {
- $hash = make_xchan_hash($xchan['xchan_guid'],$xchan['xchan_guid_sig']);
- if($xchan['xchan_network'] === 'zot' && $hash !== $xchan['xchan_hash']) {
- logger('forged xchan: ' . print_r($xchan,true));
- continue;
- }
+ $xchans = $data['xchan'];
+ if($xchans) {
+ foreach($xchans as $xchan) {
- if(! array_key_exists('xchan_hidden',$xchan)) {
- $xchan['xchan_hidden'] = (($xchan['xchan_flags'] & 0x0001) ? 1 : 0);
- $xchan['xchan_orphan'] = (($xchan['xchan_flags'] & 0x0002) ? 1 : 0);
- $xchan['xchan_censored'] = (($xchan['xchan_flags'] & 0x0004) ? 1 : 0);
- $xchan['xchan_selfcensored'] = (($xchan['xchan_flags'] & 0x0008) ? 1 : 0);
- $xchan['xchan_system'] = (($xchan['xchan_flags'] & 0x0010) ? 1 : 0);
- $xchan['xchan_pubforum'] = (($xchan['xchan_flags'] & 0x0020) ? 1 : 0);
- $xchan['xchan_deleted'] = (($xchan['xchan_flags'] & 0x1000) ? 1 : 0);
- }
+ $hash = make_xchan_hash($xchan['xchan_guid'],$xchan['xchan_guid_sig']);
+ if($xchan['xchan_network'] === 'zot' && $hash !== $xchan['xchan_hash']) {
+ logger('forged xchan: ' . print_r($xchan,true));
+ continue;
+ }
- $r = q("select xchan_hash from xchan where xchan_hash = '%s' limit 1",
- dbesc($xchan['xchan_hash'])
- );
- if($r)
- continue;
+ if(! array_key_exists('xchan_hidden',$xchan)) {
+ $xchan['xchan_hidden'] = (($xchan['xchan_flags'] & 0x0001) ? 1 : 0);
+ $xchan['xchan_orphan'] = (($xchan['xchan_flags'] & 0x0002) ? 1 : 0);
+ $xchan['xchan_censored'] = (($xchan['xchan_flags'] & 0x0004) ? 1 : 0);
+ $xchan['xchan_selfcensored'] = (($xchan['xchan_flags'] & 0x0008) ? 1 : 0);
+ $xchan['xchan_system'] = (($xchan['xchan_flags'] & 0x0010) ? 1 : 0);
+ $xchan['xchan_pubforum'] = (($xchan['xchan_flags'] & 0x0020) ? 1 : 0);
+ $xchan['xchan_deleted'] = (($xchan['xchan_flags'] & 0x1000) ? 1 : 0);
+ }
+
+ $r = q("select xchan_hash from xchan where xchan_hash = '%s' limit 1",
+ dbesc($xchan['xchan_hash'])
+ );
+ if($r)
+ continue;
- create_table_from_array('xchan',$xchan);
+ create_table_from_array('xchan',$xchan);
- require_once('include/photo/photo_driver.php');
- $photos = import_xchan_photo($xchan['xchan_photo_l'],$xchan['xchan_hash']);
- if($photos[4])
- $photodate = NULL_DATE;
- else
- $photodate = $xchan['xchan_photo_date'];
-
- $r = q("update xchan set xchan_photo_l = '%s', xchan_photo_m = '%s', xchan_photo_s = '%s', xchan_photo_mimetype = '%s', xchan_photo_date = '%s'
- where xchan_hash = '%s'",
- dbesc($photos[0]),
- dbesc($photos[1]),
- dbesc($photos[2]),
- dbesc($photos[3]),
- dbesc($photodate),
- dbesc($xchan['xchan_hash'])
- );
+ require_once('include/photo/photo_driver.php');
+ $photos = import_xchan_photo($xchan['xchan_photo_l'],$xchan['xchan_hash']);
+ if($photos[4])
+ $photodate = NULL_DATE;
+ else
+ $photodate = $xchan['xchan_photo_date'];
+
+ $r = q("update xchan set xchan_photo_l = '%s', xchan_photo_m = '%s', xchan_photo_s = '%s', xchan_photo_mimetype = '%s', xchan_photo_date = '%s' where xchan_hash = '%s'",
+ dbesc($photos[0]),
+ dbesc($photos[1]),
+ dbesc($photos[2]),
+ dbesc($photos[3]),
+ dbesc($photodate),
+ dbesc($xchan['xchan_hash'])
+ );
- }
}
- logger('import step 7');
- $_SESSION['import_step'] = 7;
-
+
+ logger('import step 7');
}
-
-
-
- // FIXME - ensure we have an xchan if somebody is trying to pull a fast one
-
- if($completed < 8) {
- $friends = 0;
- $feeds = 0;
-
- // import contacts
- $abooks = $data['abook'];
- if($abooks) {
- foreach($abooks as $abook) {
+
- $abook_copy = $abook;
+ $friends = 0;
+ $feeds = 0;
- $abconfig = null;
- if(array_key_exists('abconfig',$abook) && is_array($abook['abconfig']) && count($abook['abconfig']))
- $abconfig = $abook['abconfig'];
-
- unset($abook['abook_id']);
- unset($abook['abook_rating']);
- unset($abook['abook_rating_text']);
- unset($abook['abconfig']);
- unset($abook['abook_their_perms']);
- unset($abook['abook_my_perms']);
+ // import contacts
+ $abooks = $data['abook'];
+ if($abooks) {
+ foreach($abooks as $abook) {
- $abook['abook_account'] = $account_id;
- $abook['abook_channel'] = $channel['channel_id'];
- if(! array_key_exists('abook_blocked',$abook)) {
- $abook['abook_blocked'] = (($abook['abook_flags'] & 0x0001 ) ? 1 : 0);
- $abook['abook_ignored'] = (($abook['abook_flags'] & 0x0002 ) ? 1 : 0);
- $abook['abook_hidden'] = (($abook['abook_flags'] & 0x0004 ) ? 1 : 0);
- $abook['abook_archived'] = (($abook['abook_flags'] & 0x0008 ) ? 1 : 0);
- $abook['abook_pending'] = (($abook['abook_flags'] & 0x0010 ) ? 1 : 0);
- $abook['abook_unconnected'] = (($abook['abook_flags'] & 0x0020 ) ? 1 : 0);
- $abook['abook_self'] = (($abook['abook_flags'] & 0x0080 ) ? 1 : 0);
- $abook['abook_feed'] = (($abook['abook_flags'] & 0x0100 ) ? 1 : 0);
- }
+ $abook_copy = $abook;
+
+ $abconfig = null;
+ if(array_key_exists('abconfig',$abook) && is_array($abook['abconfig']) && count($abook['abconfig']))
+ $abconfig = $abook['abconfig'];
+
+ unset($abook['abook_id']);
+ unset($abook['abook_rating']);
+ unset($abook['abook_rating_text']);
+ unset($abook['abconfig']);
+ unset($abook['abook_their_perms']);
+ unset($abook['abook_my_perms']);
+
+ $abook['abook_account'] = $account_id;
+ $abook['abook_channel'] = $channel['channel_id'];
+ if(! array_key_exists('abook_blocked',$abook)) {
+ $abook['abook_blocked'] = (($abook['abook_flags'] & 0x0001 ) ? 1 : 0);
+ $abook['abook_ignored'] = (($abook['abook_flags'] & 0x0002 ) ? 1 : 0);
+ $abook['abook_hidden'] = (($abook['abook_flags'] & 0x0004 ) ? 1 : 0);
+ $abook['abook_archived'] = (($abook['abook_flags'] & 0x0008 ) ? 1 : 0);
+ $abook['abook_pending'] = (($abook['abook_flags'] & 0x0010 ) ? 1 : 0);
+ $abook['abook_unconnected'] = (($abook['abook_flags'] & 0x0020 ) ? 1 : 0);
+ $abook['abook_self'] = (($abook['abook_flags'] & 0x0080 ) ? 1 : 0);
+ $abook['abook_feed'] = (($abook['abook_flags'] & 0x0100 ) ? 1 : 0);
+ }
- if($abook['abook_self']) {
- $role = get_pconfig($channel['channel_id'],'system','permissions_role');
- if(($role === 'forum') || ($abook['abook_my_perms'] & PERMS_W_TAGWALL)) {
- q("update xchan set xchan_pubforum = 1 where xchan_hash = '%s' ",
- dbesc($abook['abook_xchan'])
- );
- }
- }
- else {
- if($max_friends !== false && $friends > $max_friends)
- continue;
- if($max_feeds !== false && intval($abook['abook_feed']) && ($feeds > $max_feeds))
- continue;
+ if($abook['abook_self']) {
+ $role = get_pconfig($channel['channel_id'],'system','permissions_role');
+ if(($role === 'forum') || ($abook['abook_my_perms'] & PERMS_W_TAGWALL)) {
+ q("update xchan set xchan_pubforum = 1 where xchan_hash = '%s' ",
+ dbesc($abook['abook_xchan'])
+ );
}
+ }
+ else {
+ if($max_friends !== false && $friends > $max_friends)
+ continue;
+ if($max_feeds !== false && intval($abook['abook_feed']) && ($feeds > $max_feeds))
+ continue;
+ }
- create_table_from_array('abook',$abook);
+ create_table_from_array('abook',$abook);
- $friends ++;
- if(intval($abook['abook_feed']))
- $feeds ++;
+ $friends ++;
+ if(intval($abook['abook_feed']))
+ $feeds ++;
- translate_abook_perms_inbound($channel,$abook_copy);
+ translate_abook_perms_inbound($channel,$abook_copy);
- if($abconfig) {
- // @fixme does not handle sync of del_abconfig
- foreach($abconfig as $abc) {
- set_abconfig($channel['channel_id'],$abc['xchan'],$abc['cat'],$abc['k'],$abc['v']);
- }
+ if($abconfig) {
+ // @fixme does not handle sync of del_abconfig
+ foreach($abconfig as $abc) {
+ set_abconfig($channel['channel_id'],$abc['xchan'],$abc['cat'],$abc['k'],$abc['v']);
}
-
-
-
}
}
+
logger('import step 8');
- $_SESSION['import_step'] = 8;
}
-
-
- if($completed < 9) {
- $groups = $data['group'];
- if($groups) {
- $saved = array();
- foreach($groups as $group) {
- $saved[$group['hash']] = array('old' => $group['id']);
- if(array_key_exists('name',$group)) {
- $group['gname'] = $group['name'];
- unset($group['name']);
- }
- unset($group['id']);
- $group['uid'] = $channel['channel_id'];
-
- create_table_from_array('groups',$group);
+ $groups = $data['group'];
+ if($groups) {
+ $saved = array();
+ foreach($groups as $group) {
+ $saved[$group['hash']] = array('old' => $group['id']);
+ if(array_key_exists('name',$group)) {
+ $group['gname'] = $group['name'];
+ unset($group['name']);
}
- $r = q("select * from groups where uid = %d",
- intval($channel['channel_id'])
- );
- if($r) {
- foreach($r as $rr) {
- $saved[$rr['hash']]['new'] = $rr['id'];
- }
- }
+ unset($group['id']);
+ $group['uid'] = $channel['channel_id'];
+
+ create_table_from_array('groups',$group);
}
+ $r = q("select * from groups where uid = %d",
+ intval($channel['channel_id'])
+ );
+ if($r) {
+ foreach($r as $rr) {
+ $saved[$rr['hash']]['new'] = $rr['id'];
+ }
+ }
+ }
- $group_members = $data['group_member'];
- if($group_members) {
- foreach($group_members as $group_member) {
- unset($group_member['id']);
- $group_member['uid'] = $channel['channel_id'];
- foreach($saved as $x) {
- if($x['old'] == $group_member['gid'])
- $group_member['gid'] = $x['new'];
- }
- create_table_from_array('group_member',$group_member);
+ $group_members = $data['group_member'];
+ if($group_members) {
+ foreach($group_members as $group_member) {
+ unset($group_member['id']);
+ $group_member['uid'] = $channel['channel_id'];
+ foreach($saved as $x) {
+ if($x['old'] == $group_member['gid'])
+ $group_member['gid'] = $x['new'];
}
+ create_table_from_array('group_member',$group_member);
}
- logger('import step 9');
- $_SESSION['import_step'] = 9;
}
+
+ logger('import step 9');
if(is_array($data['obj']))
import_objs($channel,$data['obj']);
@@ -472,6 +433,12 @@ class Import extends \Zotlabs\Web\Controller {
if(is_array($data['menu']))
import_menus($channel,$data['menu']);
+
+ if(is_array($data['wiki']))
+ import_items($channel,$data['wiki'],false,$relocate);
+
+ if(is_array($data['webpages']))
+ import_items($channel,$data['webpages'],false,$relocate);
$addon = array('channel' => $channel,'data' => $data);
call_hooks('import_channel',$addon);
@@ -487,9 +454,6 @@ class Import extends \Zotlabs\Web\Controller {
if(array_key_exists('item_id',$data) && $data['item_id'])
import_item_ids($channel,$data['item_id']);
-
- // FIXME - ensure we have a self entry if somebody is trying to pull a fast one
-
// send out refresh requests
// notify old server that it may no longer be primary.
@@ -504,7 +468,6 @@ class Import extends \Zotlabs\Web\Controller {
change_channel($channel['channel_id']);
- unset($_SESSION['import_step']);
goaway(z_root() . '/network' );
}
@@ -536,7 +499,8 @@ class Import extends \Zotlabs\Web\Controller {
'$label_old_pass' => t('Your old login password'),
'$common' => t('For either option, please choose whether to make this hub your new primary address, or whether your old location should continue this role. You will be able to post from either location, but only one can be marked as the primary location for files, photos, and media.'),
'$label_import_primary' => t('Make this hub my primary location'),
- '$label_import_posts' => t('Import existing posts if possible (experimental - limited by available memory'),
+ '$label_import_moving' => t('Move this channel (disable all previous locations)'),
+ '$label_import_posts' => t('Import a few months of posts if possible (limited by available memory'),
'$pleasewait' => t('This process may take several minutes to complete. Please submit the form only once and leave this page open until finished.'),
'$email' => '',
'$pass' => '',
diff --git a/Zotlabs/Module/Item.php b/Zotlabs/Module/Item.php
index 085c02742..4725ecb38 100644
--- a/Zotlabs/Module/Item.php
+++ b/Zotlabs/Module/Item.php
@@ -21,6 +21,7 @@ require_once('include/crypto.php');
require_once('include/items.php');
require_once('include/attach.php');
require_once('include/bbcode.php');
+require_once('include/security.php');
use \Zotlabs\Lib as Zlib;
@@ -34,9 +35,7 @@ class Item extends \Zotlabs\Web\Controller {
if((! local_channel()) && (! remote_channel()) && (! x($_REQUEST,'commenter')))
return;
-
- require_once('include/security.php');
-
+
$uid = local_channel();
$channel = null;
$observer = null;
@@ -141,6 +140,7 @@ class Item extends \Zotlabs\Web\Controller {
$item_flags = $item_restrict = 0;
+ $expires = NULL_DATE;
$route = '';
$parent_item = null;
@@ -395,6 +395,7 @@ class Item extends \Zotlabs\Web\Controller {
$postopts = $orig_post['postopts'];
$created = $orig_post['created'];
+ $expires = $orig_post['expires'];
$mid = $orig_post['mid'];
$parent_mid = $orig_post['parent_mid'];
$plink = $orig_post['plink'];
@@ -428,7 +429,9 @@ class Item extends \Zotlabs\Web\Controller {
$body = trim($_REQUEST['body']);
$body .= trim($_REQUEST['attachment']);
$postopts = '';
-
+
+ $allow_empty = ((array_key_exists('allow_empty',$_REQUEST)) ? intval($_REQUEST['allow_empty']) : 0);
+
$private = intval($acl->is_private() || ($public_policy));
// If this is a comment, set the permissions from the parent.
@@ -441,7 +444,7 @@ class Item extends \Zotlabs\Web\Controller {
$owner_hash = $parent_item['owner_xchan'];
}
- if(! strlen($body)) {
+ if((! $allow_empty) && (! strlen($body))) {
if($preview)
killme();
info( t('Empty post discarded.') . EOL );
@@ -454,7 +457,6 @@ class Item extends \Zotlabs\Web\Controller {
}
- $expires = NULL_DATE;
if(feature_enabled($profile_uid,'content_expire')) {
if(x($_REQUEST,'expire')) {
@@ -463,7 +465,8 @@ class Item extends \Zotlabs\Web\Controller {
$expires = NULL_DATE;
}
}
-
+
+
$mimetype = notags(trim($_REQUEST['mimetype']));
if(! $mimetype)
$mimetype = 'text/bbcode';
@@ -520,7 +523,7 @@ class Item extends \Zotlabs\Web\Controller {
// <img src="javascript:alert('hacked');" />
// if($uid && $uid == $profile_uid && feature_enabled($uid,'markdown')) {
- // require_once('include/bb2diaspora.php');
+ // require_once('include/markdown.php');
// $body = escape_tags(trim($body));
// $body = str_replace("\n",'<br />', $body);
// $body = preg_replace_callback('/\[share(.*?)\]/ism','\share_shield',$body);
@@ -556,42 +559,8 @@ class Item extends \Zotlabs\Web\Controller {
if($x)
$body .= "\n\n@group+" . $x[0]['abook_id'] . "\n";
}
-
- /**
- * fix naked links by passing through a callback to see if this is a hubzilla site
- * (already known to us) which will get a zrl, otherwise link with url, add bookmark tag to both.
- * First protect any url inside certain bbcode tags so we don't double link it.
- */
-
-
- $body = preg_replace_callback('/\[code(.*?)\[\/(code)\]/ism','\red_escape_codeblock',$body);
- $body = preg_replace_callback('/\[url(.*?)\[\/(url)\]/ism','\red_escape_codeblock',$body);
- $body = preg_replace_callback('/\[zrl(.*?)\[\/(zrl)\]/ism','\red_escape_codeblock',$body);
-
- $body = preg_replace_callback("/([^\]\='".'"'."\/]|^|\#\^)(https?\:\/\/[a-zA-Z0-9\:\/\-\?\&\;\.\=\@\_\~\#\%\$\!\+\,\(\)]+)/ism", 'nakedoembed', $body);
- $body = preg_replace_callback("/([^\]\='".'"'."\/]|^|\#\^)(https?\:\/\/[a-zA-Z0-9\:\/\-\?\&\;\.\=\@\_\~\#\%\$\!\+\,\(\)]+)/ism", '\red_zrl_callback', $body);
-
- $body = preg_replace_callback('/\[\$b64zrl(.*?)\[\/(zrl)\]/ism','\red_unescape_codeblock',$body);
- $body = preg_replace_callback('/\[\$b64url(.*?)\[\/(url)\]/ism','\red_unescape_codeblock',$body);
- $body = preg_replace_callback('/\[\$b64code(.*?)\[\/(code)\]/ism','\red_unescape_codeblock',$body);
-
-
- // fix any img tags that should be zmg
-
- $body = preg_replace_callback('/\[img(.*?)\](.*?)\[\/img\]/ism','\red_zrlify_img_callback',$body);
-
-
- $body = bb_translate_video($body);
-
- /**
- * Fold multi-line [code] sequences
- */
-
- $body = preg_replace('/\[\/code\]\s*\[code\]/ism',"\n",$body);
-
- $body = scale_external_images($body,false);
-
+ $body = cleanup_bbcode($body);
// Look for tags and linkify them
$results = linkify_tags($a, $body, ($uid) ? $uid : $profile_uid);
@@ -755,6 +724,8 @@ class Item extends \Zotlabs\Web\Controller {
if(! $mid) {
$mid = (($message_id) ? $message_id : item_message_id());
}
+
+
if(! $parent_mid) {
$parent_mid = $mid;
}
@@ -768,7 +739,7 @@ class Item extends \Zotlabs\Web\Controller {
$thr_parent = $mid;
$datarray = array();
-
+
$item_thread_top = ((! $parent) ? 1 : 0);
if ((! $plink) && ($item_thread_top)) {
@@ -966,7 +937,7 @@ class Item extends \Zotlabs\Web\Controller {
'from_xchan' => $datarray['author_xchan'],
'to_xchan' => $datarray['owner_xchan'],
'item' => $datarray,
- 'link' => z_root() . '/display/' . $datarray['mid'],
+ 'link' => z_root() . '/display/' . gen_link_id($datarray['mid']),
'verb' => ACTIVITY_POST,
'otype' => 'item',
'parent' => $parent,
@@ -984,7 +955,7 @@ class Item extends \Zotlabs\Web\Controller {
'from_xchan' => $datarray['author_xchan'],
'to_xchan' => $datarray['owner_xchan'],
'item' => $datarray,
- 'link' => z_root() . '/display/' . $datarray['mid'],
+ 'link' => z_root() . '/display/' . gen_link_id($datarray['mid']),
'verb' => ACTIVITY_POST,
'otype' => 'item'
));
@@ -1036,7 +1007,7 @@ class Item extends \Zotlabs\Web\Controller {
}
$datarray['id'] = $post_id;
- $datarray['llink'] = z_root() . '/display/' . $channel['channel_address'] . '/' . $post_id;
+ $datarray['llink'] = z_root() . '/display/' . gen_link_id($datarray['mid']);
call_hooks('post_local_end', $datarray);
@@ -1070,9 +1041,7 @@ class Item extends \Zotlabs\Web\Controller {
if((! local_channel()) && (! remote_channel()))
return;
-
- require_once('include/security.php');
-
+
if((argc() == 3) && (argv(1) === 'drop') && intval(argv(2))) {
require_once('include/items.php');
diff --git a/Zotlabs/Module/Like.php b/Zotlabs/Module/Like.php
index 43d318623..5ce8ec7f0 100644
--- a/Zotlabs/Module/Like.php
+++ b/Zotlabs/Module/Like.php
@@ -447,7 +447,7 @@ class Like extends \Zotlabs\Web\Controller {
$arr['thr_parent'] = $item['mid'];
$ulink = '[zrl=' . $item_author['xchan_url'] . ']' . $item_author['xchan_name'] . '[/zrl]';
$alink = '[zrl=' . $observer['xchan_url'] . ']' . $observer['xchan_name'] . '[/zrl]';
- $plink = '[zrl=' . z_root() . '/display/' . $item['mid'] . ']' . $post_type . '[/zrl]';
+ $plink = '[zrl=' . z_root() . '/display/' . gen_link_id($item['mid']) . ']' . $post_type . '[/zrl]';
$allow_cid = $item['allow_cid'];
$allow_gid = $item['allow_gid'];
$deny_cid = $item['deny_cid'];
diff --git a/Zotlabs/Module/Lockview.php b/Zotlabs/Module/Lockview.php
index 7d1d8a43f..fc7d5c7c8 100644
--- a/Zotlabs/Module/Lockview.php
+++ b/Zotlabs/Module/Lockview.php
@@ -32,10 +32,10 @@ class Lockview extends \Zotlabs\Web\Controller {
if(! $item_id)
killme();
- if (!in_array($type, array('item','photo','event', 'menu_item', 'chatroom')))
+ if (! in_array($type, array('item', 'photo', 'attach', 'event', 'menu_item', 'chatroom')))
killme();
- //we have different naming in in menu_item table and chatroom table
+ // we have different naming in in menu_item table and chatroom table
switch($type) {
case 'menu_item':
$id = 'mitem_id';
@@ -101,6 +101,22 @@ class Lockview extends \Zotlabs\Web\Controller {
stringify_array_elms($deny_groups,true);
stringify_array_elms($deny_users,true);
+
+ $profile_groups = [];
+ if($allowed_groups) {
+ foreach($allowed_groups as $g) {
+ if(substr($g,0,4) === '\'vp.') {
+ $profile_groups[] = '\'' . substr($g,4);
+ }
+ }
+ }
+ if(count($profile_groups)) {
+ $r = q("SELECT profile_name FROM profile WHERE profile_guid IN ( " . implode(', ', $profile_groups) . " )");
+ if($r)
+ foreach($r as $rr)
+ $l[] = '<li><b>' . t('Profile','acl') . ' ' . $rr['profile_name'] . '</b></li>';
+ }
+
if(count($allowed_groups)) {
$r = q("SELECT gname FROM groups WHERE hash IN ( " . implode(', ', $allowed_groups) . " )");
if($r)
@@ -120,6 +136,25 @@ class Lockview extends \Zotlabs\Web\Controller {
}
}
}
+
+
+ $profile_groups = [];
+ if($deny_groups) {
+ foreach($deny_groups as $g) {
+ if(substr($g,0,4) === '\'vp.') {
+ $profile_groups[] = '\'' . substr($g,4);
+ }
+ }
+ }
+ if(count($profile_groups)) {
+ $r = q("SELECT profile_name FROM profile WHERE profile_guid IN ( " . implode(', ', $profile_groups) . " )");
+ if($r)
+ foreach($r as $rr)
+ $l[] = '<li><b><strike>' . t('Profile','acl') . ' ' . $rr['profile_name'] . '</strike></b></li>';
+ }
+
+
+
if(count($deny_groups)) {
$r = q("SELECT gname FROM groups WHERE hash IN ( " . implode(', ', $deny_groups) . " )");
if($r)
diff --git a/Zotlabs/Module/Mail.php b/Zotlabs/Module/Mail.php
index c767c8e56..459ce5acf 100644
--- a/Zotlabs/Module/Mail.php
+++ b/Zotlabs/Module/Mail.php
@@ -23,7 +23,34 @@ class Mail extends \Zotlabs\Web\Controller {
$rstr = ((x($_REQUEST,'messagerecip')) ? notags(trim($_REQUEST['messagerecip'])) : '');
$preview = ((x($_REQUEST,'preview')) ? intval($_REQUEST['preview']) : 0);
$expires = ((x($_REQUEST,'expires')) ? datetime_convert(date_default_timezone_get(),'UTC', $_REQUEST['expires']) : NULL_DATE);
-
+
+ if($preview) {
+
+ $body = cleanup_bbcode($body);
+ $results = linkify_tags($a, $body, local_channel());
+
+ if(preg_match_all('/(\[attachment\](.*?)\[\/attachment\])/',$body,$match)) {
+ $attachments = array();
+ foreach($match[2] as $mtch) {
+ $hash = substr($mtch,0,strpos($mtch,','));
+ $rev = intval(substr($mtch,strpos($mtch,',')));
+ $r = attach_by_hash_nodata($hash,get_observer_hash(),$rev);
+ if($r['success']) {
+ $attachments[] = array(
+ 'href' => z_root() . '/attach/' . $r['data']['hash'],
+ 'length' => $r['data']['filesize'],
+ 'type' => $r['data']['filetype'],
+ 'title' => urlencode($r['data']['filename']),
+ 'revision' => $r['data']['revision']
+ );
+ }
+ $body = trim(str_replace($match[1],'',$body));
+ }
+ }
+ echo json_encode(['preview' => zidify_links(smilies(bbcode($body)))]);
+ killme();
+ }
+
// If we have a raw string for a recipient which hasn't been auto-filled,
// it means they probably aren't in our address book, hence we don't know
// if we have permission to send them private messages.
@@ -82,6 +109,8 @@ class Mail extends \Zotlabs\Web\Controller {
require_once('include/text.php');
linkify_tags($a, $body, local_channel());
+ // I don't think this is used any more.
+
if($preview) {
$mail = [
'mailbox' => 'outbox',
@@ -90,8 +119,8 @@ class Mail extends \Zotlabs\Web\Controller {
'from_name' => $channel['xchan_name'],
'from_url' => $channel['xchan_url'],
'from_photo' => $channel['xchan_photo_s'],
- 'subject' => smilies(bbcode($subject)),
- 'body' => smilies(bbcode($body)),
+ 'subject' => zidify_links(smilies(bbcode($subject))),
+ 'body' => zidify_links(smilies(bbcode($body))),
'attachments' => '',
'can_recall' => false,
'is_recalled' => '',
@@ -341,7 +370,7 @@ class Mail extends \Zotlabs\Web\Controller {
'to_url' => chanlink_hash($message['to_xchan']),
'to_photo' => $message['to']['xchan_photo_s'],
'subject' => $message['title'],
- 'body' => smilies(bbcode($message['body'])),
+ 'body' => zidify_links(smilies(bbcode($message['body']))),
'attachments' => $s,
'delete' => t('Delete message'),
'dreport' => t('Delivery report'),
diff --git a/Zotlabs/Module/Match.php b/Zotlabs/Module/Match.php
deleted file mode 100644
index 63bdb60a4..000000000
--- a/Zotlabs/Module/Match.php
+++ /dev/null
@@ -1,84 +0,0 @@
-<?php
-namespace Zotlabs\Module;
-
-/**
- * @brief Controller for /match.
- *
- * It takes keywords from your profile and queries the directory server for
- * matching keywords from other profiles.
- *
- * @FIXME this has never been properly ported from Friendica.
- *
- * @param App &$a
- * @return void|string
- */
-
-class Match extends \Zotlabs\Web\Controller {
-
- function get() {
-
- $o = '';
- if (! local_channel())
- return;
-
- $_SESSION['return_url'] = z_root() . '/' . \App::$cmd;
-
- $o .= '<h2>' . t('Profile Match') . '</h2>';
-
- $r = q("SELECT keywords FROM profile WHERE is_default = 1 AND uid = %d LIMIT 1",
- intval(local_channel())
- );
- if (! count($r))
- return;
-
- if (! $r[0]['keywords']) {
- notice( t('No keywords to match. Please add keywords to your default profile.') . EOL);
- return;
- }
-
- $params = array();
- $tags = trim($r[0]['keywords']);
-
- if ($tags) {
- $params['s'] = $tags;
- if (\App::$pager['page'] != 1)
- $params['p'] = \App::$pager['page'];
-
- // if(strlen(get_config('system','directory_submit_url')))
- // $x = post_url('http://dir.friendica.com/msearch', $params);
- // else
- // $x = post_url(z_root() . '/msearch', $params);
-
- $j = json_decode($x);
-
- if ($j->total) {
- \App::set_pager_total($j->total);
- \App::set_pager_itemspage($j->items_page);
- }
-
- if (count($j->results)) {
- $tpl = get_markup_template('match.tpl');
- foreach ($j->results as $jj) {
- $connlnk = z_root() . '/follow/?url=' . $jj->url;
- $o .= replace_macros($tpl,array(
- '$url' => zid($jj->url),
- '$name' => $jj->name,
- '$photo' => $jj->photo,
- '$inttxt' => ' ' . t('is interested in:'),
- '$conntxt' => t('Connect'),
- '$connlnk' => $connlnk,
- '$tags' => $jj->tags
- ));
- }
- } else {
- info( t('No matches') . EOL);
- }
- }
-
- $o .= cleardiv();
- $o .= paginate($a);
-
- return $o;
- }
-
-}
diff --git a/Zotlabs/Module/Message.php b/Zotlabs/Module/Message.php
index ea2127a1d..7494f4bf4 100644
--- a/Zotlabs/Module/Message.php
+++ b/Zotlabs/Module/Message.php
@@ -79,7 +79,7 @@ class Message extends \Zotlabs\Web\Controller {
'to_photo' => $rr['to']['xchan_photo_s'],
'subject' => (($rr['seen']) ? $rr['title'] : '<strong>' . $rr['title'] . '</strong>'),
'delete' => t('Delete conversation'),
- 'body' => smilies(bbcode($rr['body'])),
+ 'body' => zidify_links(smilies(bbcode($rr['body']))),
'date' => datetime_convert('UTC',date_default_timezone_get(),$rr['created'], t('D, d M Y - g:i A')),
'seen' => $rr['seen']
);
diff --git a/Zotlabs/Module/Mood.php b/Zotlabs/Module/Mood.php
index d1bd44526..eeb050040 100644
--- a/Zotlabs/Module/Mood.php
+++ b/Zotlabs/Module/Mood.php
@@ -89,7 +89,7 @@ class Mood extends \Zotlabs\Web\Controller {
$item['item_thread_top'] = 1;
if ((! $arr['plink']) && intval($arr['item_thread_top'])) {
- $arr['plink'] = z_root() . '/channel/' . $channel['channel_address'] . '/?f=&mid=' . $arr['mid'];
+ $arr['plink'] = z_root() . '/channel/' . $channel['channel_address'] . '/?f=&mid=' . urlencode($arr['mid']);
}
diff --git a/Zotlabs/Module/Notifications.php b/Zotlabs/Module/Notifications.php
index 2db02c758..e0313dd8b 100644
--- a/Zotlabs/Module/Notifications.php
+++ b/Zotlabs/Module/Notifications.php
@@ -23,10 +23,13 @@ class Notifications extends \Zotlabs\Web\Controller {
if($r) {
$notifications_available = 1;
foreach ($r as $it) {
+ $x = strip_tags(bbcode($it['msg']));
+ if(strpos($x,','))
+ $x = substr($x,strpos($x,',')+1);
$notif_content .= replace_macros(get_markup_template('notify.tpl'),array(
'$item_link' => z_root().'/notify/view/'. $it['id'],
'$item_image' => $it['photo'],
- '$item_text' => strip_tags(bbcode($it['msg'])),
+ '$item_text' => $x,
'$item_when' => relative_date($it['created'])
));
}
diff --git a/Zotlabs/Module/Oexchange.php b/Zotlabs/Module/Oexchange.php
index 24fc14821..f36511134 100644
--- a/Zotlabs/Module/Oexchange.php
+++ b/Zotlabs/Module/Oexchange.php
@@ -16,7 +16,7 @@ class Oexchange extends \Zotlabs\Web\Controller {
}
}
- function get() {
+ function get() {
if(! local_channel()) {
if(remote_channel()) {
diff --git a/Zotlabs/Module/Opensearch.php b/Zotlabs/Module/Opensearch.php
deleted file mode 100644
index 8e76038c9..000000000
--- a/Zotlabs/Module/Opensearch.php
+++ /dev/null
@@ -1,24 +0,0 @@
-<?php
-namespace Zotlabs\Module;
-
-
-class Opensearch extends \Zotlabs\Web\Controller {
-
- function init() {
-
- $tpl = get_markup_template('opensearch.tpl');
-
- header("Content-type: application/opensearchdescription+xml");
-
- $o = replace_macros($tpl, array(
- '$baseurl' => z_root(),
- '$nodename' => \App::get_hostname(),
- ));
-
- echo $o;
-
- killme();
-
- }
-
-}
diff --git a/Zotlabs/Module/Permcat.php b/Zotlabs/Module/Permcat.php
new file mode 100644
index 000000000..064c9cefb
--- /dev/null
+++ b/Zotlabs/Module/Permcat.php
@@ -0,0 +1,25 @@
+<?php
+
+namespace Zotlabs\Module;
+
+use \Zotlabs\Lib as Zlib;
+
+class Permcat extends \Zotlabs\Web\Controller {
+
+ private $permcats = [];
+
+ public function init() {
+ if(! local_channel())
+ return;
+
+ $permcat = new Zlib\Permcat(local_channel());
+
+ if(argc() > 1)
+ json_return_and_die($permcat->fetch(argv(1)));
+
+ json_return_and_die($permcat->listing());
+
+ }
+
+
+} \ No newline at end of file
diff --git a/Zotlabs/Module/Photos.php b/Zotlabs/Module/Photos.php
index e459469ef..582174d0e 100644
--- a/Zotlabs/Module/Photos.php
+++ b/Zotlabs/Module/Photos.php
@@ -188,13 +188,12 @@ class Photos extends \Zotlabs\Web\Controller {
}
if((argc() > 2) && (x($_REQUEST,'delete')) && ($_REQUEST['delete'] === t('Delete Photo'))) {
-
// same as above but remove single photo
$ob_hash = get_observer_hash();
if(! $ob_hash)
goaway(z_root() . '/' . $_SESSION['photo_return']);
-
+
$r = q("SELECT id, resource_id FROM photo WHERE ( xchan = '%s' or uid = %d ) AND resource_id = '%s' LIMIT 1",
dbesc($ob_hash),
intval(local_channel()),
@@ -686,36 +685,32 @@ class Photos extends \Zotlabs\Web\Controller {
notice( t('Album name could not be decoded') . EOL);
logger('mod_photos: illegal album encoding: ' . $datum);
$datum = '';
+ goaway(z_root() . '/photos/' . \App::$data['channel']['channel_address']);
}
}
$album = (($datum) ? hex2bin($datum) : '');
-
-
+
\App::$page['htmlhead'] .= "\r\n" . '<link rel="alternate" type="application/json+oembed" href="' . z_root() . '/oep?f=&url=' . urlencode(z_root() . '/' . \App::$cmd) . '" title="oembed" />' . "\r\n";
-
-
- $r = q("SELECT resource_id, max(imgscale) AS imgscale FROM photo WHERE uid = %d AND album = '%s'
- AND imgscale <= 4 and photo_usage IN ( %d, %d ) and is_nsfw = %d $sql_extra GROUP BY resource_id",
+
+ //check if the album exists and if we have perms
+ $r = q("SELECT album FROM photo WHERE uid = %d AND album = '%s' and is_nsfw = %d $sql_extra LIMIT 1",
intval($owner_uid),
dbesc($album),
- intval(PHOTO_NORMAL),
- intval(PHOTO_PROFILE),
intval($unsafe)
);
- if(count($r)) {
- \App::set_pager_total(count($r));
+
+ if($r) {
\App::set_pager_itemspage(60);
} else {
goaway(z_root() . '/photos/' . \App::$data['channel']['channel_address']);
}
-
+
if($_GET['order'] === 'posted')
$order = 'ASC';
else
$order = 'DESC';
-
-
+
$r = q("SELECT p.resource_id, p.id, p.filename, p.mimetype, p.imgscale, p.description, p.created FROM photo p INNER JOIN
(SELECT resource_id, max(imgscale) imgscale FROM photo WHERE uid = %d AND album = '%s' AND imgscale <= 4 AND photo_usage IN ( %d, %d ) and is_nsfw = %d $sql_extra GROUP BY resource_id) ph
ON (p.resource_id = ph.resource_id AND p.imgscale = ph.imgscale)
@@ -1280,9 +1275,9 @@ class Photos extends \Zotlabs\Web\Controller {
// Default - show recent photos with upload link (if applicable)
//$o = '';
- \App::$page['htmlhead'] .= "\r\n" . '<link rel="alternate" type="application/json+oembed" href="' . z_root() . '/oep?f=&url=' . urlencode(z_root() . '/' . \App::$cmd) . '" title="oembed" />' . "\r\n";
-
+ \App::$page['htmlhead'] .= "\r\n" . '<link rel="alternate" type="application/json+oembed" href="' . z_root() . '/oep?f=&url=' . urlencode(z_root() . '/' . \App::$cmd) . '" title="oembed" />' . "\r\n";
+ /*
$r = q("SELECT resource_id, max(imgscale) AS imgscale FROM photo WHERE uid = %d
and photo_usage in ( %d, %d ) and is_nsfw = %d $sql_extra GROUP BY resource_id",
intval(\App::$data['channel']['channel_id']),
@@ -1294,6 +1289,9 @@ class Photos extends \Zotlabs\Web\Controller {
\App::set_pager_total(count($r));
\App::set_pager_itemspage(60);
}
+ */
+
+ \App::set_pager_itemspage(60);
$r = q("SELECT p.resource_id, p.id, p.filename, p.mimetype, p.album, p.imgscale, p.created FROM photo p
INNER JOIN ( SELECT resource_id, max(imgscale) imgscale FROM photo
diff --git a/Zotlabs/Module/Profile.php b/Zotlabs/Module/Profile.php
index 9e868db92..fda88da52 100644
--- a/Zotlabs/Module/Profile.php
+++ b/Zotlabs/Module/Profile.php
@@ -37,8 +37,21 @@ class Profile extends \Zotlabs\Web\Controller {
$profile = $r[0]['profile_guid'];
}
- \App::$page['htmlhead'] .= '<link rel="alternate" type="application/atom+xml" href="' . z_root() . '/feed/' . $which .'" />' . "\r\n" ;
-
+ head_add_link( [
+ 'rel' => 'alternate',
+ 'type' => 'application/atom+xml',
+ 'title' => t('Posts and comments'),
+ 'href' => z_root() . '/feed/' . $which
+ ]);
+
+ head_add_link( [
+ 'rel' => 'alternate',
+ 'type' => 'application/atom+xml',
+ 'title' => t('Only posts'),
+ 'href' => z_root() . '/feed/' . $which . '?f=&top=1'
+ ]);
+
+
if(! $profile) {
$x = q("select channel_id as profile_uid from channel where channel_address = '%s' limit 1",
dbesc(argv(1))
@@ -60,7 +73,9 @@ class Profile extends \Zotlabs\Web\Controller {
}
$groups = array();
-
+
+
+
$tab = 'profile';
$o = '';
@@ -69,6 +84,15 @@ class Profile extends \Zotlabs\Web\Controller {
return;
}
+
+
+ if(argc() > 2 && argv(2) === 'vcard') {
+ header('Content-type: text/vcard');
+ header('content-disposition: attachment; filename="' . t('vcard') . '-' . $profile['channel_address'] . '.vcf"' );
+ echo \App::$profile['profile_vcard'];
+ killme();
+ }
+
$is_owner = ((local_channel()) && (local_channel() == \App::$profile['profile_uid']) ? true : false);
diff --git a/Zotlabs/Module/Profile_photo.php b/Zotlabs/Module/Profile_photo.php
index 5b88f67f5..438580917 100644
--- a/Zotlabs/Module/Profile_photo.php
+++ b/Zotlabs/Module/Profile_photo.php
@@ -180,6 +180,14 @@ class Profile_photo extends \Zotlabs\Web\Controller {
dbesc(datetime_convert()),
dbesc($channel['xchan_hash'])
);
+
+ photo_profile_setperms(local_channel(),$base_image['resource_id'],$_REQUEST['profile']);
+
+ $sync = attach_export_data($channel,$base_image['resource_id']);
+ if($sync)
+ build_sync_packet($channel['channel_id'],array('file' => array($sync)));
+
+
// Similarly, tell the nav bar to bypass the cache and update the avater image.
$_SESSION['reload_avatar'] = true;
@@ -188,9 +196,6 @@ class Profile_photo extends \Zotlabs\Web\Controller {
// Update directory in background
\Zotlabs\Daemon\Master::Summon(array('Directory',$channel['channel_id']));
- // Now copy profile-permissions to pictures, to prevent privacyleaks by automatically created folder 'Profile Pictures'
-
- profile_photo_set_profile_perms(local_channel(),$_REQUEST['profile']);
}
else
notice( t('Unable to process image') . EOL);
@@ -338,7 +343,13 @@ class Profile_photo extends \Zotlabs\Web\Controller {
dbesc($channel['xchan_hash'])
);
- profile_photo_set_profile_perms(local_channel()); // Reset default photo permissions to public
+ photo_profile_setperms(local_channel(),$resource_id,$_REQUEST['profile']);
+
+ $sync = attach_export_data($channel,$resource_id);
+ if($sync)
+ build_sync_packet($channel['channel_id'],array('file' => array($sync)));
+
+
\Zotlabs\Daemon\Master::Summon(array('Directory',local_channel()));
goaway(z_root() . '/profiles');
}
diff --git a/Zotlabs/Module/Profiles.php b/Zotlabs/Module/Profiles.php
index 19a642a83..32e888f14 100644
--- a/Zotlabs/Module/Profiles.php
+++ b/Zotlabs/Module/Profiles.php
@@ -70,15 +70,16 @@ class Profiles extends \Zotlabs\Web\Controller {
$r1 = q("SELECT fullname, photo, thumb FROM profile WHERE uid = %d AND is_default = 1 LIMIT 1",
intval(local_channel()));
- $r2 = q("INSERT INTO profile (aid, uid , profile_guid, profile_name , fullname, photo, thumb)
- VALUES ( %d, '%s', '%s', '%s', '%s', '%s', '%s' )",
- intval(get_account_id()),
- intval(local_channel()),
- dbesc(random_string()),
- dbesc($name),
- dbesc($r1[0]['fullname']),
- dbesc($r1[0]['photo']),
- dbesc($r1[0]['thumb'])
+ $r2 = profile_store_lowlevel(
+ [
+ 'aid' => intval(get_account_id()),
+ 'uid' => intval(local_channel()),
+ 'profile_guid' => random_string(),
+ 'profile_name' => $name,
+ 'fullname' => $r1[0]['fullname'],
+ 'photo' => $r1[0]['photo'],
+ 'thumb' => $r1[0]['thumb']
+ ]
);
$r3 = q("SELECT id FROM profile WHERE uid = %d AND profile_name = '%s' LIMIT 1",
@@ -191,7 +192,7 @@ class Profiles extends \Zotlabs\Web\Controller {
}
}
- function post() {
+ function post() {
if(! local_channel()) {
notice( t('Permission denied.') . EOL);
@@ -243,6 +244,7 @@ class Profiles extends \Zotlabs\Web\Controller {
check_form_security_token_redirectOnErr('/profiles', 'profile_edit');
+
$is_default = (($orig[0]['is_default']) ? 1 : 0);
$profile_name = notags(trim($_POST['profile_name']));
@@ -315,6 +317,43 @@ class Profiles extends \Zotlabs\Web\Controller {
$hide_friends = ((intval($_POST['hide_friends'])) ? 1: 0);
+
+ $orig_vcard = (($orig[0]['profile_vcard']) ? \Sabre\VObject\Reader::read($orig[0]['profile_vcard']) : null);
+
+ $channel = \App::get_channel();
+
+ $default_vcard_cat = ((defined('DEFAULT_VCARD_CAT')) ? DEFAULT_VCARD_CAT : 'HOME');
+
+ $defcard = [
+ 'fn' => $name,
+ 'title' => $pdesc,
+ 'photo' => $channel['xchan_photo_l'],
+ 'adr' => [],
+ 'adr_type' => [ $default_vcard_cat ],
+ 'tel' => [],
+ 'tel_type' => [ $default_vcard_cat ],
+ 'email' => [],
+ 'email_type' => [ $default_vcard_cat ],
+ 'impp' => [],
+ 'impp_type' => [ $default_vcard_cat ],
+ 'url' => [],
+ 'url_type' => [ $default_vcard_cat ]
+ ];
+
+ $defcard['adr'][] = [
+ 0 => '',
+ 1 => '',
+ 2 => $address,
+ 3 => $locality,
+ 4 => $region,
+ 5 => $postal_code,
+ 6 => $country_name
+ ];
+
+
+ $profile_vcard = update_vcard($defcard,$orig_vcard);
+
+
require_once('include/text.php');
linkify_tags($a, $likes, local_channel());
linkify_tags($a, $dislikes, local_channel());
@@ -511,7 +550,8 @@ class Profiles extends \Zotlabs\Web\Controller {
romance = '%s',
employment = '%s',
education = '%s',
- hide_friends = %d
+ hide_friends = %d,
+ profile_vcard = '%s'
WHERE id = %d AND uid = %d",
dbesc($profile_name),
dbesc($name),
@@ -546,6 +586,7 @@ class Profiles extends \Zotlabs\Web\Controller {
dbesc($work),
dbesc($education),
intval($hide_friends),
+ dbesc($profile_vcard),
intval(argv(1)),
intval(local_channel())
);
diff --git a/Zotlabs/Module/Profperm.php b/Zotlabs/Module/Profperm.php
index 99cd4c58f..900e2f981 100644
--- a/Zotlabs/Module/Profperm.php
+++ b/Zotlabs/Module/Profperm.php
@@ -22,7 +22,7 @@ class Profperm extends \Zotlabs\Web\Controller {
}
- function get() {
+ function get() {
if(! local_channel()) {
notice( t('Permission denied') . EOL);
@@ -94,12 +94,8 @@ class Profperm extends \Zotlabs\Web\Controller {
}
-
- //Time to update the permissions on the profile-pictures as well
-
- profile_photo_set_profile_perms(local_channel(),$profile['id']);
-
- $r = q("SELECT * FROM abook left join xchan on abook_xchan = xchan_hash WHERE abook_channel = %d AND abook_profile = '%s'",
+ $r = q("SELECT * FROM abook left join xchan on abook_xchan = xchan_hash
+ WHERE abook_channel = %d AND abook_profile = '%s'",
intval(local_channel()),
dbesc($profile['profile_guid'])
);
diff --git a/Zotlabs/Module/Rmagic.php b/Zotlabs/Module/Rmagic.php
index 9252d1f1d..9fcc72441 100644
--- a/Zotlabs/Module/Rmagic.php
+++ b/Zotlabs/Module/Rmagic.php
@@ -70,13 +70,12 @@ class Rmagic extends \Zotlabs\Web\Controller {
function get() {
-
- $o = replace_macros(get_markup_template('rmagic.tpl'),array(
- '$title' => t('Remote Authentication'),
- '$desc' => t('Enter your channel address (e.g. channel@example.com)'),
- '$submit' => t('Authenticate')
- ));
- return $o;
-
+ return replace_macros(get_markup_template('rmagic.tpl'),
+ [
+ '$title' => t('Remote Authentication'),
+ '$address' => [ 'address', t('Enter your channel address (e.g. channel@example.com)'), '', '' ],
+ '$submit' => t('Authenticate')
+ ]
+ );
}
}
diff --git a/Zotlabs/Module/Rsd_xml.php b/Zotlabs/Module/Rsd_xml.php
deleted file mode 100644
index e5059834b..000000000
--- a/Zotlabs/Module/Rsd_xml.php
+++ /dev/null
@@ -1,17 +0,0 @@
-<?php
-namespace Zotlabs\Module;
-
-class Rsd_xml extends \Zotlabs\Web\Controller {
-
- function init() {
- header ("Content-Type: text/xml");
- echo replace_macros(get_markup_template('rsd.tpl'),array(
- '$project' => \Zotlabs\Lib\System::get_platform_name(),
- '$baseurl' => z_root(),
- '$apipath' => z_root() . '/api/'
- ));
- killme();
- }
-
-}
-
diff --git a/Zotlabs/Module/Search.php b/Zotlabs/Module/Search.php
index b319b19d6..89eaa4ffa 100644
--- a/Zotlabs/Module/Search.php
+++ b/Zotlabs/Module/Search.php
@@ -211,7 +211,7 @@ class Search extends \Zotlabs\Web\Controller {
$result = array();
require_once('include/conversation.php');
foreach($items as $item) {
- $item['html'] = bbcode($item['body']);
+ $item['html'] = zidify_links(bbcode($item['body']));
$x = encode_item($item);
$x['html'] = prepare_text($item['body'],$item['mimetype']);
$result[] = $x;
diff --git a/Zotlabs/Module/Settings/Channel.php b/Zotlabs/Module/Settings/Channel.php
index a73aa2e60..5b9cfdaca 100644
--- a/Zotlabs/Module/Settings/Channel.php
+++ b/Zotlabs/Module/Settings/Channel.php
@@ -18,6 +18,7 @@ class Channel {
$role = ((x($_POST,'permissions_role')) ? notags(trim($_POST['permissions_role'])) : '');
$oldrole = get_pconfig(local_channel(),'system','permissions_role');
+
if(($role != $oldrole) || ($role === 'custom')) {
@@ -88,15 +89,17 @@ class Channel {
intval(local_channel())
);
}
-
- $x = \Zotlabs\Access\Permissions::FilledPerms($role_permissions['perms_connect']);
- foreach($x as $k => $v) {
- set_abconfig(local_channel(),$channel['channel_hash'],'my_perms',$k, $v);
- if($role_permissions['perms_auto']) {
- set_pconfig(local_channel(),'autoperms',$k,$v);
- }
- else {
- del_pconfig(local_channel(),'autoperms',$k);
+
+ if($role_permissions['perms_connect']) {
+ $x = \Zotlabs\Access\Permissions::FilledPerms($role_permissions['perms_connect']);
+ foreach($x as $k => $v) {
+ set_abconfig(local_channel(),$channel['channel_hash'],'my_perms',$k, $v);
+ if($role_permissions['perms_auto']) {
+ set_pconfig(local_channel(),'autoperms',$k,$v);
+ }
+ else {
+ del_pconfig(local_channel(),'autoperms',$k);
+ }
}
}
@@ -142,6 +145,7 @@ class Channel {
$post_joingroup = (($_POST['post_joingroup'] == 1) ? 1: 0);
$post_profilechange = (($_POST['post_profilechange'] == 1) ? 1: 0);
$adult = (($_POST['adult'] == 1) ? 1 : 0);
+ $defpermcat = ((x($_POST,'defpermcat')) ? notags(trim($_POST['defpermcat'])) : 'default');
$cal_first_day = (((x($_POST,'first_day')) && (intval($_POST['first_day']) == 1)) ? 1: 0);
@@ -230,6 +234,7 @@ 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','cal_first_day',$cal_first_day);
+ set_pconfig(local_channel(),'system','default_permcat',$defpermcat);
$r = q("update channel set channel_name = '%s', channel_pageflags = %d, channel_timezone = '%s', channel_location = '%s', channel_notifyflags = %d, channel_max_anon_mail = %d, channel_max_friend_req = %d, channel_expire_days = %d $set_perms where channel_id = %d",
dbesc($username),
@@ -409,6 +414,19 @@ class Channel {
'$basepath' => \App::get_hostname()
));
+
+
+ $pcat = new \Zotlabs\Lib\Permcat(local_channel());
+ $pcatlist = $pcat->listing();
+ $permcats = [];
+ if($pcatlist) {
+ foreach($pcatlist as $pc) {
+ $permcats[$pc['name']] = $pc['localname'];
+ }
+ }
+
+ $default_permcat = get_pconfig(local_channel(),'system','default_permcat','default');
+
$stpl = get_markup_template('settings.tpl');
@@ -448,7 +466,10 @@ class Channel {
$always_show_in_notices = get_pconfig(local_channel(),'system','always_show_in_notices');
if($vnotify === false)
$vnotify = (-1);
-
+
+ $plugin = [ 'basic' => '', 'security' => '', 'notify' => '', 'misc' => '' ];
+ call_hooks('channel_settings',$plugin);
+
$o .= replace_macros($stpl,array(
'$ptitle' => t('Channel Settings'),
@@ -495,7 +516,8 @@ class Channel {
'$suggestme' => $suggestme,
'$group_select' => $group_select,
'$role' => array('permissions_role' , t('Channel permissions category:'), $permissions_role, '', $perm_roles),
-
+ '$defpermcat' => [ 'defpermcat', t('Default Permissions Group'), $default_permcat, '', $permcats ],
+ '$permcat_enable' => feature_enabled(local_channel(),'permcats'),
'$profile_in_dir' => $profile_in_dir,
'$hide_friends' => $hide_friends,
'$hide_wall' => $hide_wall,
@@ -537,6 +559,10 @@ class Channel {
'$always_show_in_notices' => array('always_show_in_notices', t('Also show new wall posts, private messages and connections under Notices'), $always_show_in_notices, 1, '', $yes_no),
'$evdays' => array('evdays', t('Notify me of events this many days in advance'), $evdays, t('Must be greater than 0')),
+ '$basic_addon' => $plugin['basic'],
+ '$sec_addon' => $plugin['security'],
+ '$notify_addon' => $plugin['notify'],
+ '$misc_addon' => $plugin['misc'],
'$h_advn' => t('Advanced Account/Page Type Settings'),
'$h_descadvn' => t('Change the behaviour of this account for special situations'),
diff --git a/Zotlabs/Module/Settings/Display.php b/Zotlabs/Module/Settings/Display.php
index 25d1d21a0..eae44e82c 100644
--- a/Zotlabs/Module/Settings/Display.php
+++ b/Zotlabs/Module/Settings/Display.php
@@ -65,7 +65,7 @@ class Display {
set_pconfig(local_channel(),'system','manual_conversation_update', $manual_update);
$newschema = '';
- if($theme == $existing_theme){
+ if($theme){
// call theme_post only if theme has not been changed
if( ($themeconfigfile = $this->get_theme_config_file($theme)) != null){
require_once($themeconfigfile);
@@ -130,12 +130,20 @@ class Display {
if($allowed_themes) {
foreach($allowed_themes as $th) {
$f = $th;
+
+ $info = get_theme_info($th);
+ $compatible = check_plugin_versions($info);
+ if(!$compatible) {
+ $mobile_themes[$f] = $themes[$f] = sprintf(t('%s - (Incompatible)'), $f);
+ continue;
+ }
+
$is_experimental = file_exists('view/theme/' . $th . '/experimental');
$unsupported = file_exists('view/theme/' . $th . '/unsupported');
$is_mobile = file_exists('view/theme/' . $th . '/mobile');
$is_library = file_exists('view/theme/'. $th . '/library');
- $mobile_themes["---"] = t("No special theme for mobile devices");
-
+ $mobile_themes['---'] = t("No special theme for mobile devices");
+
if (!$is_experimental or ($is_experimental && (get_config('experimentals','exp_themes')==1 or get_config('experimentals','exp_themes')===false))){
$theme_name = (($is_experimental) ? sprintf(t('%s - (Experimental)'), $f) : $f);
if (! $is_library) {
@@ -147,7 +155,6 @@ class Display {
}
}
}
-
}
}
@@ -206,7 +213,7 @@ class Display {
'$ajaxint' => array('browser_update', t("Update browser every xx seconds"), $browser_update, t('Minimum of 10 seconds, no maximum')),
'$itemspage' => array('itemspage', t("Maximum number of conversations to load at any time:"), $itemspage, t('Maximum of 100 items')),
'$nosmile' => array('nosmile', t("Show emoticons (smilies) as images"), 1-intval($nosmile), '', $yes_no),
- '$manual_update' => array('manual_update', t('Manual conversation updates'), channel_manual_conv_update(local_channel()), t('Default is automatic, which may increase screen jumping'), $yes_no),
+ '$manual_update' => array('manual_update', t('Manual conversation updates'), channel_manual_conv_update(local_channel()), t('Default is on, turning this off may increase screen jumping'), $yes_no),
'$title_tosource' => array('title_tosource', t("Link post titles to source"), $title_tosource, '', $yes_no),
'$layout_editor' => t('System Page Layout Editor - (advanced)'),
'$theme_config' => $theme_config,
diff --git a/Zotlabs/Module/Settings/Featured.php b/Zotlabs/Module/Settings/Featured.php
index eec5f6c02..4885abd1d 100644
--- a/Zotlabs/Module/Settings/Featured.php
+++ b/Zotlabs/Module/Settings/Featured.php
@@ -10,6 +10,16 @@ class Featured {
call_hooks('feature_settings_post', $_POST);
+ if(intval($_POST['affinity_cmax'])) {
+ set_pconfig(local_channel(),'affinity','cmax',intval($_POST['affinity_cmax']));
+ }
+ if(intval($_POST['affinity_cmin'])) {
+ set_pconfig(local_channel(),'affinity','cmin',intval($_POST['affinity_cmin']));
+ }
+ if(intval($_POST['affinity_cmax']) || intval($_POST['affinity_cmin'])) {
+ info( t('Affinity Slider settings updated.') . EOL);
+ }
+
build_sync_packet();
return;
}
@@ -23,6 +33,25 @@ class Featured {
if(! $r)
$settings_addons = t('No feature settings configured');
+ if(feature_enabled(local_channel(),'affinity')) {
+
+ $cmax = intval(get_pconfig(local_channel(),'affinity','cmax'));
+ $cmax = (($cmax) ? $cmax : 99);
+ $setting_fields .= replace_macros(get_markup_template('field_input.tpl'), array(
+ '$field' => array('affinity_cmax', t('Default maximum affinity level'), $cmax, '')
+ ));
+ $cmin = intval(get_pconfig(local_channel(),'affinity','cmin'));
+ $cmin = (($cmin) ? $cmin : 0);
+ $setting_fields .= replace_macros(get_markup_template('field_input.tpl'), array(
+ '$field' => array('affinity_cmin', t('Default minimum affinity level'), $cmin, '')
+ ));
+
+ $settings_addons .= replace_macros(get_markup_template('generic_addon_settings.tpl'), array(
+ '$addon' => array('affinity_slider', '' . t('Affinity Slider Settings'), '', t('Submit')),
+ '$content' => $setting_fields
+ ));
+ }
+
call_hooks('feature_settings', $settings_addons);
$tpl = get_markup_template("settings_addons.tpl");
diff --git a/Zotlabs/Module/Settings/Permcats.php b/Zotlabs/Module/Settings/Permcats.php
new file mode 100644
index 000000000..35d533196
--- /dev/null
+++ b/Zotlabs/Module/Settings/Permcats.php
@@ -0,0 +1,117 @@
+<?php
+
+namespace Zotlabs\Module\Settings;
+
+
+
+class Permcats {
+
+ function post() {
+
+ if(! local_channel())
+ return;
+
+ $channel = \App::get_channel();
+
+ check_form_security_token_redirectOnErr('/settings/permcats', 'settings_permcats');
+
+
+ $all_perms = \Zotlabs\Access\Permissions::Perms();
+
+ $name = escape_tags(trim($_POST['name']));
+
+ $pcarr = [];
+
+ if($all_perms) {
+ foreach($all_perms as $perm => $desc) {
+ if(array_key_exists('perms_' . $perm, $_POST)) {
+ $pcarr[] = $perm;
+ }
+ }
+ }
+
+ \Zotlabs\Lib\Permcat::update(local_channel(),$name,$pcarr);
+
+ build_sync_packet();
+
+ info( t('Permission category saved.') . EOL);
+
+ return;
+ }
+
+
+ function get() {
+
+logger('cmd: ' . \App::$cmd);
+
+ if(! local_channel())
+ return;
+
+ $channel = \App::get_channel();
+
+
+ if(argc() > 2)
+ $name = argv(2);
+
+ if(argc() > 3 && argv(3) === 'drop') {
+ \Zotlabs\Lib\Permcat::delete(local_channel(),$name);
+ build_sync_packet();
+ json_return_and_die([ 'success' => true ]);
+ }
+
+
+ $desc = t('Use this form to create permission rules for various classes of people or connections.');
+
+ $existing = [];
+
+ $pcat = new \Zotlabs\Lib\Permcat(local_channel());
+ $pcatlist = $pcat->listing();
+ $permcats = [];
+ if($pcatlist) {
+ foreach($pcatlist as $pc) {
+ if(($pc['name']) && ($name) && ($pc['name'] == $name))
+ $existing = $pc['perms'];
+ if(! $pc['system'])
+ $permcats[$pc['name']] = $pc['localname'];
+ }
+ }
+
+ $global_perms = \Zotlabs\Access\Permissions::Perms();
+
+ foreach($global_perms as $k => $v) {
+ $thisperm = \Zotlabs\Lib\Permcat::find_permcat($existing,$k);
+ $checkinherited = \Zotlabs\Access\PermissionLimits::Get(local_channel(),$k);
+
+ if($existing[$k])
+ $thisperm = "1";
+
+ $perms[] = array('perms_' . $k, $v, ((array_key_exists($k,$their_perms)) ? intval($their_perms[$k]) : ''),$thisperm, 1, (($checkinherited & PERMS_SPECIFIC) ? '' : '1'), '', $checkinherited);
+ }
+
+
+
+ $tpl = get_markup_template("settings_permcats.tpl");
+ $o .= replace_macros($tpl, array(
+ '$form_security_token' => get_form_security_token("settings_permcats"),
+ '$title' => t('Permission Categories'),
+ '$desc' => $desc,
+ '$desc2' => $desc2,
+ '$tokens' => $t,
+ '$permcats' => $permcats,
+ '$atoken' => $atoken,
+ '$url1' => z_root() . '/channel/' . $channel['channel_address'],
+ '$url2' => z_root() . '/photos/' . $channel['channel_address'],
+ '$name' => array('name', t('Permission Name') . ' <span class="required">*</span>', (($name) ? $name : ''), ''),
+ '$me' => t('My Settings'),
+ '$perms' => $perms,
+ '$inherited' => t('inherited'),
+ '$notself' => 0,
+ '$self' => 1,
+ '$permlbl' => t('Individual Permissions'),
+ '$permnote' => t('Some permissions may be inherited from your channel\'s <a href="settings"><strong>privacy settings</strong></a>, which have higher priority than individual settings. You can <strong>not</strong> change those settings here.'),
+ '$submit' => t('Submit')
+ ));
+ return $o;
+ }
+
+} \ No newline at end of file
diff --git a/Zotlabs/Module/Settings/Tokens.php b/Zotlabs/Module/Settings/Tokens.php
index d32a00c95..bf22ec7aa 100644
--- a/Zotlabs/Module/Settings/Tokens.php
+++ b/Zotlabs/Module/Settings/Tokens.php
@@ -161,7 +161,8 @@ class Tokens {
'$me' => t('My Settings'),
'$perms' => $perms,
'$inherited' => t('inherited'),
- '$notself' => '1',
+ '$notself' => 0,
+ '$self' => 1,
'$permlbl' => t('Individual Permissions'),
'$permnote' => t('Some permissions may be inherited from your channel\'s <a href="settings"><strong>privacy settings</strong></a>, which have higher priority than individual settings. You can <strong>not</strong> change those settings here.'),
'$submit' => t('Submit')
diff --git a/Zotlabs/Module/Setup.php b/Zotlabs/Module/Setup.php
index b5258a28f..9c688af01 100644
--- a/Zotlabs/Module/Setup.php
+++ b/Zotlabs/Module/Setup.php
@@ -496,6 +496,11 @@ class Setup extends \Zotlabs\Web\Controller {
function check_funcs(&$checks) {
$ck_funcs = array();
+ $disabled = explode(',',ini_get('disable_functions'));
+ if($disabled)
+ array_walk($disabled,'array_trim');
+
+
// add check metadata, the real check is done bit later and return values set
$this->check_add($ck_funcs, t('libCurl PHP module'), true, true);
$this->check_add($ck_funcs, t('GD graphics PHP module'), true, true);
@@ -511,13 +516,13 @@ class Setup extends \Zotlabs\Web\Controller {
$this->check_add($ck_funcs, t('Apache mod_rewrite module'), true, true);
}
}
- if((! function_exists('exec')) || strstr(ini_get('disable_functions'),'exec')) {
+ if((! function_exists('exec')) || in_array('exec',$disabled)) {
$this->check_add($ck_funcs, t('exec'), false, true, t('Error: exec is required but is either not installed or has been disabled in php.ini'));
}
else {
$this->check_add($ck_funcs, t('exec'), true, true);
}
- if((! function_exists('shell_exec')) || strstr(ini_get('disable_functions'),'shell_exec')) {
+ if((! function_exists('shell_exec')) || in_array('shell_exec',$disabled)) {
$this->check_add($ck_funcs, t('shell_exec'), false, true, t('Error: shell_exec is required but is either not installed or has been disabled in php.ini'));
}
else {
diff --git a/Zotlabs/Module/Subthread.php b/Zotlabs/Module/Subthread.php
index 0226664d7..dae8bf020 100644
--- a/Zotlabs/Module/Subthread.php
+++ b/Zotlabs/Module/Subthread.php
@@ -138,7 +138,7 @@ class Subthread extends \Zotlabs\Web\Controller {
$ulink = '[zrl=' . $item_author['xchan_url'] . ']' . $item_author['xchan_name'] . '[/zrl]';
$alink = '[zrl=' . $observer['xchan_url'] . ']' . $observer['xchan_name'] . '[/zrl]';
- $plink = '[zrl=' . z_root() . '/display/' . $item['mid'] . ']' . $post_type . '[/zrl]';
+ $plink = '[zrl=' . z_root() . '/display/' . gen_link_id($item['mid']) . ']' . $post_type . '[/zrl]';
$arr['body'] = sprintf( $bodyverb, $alink, $ulink, $plink );
diff --git a/Zotlabs/Module/Tagger.php b/Zotlabs/Module/Tagger.php
index 25f518d53..98e901965 100644
--- a/Zotlabs/Module/Tagger.php
+++ b/Zotlabs/Module/Tagger.php
@@ -60,7 +60,7 @@ class Tagger extends \Zotlabs\Web\Controller {
$links = array(array('rel' => 'alternate','type' => 'text/html',
- 'href' => z_root() . '/display/' . $item['mid']));
+ 'href' => z_root() . '/display/' . gen_link_id($item['mid'])));
$target = json_encode(array(
'type' => $targettype,
@@ -81,11 +81,6 @@ class Tagger extends \Zotlabs\Web\Controller {
),
));
-
-
- $link = xmlify('<link rel="alternate" type="text/html" href="'
- . z_root() . '/display/' . $owner['nickname'] . '/' . $item['id'] . '" />' . "\n") ;
-
$tagid = z_root() . '/search?tag=' . $term;
$objtype = ACTIVITY_OBJ_TAGTERM;
diff --git a/Zotlabs/Module/Uexport.php b/Zotlabs/Module/Uexport.php
index f36d77174..28c840ceb 100644
--- a/Zotlabs/Module/Uexport.php
+++ b/Zotlabs/Module/Uexport.php
@@ -9,10 +9,11 @@ class Uexport extends \Zotlabs\Web\Controller {
killme();
if(argc() > 1) {
+
+ $sections = (($_REQUEST['sections']) ? explode(',',$_REQUEST['sections']) : '');
+
$channel = \App::get_channel();
-
- require_once('include/channel.php');
-
+
if(argc() > 1 && intval(argv(1)) > 1900) {
$year = intval(argv(1));
}
@@ -30,15 +31,16 @@ class Uexport extends \Zotlabs\Web\Controller {
}
if(argc() > 1 && argv(1) === 'basic') {
- echo json_encode(identity_basic_export(local_channel()));
+ echo json_encode(identity_basic_export(local_channel(),$sections));
killme();
}
- // FIXME - this basically doesn't work in the wild with a channel more than a few months old due to memory and execution time limits.
- // It probably needs to be built at the CLI and offered to download as a tarball. Maybe stored in the members dav.
+ // Warning: this option may consume a lot of memory
if(argc() > 1 && argv(1) === 'complete') {
- echo json_encode(identity_basic_export(local_channel(),true));
+ $sections = get_default_export_sections();
+ $sections[] = 'items';
+ echo json_encode(identity_basic_export(local_channel(),$sections));
killme();
}
}
@@ -57,6 +59,7 @@ class Uexport extends \Zotlabs\Web\Controller {
'$basic' => t('Export your basic channel information to a file. This acts as a backup of your connections, permissions, profile and basic data, which can be used to import your data to a new server hub, but does not contain your content.'),
'$fulltitle' => t('Export Content'),
'$full' => t('Export your channel information and recent content to a JSON backup that can be restored or imported to another server hub. This backs up all of your connections, permissions, profile data and several months of posts. This file may be VERY large. Please be patient - it may take several minutes for this download to begin.'),
+
'$by_year' => t('Export your posts from a given year.'),
'$extra' => t('You may also export your posts and conversations for a particular year or month. Adjust the date in your browser location bar to select other dates. If the export fails (possibly due to memory exhaustion on your server hub), please try again selecting a more limited date range.'),
diff --git a/Zotlabs/Module/Update_display.php b/Zotlabs/Module/Update_display.php
index 13b04204d..b2c6a56f5 100644
--- a/Zotlabs/Module/Update_display.php
+++ b/Zotlabs/Module/Update_display.php
@@ -21,26 +21,10 @@ class Update_display extends \Zotlabs\Web\Controller {
$mod = new Display();
$text = $mod->get($profile_uid, $load);
- $pattern = "/<img([^>]*) src=\"([^\"]*)\"/";
- $replace = "<img\${1} dst=\"\${2}\"";
- // $text = preg_replace($pattern, $replace, $text);
- /*
- if(! $load) {
- $replace = '<br />' . t('[Embedded content - reload page to view]') . '<br />';
- $pattern = "/<\s*audio[^>]*>(.*?)<\s*\/\s*audio>/i";
- $text = preg_replace($pattern, $replace, $text);
- $pattern = "/<\s*video[^>]*>(.*?)<\s*\/\s*video>/i";
- $text = preg_replace($pattern, $replace, $text);
- $pattern = "/<\s*embed[^>]*>(.*?)<\s*\/\s*embed>/i";
- $text = preg_replace($pattern, $replace, $text);
- $pattern = "/<\s*iframe[^>]*>(.*?)<\s*\/\s*iframe>/i";
- $text = preg_replace($pattern, $replace, $text);
- }
- */
echo str_replace("\t",' ',$text);
echo (($_GET['msie'] == 1) ? '</div>' : '</section>');
echo "</body></html>\r\n";
- // logger('update_display: ' . $text);
+
killme();
}
diff --git a/Zotlabs/Module/Viewconnections.php b/Zotlabs/Module/Viewconnections.php
index 4364d482a..1f9c03751 100644
--- a/Zotlabs/Module/Viewconnections.php
+++ b/Zotlabs/Module/Viewconnections.php
@@ -70,7 +70,7 @@ class Viewconnections extends \Zotlabs\Web\Controller {
foreach($r as $rr) {
- $url = chanlink_url($rr['xchan_url']);
+ $url = chanlink_hash($rr['xchan_hash']);
if($url) {
$contacts[] = array(
'id' => $rr['abook_id'],
diff --git a/Zotlabs/Module/Viewsrc.php b/Zotlabs/Module/Viewsrc.php
index fa755a3ec..cb305efc6 100644
--- a/Zotlabs/Module/Viewsrc.php
+++ b/Zotlabs/Module/Viewsrc.php
@@ -36,7 +36,9 @@ class Viewsrc extends \Zotlabs\Web\Controller {
if($r) {
if(intval($r[0]['item_obscured']))
$r[0]['body'] = crypto_unencapsulate(json_decode($r[0]['body'],true),get_config('system','prvkey'));
- $o = (($json) ? json_encode($r[0]['body']) : str_replace("\n",'<br />',$r[0]['body']));
+
+ $content = escape_tags($r[0]['body']);
+ $o = (($json) ? json_encode($content) : str_replace("\n",'<br />',$content));
}
}
diff --git a/Zotlabs/Module/Webpages.php b/Zotlabs/Module/Webpages.php
index 0da699c73..46b94f091 100644
--- a/Zotlabs/Module/Webpages.php
+++ b/Zotlabs/Module/Webpages.php
@@ -173,7 +173,6 @@ class Webpages extends \Zotlabs\Web\Controller {
if($_REQUEST['pagetitle'])
$x['pagetitle'] = $_REQUEST['pagetitle'];
- $editor = status_editor($a,$x);
// Get a list of webpages. We can't display all them because endless scroll makes that unusable,
// so just list titles and an edit link.
@@ -197,6 +196,11 @@ class Webpages extends \Zotlabs\Web\Controller {
// intval(ITEM_TYPE_WEBPAGE)
// );
+ if(! $r)
+ $x['pagetitle'] = 'home';
+
+ $editor = status_editor($a,$x);
+
$pages = null;
if($r) {
diff --git a/Zotlabs/Module/Wfinger.php b/Zotlabs/Module/Wfinger.php
index fa1e11518..04eed47c3 100644
--- a/Zotlabs/Module/Wfinger.php
+++ b/Zotlabs/Module/Wfinger.php
@@ -8,6 +8,8 @@ class Wfinger extends \Zotlabs\Web\Controller {
function init() {
+ session_write_close();
+
$result = array();
$scheme = '';
diff --git a/Zotlabs/Module/Wiki.php b/Zotlabs/Module/Wiki.php
index 7b0ec9d83..15806ffc3 100644
--- a/Zotlabs/Module/Wiki.php
+++ b/Zotlabs/Module/Wiki.php
@@ -2,26 +2,35 @@
namespace Zotlabs\Module;
+use \Zotlabs\Lib as Zlib;
+
+require_once('include/acl_selectors.php');
+require_once('include/conversation.php');
+require_once('include/bbcode.php');
+
+
class Wiki extends \Zotlabs\Web\Controller {
+ private $wiki = null;
+
function init() {
// Determine which channel's wikis to display to the observer
$nick = null;
if (argc() > 1)
$nick = argv(1); // if the channel name is in the URL, use that
- if (!$nick && local_channel()) { // if no channel name was provided, assume the current logged in channel
+ if (! $nick && local_channel()) { // if no channel name was provided, assume the current logged in channel
$channel = \App::get_channel();
if ($channel && $channel['channel_address']) {
$nick = $channel['channel_address'];
goaway(z_root() . '/wiki/' . $nick);
}
}
- if (!$nick) {
- notice(t('You must be logged in to see this page.') . EOL);
- goaway('/login');
+ if (! $nick) {
+ notice( t('Profile Unavailable.') . EOL);
+ goaway(z_root());
}
- profile_load($nick);
+ profile_load($nick);
}
function get() {
@@ -35,13 +44,15 @@ class Wiki extends \Zotlabs\Web\Controller {
return;
}
- require_once('include/wiki.php');
- require_once('include/acl_selectors.php');
- require_once('include/conversation.php');
- require_once('include/bbcode.php');
+
+ if(! perm_is_allowed(\App::$profile_uid,get_observer_hash(),'view_wiki')) {
+ notice( t('Permission denied.') . EOL);
+ return;
+ }
// TODO: Combine the interface configuration into a unified object
// Something like $interface = array('new_page_button' => false, 'new_wiki_button' => false, ...)
+
$wiki_owner = false;
$showNewWikiButton = false;
$pageHistory = array();
@@ -49,12 +60,16 @@ class Wiki extends \Zotlabs\Web\Controller {
$resource_id = '';
// init() should have forced the URL to redirect to /wiki/channel so assume argc() > 1
+
$nick = argv(1);
$owner = channelx_by_nick($nick); // The channel who owns the wikis being viewed
if(! $owner) {
notice( t('Invalid channel') . EOL);
goaway('/' . argv(0));
}
+
+ $observer_hash = get_observer_hash();
+
// Determine if the observer is the channel owner so the ACL dialog can be populated
if (local_channel() === intval($owner['channel_id'])) {
@@ -62,12 +77,14 @@ class Wiki extends \Zotlabs\Web\Controller {
// Obtain the default permission settings of the channel
$owner_acl = array(
- 'allow_cid' => $owner['channel_allow_cid'],
- 'allow_gid' => $owner['channel_allow_gid'],
- 'deny_cid' => $owner['channel_deny_cid'],
- 'deny_gid' => $owner['channel_deny_gid']
+ 'allow_cid' => $owner['channel_allow_cid'],
+ 'allow_gid' => $owner['channel_allow_gid'],
+ 'deny_cid' => $owner['channel_deny_cid'],
+ 'deny_gid' => $owner['channel_deny_gid']
);
+
// Initialize the ACL to the channel default permissions
+
$x = array(
'lockstate' => (( $owner['channel_allow_cid'] ||
$owner['channel_allow_gid'] ||
@@ -78,11 +95,12 @@ class Wiki extends \Zotlabs\Web\Controller {
'acl' => populate_acl($owner_acl),
'allow_cid' => acl2json($owner_acl['allow_cid']),
'allow_gid' => acl2json($owner_acl['allow_gid']),
- 'deny_cid' => acl2json($owner_acl['deny_cid']),
- 'deny_gid' => acl2json($owner_acl['deny_gid']),
+ 'deny_cid' => acl2json($owner_acl['deny_cid']),
+ 'deny_gid' => acl2json($owner_acl['deny_gid']),
'bang' => ''
);
- } else {
+ }
+ else {
// Not the channel owner
$owner_acl = $x = array();
}
@@ -91,12 +109,13 @@ class Wiki extends \Zotlabs\Web\Controller {
$o = profile_tabs($a, $is_owner, \App::$profile['channel_address']);
// Download a wiki
+/*
if((argc() > 3) && (argv(2) === 'download') && (argv(3) === 'wiki')) {
$resource_id = argv(4);
- $w = wiki_get_wiki($resource_id);
- if(!$w['path']) {
+ $w = Zlib\NativeWiki::get_wiki($owner,$observer_hash,$resource_id);
+ if(! $w['htmlName']) {
notice(t('Error retrieving wiki') . EOL);
}
@@ -111,7 +130,7 @@ class Wiki extends \Zotlabs\Web\Controller {
$zip_filepath = '/tmp/' . $zip_folder_name . '/' . $zip_filename;
// Generate the zip file
- \Zotlabs\Lib\ExtendedZip::zipTree($w['path'], $zip_filepath, \ZipArchive::CREATE);
+ ZLib\ExtendedZip::zipTree($w['path'], $zip_filepath, \ZipArchive::CREATE);
// Output the file for download
@@ -130,11 +149,11 @@ class Wiki extends \Zotlabs\Web\Controller {
killme();
}
-
- switch (argc()) {
+*/
+ switch(argc()) {
case 2:
- $wikis = wiki_list($owner, get_observer_hash());
- if ($wikis) {
+ $wikis = Zlib\NativeWiki::listwikis($owner, get_observer_hash());
+ if($wikis) {
$o .= replace_macros(get_markup_template('wikilist.tpl'), array(
'$header' => t('Wikis'),
'$channel' => $owner['channel_address'],
@@ -161,72 +180,76 @@ class Wiki extends \Zotlabs\Web\Controller {
return $o;
}
-
break;
+
case 3:
+
// /wiki/channel/wiki -> No page was specified, so redirect to Home.md
+
$wikiUrlName = urlencode(argv(2));
- goaway('/'.argv(0).'/'.argv(1).'/'.$wikiUrlName.'/Home');
+ goaway(z_root() . '/' . argv(0) . '/' . argv(1) . '/' . $wikiUrlName . '/Home');
+
case 4:
+
// GET /wiki/channel/wiki/page
// Fetch the wiki info and determine observer permissions
- $wikiUrlName = urlencode(argv(2));
- $pageUrlName = urlencode(argv(3));
- $w = wiki_exists_by_name($owner['channel_id'], $wikiUrlName);
- if(!$w['resource_id']) {
+ $wikiUrlName = urldecode(argv(2));
+ $pageUrlName = urldecode(argv(3));
+
+ $w = Zlib\NativeWiki::exists_by_name($owner['channel_id'], $wikiUrlName);
+
+ if(! $w['resource_id']) {
notice(t('Wiki not found') . EOL);
- goaway('/'.argv(0).'/'.argv(1));
- return; //not reached
+ goaway(z_root() . '/' . argv(0) . '/' . argv(1));
}
+
$resource_id = $w['resource_id'];
- if (!$wiki_owner) {
+ if(! $wiki_owner) {
// Check for observer permissions
$observer_hash = get_observer_hash();
- $perms = wiki_get_permissions($resource_id, intval($owner['channel_id']), $observer_hash);
- if(!$perms['read']) {
+ $perms = Zlib\NativeWiki::get_permissions($resource_id, intval($owner['channel_id']), $observer_hash);
+ if(! $perms['read']) {
notice(t('Permission denied.') . EOL);
- goaway('/'.argv(0).'/'.argv(1));
+ goaway(z_root() . '/' . argv(0) . '/' . argv(1));
return; //not reached
}
- if($perms['write']) {
- $wiki_editor = true;
- } else {
- $wiki_editor = false;
- }
- } else {
+ $wiki_editor = (($perms['write']) ? true : false);
+ }
+ else {
$wiki_editor = true;
}
+
$wikiheaderName = urldecode($wikiUrlName);
$wikiheaderPage = urldecode($pageUrlName);
+
$renamePage = (($wikiheaderPage === 'Home') ? '' : t('Rename page'));
- $p = wiki_get_page_content(array('resource_id' => $resource_id, 'pageUrlName' => $pageUrlName));
- if(!$p['success']) {
- notice(t('Error retrieving page content') . EOL);
- goaway('/'.argv(0).'/'.argv(1).'/'.$wikiUrlName);
- return; //not reached
+ $p = Zlib\NativeWikiPage::get_page_content(array('channel_id' => $owner['channel_id'], 'observer_hash' => $observer_hash, 'resource_id' => $resource_id, 'pageUrlName' => $pageUrlName));
+ if(! $p['success']) {
+ notice( t('Error retrieving page content') . EOL);
+ goaway(z_root() . '/' . argv(0) . '/' . argv(1) );
}
$mimeType = $p['mimeType'];
- $rawContent = (($p['mimeType'] == 'text/bbcode') ? htmlspecialchars_decode(json_decode($p['content']),ENT_COMPAT) : htmlspecialchars_decode($p['content'],ENT_COMPAT));
+ $rawContent = htmlspecialchars_decode(json_decode($p['content']),ENT_COMPAT);
+
$content = ($p['content'] !== '' ? $rawContent : '"# New page\n"');
// Render the Markdown-formatted page content in HTML
if($mimeType == 'text/bbcode') {
- $renderedContent = wiki_convert_links(bbcode($content),argv(0).'/'.argv(1).'/'.$wikiUrlName);
+ $renderedContent = Zlib\NativeWikiPage::convert_links(zidify_links(smilies(bbcode($content))), argv(0) . '/' . argv(1) . '/' . $wikiUrlName);
}
else {
require_once('library/markdown.php');
- $html = wiki_generate_toc(zidify_text(purify_html(Markdown(wiki_bbcode(json_decode($content))))));
- $renderedContent = wiki_convert_links($html,argv(0).'/'.argv(1).'/'.$wikiUrlName);
+ $html = Zlib\NativeWikiPage::generate_toc(zidify_text(purify_html(Markdown(Zlib\NativeWikiPage::bbcode($content)))));
+ $renderedContent = Zlib\NativeWikiPage::convert_links($html, argv(0) . '/' . argv(1) . '/' . $wikiUrlName);
}
$showPageControls = $wiki_editor;
break;
default: // Strip the extraneous URL components
goaway('/' . argv(0) . '/' . argv(1) . '/' . $wikiUrlName . '/' . $pageUrlName);
- return; //not reached
}
$wikiModalID = random_string(3);
@@ -237,6 +260,8 @@ class Wiki extends \Zotlabs\Web\Controller {
'$ok' => (($showPageControls) ? t('Revert') : ''),
'$cancel' => t('Cancel')
));
+
+ $placeholder = t('Short description of your changes (optional)');
$o .= replace_macros(get_markup_template('wiki.tpl'),array(
'$wikiheaderName' => $wikiheaderName,
@@ -252,7 +277,7 @@ class Wiki extends \Zotlabs\Web\Controller {
'$content' => $content,
'$renderedContent' => $renderedContent,
'$pageRename' => array('pageRename', t('New page name'), '', ''),
- '$commitMsg' => array('commitMsg', '', '', '', '', 'placeholder="Short description of your changes (optional)"'),
+ '$commitMsg' => array('commitMsg', '', '', '', '', 'placeholder="' . $placeholder . '"'),
'$wikiModal' => $wikiModal,
'$wikiModalID' => $wikiModalID,
'$commit' => 'HEAD',
@@ -269,13 +294,13 @@ class Wiki extends \Zotlabs\Web\Controller {
));
if($p['mimeType'] != 'text/bbcode')
- head_add_js('library/ace/ace.js'); // Ace Code Editor
+ head_add_js('/library/ace/ace.js'); // Ace Code Editor
return $o;
}
function post() {
- require_once('include/wiki.php');
+
require_once('include/bbcode.php');
$nick = argv(1);
@@ -287,25 +312,25 @@ class Wiki extends \Zotlabs\Web\Controller {
return;
}
-
// /wiki/channel/preview
// Render mardown-formatted text in HTML for preview
if((argc() > 2) && (argv(2) === 'preview')) {
$content = $_POST['content'];
$resource_id = $_POST['resource_id'];
- $w = wiki_get_wiki($resource_id);
- $wikiURL = argv(0).'/'.argv(1).'/'.$w['urlName'];
+ $w = Zlib\NativeWiki::get_wiki($owner['channel_id'],$observer_hash,$resource_id);
+
+ $wikiURL = argv(0) . '/' . argv(1) . '/' . $w['urlName'];
$mimeType = $w['mimeType'];
if($mimeType == 'text/bbcode') {
- $html = wiki_convert_links(bbcode($content),$wikiURL);
+ $html = Zlib\NativeWikiPage::convert_links(zidify_links(smilies(bbcode($content))),$wikiURL);
}
else {
require_once('library/markdown.php');
- $content = wiki_bbcode($content);
- $html = wiki_generate_toc(zidify_text(purify_html(Markdown($content))));
- $html = wiki_convert_links($html,$wikiURL);
+ $content = Zlib\NativeWikiPage::bbcode($content);
+ $html = Zlib\NativeWikiPage::generate_toc(zidify_text(purify_html(Markdown($content))));
+ $html = Zlib\NativeWikiPage::convert_links($html,$wikiURL);
}
json_return_and_die(array('html' => $html, 'success' => true));
}
@@ -322,11 +347,11 @@ class Wiki extends \Zotlabs\Web\Controller {
}
$wiki = array();
// Generate new wiki info from input name
- $wiki['postVisible'] = ((intval($_POST['postVisible']) === 0) ? 0 : 1);
- $wiki['rawName'] = $_POST['wikiName'];
- $wiki['htmlName'] = escape_tags($_POST['wikiName']);
- $wiki['urlName'] = urlencode($_POST['wikiName']);
- $wiki['mimeType'] = $_POST['mimeType'];
+ $wiki['postVisible'] = ((intval($_POST['postVisible'])) ? 1 : 0);
+ $wiki['rawName'] = $_POST['wikiName'];
+ $wiki['htmlName'] = escape_tags($_POST['wikiName']);
+ $wiki['urlName'] = urlencode(urlencode($_POST['wikiName']));
+ $wiki['mimeType'] = $_POST['mimeType'];
if($wiki['urlName'] === '') {
notice( t('Error creating wiki. Invalid name.') . EOL);
@@ -336,17 +361,20 @@ class Wiki extends \Zotlabs\Web\Controller {
// Get ACL for permissions
$acl = new \Zotlabs\Access\AccessList($owner);
$acl->set_from_array($_POST);
- $r = wiki_create_wiki($owner, $observer_hash, $wiki, $acl);
- if ($r['success']) {
- $homePage = wiki_create_page('Home', $r['item']['resource_id']);
- if(!$homePage['success']) {
+ $r = Zlib\NativeWiki::create_wiki($owner, $observer_hash, $wiki, $acl);
+ if($r['success']) {
+ Zlib\NativeWiki::sync_a_wiki_item($owner['channel_id'],$r['item_id'],$r['item']['resource_id']);
+ $homePage = Zlib\NativeWikiPage::create_page($owner['channel_id'],$observer_hash,'Home', $r['item']['resource_id']);
+ if(! $homePage['success']) {
notice( t('Wiki created, but error creating Home page.'));
- goaway('/wiki/'.$nick.'/'.$wiki['urlName']);
+ goaway(z_root() . '/wiki/' . $nick . '/' . $wiki['urlName']);
}
- goaway('/wiki/'.$nick.'/'.$wiki['urlName'].'/'.$homePage['page']['urlName']);
- } else {
- notice(t('Error creating wiki'));
- goaway('/wiki');
+ Zlib\NativeWiki::sync_a_wiki_item($owner['channel_id'],$homePage['item_id'],$r['item']['resource_id']);
+ goaway(z_root() . '/wiki/' . $nick . '/' . $wiki['urlName'] . '/' . $homePage['page']['urlName']);
+ }
+ else {
+ notice( t('Error creating wiki'));
+ goaway(z_root() . '/wiki');
}
}
@@ -357,15 +385,17 @@ class Wiki extends \Zotlabs\Web\Controller {
// more detail permissions framework
if (local_channel() !== intval($owner['channel_id'])) {
logger('Wiki delete permission denied.');
- json_return_and_die(array('message' => 'Wiki delete permission denied.', 'success' => false));
+ json_return_and_die(array('message' => t('Wiki delete permission denied.'), 'success' => false));
}
$resource_id = $_POST['resource_id'];
- $deleted = wiki_delete_wiki($resource_id);
+ $deleted = Zlib\NativeWiki::delete_wiki($owner['channel_id'],$observer_hash,$resource_id);
if ($deleted['success']) {
+ Zlib\NativeWiki::sync_a_wiki_item($owner['channel_id'],$deleted['item_id'],$resource_id);
json_return_and_die(array('message' => '', 'success' => true));
- } else {
- logger('Error deleting wiki: ' . $resource_id);
- json_return_and_die(array('message' => 'Error deleting wiki', 'success' => false));
+ }
+ else {
+ logger('Error deleting wiki: ' . $resource_id . ' ' . $deleted['message']);
+ json_return_and_die(array('message' => t('Error deleting wiki'), 'success' => false));
}
}
@@ -377,41 +407,48 @@ class Wiki extends \Zotlabs\Web\Controller {
// Determine if observer has permission to create a page
- $perms = wiki_get_permissions($resource_id, intval($owner['channel_id']), $observer_hash);
- if(!$perms['write']) {
+ $perms = Zlib\NativeWiki::get_permissions($resource_id, intval($owner['channel_id']), $observer_hash);
+ if(! $perms['write']) {
logger('Wiki write permission denied. ' . EOL);
json_return_and_die(array('success' => false));
}
- $name = $_POST['name']; //Get new page name
- if(urlencode(escape_tags($_POST['name'])) === '') {
+ $name = $_POST['pageName']; //Get new page name
+ if(urlencode(escape_tags($_POST['pageName'])) === '') {
json_return_and_die(array('message' => 'Error creating page. Invalid name.', 'success' => false));
}
- $page = wiki_create_page($name, $resource_id);
- if ($page['success']) {
- $ob = \App::get_observer();
- $commit = wiki_git_commit(array(
- 'commit_msg' => t('New page created'),
- 'resource_id' => $resource_id,
- 'observer' => $ob,
- 'files' => array($page['page']['fileName'])
- ));
+ $page = Zlib\NativeWikiPage::create_page($owner['channel_id'],$observer_hash, $name, $resource_id);
+
+ if($page['item_id']) {
+ $commit = Zlib\NativeWikiPage::commit(array(
+ 'commit_msg' => t('New page created'),
+ 'resource_id' => $resource_id,
+ 'channel_id' => $owner['channel_id'],
+ 'observer_hash' => $observer_hash,
+ 'pageUrlName' => $name
+ ));
+
if($commit['success']) {
- json_return_and_die(array('url' => '/'.argv(0).'/'.argv(1).'/'.$page['wiki']['urlName'].'/'.$page['page']['urlName'], 'success' => true));
- } else {
- json_return_and_die(array('message' => 'Error making git commit','url' => '/'.argv(0).'/'.argv(1).'/'.$page['wiki']['urlName'].'/'.urlencode($page['page']['urlName']),'success' => false));
+ Zlib\NativeWiki::sync_a_wiki_item($owner['channel_id'],$commit['item_id'],$resource_id);
+ json_return_and_die(array('url' => '/' . argv(0) . '/' . argv(1) . '/' . urlencode($page['wiki']['urlName']) . '/' . urlencode($page['page']['urlName']), 'success' => true));
+ }
+ else {
+ json_return_and_die(array('message' => 'Error making git commit','url' => '/' . argv(0) . '/' . argv(1) . '/' . urlencode($page['wiki']['urlName']) . '/' . urlencode($page['page']['urlName']),'success' => false));
}
- } else {
+
+
+ }
+ else {
logger('Error creating page');
json_return_and_die(array('message' => 'Error creating page.', 'success' => false));
}
}
// Fetch page list for a wiki
- if ((argc() === 5) && (argv(2) === 'get') && (argv(3) === 'page') && (argv(4) === 'list')) {
+ if((argc() === 5) && (argv(2) === 'get') && (argv(3) === 'page') && (argv(4) === 'list')) {
$resource_id = $_POST['resource_id']; // resource_id for wiki in db
- $perms = wiki_get_permissions($resource_id, intval($owner['channel_id']), $observer_hash);
+ $perms = Zlib\NativeWiki::get_permissions($resource_id, intval($owner['channel_id']), $observer_hash);
if(!$perms['read']) {
logger('Wiki read permission denied.' . EOL);
json_return_and_die(array('pages' => null, 'message' => 'Permission denied.', 'success' => false));
@@ -437,27 +474,33 @@ class Wiki extends \Zotlabs\Web\Controller {
}
// Determine if observer has permission to save content
- $perms = wiki_get_permissions($resource_id, intval($owner['channel_id']), $observer_hash);
- if(!$perms['write']) {
+ $perms = Zlib\NativeWiki::get_permissions($resource_id, intval($owner['channel_id']), $observer_hash);
+ if(! $perms['write']) {
logger('Wiki write permission denied. ' . EOL);
json_return_and_die(array('success' => false));
}
- $saved = wiki_save_page(array('resource_id' => $resource_id, 'pageUrlName' => $pageUrlName, 'content' => $content));
+ $saved = Zlib\NativeWikiPage::save_page(array('channel_id' => $owner['channel_id'], 'observer_hash' => $observer_hash, 'resource_id' => $resource_id, 'pageUrlName' => $pageUrlName, 'content' => $content));
+
if($saved['success']) {
- $ob = \App::get_observer();
- $commit = wiki_git_commit(array(
- 'commit_msg' => $commitMsg,
- 'resource_id' => $resource_id,
- 'observer' => $ob,
- 'files' => array($saved['fileName'])
- ));
+ $commit = Zlib\NativeWikiPage::commit(array(
+ 'commit_msg' => $commitMsg,
+ 'pageUrlName' => $pageUrlName,
+ 'resource_id' => $resource_id,
+ 'channel_id' => $owner['channel_id'],
+ 'observer_hash' => $observer_hash,
+ 'revision' => (-1)
+ ));
+
if($commit['success']) {
+ Zlib\NativeWiki::sync_a_wiki_item($owner['channel_id'],$commit['item_id'],$resource_id);
json_return_and_die(array('message' => 'Wiki git repo commit made', 'success' => true));
- } else {
+ }
+ else {
json_return_and_die(array('message' => 'Error making git commit','success' => false));
}
- } else {
+ }
+ else {
json_return_and_die(array('message' => 'Error saving page', 'success' => false));
}
}
@@ -472,8 +515,8 @@ class Wiki extends \Zotlabs\Web\Controller {
// Determine if observer has permission to read content
- $perms = wiki_get_permissions($resource_id, intval($owner['channel_id']), $observer_hash);
- if(!$perms['read']) {
+ $perms = Zlib\NativeWiki::get_permissions($resource_id, intval($owner['channel_id']), $observer_hash);
+ if(! $perms['read']) {
logger('Wiki read permission denied.' . EOL);
json_return_and_die(array('historyHTML' => '', 'message' => 'Permission denied.', 'success' => false));
}
@@ -481,59 +524,59 @@ class Wiki extends \Zotlabs\Web\Controller {
$historyHTML = widget_wiki_page_history(array(
'resource_id' => $resource_id,
'pageUrlName' => $pageUrlName,
- 'permsWrite' => $perms['write']
+ 'permsWrite' => $perms['write']
));
json_return_and_die(array('historyHTML' => $historyHTML, 'message' => '', 'success' => true));
}
// Delete a page
if ((argc() === 4) && (argv(2) === 'delete') && (argv(3) === 'page')) {
+
$resource_id = $_POST['resource_id'];
$pageUrlName = $_POST['name'];
+
if ($pageUrlName === 'Home') {
- json_return_and_die(array('message' => 'Cannot delete Home','success' => false));
+ json_return_and_die(array('message' => t('Cannot delete Home'),'success' => false));
}
// Determine if observer has permission to delete pages
+ // currently just allow page owner
+
+ if((! local_channel()) || (local_channel() != $owner['channel_id'])) {
+ logger('Wiki write permission denied. ' . EOL);
+ json_return_and_die(array('success' => false));
+ }
- $perms = wiki_get_permissions($resource_id, intval($owner['channel_id']), $observer_hash);
- if(!$perms['write']) {
+ $perms = Zlib\NativeWiki::get_permissions($resource_id, intval($owner['channel_id']), $observer_hash);
+ if(! $perms['write']) {
logger('Wiki write permission denied. ' . EOL);
json_return_and_die(array('success' => false));
}
- $deleted = wiki_delete_page(array('resource_id' => $resource_id, 'pageUrlName' => $pageUrlName));
+ $deleted = Zlib\NativeWikiPage::delete_page(array('channel_id' => $owner['channel_id'], 'observer_hash' => $observer_hash, 'resource_id' => $resource_id, 'pageUrlName' => $pageUrlName));
if($deleted['success']) {
- $ob = \App::get_observer();
- $commit = wiki_git_commit(array(
- 'commit_msg' => 'Deleted ' . $pageUrlName,
- 'resource_id' => $resource_id,
- 'observer' => $ob,
- 'files' => null
- ));
- if($commit['success']) {
- json_return_and_die(array('message' => 'Wiki git repo commit made', 'success' => true));
- } else {
- json_return_and_die(array('message' => 'Error making git commit','success' => false));
- }
- } else {
+ Zlib\NativeWiki::sync_a_wiki_item($owner['channel_id'],$commit['item_id'],$resource_id);
+ json_return_and_die(array('message' => 'Wiki git repo commit made', 'success' => true));
+ }
+ else {
json_return_and_die(array('message' => 'Error deleting page', 'success' => false));
}
}
// Revert a page
if ((argc() === 4) && (argv(2) === 'revert') && (argv(3) === 'page')) {
+
$resource_id = $_POST['resource_id'];
$pageUrlName = $_POST['name'];
$commitHash = $_POST['commitHash'];
// Determine if observer has permission to revert pages
- $perms = wiki_get_permissions($resource_id, intval($owner['channel_id']), $observer_hash);
- if(!$perms['write']) {
+ $perms = Zlib\NativeWiki::get_permissions($resource_id, intval($owner['channel_id']), $observer_hash);
+ if(! $perms['write']) {
logger('Wiki write permission denied.' . EOL);
json_return_and_die(array('success' => false));
}
- $reverted = wiki_revert_page(array('commitHash' => $commitHash, 'resource_id' => $resource_id, 'pageUrlName' => $pageUrlName));
+ $reverted = Zlib\NativeWikiPage::revert_page(array('channel_id' => $owner['channel_id'], 'observer_hash' => $observer_hash, 'commitHash' => $commitHash, 'resource_id' => $resource_id, 'pageUrlName' => $pageUrlName));
if($reverted['success']) {
json_return_and_die(array('content' => $reverted['content'], 'message' => '', 'success' => true));
} else {
@@ -549,15 +592,15 @@ class Wiki extends \Zotlabs\Web\Controller {
$currentCommit = $_POST['currentCommit'];
// Determine if observer has permission to revert pages
- $perms = wiki_get_permissions($resource_id, intval($owner['channel_id']), $observer_hash);
+ $perms = Zlib\NativeWiki::get_permissions($resource_id, intval($owner['channel_id']), $observer_hash);
if(!$perms['read']) {
logger('Wiki read permission denied.' . EOL);
json_return_and_die(array('success' => false));
}
- $compare = wiki_compare_page(array('currentCommit' => $currentCommit, 'compareCommit' => $compareCommit, 'resource_id' => $resource_id, 'pageUrlName' => $pageUrlName));
+ $compare = Zlib\NativeWikiPage::compare_page(array('channel_id' => $owner['channel_id'], 'observer_hash' => $observer_hash, 'currentCommit' => $currentCommit, 'compareCommit' => $compareCommit, 'resource_id' => $resource_id, 'pageUrlName' => $pageUrlName));
if($compare['success']) {
- $diffHTML = '<table class="text-center" width="100%"><tr><td class="lead" width="50%">Current Revision</td><td class="lead" width="50%">Selected Revision</td></tr></table>' . $compare['diff'];
+ $diffHTML = '<table class="text-center" width="100%"><tr><td class="lead" width="50%">' . t('Current Revision') . '</td><td class="lead" width="50%">' . t('Selected Revision') . '</td></tr></table>' . $compare['diff'];
json_return_and_die(array('diff' => $diffHTML, 'message' => '', 'success' => true));
} else {
json_return_and_die(array('diff' => '', 'message' => 'Error comparing page', 'success' => false));
@@ -577,34 +620,37 @@ class Wiki extends \Zotlabs\Web\Controller {
}
// Determine if observer has permission to rename pages
- $perms = wiki_get_permissions($resource_id, intval($owner['channel_id']), $observer_hash);
- if(!$perms['write']) {
+ $perms = Zlib\NativeWiki::get_permissions($resource_id, intval($owner['channel_id']), $observer_hash);
+ if(! $perms['write']) {
logger('Wiki write permission denied. ' . EOL);
json_return_and_die(array('success' => false));
}
- $renamed = wiki_rename_page(array('resource_id' => $resource_id, 'pageUrlName' => $pageUrlName, 'pageNewName' => $pageNewName));
+ $renamed = Zlib\NativeWikiPage::rename_page(array('channel_id' => $owner['channel_id'], 'observer_hash' => $observer_hash, 'resource_id' => $resource_id, 'pageUrlName' => $pageUrlName, 'pageNewName' => $pageNewName));
+
if($renamed['success']) {
- $ob = \App::get_observer();
- $commit = wiki_git_commit(array(
- 'commit_msg' => 'Renamed ' . urldecode($pageUrlName) . ' to ' . $renamed['page']['htmlName'],
- 'resource_id' => $resource_id,
- 'observer' => $ob,
- 'files' => array($pageUrlName . substr($renamed['page']['fileName'], -3), $renamed['page']['fileName']),
- 'all' => true
- ));
+ $commit = Zlib\NativeWikiPage::commit(array(
+ 'channel_id' => $owner['channel_id'],
+ 'commit_msg' => 'Renamed ' . urldecode($pageUrlName) . ' to ' . $renamed['page']['htmlName'],
+ 'resource_id' => $resource_id,
+ 'observer_hash' => $observer_hash,
+ 'pageUrlName' => $pageNewName
+ ));
if($commit['success']) {
+ Zlib\NativeWiki::sync_a_wiki_item($owner['channel_id'],$commit['item_id'],$resource_id);
json_return_and_die(array('name' => $renamed['page'], 'message' => 'Wiki git repo commit made', 'success' => true));
- } else {
+ }
+ else {
json_return_and_die(array('message' => 'Error making git commit','success' => false));
}
- } else {
+ }
+ else {
json_return_and_die(array('message' => 'Error renaming page', 'success' => false));
}
}
//notice( t('You must be authenticated.'));
- json_return_and_die(array('message' => 'You must be authenticated.', 'success' => false));
+ json_return_and_die(array('message' => t('You must be authenticated.'), 'success' => false));
}
}
diff --git a/Zotlabs/Render/Comanche.php b/Zotlabs/Render/Comanche.php
index 562a9f791..5826063fd 100644
--- a/Zotlabs/Render/Comanche.php
+++ b/Zotlabs/Render/Comanche.php
@@ -99,13 +99,28 @@ class Comanche {
}
}
+ /**
+ * Currently supported condition variables:
+ *
+ * $config.xxx.yyy - get_config with cat = xxx and k = yyy
+ * $request - request uri for this page
+ * $observer.language - viewer's preferred language (closest match)
+ * $observer.address - xchan_addr or false
+ * $observer.name - xchan_name or false
+ * $observer - xchan_hash of observer or empty string
+ */
+
function get_condition_var($v) {
if($v) {
$x = explode('.',$v);
if($x[0] == 'config')
return get_config($x[1],$x[2]);
+ elseif($x[0] === 'request')
+ return $_SERVER['REQUEST_URI'];
elseif($x[0] === 'observer') {
if(count($x) > 1) {
+ if($x[1] == 'language')
+ return \App::$language;
$y = \App::get_observer();
if(! $y)
return false;
@@ -125,20 +140,35 @@ class Comanche {
function test_condition($s) {
// This is extensible. The first version of variable testing supports tests of the forms:
+
+ // [if $config.system.foo ~= baz] which will check if get_config('system','foo') contains the string 'baz';
// [if $config.system.foo == baz] which will check if get_config('system','foo') is the string 'baz';
// [if $config.system.foo != baz] which will check if get_config('system','foo') is not the string 'baz';
- // You may check numeric entries, but these checks are evaluated as strings.
+ // [if $config.system.foo >= 3] which will check if get_config('system','foo') is greater than or equal to 3;
+ // [if $config.system.foo > 3] which will check if get_config('system','foo') is greater than 3;
+
+ // [if $config.system.foo <= 3] which will check if get_config('system','foo') is less than or equal to 3;
+ // [if $config.system.foo < 3] which will check if get_config('system','foo') is less than 3;
+
// [if $config.system.foo {} baz] which will check if 'baz' is an array element in get_config('system','foo')
// [if $config.system.foo {*} baz] which will check if 'baz' is an array key in get_config('system','foo')
// [if $config.system.foo] which will check for a return of a true condition for get_config('system','foo');
// The values 0, '', an empty array, and an unset value will all evaluate to false.
+ if(preg_match('/[\$](.*?)\s\~\=\s(.*?)$/',$s,$matches)) {
+ $x = $this->get_condition_var($matches[1]);
+ if(stripos($x,trim($matches[2])) !== false)
+ return true;
+ return false;
+ }
+
if(preg_match('/[\$](.*?)\s\=\=\s(.*?)$/',$s,$matches)) {
$x = $this->get_condition_var($matches[1]);
if($x == trim($matches[2]))
return true;
return false;
}
+
if(preg_match('/[\$](.*?)\s\!\=\s(.*?)$/',$s,$matches)) {
$x = $this->get_condition_var($matches[1]);
if($x != trim($matches[2]))
@@ -146,6 +176,31 @@ class Comanche {
return false;
}
+ if(preg_match('/[\$](.*?)\s\>\=\s(.*?)$/',$s,$matches)) {
+ $x = $this->get_condition_var($matches[1]);
+ if($x >= trim($matches[2]))
+ return true;
+ return false;
+ }
+ if(preg_match('/[\$](.*?)\s\<\=\s(.*?)$/',$s,$matches)) {
+ $x = $this->get_condition_var($matches[1]);
+ if($x <= trim($matches[2]))
+ return true;
+ return false;
+ }
+ if(preg_match('/[\$](.*?)\s\>\s(.*?)$/',$s,$matches)) {
+ $x = $this->get_condition_var($matches[1]);
+ if($x > trim($matches[2]))
+ return true;
+ return false;
+ }
+ if(preg_match('/[\$](.*?)\s\>\s(.*?)$/',$s,$matches)) {
+ $x = $this->get_condition_var($matches[1]);
+ if($x < trim($matches[2]))
+ return true;
+ return false;
+ }
+
if(preg_match('/[\$](.*?)\s\{\}\s(.*?)$/',$s,$matches)) {
$x = $this->get_condition_var($matches[1]);
if(is_array($x) && in_array(trim($matches[2]),$x))
diff --git a/Zotlabs/Render/Theme.php b/Zotlabs/Render/Theme.php
index 9f9009d72..3a0116abe 100644
--- a/Zotlabs/Render/Theme.php
+++ b/Zotlabs/Render/Theme.php
@@ -70,9 +70,15 @@ class Theme {
$chosen_theme = $_GET['theme_preview'];
// Allow theme selection of the form 'theme_name:schema_name'
-
$themepair = explode(':', $chosen_theme);
+ // Check if $chosen_theme is compatible with core. If not fall back to default
+ $info = get_theme_info($themepair[0]);
+ $compatible = check_plugin_versions($info);
+ if(!$compatible) {
+ $chosen_theme = '';
+ }
+
if($chosen_theme && (file_exists('view/theme/' . $themepair[0] . '/css/style.css') || file_exists('view/theme/' . $themepair[0] . '/php/style.php'))) {
return($themepair);
}
@@ -125,9 +131,9 @@ class Theme {
$opts .= $schema_str;
if(file_exists('view/theme/' . $t . '/php/style.php'))
- return('view/theme/' . $t . '/php/style.pcss' . $opts);
+ return('/view/theme/' . $t . '/php/style.pcss' . $opts);
- return('view/theme/' . $t . '/css/style.css');
+ return('/view/theme/' . $t . '/css/style.css');
}
function debug() {
diff --git a/Zotlabs/Storage/Browser.php b/Zotlabs/Storage/Browser.php
index a30eedba5..f527a6a44 100644
--- a/Zotlabs/Storage/Browser.php
+++ b/Zotlabs/Storage/Browser.php
@@ -314,7 +314,13 @@ class Browser extends DAV\Browser\Plugin {
$quota['desc'] = $quotaDesc;
$quota['warning'] = ((($limit) && ((round($used / $limit, 1) * 100) >= 90)) ? t('WARNING:') : ''); // 10485760 bytes = 100MB
- $path = trim(str_replace('cloud/' . $this->auth->owner_nick, '', $path), '/');
+ // strip 'cloud/nickname', but only at the beginning of the path
+
+ $special = 'cloud/' . $this->auth->owner_nick;
+ $count = strlen($special);
+
+ if(strpos($path,$special) === 0)
+ $path = trim(substr($path,$count),'/');
$output .= replace_macros(get_markup_template('cloud_actionspanel.tpl'), array(
'$folder_header' => t('Create new folder'),
diff --git a/Zotlabs/Web/HTTPHeaders.php b/Zotlabs/Web/HTTPHeaders.php
new file mode 100644
index 000000000..1e4c1bf84
--- /dev/null
+++ b/Zotlabs/Web/HTTPHeaders.php
@@ -0,0 +1,46 @@
+<?php
+
+namespace Zotlabs\Web;
+
+class HTTPHeaders {
+
+ private $in_progress = [];
+ private $parsed = [];
+
+
+ function __construct($headers) {
+
+ $lines = explode("\n",str_replace("\r",'',$headers));
+ if($lines) {
+ foreach($lines as $line) {
+ if(preg_match('/^\s+/',$line,$matches) && trim($line)) {
+ if($this->in_progress['k']) {
+ $this->in_progress['v'] .= ' ' . ltrim($line);
+ continue;
+ }
+ }
+ else {
+ if($this->in_progress['k']) {
+ $this->parsed[] = [ $this->in_progress['k'] => $this->in_progress['v'] ];
+ $this->in_progress = [];
+ }
+
+ $this->in_progress['k'] = strtolower(substr($line,0,strpos($line,':')));
+ $this->in_progress['v'] = ltrim(substr($line,strpos($line,':') + 1));
+ }
+
+ }
+ if($this->in_progress['k']) {
+ $this->parsed[] = [ $this->in_progress['k'] => $this->in_progress['v'] ];
+ $this->in_progress = [];
+ }
+ }
+ }
+
+ function fetch() {
+ return $this->parsed;
+ }
+}
+
+
+
diff --git a/Zotlabs/Web/Router.php b/Zotlabs/Web/Router.php
index 271836ba9..ba2e78b25 100644
--- a/Zotlabs/Web/Router.php
+++ b/Zotlabs/Web/Router.php
@@ -121,29 +121,24 @@ class Router {
/*
* The URL provided does not resolve to a valid module.
- *
- * On Dreamhost sites, quite often things go wrong for no apparent reason and they send us to '/internal_error.html'.
- * We don't like doing this, but as it occasionally accounts for 10-20% or more of all site traffic -
- * we are going to trap this and redirect back to the requested page. As long as you don't have a critical error on your page
- * this will often succeed and eventually do the right thing.
- *
- * Otherwise we are going to emit a 404 not found.
*/
if(! (\App::$module_loaded)) {
- // Stupid browser tried to pre-fetch our Javascript img template. Don't log the event or return anything - just quietly exit.
+ $x = [
+ 'module' => $module,
+ 'installed' => \App::$module_loaded,
+ 'controller' => $this->controller
+ ];
+ call_hooks('page_not_found',$x);
+
+ // Stupid browser tried to pre-fetch our Javascript img template.
+ // Don't log the event or return anything - just quietly exit.
+
if((x($_SERVER, 'QUERY_STRING')) && preg_match('/{[0-9]}/', $_SERVER['QUERY_STRING']) !== 0) {
killme();
}
- if((x($_SERVER, 'QUERY_STRING'))
- && ($_SERVER['QUERY_STRING'] === 'q=internal_error.html')
- && \App::$config['system']['dreamhost_error_hack']) {
- logger('index.php: dreamhost_error_hack invoked. Original URI =' . $_SERVER['REQUEST_URI'],LOGGER_DEBUG);
- goaway(z_root() . $_SERVER['REQUEST_URI']);
- }
-
if(get_config('system','log_404',true)) {
logger("Module {$module} not found.", LOGGER_DEBUG, LOG_WARNING);
logger('index.php: page not found: ' . $_SERVER['REQUEST_URI']