aboutsummaryrefslogtreecommitdiffstats
path: root/Zotlabs
diff options
context:
space:
mode:
Diffstat (limited to 'Zotlabs')
-rw-r--r--Zotlabs/Daemon/Checksites.php55
-rw-r--r--Zotlabs/Daemon/Cli_suggest.php14
-rw-r--r--Zotlabs/Daemon/Cron.php181
-rw-r--r--Zotlabs/Daemon/Cron_daily.php90
-rw-r--r--Zotlabs/Daemon/Cron_weekly.php49
-rw-r--r--Zotlabs/Daemon/Cronhooks.php17
-rw-r--r--Zotlabs/Daemon/Deliver.php85
-rw-r--r--Zotlabs/Daemon/Deliver_hooks.php24
-rw-r--r--Zotlabs/Daemon/Directory.php100
-rw-r--r--Zotlabs/Daemon/Expire.php93
-rw-r--r--Zotlabs/Daemon/Externals.php98
-rw-r--r--Zotlabs/Daemon/Gprobe.php33
-rwxr-xr-xZotlabs/Daemon/Importdoc.php35
-rw-r--r--Zotlabs/Daemon/Master.php31
-rw-r--r--Zotlabs/Daemon/Notifier.php663
-rw-r--r--Zotlabs/Daemon/Onedirsync.php76
-rw-r--r--Zotlabs/Daemon/Onepoll.php152
-rw-r--r--Zotlabs/Daemon/Poller.php202
-rw-r--r--Zotlabs/Daemon/Queue.php90
-rw-r--r--Zotlabs/Daemon/Ratenotif.php113
-rw-r--r--Zotlabs/Extend/Hook.php8
-rw-r--r--Zotlabs/Lib/AConfig.php25
-rw-r--r--Zotlabs/Lib/AbConfig.php73
-rw-r--r--Zotlabs/Lib/Apps.php708
-rw-r--r--Zotlabs/Lib/Chatroom.php267
-rw-r--r--Zotlabs/Lib/Config.php166
-rw-r--r--Zotlabs/Lib/Enotify.php685
-rw-r--r--Zotlabs/Lib/IConfig.php165
-rw-r--r--Zotlabs/Lib/PConfig.php189
-rw-r--r--Zotlabs/Lib/ProtoDriver.php19
-rw-r--r--Zotlabs/Lib/System.php (renamed from Zotlabs/Project/System.php)6
-rw-r--r--Zotlabs/Lib/ThreadItem.php780
-rw-r--r--Zotlabs/Lib/ThreadStream.php220
-rw-r--r--Zotlabs/Lib/XConfig.php160
-rw-r--r--Zotlabs/Lib/ZotDriver.php30
-rw-r--r--Zotlabs/Module/Acl.php34
-rw-r--r--Zotlabs/Module/Admin.php168
-rw-r--r--Zotlabs/Module/Api.php2
-rw-r--r--Zotlabs/Module/Appman.php17
-rw-r--r--Zotlabs/Module/Apps.php17
-rw-r--r--Zotlabs/Module/Attach.php4
-rw-r--r--Zotlabs/Module/Blocks.php2
-rw-r--r--Zotlabs/Module/Cal.php31
-rw-r--r--Zotlabs/Module/Channel.php550
-rw-r--r--Zotlabs/Module/Chanview.php11
-rw-r--r--Zotlabs/Module/Chat.php24
-rw-r--r--Zotlabs/Module/Chatsvc.php12
-rw-r--r--Zotlabs/Module/Cloud.php5
-rw-r--r--Zotlabs/Module/Connect.php5
-rw-r--r--Zotlabs/Module/Connections.php4
-rw-r--r--Zotlabs/Module/Connedit.php19
-rw-r--r--Zotlabs/Module/Contactgroup.php4
-rw-r--r--Zotlabs/Module/Cover_photo.php46
-rw-r--r--Zotlabs/Module/Dav.php1
-rw-r--r--Zotlabs/Module/Directory.php4
-rw-r--r--Zotlabs/Module/Display.php10
-rw-r--r--Zotlabs/Module/Editblock.php2
-rw-r--r--Zotlabs/Module/Editlayout.php2
-rw-r--r--Zotlabs/Module/Editpost.php4
-rw-r--r--Zotlabs/Module/Editwebpage.php2
-rw-r--r--Zotlabs/Module/Events.php46
-rw-r--r--Zotlabs/Module/Fbrowser.php4
-rw-r--r--Zotlabs/Module/Feed.php2
-rw-r--r--Zotlabs/Module/Filer.php2
-rw-r--r--Zotlabs/Module/Filerm.php2
-rw-r--r--Zotlabs/Module/Follow.php5
-rw-r--r--Zotlabs/Module/Fsuggest.php117
-rw-r--r--Zotlabs/Module/Getfile.php1
-rw-r--r--Zotlabs/Module/Group.php14
-rw-r--r--Zotlabs/Module/Help.php2
-rw-r--r--Zotlabs/Module/Import.php14
-rw-r--r--Zotlabs/Module/Item.php20
-rw-r--r--Zotlabs/Module/Layouts.php2
-rw-r--r--Zotlabs/Module/Like.php6
-rw-r--r--Zotlabs/Module/Linkinfo.php2
-rw-r--r--Zotlabs/Module/Lockview.php8
-rw-r--r--Zotlabs/Module/Locs.php6
-rw-r--r--Zotlabs/Module/Magic.php8
-rw-r--r--Zotlabs/Module/Mail.php16
-rw-r--r--Zotlabs/Module/Manage.php10
-rw-r--r--Zotlabs/Module/Menu.php2
-rw-r--r--Zotlabs/Module/Message.php2
-rw-r--r--Zotlabs/Module/Mood.php2
-rw-r--r--Zotlabs/Module/Network.php4
-rw-r--r--Zotlabs/Module/New_channel.php2
-rw-r--r--Zotlabs/Module/Notifications.php6
-rw-r--r--Zotlabs/Module/Notify.php4
-rw-r--r--Zotlabs/Module/Oep.php20
-rw-r--r--Zotlabs/Module/Photo.php18
-rw-r--r--Zotlabs/Module/Photos.php87
-rw-r--r--Zotlabs/Module/Ping.php43
-rw-r--r--Zotlabs/Module/Poke.php2
-rw-r--r--Zotlabs/Module/Prate.php2
-rw-r--r--Zotlabs/Module/Probe.php16
-rw-r--r--Zotlabs/Module/Profile.php4
-rw-r--r--Zotlabs/Module/Profile_photo.php50
-rw-r--r--Zotlabs/Module/Profiles.php49
-rw-r--r--Zotlabs/Module/Profperm.php2
-rw-r--r--Zotlabs/Module/Pubsites.php7
-rw-r--r--Zotlabs/Module/Pubstream.php4
-rw-r--r--Zotlabs/Module/Randprof.php1
-rw-r--r--Zotlabs/Module/Rate.php6
-rw-r--r--Zotlabs/Module/Ratings.php6
-rw-r--r--Zotlabs/Module/React.php51
-rw-r--r--Zotlabs/Module/Regdir.php13
-rw-r--r--Zotlabs/Module/Register.php2
-rw-r--r--Zotlabs/Module/Removeaccount.php11
-rw-r--r--Zotlabs/Module/Removeme.php5
-rw-r--r--Zotlabs/Module/Rmagic.php8
-rw-r--r--Zotlabs/Module/Rsd_xml.php2
-rw-r--r--Zotlabs/Module/Search.php4
-rw-r--r--Zotlabs/Module/Search_ac.php2
-rw-r--r--Zotlabs/Module/Settings.php26
-rw-r--r--Zotlabs/Module/Setup.php73
-rw-r--r--Zotlabs/Module/Share.php2
-rw-r--r--Zotlabs/Module/Sharedwithme.php4
-rw-r--r--Zotlabs/Module/Siteinfo.php4
-rw-r--r--Zotlabs/Module/Subthread.php2
-rw-r--r--Zotlabs/Module/Tagger.php4
-rw-r--r--Zotlabs/Module/Tagrm.php2
-rw-r--r--Zotlabs/Module/Tasks.php20
-rw-r--r--Zotlabs/Module/Thing.php8
-rw-r--r--Zotlabs/Module/Uexport.php2
-rw-r--r--Zotlabs/Module/Viewconnections.php9
-rw-r--r--Zotlabs/Module/Wall_attach.php2
-rw-r--r--Zotlabs/Module/Wall_upload.php2
-rw-r--r--Zotlabs/Module/Webpages.php2
-rw-r--r--Zotlabs/Module/Wiki.php424
-rw-r--r--Zotlabs/Module/Zotfeed.php4
-rw-r--r--Zotlabs/Render/Comanche.php7
-rwxr-xr-xZotlabs/Render/SimpleTemplate.php310
-rwxr-xr-xZotlabs/Render/SmartyInterface.php48
-rwxr-xr-xZotlabs/Render/SmartyTemplate.php75
-rwxr-xr-xZotlabs/Render/TemplateEngine.php12
-rw-r--r--Zotlabs/Render/Theme.php131
-rw-r--r--Zotlabs/Storage/BasicAuth.php25
-rw-r--r--Zotlabs/Storage/Browser.php9
-rw-r--r--Zotlabs/Storage/Directory.php12
-rw-r--r--Zotlabs/Storage/File.php14
-rw-r--r--Zotlabs/Storage/GitRepo.php18
-rw-r--r--Zotlabs/Web/Router.php8
-rw-r--r--Zotlabs/Web/Session.php48
-rw-r--r--Zotlabs/Web/SessionHandler.php6
-rw-r--r--Zotlabs/Web/WebServer.php130
-rw-r--r--Zotlabs/Zot/Auth.php8
-rw-r--r--Zotlabs/Zot/Finger.php130
-rw-r--r--Zotlabs/Zot/Verify.php6
147 files changed, 7951 insertions, 1042 deletions
diff --git a/Zotlabs/Daemon/Checksites.php b/Zotlabs/Daemon/Checksites.php
new file mode 100644
index 000000000..991456319
--- /dev/null
+++ b/Zotlabs/Daemon/Checksites.php
@@ -0,0 +1,55 @@
+<?php /** @file */
+
+namespace Zotlabs\Daemon;
+
+require_once('include/zot.php');
+require_once('include/hubloc.php');
+
+
+class Checksites {
+
+ static public function run($argc,$argv) {
+
+ logger('checksites: start');
+
+ if(($argc > 1) && ($argv[1]))
+ $site_id = $argv[1];
+
+ if($site_id)
+ $sql_options = " and site_url = '" . dbesc($argv[1]) . "' ";
+
+ $days = intval(get_config('system','sitecheckdays'));
+ if($days < 1)
+ $days = 30;
+
+ $r = q("select * from site where site_dead = 0 and site_update < %s - INTERVAL %s and site_type = %d $sql_options ",
+ db_utcnow(), db_quoteinterval($days . ' DAY'),
+ intval(SITE_TYPE_ZOT)
+ );
+
+ if(! $r)
+ return;
+
+ foreach($r as $rr) {
+ if(! strcasecmp($rr['site_url'],z_root()))
+ continue;
+
+ $x = ping_site($rr['site_url']);
+ if($x['success']) {
+ logger('checksites: ' . $rr['site_url']);
+ q("update site set site_update = '%s' where site_url = '%s' ",
+ dbesc(datetime_convert()),
+ dbesc($rr['site_url'])
+ );
+ }
+ else {
+ logger('marking dead site: ' . $x['message']);
+ q("update site set site_dead = 1 where site_url = '%s' ",
+ dbesc($rr['site_url'])
+ );
+ }
+ }
+
+ return;
+ }
+}
diff --git a/Zotlabs/Daemon/Cli_suggest.php b/Zotlabs/Daemon/Cli_suggest.php
new file mode 100644
index 000000000..5dced462d
--- /dev/null
+++ b/Zotlabs/Daemon/Cli_suggest.php
@@ -0,0 +1,14 @@
+<?php /** @file */
+
+namespace Zotlabs\Daemon;
+
+require_once('include/socgraph.php');
+
+class Cli_suggest {
+
+ static public function run($argc,$argv) {
+
+ update_suggestions();
+
+ }
+}
diff --git a/Zotlabs/Daemon/Cron.php b/Zotlabs/Daemon/Cron.php
new file mode 100644
index 000000000..f23cb14dc
--- /dev/null
+++ b/Zotlabs/Daemon/Cron.php
@@ -0,0 +1,181 @@
+<?php /** @file */
+
+namespace Zotlabs\Daemon;
+
+class Cron {
+
+ static public function run($argc,$argv) {
+
+ $maxsysload = intval(get_config('system','maxloadavg'));
+ if($maxsysload < 1)
+ $maxsysload = 50;
+ if(function_exists('sys_getloadavg')) {
+ $load = sys_getloadavg();
+ if(intval($load[0]) > $maxsysload) {
+ logger('system: load ' . $load . ' too high. Cron deferred to next scheduled run.');
+ return;
+ }
+ }
+
+ // Check for a lockfile. If it exists, but is over an hour old, it's stale. Ignore it.
+ $lockfile = 'store/[data]/cron';
+ if((file_exists($lockfile)) && (filemtime($lockfile) > (time() - 3600))
+ && (! get_config('system','override_cron_lockfile'))) {
+ logger("cron: Already running");
+ return;
+ }
+
+ // Create a lockfile. Needs two vars, but $x doesn't need to contain anything.
+ file_put_contents($lockfile, $x);
+
+ logger('cron: start');
+
+ // run queue delivery process in the background
+
+ Master::Summon(array('Queue'));
+
+ Master::Summon(array('Poller'));
+
+ // maintenance for mod sharedwithme - check for updated items and remove them
+
+ require_once('include/sharedwithme.php');
+ apply_updates();
+
+
+ // expire any expired mail
+
+ q("delete from mail where expires != '%s' and expires < %s ",
+ dbesc(NULL_DATE),
+ db_utcnow()
+ );
+
+ // expire any expired items
+
+ $r = q("select id from item where expires != '%s' and expires < %s
+ and item_deleted = 0 ",
+ dbesc(NULL_DATE),
+ db_utcnow()
+ );
+ if($r) {
+ require_once('include/items.php');
+ foreach($r as $rr)
+ drop_item($rr['id'],false);
+ }
+
+
+ // Ensure that every channel pings a directory server once a month. This way we can discover
+ // channels and sites that quietly vanished and prevent the directory from accumulating stale
+ // or dead entries.
+
+ $r = q("select channel_id from channel where channel_dirdate < %s - INTERVAL %s",
+ db_utcnow(),
+ db_quoteinterval('30 DAY')
+ );
+ if($r) {
+ foreach($r as $rr) {
+ Master::Summon(array('Directory',$rr['channel_id'],'force'));
+ if($interval)
+ @time_sleep_until(microtime(true) + (float) $interval);
+ }
+ }
+
+ // publish any applicable items that were set to be published in the future
+ // (time travel posts). Restrict to items that have come of age in the last
+ // couple of days to limit the query to something reasonable.
+
+ $r = q("select id from item where item_delayed = 1 and created <= %s and created > '%s' ",
+ db_utcnow(),
+ dbesc(datetime_convert('UTC','UTC','now - 2 days'))
+ );
+ if($r) {
+ foreach($r as $rr) {
+ $x = q("update item set item_delayed = 0 where id = %d",
+ intval($rr['id'])
+ );
+ if($x) {
+ Master::Summon(array('Notifier','wall-new',$rr['id']));
+ }
+ }
+ }
+
+ $abandon_days = intval(get_config('system','account_abandon_days'));
+ if($abandon_days < 1)
+ $abandon_days = 0;
+
+
+ // once daily run birthday_updates and then expire in background
+
+ // FIXME: add birthday updates, both locally and for xprof for use
+ // by directory servers
+
+ $d1 = intval(get_config('system','last_expire_day'));
+ $d2 = intval(datetime_convert('UTC','UTC','now','d'));
+
+ // Allow somebody to staggger daily activities if they have more than one site on their server,
+ // or if it happens at an inconvenient (busy) hour.
+
+ $h1 = intval(get_config('system','cron_hour'));
+ $h2 = intval(datetime_convert('UTC','UTC','now','G'));
+
+
+ if(($d2 != $d1) && ($h1 == $h2)) {
+ Master::Summon(array('Cron_daily'));
+ }
+
+ // update any photos which didn't get imported properly
+ // This should be rare
+
+ $r = q("select xchan_photo_l, xchan_hash from xchan where xchan_photo_l != '' and xchan_photo_m = ''
+ and xchan_photo_date < %s - INTERVAL %s",
+ db_utcnow(),
+ db_quoteinterval('1 DAY')
+ );
+ if($r) {
+ require_once('include/photo/photo_driver.php');
+ foreach($r as $rr) {
+ $photos = import_xchan_photo($rr['xchan_photo_l'],$rr['xchan_hash']);
+ $x = q("update xchan set xchan_photo_l = '%s', xchan_photo_m = '%s', xchan_photo_s = '%s', xchan_photo_mimetype = '%s'
+ where xchan_hash = '%s'",
+ dbesc($photos[0]),
+ dbesc($photos[1]),
+ dbesc($photos[2]),
+ dbesc($photos[3]),
+ dbesc($rr['xchan_hash'])
+ );
+ }
+ }
+
+
+ // pull in some public posts
+
+ if(! get_config('system','disable_discover_tab'))
+ Master::Summon(array('Externals'));
+
+ $generation = 0;
+
+ $restart = false;
+
+ if(($argc > 1) && ($argv[1] == 'restart')) {
+ $restart = true;
+ $generation = intval($argv[2]);
+ if(! $generation)
+ killme();
+ }
+
+ reload_plugins();
+
+ $d = datetime_convert();
+
+ // TODO check to see if there are any cronhooks before wasting a process
+
+ if(! $restart)
+ Master::Summon(array('Cronhooks'));
+
+ set_config('system','lastcron',datetime_convert());
+
+ //All done - clear the lockfile
+ @unlink($lockfile);
+
+ return;
+ }
+}
diff --git a/Zotlabs/Daemon/Cron_daily.php b/Zotlabs/Daemon/Cron_daily.php
new file mode 100644
index 000000000..a16d49853
--- /dev/null
+++ b/Zotlabs/Daemon/Cron_daily.php
@@ -0,0 +1,90 @@
+<?php /** @file */
+
+namespace Zotlabs\Daemon;
+
+class Cron_daily {
+
+ static public function run($argc,$argv) {
+
+ logger('cron_daily: start');
+
+ /**
+ * Cron Daily
+ *
+ */
+
+
+ require_once('include/dir_fns.php');
+ check_upstream_directory();
+
+
+ // Fire off the Cron_weekly process if it's the correct day.
+
+ $d3 = intval(datetime_convert('UTC','UTC','now','N'));
+ if($d3 == 7) {
+ Master::Summon(array('Cron_weekly'));
+ }
+
+ // once daily run birthday_updates and then expire in background
+
+ // FIXME: add birthday updates, both locally and for xprof for use
+ // by directory servers
+
+ update_birthdays();
+
+ // expire any read notifications over a month old
+
+ q("delete from notify where seen = 1 and created < %s - INTERVAL %s",
+ db_utcnow(), db_quoteinterval('30 DAY')
+ );
+
+ //update statistics in config
+ require_once('include/statistics_fns.php');
+ update_channels_total_stat();
+ update_channels_active_halfyear_stat();
+ update_channels_active_monthly_stat();
+ update_local_posts_stat();
+
+
+ // expire old delivery reports
+
+ $keep_reports = intval(get_config('system','expire_delivery_reports'));
+ if($keep_reports === 0)
+ $keep_reports = 10;
+
+ q("delete from dreport where dreport_time < %s - INTERVAL %s",
+ db_utcnow(),
+ db_quoteinterval($keep_reports . ' DAY')
+ );
+
+ // expire any expired accounts
+ downgrade_accounts();
+
+ // If this is a directory server, request a sync with an upstream
+ // directory at least once a day, up to once every poll interval.
+ // Pull remote changes and push local changes.
+ // potential issue: how do we keep from creating an endless update loop?
+
+ $dirmode = get_config('system','directory_mode');
+
+ if($dirmode == DIRECTORY_MODE_SECONDARY || $dirmode == DIRECTORY_MODE_PRIMARY) {
+ require_once('include/dir_fns.php');
+ sync_directories($dirmode);
+ }
+
+
+ Master::Summon(array('Expire'));
+ Master::Summon(array('Cli_suggest'));
+
+ require_once('include/hubloc.php');
+ remove_obsolete_hublocs();
+
+ call_hooks('cron_daily',datetime_convert());
+
+ set_config('system','last_expire_day',$d2);
+
+ /**
+ * End Cron Daily
+ */
+ }
+}
diff --git a/Zotlabs/Daemon/Cron_weekly.php b/Zotlabs/Daemon/Cron_weekly.php
new file mode 100644
index 000000000..1d8420947
--- /dev/null
+++ b/Zotlabs/Daemon/Cron_weekly.php
@@ -0,0 +1,49 @@
+<?php
+
+namespace Zotlabs\Daemon;
+
+class Cron_weekly {
+
+ static public function run($argc,$argv) {
+
+ /**
+ * Cron Weekly
+ *
+ * Actions in the following block are executed once per day only on Sunday (once per week).
+ *
+ */
+
+ call_hooks('cron_weekly',datetime_convert());
+
+
+ z_check_cert();
+
+ require_once('include/hubloc.php');
+ prune_hub_reinstalls();
+
+ mark_orphan_hubsxchans();
+
+
+ // get rid of really old poco records
+
+ q("delete from xlink where xlink_updated < %s - INTERVAL %s and xlink_static = 0 ",
+ db_utcnow(), db_quoteinterval('14 DAY')
+ );
+
+ $dirmode = intval(get_config('system','directory_mode'));
+ if($dirmode === DIRECTORY_MODE_SECONDARY || $dirmode === DIRECTORY_MODE_PRIMARY) {
+ logger('regdir: ' . print_r(z_fetch_url(get_directory_primary() . '/regdir?f=&url=' . urlencode(z_root()) . '&realm=' . urlencode(get_directory_realm())),true));
+ }
+
+ // Check for dead sites
+ Master::Summon(array('Checksites'));
+
+ // update searchable doc indexes
+ Master::Summon(array('Importdoc'));
+
+ /**
+ * End Cron Weekly
+ */
+
+ }
+} \ No newline at end of file
diff --git a/Zotlabs/Daemon/Cronhooks.php b/Zotlabs/Daemon/Cronhooks.php
new file mode 100644
index 000000000..df0a5442e
--- /dev/null
+++ b/Zotlabs/Daemon/Cronhooks.php
@@ -0,0 +1,17 @@
+<?php /** @file */
+
+namespace Zotlabs\Daemon;
+
+class Cronhooks {
+
+ static public function run($argc,$argv){
+
+ logger('cronhooks: start');
+
+ $d = datetime_convert();
+
+ call_hooks('cron', $d);
+
+ return;
+ }
+}
diff --git a/Zotlabs/Daemon/Deliver.php b/Zotlabs/Daemon/Deliver.php
new file mode 100644
index 000000000..dbc311cf5
--- /dev/null
+++ b/Zotlabs/Daemon/Deliver.php
@@ -0,0 +1,85 @@
+<?php /** @file */
+
+namespace Zotlabs\Daemon;
+
+require_once('include/zot.php');
+require_once('include/queue_fn.php');
+
+
+class Deliver {
+
+ static public function run($argc,$argv) {
+
+ if($argc < 2)
+ return;
+
+ logger('deliver: invoked: ' . print_r($argv,true), LOGGER_DATA);
+
+ for($x = 1; $x < $argc; $x ++) {
+
+ if(! $argv[$x])
+ continue;
+
+ $dresult = null;
+ $r = q("select * from outq where outq_hash = '%s' limit 1",
+ dbesc($argv[$x])
+ );
+ if($r) {
+
+ $notify = json_decode($r[0]['outq_notify'],true);
+
+ // Messages without an outq_msg will need to go via the web, even if it's a
+ // local delivery. This includes conversation requests and refresh packets.
+
+ if(($r[0]['outq_posturl'] === z_root() . '/post') && ($r[0]['outq_msg'])) {
+ logger('deliver: local delivery', LOGGER_DEBUG);
+
+ // local delivery
+ // we should probably batch these and save a few delivery processes
+
+ if($r[0]['outq_msg']) {
+ $m = json_decode($r[0]['outq_msg'],true);
+ if(array_key_exists('message_list',$m)) {
+ foreach($m['message_list'] as $mm) {
+ $msg = array('body' => json_encode(array('success' => true, 'pickup' => array(array('notify' => $notify,'message' => $mm)))));
+ zot_import($msg,z_root());
+ }
+ }
+ else {
+ $msg = array('body' => json_encode(array('success' => true, 'pickup' => array(array('notify' => $notify,'message' => $m)))));
+ $dresult = zot_import($msg,z_root());
+ }
+
+ remove_queue_item($r[0]['outq_hash']);
+
+ if($dresult && is_array($dresult)) {
+ foreach($dresult as $xx) {
+ if(is_array($xx) && array_key_exists('message_id',$xx)) {
+ if(delivery_report_is_storable($xx)) {
+ q("insert into dreport ( dreport_mid, dreport_site, dreport_recip, dreport_result, dreport_time, dreport_xchan ) values ( '%s', '%s','%s','%s','%s','%s' ) ",
+ dbesc($xx['message_id']),
+ dbesc($xx['location']),
+ dbesc($xx['recipient']),
+ dbesc($xx['status']),
+ dbesc(datetime_convert($xx['date'])),
+ dbesc($xx['sender'])
+ );
+ }
+ }
+ }
+ }
+
+ q("delete from dreport where dreport_queue = '%s'",
+ dbesc($argv[$x])
+ );
+ }
+ }
+
+ // otherwise it's a remote delivery - call queue_deliver() with the $immediate flag
+
+ queue_deliver($r[0],true);
+
+ }
+ }
+ }
+}
diff --git a/Zotlabs/Daemon/Deliver_hooks.php b/Zotlabs/Daemon/Deliver_hooks.php
new file mode 100644
index 000000000..e8b5acef0
--- /dev/null
+++ b/Zotlabs/Daemon/Deliver_hooks.php
@@ -0,0 +1,24 @@
+<?php
+
+namespace Zotlabs\Daemon;
+
+require_once('include/zot.php');
+
+class Deliver_hooks {
+
+ static public function run($argc,$argv) {
+
+ if($argc < 2)
+ return;
+
+
+ $r = q("select * from item where id = '%d'",
+ intval($argv[1])
+ );
+ if($r)
+ call_hooks('notifier_normal',$r[0]);
+
+ }
+}
+
+
diff --git a/Zotlabs/Daemon/Directory.php b/Zotlabs/Daemon/Directory.php
new file mode 100644
index 000000000..c8cdafdf5
--- /dev/null
+++ b/Zotlabs/Daemon/Directory.php
@@ -0,0 +1,100 @@
+<?php
+
+namespace Zotlabs\Daemon;
+
+require_once('include/zot.php');
+require_once('include/dir_fns.php');
+require_once('include/queue_fn.php');
+
+
+class Directory {
+
+ static public function run($argc,$argv){
+
+ if($argc < 2)
+ return;
+
+ $force = false;
+ $pushall = true;
+
+ if($argc > 2) {
+ if($argv[2] === 'force')
+ $force = true;
+ if($argv[2] === 'nopush')
+ $pushall = false;
+ }
+
+ logger('directory update', LOGGER_DEBUG);
+
+ $dirmode = get_config('system','directory_mode');
+ if($dirmode === false)
+ $dirmode = DIRECTORY_MODE_NORMAL;
+
+ $x = q("select * from channel where channel_id = %d limit 1",
+ intval($argv[1])
+ );
+ if(! $x)
+ return;
+
+ $channel = $x[0];
+
+ if($dirmode != DIRECTORY_MODE_NORMAL) {
+
+ // this is an in-memory update and we don't need to send a network packet.
+
+ local_dir_update($argv[1],$force);
+
+ q("update channel set channel_dirdate = '%s' where channel_id = %d",
+ dbesc(datetime_convert()),
+ intval($channel['channel_id'])
+ );
+
+ // Now update all the connections
+ if($pushall)
+ Master::Summon(array('Notifier','refresh_all',$channel['channel_id']));
+
+ return;
+ }
+
+ // otherwise send the changes upstream
+
+ $directory = find_upstream_directory($dirmode);
+ $url = $directory['url'] . '/post';
+
+ // ensure the upstream directory is updated
+
+ $packet = zot_build_packet($channel,(($force) ? 'force_refresh' : 'refresh'));
+ $z = zot_zot($url,$packet);
+
+ // re-queue if unsuccessful
+
+ if(! $z['success']) {
+
+ /** @FIXME we aren't updating channel_dirdate if we have to queue
+ * the directory packet. That means we'll try again on the next poll run.
+ */
+
+ $hash = random_string();
+
+ queue_insert(array(
+ 'hash' => $hash,
+ 'account_id' => $channel['channel_account_id'],
+ 'channel_id' => $channel['channel_id'],
+ 'posturl' => $url,
+ 'notify' => $packet,
+ ));
+
+ }
+ else {
+ q("update channel set channel_dirdate = '%s' where channel_id = %d",
+ dbesc(datetime_convert()),
+ intval($channel['channel_id'])
+ );
+ }
+
+ // Now update all the connections
+ if($pushall)
+ Master::Summon(array('Notifier','refresh_all',$channel['channel_id']));
+
+ }
+}
diff --git a/Zotlabs/Daemon/Expire.php b/Zotlabs/Daemon/Expire.php
new file mode 100644
index 000000000..0ba83b240
--- /dev/null
+++ b/Zotlabs/Daemon/Expire.php
@@ -0,0 +1,93 @@
+<?php
+
+namespace Zotlabs\Daemon;
+
+
+class Expire {
+
+ static public function run($argc,$argv){
+
+ cli_startup();
+
+ // perform final cleanup on previously delete items
+
+ $r = q("select id from item where item_deleted = 1 and item_pending_remove = 0 and changed < %s - INTERVAL %s",
+ db_utcnow(), db_quoteinterval('10 DAY')
+ );
+ if ($r) {
+ foreach ($r as $rr) {
+ drop_item($rr['id'], false, DROPITEM_PHASE2);
+ }
+ }
+
+ // physically remove anything that has been deleted for more than two months
+ /** @FIXME - this is a wretchedly inefficient query */
+
+ $r = q("delete from item where item_pending_remove = 1 and changed < %s - INTERVAL %s",
+ db_utcnow(), db_quoteinterval('36 DAY')
+ );
+
+ /** @FIXME make this optional as it could have a performance impact on large sites */
+
+ if (intval(get_config('system', 'optimize_items')))
+ q("optimize table item");
+
+ logger('expire: start', LOGGER_DEBUG);
+
+ $site_expire = get_config('system', 'default_expire_days');
+
+ logger('site_expire: ' . $site_expire);
+
+ $r = q("SELECT channel_id, channel_address, channel_pageflags, channel_expire_days from channel where true");
+
+ if ($r) {
+ foreach ($r as $rr) {
+
+ // expire the sys channel separately
+ if (intval($rr['channel_system']))
+ continue;
+
+ // service class default (if non-zero) over-rides the site default
+
+ $service_class_expire = service_class_fetch($rr['channel_id'], 'expire_days');
+ if (intval($service_class_expire))
+ $channel_expire = $service_class_expire;
+ else
+ $channel_expire = $site_expire;
+
+ if (intval($channel_expire) && (intval($channel_expire) < intval($rr['channel_expire_days'])) ||
+ intval($rr['channel_expire_days'] == 0)) {
+ $expire_days = $channel_expire;
+ } else {
+ $expire_days = $rr['channel_expire_days'];
+ }
+
+ // if the site or service class expiration is non-zero and less than person expiration, use that
+ logger('Expire: ' . $rr['channel_address'] . ' interval: ' . $expire_days, LOGGER_DEBUG);
+ item_expire($rr['channel_id'], $expire_days);
+ }
+ }
+
+ $x = get_sys_channel();
+ if ($x) {
+
+ // this should probably just fetch the channel_expire_days from the sys channel,
+ // but there's no convenient way to set it.
+
+ $expire_days = get_config('system', 'sys_expire_days');
+ if ($expire_days === false)
+ $expire_days = 30;
+
+ if (intval($site_expire) && (intval($site_expire) < intval($expire_days))) {
+ $expire_days = $site_expire;
+ }
+
+ logger('Expire: sys interval: ' . $expire_days, LOGGER_DEBUG);
+
+ if ($expire_days)
+ item_expire($x['channel_id'], $expire_days);
+
+ logger('Expire: sys: done', LOGGER_DEBUG);
+ }
+ }
+}
diff --git a/Zotlabs/Daemon/Externals.php b/Zotlabs/Daemon/Externals.php
new file mode 100644
index 000000000..24cfe64ec
--- /dev/null
+++ b/Zotlabs/Daemon/Externals.php
@@ -0,0 +1,98 @@
+<?php /** @file */
+
+namespace Zotlabs\Daemon;
+
+require_once('include/zot.php');
+require_once('include/channel.php');
+
+
+class Externals {
+
+ static public function run($argc,$argv){
+
+ $total = 0;
+ $attempts = 0;
+
+ logger('externals: startup', LOGGER_DEBUG);
+
+ // pull in some public posts
+
+
+ while($total == 0 && $attempts < 3) {
+ $arr = array('url' => '');
+ call_hooks('externals_url_select',$arr);
+
+ if($arr['url']) {
+ $url = $arr['url'];
+ }
+ else {
+ $randfunc = db_getfunc('RAND');
+
+ // fixme this query does not deal with directory realms.
+
+ $r = q("select site_url, site_pull from site where site_url != '%s' and site_flags != %d and site_type = %d and site_dead = 0 order by $randfunc limit 1",
+ dbesc(z_root()),
+ intval(DIRECTORY_MODE_STANDALONE),
+ intval(SITE_TYPE_ZOT)
+ );
+ if($r)
+ $url = $r[0]['site_url'];
+ }
+
+ $blacklisted = false;
+
+ if(! check_siteallowed($url)) {
+ logger('blacklisted site: ' . $url);
+ $blacklisted = true;
+ }
+
+ $attempts ++;
+
+ // make sure we can eventually break out if somebody blacklists all known sites
+
+ if($blacklisted) {
+ if($attempts > 20)
+ break;
+ $attempts --;
+ continue;
+ }
+
+ if($url) {
+ if($r[0]['site_pull'] !== NULL_DATE)
+ $mindate = urlencode(datetime_convert('','',$r[0]['site_pull'] . ' - 1 day'));
+ else {
+ $days = get_config('externals','since_days');
+ if($days === false)
+ $days = 15;
+ $mindate = urlencode(datetime_convert('','','now - ' . intval($days) . ' days'));
+ }
+
+ $feedurl = $url . '/zotfeed?f=&mindate=' . $mindate;
+
+ logger('externals: pulling public content from ' . $feedurl, LOGGER_DEBUG);
+
+ $x = z_fetch_url($feedurl);
+ if(($x) && ($x['success'])) {
+
+ q("update site set site_pull = '%s' where site_url = '%s'",
+ dbesc(datetime_convert()),
+ dbesc($url)
+ );
+
+ $j = json_decode($x['body'],true);
+ if($j['success'] && $j['messages']) {
+ $sys = get_sys_channel();
+ foreach($j['messages'] as $message) {
+ // on these posts, clear any route info.
+ $message['route'] = '';
+ $results = process_delivery(array('hash' => 'undefined'), get_item_elements($message),
+ array(array('hash' => $sys['xchan_hash'])), false, true);
+ $total ++;
+ }
+ logger('externals: import_public_posts: ' . $total . ' messages imported', LOGGER_DEBUG);
+ }
+ }
+ }
+ }
+ }
+}
diff --git a/Zotlabs/Daemon/Gprobe.php b/Zotlabs/Daemon/Gprobe.php
new file mode 100644
index 000000000..43cce93c3
--- /dev/null
+++ b/Zotlabs/Daemon/Gprobe.php
@@ -0,0 +1,33 @@
+<?php /** @file */
+
+namespace Zotlabs\Daemon;
+
+require_once('include/zot.php');
+
+// performs zot_finger on $argv[1], which is a hex_encoded webbie/reddress
+
+class Gprobe {
+ static public function run($argc,$argv) {
+
+ if($argc != 2)
+ return;
+
+ $url = hex2bin($argv[1]);
+
+ if(! strpos($url,'@'))
+ return;
+
+ $r = q("select * from xchan where xchan_addr = '%s' limit 1",
+ dbesc($url)
+ );
+
+ if(! $r) {
+ $j = \Zotlabs\Zot\Finger::run($url,null);
+ if($j['success']) {
+ $y = import_xchan($j);
+ }
+ }
+
+ return;
+ }
+}
diff --git a/Zotlabs/Daemon/Importdoc.php b/Zotlabs/Daemon/Importdoc.php
new file mode 100755
index 000000000..3109a5d86
--- /dev/null
+++ b/Zotlabs/Daemon/Importdoc.php
@@ -0,0 +1,35 @@
+<?php
+
+namespace Zotlabs\Daemon;
+
+
+class Importdoc {
+
+ static public function run($argc,$argv) {
+
+ require_once('include/help.php');
+
+ self::update_docs_dir('doc/*');
+
+ }
+
+ static public function update_docs_dir($s) {
+ $f = basename($s);
+ $d = dirname($s);
+ if($s === 'doc/html')
+ return;
+ $files = glob("$d/$f");
+ if($files) {
+ foreach($files as $fi) {
+ if($fi === 'doc/html')
+ continue;
+ if(is_dir($fi))
+ self::update_docs_dir("$fi/*");
+ else
+ store_doc_file($fi);
+ }
+ }
+ }
+}
+
+
diff --git a/Zotlabs/Daemon/Master.php b/Zotlabs/Daemon/Master.php
new file mode 100644
index 000000000..56076f612
--- /dev/null
+++ b/Zotlabs/Daemon/Master.php
@@ -0,0 +1,31 @@
+<?php
+
+namespace Zotlabs\Daemon;
+
+if(array_search( __file__ , get_included_files()) === 0) {
+
+ require_once('include/cli_startup.php');
+ array_shift($argv);
+ $argc = count($argv);
+
+ if($argc)
+ Master::Release($argc,$argv);
+ killme();
+}
+
+
+
+class Master {
+
+ static public function Summon($arr) {
+ proc_run('php','Zotlabs/Daemon/Master.php',$arr);
+ }
+
+ static public function Release($argc,$argv) {
+ cli_startup();
+ logger('Master: release: ' . print_r($argv,true), LOGGER_ALL,LOG_DEBUG);
+ require_once('Zotlabs/Daemon/' . $argv[0] . '.php');
+ $cls = '\\Zotlabs\\Daemon\\' . $argv[0];
+ $cls::run($argc,$argv);
+ }
+} \ No newline at end of file
diff --git a/Zotlabs/Daemon/Notifier.php b/Zotlabs/Daemon/Notifier.php
new file mode 100644
index 000000000..ebc9d83a5
--- /dev/null
+++ b/Zotlabs/Daemon/Notifier.php
@@ -0,0 +1,663 @@
+<?php /** @file */
+
+namespace Zotlabs\Daemon;
+
+require_once('include/queue_fn.php');
+require_once('include/html2plain.php');
+
+/*
+ * This file was at one time responsible for doing all deliveries, but this caused
+ * big problems on shared hosting systems, where the process might get killed by the
+ * hosting provider and nothing would get delivered.
+ * It now only delivers one message under certain cases, and invokes a queued
+ * delivery mechanism (include/deliver.php) to deliver individual contacts at
+ * controlled intervals.
+ * This has a much better chance of surviving random processes getting killed
+ * by the hosting provider.
+ *
+ * The basic flow is:
+ * Identify the type of message
+ * Collect any information that needs to be sent
+ * Convert it into a suitable generic format for sending
+ * Figure out who the recipients are and if we need to relay
+ * through a conversation owner
+ * Once we know what recipients are involved, collect a list of
+ * destination sites
+ * Build and store a queue item for each unique site and invoke
+ * a delivery process for each site or a small number of sites (1-3)
+ * and add a slight delay between each delivery invocation if desired (usually)
+ *
+ */
+
+/*
+ * The notifier is typically called with:
+ *
+ * Zotlabs\Daemon\Master::Summon(array('Notifier', COMMAND, ITEM_ID));
+ *
+ * where COMMAND is one of the following:
+ *
+ * activity (in diaspora.php, dfrn_confirm.php, profiles.php)
+ * comment-import (in diaspora.php, items.php)
+ * comment-new (in item.php)
+ * drop (in diaspora.php, items.php, photos.php)
+ * edit_post (in item.php)
+ * event (in events.php)
+ * expire (in items.php)
+ * like (in like.php, poke.php)
+ * mail (in message.php)
+ * tag (in photos.php, poke.php, tagger.php)
+ * tgroup (in items.php)
+ * wall-new (in photos.php, item.php)
+ *
+ * and ITEM_ID is the id of the item in the database that needs to be sent to others.
+ *
+ * ZOT
+ * permission_create abook_id
+ * permission_update abook_id
+ * refresh_all channel_id
+ * purge_all channel_id
+ * expire channel_id
+ * relay item_id (item was relayed to owner, we will deliver it as owner)
+ * single_activity item_id (deliver to a singleton network from the appropriate clone)
+ * single_mail mail_id (deliver to a singleton network from the appropriate clone)
+ * location channel_id
+ * request channel_id xchan_hash message_id
+ * rating xlink_id
+ *
+ */
+
+
+require_once('include/zot.php');
+require_once('include/queue_fn.php');
+require_once('include/datetime.php');
+require_once('include/items.php');
+require_once('include/bbcode.php');
+require_once('include/channel.php');
+
+
+class Notifier {
+
+ static public function run($argc,$argv){
+
+ if($argc < 3)
+ return;
+
+ logger('notifier: invoked: ' . print_r($argv,true), LOGGER_DEBUG);
+
+ $cmd = $argv[1];
+
+ $item_id = $argv[2];
+
+ $extra = (($argc > 3) ? $argv[3] : null);
+
+ if(! $item_id)
+ return;
+
+ $sys = get_sys_channel();
+
+ $deliveries = array();
+
+ $dead_hubs = array();
+
+ $dh = q("select site_url from site where site_dead = 1");
+ if($dh) {
+ foreach($dh as $dead) {
+ $dead_hubs[] = $dead['site_url'];
+ }
+ }
+
+
+ $request = false;
+ $mail = false;
+ $top_level = false;
+ $location = false;
+ $recipients = array();
+ $url_recipients = array();
+ $normal_mode = true;
+ $packet_type = 'undefined';
+
+ if($cmd === 'mail' || $cmd === 'single_mail') {
+ $normal_mode = false;
+ $mail = true;
+ $private = true;
+ $message = q("SELECT * FROM `mail` WHERE `id` = %d LIMIT 1",
+ intval($item_id)
+ );
+ if(! $message) {
+ return;
+ }
+ xchan_mail_query($message[0]);
+ $uid = $message[0]['channel_id'];
+ $recipients[] = $message[0]['from_xchan']; // include clones
+ $recipients[] = $message[0]['to_xchan'];
+ $item = $message[0];
+
+ $encoded_item = encode_mail($item);
+
+ $s = q("select * from channel where channel_id = %d limit 1",
+ intval($item['channel_id'])
+ );
+ if($s)
+ $channel = $s[0];
+
+ }
+ elseif($cmd === 'request') {
+ $channel_id = $item_id;
+ $xchan = $argv[3];
+ $request_message_id = $argv[4];
+
+ $s = q("select * from channel where channel_id = %d limit 1",
+ intval($channel_id)
+ );
+ if($s)
+ $channel = $s[0];
+
+ $private = true;
+ $recipients[] = $xchan;
+ $packet_type = 'request';
+ $normal_mode = false;
+ }
+ elseif($cmd == 'permission_update' || $cmd == 'permission_create') {
+ // Get the (single) recipient
+ $r = q("select * from abook left join xchan on abook_xchan = xchan_hash where abook_id = %d and abook_self = 0",
+ intval($item_id)
+ );
+ if($r) {
+ $uid = $r[0]['abook_channel'];
+ // Get the sender
+ $channel = channelx_by_n($uid);
+ if($channel) {
+ $perm_update = array('sender' => $channel, 'recipient' => $r[0], 'success' => false, 'deliveries' => '');
+
+ if($cmd == 'permission_create')
+ call_hooks('permissions_create',$perm_update);
+ else
+ call_hooks('permissions_update',$perm_update);
+
+ if($perm_update['success']) {
+ if($perm_update['deliveries']) {
+ $deliveries[] = $perm_update['deliveries'];
+ do_delivery($deliveries);
+ }
+ return;
+ }
+ else {
+ $recipients[] = $r[0]['abook_xchan'];
+ $private = false;
+ $packet_type = 'refresh';
+ $packet_recips = array(array('guid' => $r[0]['xchan_guid'],'guid_sig' => $r[0]['xchan_guid_sig'],'hash' => $r[0]['xchan_hash']));
+ }
+ }
+ }
+ }
+ elseif($cmd === 'refresh_all') {
+ logger('notifier: refresh_all: ' . $item_id);
+ $uid = $item_id;
+ $channel = channelx_by_n($item_id);
+ $r = q("select abook_xchan from abook where abook_channel = %d",
+ intval($item_id)
+ );
+ if($r) {
+ foreach($r as $rr) {
+ $recipients[] = $rr['abook_xchan'];
+ }
+ }
+ $private = false;
+ $packet_type = 'refresh';
+ }
+ elseif($cmd === 'location') {
+ logger('notifier: location: ' . $item_id);
+ $s = q("select * from channel where channel_id = %d limit 1",
+ intval($item_id)
+ );
+ if($s)
+ $channel = $s[0];
+ $uid = $item_id;
+ $recipients = array();
+ $r = q("select abook_xchan from abook where abook_channel = %d",
+ intval($item_id)
+ );
+ if($r) {
+ foreach($r as $rr) {
+ $recipients[] = $rr['abook_xchan'];
+ }
+ }
+
+ $encoded_item = array('locations' => zot_encode_locations($channel),'type' => 'location', 'encoding' => 'zot');
+ $target_item = array('aid' => $channel['channel_account_id'],'uid' => $channel['channel_id']);
+ $private = false;
+ $packet_type = 'location';
+ $location = true;
+ }
+ elseif($cmd === 'purge_all') {
+ logger('notifier: purge_all: ' . $item_id);
+ $s = q("select * from channel where channel_id = %d limit 1",
+ intval($item_id)
+ );
+ if($s)
+ $channel = $s[0];
+ $uid = $item_id;
+ $recipients = array();
+ $r = q("select abook_xchan from abook where abook_channel = %d",
+ intval($item_id)
+ );
+ if($r) {
+ foreach($r as $rr) {
+ $recipients[] = $rr['abook_xchan'];
+ }
+ }
+ $private = false;
+ $packet_type = 'purge';
+ }
+ else {
+
+ // Normal items
+
+ // Fetch the target item
+
+ $r = q("SELECT * FROM item WHERE id = %d and parent != 0 LIMIT 1",
+ intval($item_id)
+ );
+
+ if(! $r)
+ return;
+
+ xchan_query($r);
+
+ $r = fetch_post_tags($r);
+
+ $target_item = $r[0];
+ $deleted_item = false;
+
+ if(intval($target_item['item_deleted'])) {
+ logger('notifier: target item ITEM_DELETED', LOGGER_DEBUG);
+ $deleted_item = true;
+ }
+
+ if(intval($target_item['item_type']) != ITEM_TYPE_POST) {
+ logger('notifier: target item not forwardable: type ' . $target_item['item_type'], LOGGER_DEBUG);
+ return;
+ }
+
+ // Check for non published items, but allow an exclusion for transmitting hidden file activities
+
+ if(intval($target_item['item_unpublished']) || intval($target_item['item_delayed']) ||
+ ( intval($target_item['item_hidden']) && ($target_item['obj_type'] !== ACTIVITY_OBJ_FILE))) {
+ logger('notifier: target item not published, so not forwardable', LOGGER_DEBUG);
+ return;
+ }
+
+ if(strpos($target_item['postopts'],'nodeliver') !== false) {
+ logger('notifier: target item is undeliverable', LOGGER_DEBUG);
+ return;
+ }
+
+ $s = q("select * from channel left join xchan on channel_hash = xchan_hash where channel_id = %d limit 1",
+ intval($target_item['uid'])
+ );
+ if($s)
+ $channel = $s[0];
+
+ if($channel['channel_hash'] !== $target_item['author_xchan'] && $channel['channel_hash'] !== $target_item['owner_xchan']) {
+ logger("notifier: Sending channel {$channel['channel_hash']} is not owner {$target_item['owner_xchan']} or author {$target_item['author_xchan']}", LOGGER_NORMAL, LOG_WARNING);
+ return;
+ }
+
+
+ if($target_item['id'] == $target_item['parent']) {
+ $parent_item = $target_item;
+ $top_level_post = true;
+ }
+ else {
+ // fetch the parent item
+ $r = q("SELECT * from item where id = %d order by id asc",
+ intval($target_item['parent'])
+ );
+
+ if(! $r)
+ return;
+
+ if(strpos($r[0]['postopts'],'nodeliver') !== false) {
+ logger('notifier: target item is undeliverable', LOGGER_DEBUG, LOG_NOTICE);
+ return;
+ }
+
+ xchan_query($r);
+ $r = fetch_post_tags($r);
+
+ $parent_item = $r[0];
+ $top_level_post = false;
+ }
+
+ // avoid looping of discover items 12/4/2014
+
+ if($sys && $parent_item['uid'] == $sys['channel_id'])
+ return;
+
+ $encoded_item = encode_item($target_item);
+
+ // Send comments to the owner to re-deliver to everybody in the conversation
+ // We only do this if the item in question originated on this site. This prevents looping.
+ // To clarify, a site accepting a new comment is responsible for sending it to the owner for relay.
+ // Relaying should never be initiated on a post that arrived from elsewhere.
+
+ // We should normally be able to rely on ITEM_ORIGIN, but start_delivery_chain() incorrectly set this
+ // flag on comments for an extended period. So we'll also call comment_local_origin() which looks at
+ // the hostname in the message_id and provides a second (fallback) opinion.
+
+ $relay_to_owner = (((! $top_level_post) && (intval($target_item['item_origin'])) && comment_local_origin($target_item)) ? true : false);
+
+
+
+ $uplink = false;
+
+ // $cmd === 'relay' indicates the owner is sending it to the original recipients
+ // don't allow the item in the relay command to relay to owner under any circumstances, it will loop
+
+ logger('notifier: relay_to_owner: ' . (($relay_to_owner) ? 'true' : 'false'), LOGGER_DATA, LOG_DEBUG);
+ logger('notifier: top_level_post: ' . (($top_level_post) ? 'true' : 'false'), LOGGER_DATA, LOG_DEBUG);
+
+ // tag_deliver'd post which needs to be sent back to the original author
+
+ if(($cmd === 'uplink') && intval($parent_item['item_uplink']) && (! $top_level_post)) {
+ logger('notifier: uplink');
+ $uplink = true;
+ }
+
+ if(($relay_to_owner || $uplink) && ($cmd !== 'relay')) {
+ logger('notifier: followup relay', LOGGER_DEBUG);
+ $recipients = array(($uplink) ? $parent_item['source_xchan'] : $parent_item['owner_xchan']);
+ $private = true;
+ if(! $encoded_item['flags'])
+ $encoded_item['flags'] = array();
+ $encoded_item['flags'][] = 'relay';
+ }
+ else {
+ logger('notifier: normal distribution', LOGGER_DEBUG);
+ if($cmd === 'relay')
+ logger('notifier: owner relay');
+
+ // if our parent is a tag_delivery recipient, uplink to the original author causing
+ // a delivery fork.
+
+ if(($parent_item) && intval($parent_item['item_uplink']) && (! $top_level_post) && ($cmd !== 'uplink')) {
+ // don't uplink a relayed post to the relay owner
+ if($parent_item['source_xchan'] !== $parent_item['owner_xchan']) {
+ logger('notifier: uplinking this item');
+ Master::Summon(array('Notifier','uplink',$item_id));
+ }
+ }
+
+ $private = false;
+ $recipients = collect_recipients($parent_item,$private);
+
+ // FIXME add any additional recipients such as mentions, etc.
+
+ // don't send deletions onward for other people's stuff
+ // TODO verify this is needed - copied logic from same place in old code
+
+ if(intval($target_item['item_deleted']) && (! intval($target_item['item_wall']))) {
+ logger('notifier: ignoring delete notification for non-wall item', LOGGER_NORMAL, LOG_NOTICE);
+ return;
+ }
+ }
+
+ }
+
+ $walltowall = (($top_level_post && $channel['xchan_hash'] === $target_item['author_xchan']) ? true : false);
+
+ // Generic delivery section, we have an encoded item and recipients
+ // Now start the delivery process
+
+ $x = $encoded_item;
+ $x['title'] = 'private';
+ $x['body'] = 'private';
+ logger('notifier: encoded item: ' . print_r($x,true), LOGGER_DATA, LOG_DEBUG);
+
+ stringify_array_elms($recipients);
+ if(! $recipients)
+ return;
+
+// logger('notifier: recipients: ' . print_r($recipients,true), LOGGER_NORMAL, LOG_DEBUG);
+
+ $env_recips = (($private) ? array() : null);
+
+ $details = q("select xchan_hash, xchan_instance_url, xchan_network, xchan_addr, xchan_guid, xchan_guid_sig from xchan where xchan_hash in (" . implode(',',$recipients) . ")");
+
+
+ $recip_list = array();
+
+ if($details) {
+ foreach($details as $d) {
+
+ $recip_list[] = $d['xchan_addr'] . ' (' . $d['xchan_hash'] . ')';
+ if($private)
+ $env_recips[] = array('guid' => $d['xchan_guid'],'guid_sig' => $d['xchan_guid_sig'],'hash' => $d['xchan_hash']);
+
+ if($d['xchan_network'] === 'mail' && $normal_mode) {
+ $delivery_options = get_xconfig($d['xchan_hash'],'system','delivery_mode');
+ if(! $delivery_options)
+ format_and_send_email($channel,$d,$target_item);
+ }
+ }
+ }
+
+
+ $narr = array(
+ 'channel' => $channel,
+ 'env_recips' => $env_recips,
+ 'packet_recips' => $packet_recips,
+ 'recipients' => $recipients,
+ 'item' => $item,
+ 'target_item' => $target_item,
+ 'top_level_post' => $top_level_post,
+ 'private' => $private,
+ 'relay_to_owner' => $relay_to_owner,
+ 'uplink' => $uplink,
+ 'cmd' => $cmd,
+ 'mail' => $mail,
+ 'single' => (($cmd === 'single_mail' || $cmd === 'single_activity') ? true : false),
+ 'location' => $location,
+ 'request' => $request,
+ 'normal_mode' => $normal_mode,
+ 'packet_type' => $packet_type,
+ 'walltowall' => $walltowall,
+ 'queued' => array()
+ );
+
+ call_hooks('notifier_process', $narr);
+ if($narr['queued']) {
+ foreach($narr['queued'] as $pq)
+ $deliveries[] = $pq;
+ }
+
+ // notifier_process can alter the recipient list
+
+ $recipients = $narr['recipients'];
+ $env_recips = $narr['env_recips'];
+ $packet_recips = $narr['packet_recips'];
+
+ if(($private) && (! $env_recips)) {
+ // shouldn't happen
+ logger('notifier: private message with no envelope recipients.' . print_r($argv,true), LOGGER_NORMAL, LOG_NOTICE);
+ }
+
+ logger('notifier: recipients (may be delivered to more if public): ' . print_r($recip_list,true), LOGGER_DEBUG);
+
+
+ // Now we have collected recipients (except for external mentions, FIXME)
+ // Let's reduce this to a set of hubs.
+
+ $r = q("select * from hubloc where hubloc_hash in (" . implode(',',$recipients) . ")
+ and hubloc_error = 0 and hubloc_deleted = 0"
+ );
+
+
+ if(! $r) {
+ logger('notifier: no hubs', LOGGER_NORMAL, LOG_NOTICE);
+ return;
+ }
+
+ $hubs = $r;
+
+
+
+ /**
+ * Reduce the hubs to those that are unique. For zot hubs, we need to verify uniqueness by the sitekey, since it may have been
+ * a re-install which has not yet been detected and pruned.
+ * For other networks which don't have or require sitekeys, we'll have to use the URL
+ */
+
+
+ $hublist = array(); // this provides an easily printable list for the logs
+ $dhubs = array(); // delivery hubs where we store our resulting unique array
+ $keys = array(); // array of keys to check uniquness for zot hubs
+ $urls = array(); // array of urls to check uniqueness of hubs from other networks
+
+
+ foreach($hubs as $hub) {
+ if(in_array($hub['hubloc_url'],$dead_hubs)) {
+ logger('skipping dead hub: ' . $hub['hubloc_url'], LOGGER_DEBUG, LOG_INFO);
+ continue;
+ }
+
+ if($hub['hubloc_network'] == 'zot') {
+ if(! in_array($hub['hubloc_sitekey'],$keys)) {
+ $hublist[] = $hub['hubloc_host'];
+ $dhubs[] = $hub;
+ $keys[] = $hub['hubloc_sitekey'];
+ }
+ }
+ else {
+ if(! in_array($hub['hubloc_url'],$urls)) {
+ $hublist[] = $hub['hubloc_host'];
+ $dhubs[] = $hub;
+ $urls[] = $hub['hubloc_url'];
+ }
+ }
+ }
+
+ logger('notifier: will notify/deliver to these hubs: ' . print_r($hublist,true), LOGGER_DEBUG, LOG_DEBUG);
+
+
+ foreach($dhubs as $hub) {
+
+ if($hub['hubloc_network'] !== 'zot') {
+
+ $narr = array(
+ 'channel' => $channel,
+ 'env_recips' => $env_recips,
+ 'packet_recips' => $packet_recips,
+ 'recipients' => $recipients,
+ 'item' => $item,
+ 'target_item' => $target_item,
+ 'hub' => $hub,
+ 'top_level_post' => $top_level_post,
+ 'private' => $private,
+ 'relay_to_owner' => $relay_to_owner,
+ 'uplink' => $uplink,
+ 'cmd' => $cmd,
+ 'mail' => $mail,
+ 'single' => (($cmd === 'single_mail' || $cmd === 'single_activity') ? true : false),
+ 'location' => $location,
+ 'request' => $request,
+ 'normal_mode' => $normal_mode,
+ 'packet_type' => $packet_type,
+ 'walltowall' => $walltowall,
+ 'queued' => array()
+ );
+
+
+ call_hooks('notifier_hub',$narr);
+ if($narr['queued']) {
+ foreach($narr['queued'] as $pq)
+ $deliveries[] = $pq;
+ }
+ continue;
+
+ }
+
+ // singleton deliveries by definition 'not got zot'.
+ // Single deliveries are other federated networks (plugins) and we're essentially
+ // delivering only to those that have this site url in their abook_instance
+ // and only from within a sync operation. This means if you post from a clone,
+ // and a connection is connected to one of your other clones; assuming that hub
+ // is running it will receive a sync packet. On receipt of this sync packet it
+ // will invoke a delivery to those connections which are connected to just that
+ // hub instance.
+
+ if($cmd === 'single_mail' || $cmd === 'single_activity') {
+ continue;
+ }
+
+ // default: zot protocol
+
+ $hash = random_string();
+ $packet = null;
+
+ if($packet_type === 'refresh' || $packet_type === 'purge') {
+ $packet = zot_build_packet($channel,$packet_type,(($packet_recips) ? $packet_recips : null));
+ }
+ elseif($packet_type === 'request') {
+ $packet = zot_build_packet($channel,$packet_type,$env_recips,$hub['hubloc_sitekey'],$hash,
+ array('message_id' => $request_message_id)
+ );
+ }
+
+ if($packet) {
+ queue_insert(array(
+ 'hash' => $hash,
+ 'account_id' => $channel['channel_account_id'],
+ 'channel_id' => $channel['channel_id'],
+ 'posturl' => $hub['hubloc_callback'],
+ 'notify' => $packet
+ ));
+ }
+ else {
+ $packet = zot_build_packet($channel,'notify',$env_recips,(($private) ? $hub['hubloc_sitekey'] : null),$hash);
+ queue_insert(array(
+ 'hash' => $hash,
+ 'account_id' => $target_item['aid'],
+ 'channel_id' => $target_item['uid'],
+ 'posturl' => $hub['hubloc_callback'],
+ 'notify' => $packet,
+ 'msg' => json_encode($encoded_item)
+ ));
+
+ // only create delivery reports for normal undeleted items
+ if(is_array($target_item) && array_key_exists('postopts',$target_item) && (! $target_item['item_deleted']) && (! get_config('system','disable_dreport'))) {
+ q("insert into dreport ( dreport_mid, dreport_site, dreport_recip, dreport_result, dreport_time, dreport_xchan, dreport_queue ) values ( '%s','%s','%s','%s','%s','%s','%s' ) ",
+ dbesc($target_item['mid']),
+ dbesc($hub['hubloc_host']),
+ dbesc($hub['hubloc_host']),
+ dbesc('queued'),
+ dbesc(datetime_convert()),
+ dbesc($channel['channel_hash']),
+ dbesc($hash)
+ );
+ }
+ }
+
+ $deliveries[] = $hash;
+ }
+
+ if($normal_mode) {
+ $x = q("select * from hook where hook = 'notifier_normal'");
+ if($x)
+ Master::Summon(array('Deliver_hooks',$target_item['id']));
+
+ }
+
+ if($deliveries)
+ do_delivery($deliveries);
+
+ logger('notifier: basic loop complete.', LOGGER_DEBUG);
+
+ call_hooks('notifier_end',$target_item);
+
+ logger('notifer: complete.');
+ return;
+
+ }
+}
+
diff --git a/Zotlabs/Daemon/Onedirsync.php b/Zotlabs/Daemon/Onedirsync.php
new file mode 100644
index 000000000..cc16c0b58
--- /dev/null
+++ b/Zotlabs/Daemon/Onedirsync.php
@@ -0,0 +1,76 @@
+<?php /** @file */
+
+namespace Zotlabs\Daemon;
+
+require_once('include/zot.php');
+require_once('include/dir_fns.php');
+
+
+class Onedirsync {
+
+ static public function run($argc,$argv) {
+
+ logger('onedirsync: start ' . intval($argv[1]));
+
+ if(($argc > 1) && (intval($argv[1])))
+ $update_id = intval($argv[1]);
+
+ if(! $update_id) {
+ logger('onedirsync: no update');
+ return;
+ }
+
+ $r = q("select * from updates where ud_id = %d limit 1",
+ intval($update_id)
+ );
+
+ if(! $r)
+ return;
+ if(($r[0]['ud_flags'] & UPDATE_FLAGS_UPDATED) || (! $r[0]['ud_addr']))
+ return;
+
+ // Have we probed this channel more recently than the other directory server
+ // (where we received this update from) ?
+ // If we have, we don't need to do anything except mark any older entries updated
+
+ $x = q("select * from updates where ud_addr = '%s' and ud_date > '%s' and ( ud_flags & %d )>0 order by ud_date desc limit 1",
+ dbesc($r[0]['ud_addr']),
+ dbesc($r[0]['ud_date']),
+ intval(UPDATE_FLAGS_UPDATED)
+ );
+ if($x) {
+ $y = q("update updates set ud_flags = ( ud_flags | %d ) where ud_addr = '%s' and ( ud_flags & %d ) = 0 and ud_date != '%s'",
+ intval(UPDATE_FLAGS_UPDATED),
+ dbesc($r[0]['ud_addr']),
+ intval(UPDATE_FLAGS_UPDATED),
+ dbesc($x[0]['ud_date'])
+ );
+ return;
+ }
+
+ // ignore doing an update if this ud_addr refers to a known dead hubloc
+
+ $h = q("select * from hubloc where hubloc_addr = '%s' limit 1",
+ dbesc($r[0]['ud_addr'])
+ );
+ if(($h) && ($h[0]['hubloc_status'] & HUBLOC_OFFLINE)) {
+ $y = q("update updates set ud_flags = ( ud_flags | %d ) where ud_addr = '%s' and ( ud_flags & %d ) = 0 ",
+ intval(UPDATE_FLAGS_UPDATED),
+ dbesc($r[0]['ud_addr']),
+ intval(UPDATE_FLAGS_UPDATED)
+ );
+
+ return;
+ }
+
+ // we might have to pull this out some day, but for now update_directory_entry()
+ // runs zot_finger() and is kind of zot specific
+
+ if($h && $h[0]['hubloc_network'] !== 'zot')
+ return;
+
+ update_directory_entry($r[0]);
+
+ return;
+ }
+}
diff --git a/Zotlabs/Daemon/Onepoll.php b/Zotlabs/Daemon/Onepoll.php
new file mode 100644
index 000000000..036a4991b
--- /dev/null
+++ b/Zotlabs/Daemon/Onepoll.php
@@ -0,0 +1,152 @@
+<?php /** @file */
+
+namespace Zotlabs\Daemon;
+
+require_once('include/zot.php');
+require_once('include/socgraph.php');
+
+
+class Onepoll {
+
+ static public function run($argc,$argv) {
+
+ logger('onepoll: start');
+
+ if(($argc > 1) && (intval($argv[1])))
+ $contact_id = intval($argv[1]);
+
+ if(! $contact_id) {
+ logger('onepoll: no contact');
+ return;
+ }
+
+ $d = datetime_convert();
+
+ $contacts = q("SELECT abook.*, xchan.*, account.*
+ FROM abook LEFT JOIN account on abook_account = account_id left join xchan on xchan_hash = abook_xchan
+ where abook_id = %d
+ and abook_pending = 0 and abook_archived = 0 and abook_blocked = 0 and abook_ignored = 0
+ AND (( account_flags = %d ) OR ( account_flags = %d )) limit 1",
+ intval($contact_id),
+ intval(ACCOUNT_OK),
+ intval(ACCOUNT_UNVERIFIED)
+ );
+
+ if(! $contacts) {
+ logger('onepoll: abook_id not found: ' . $contact_id);
+ return;
+ }
+
+ $contact = $contacts[0];
+
+ $t = $contact['abook_updated'];
+
+ $importer_uid = $contact['abook_channel'];
+
+ $r = q("SELECT * from channel left join xchan on channel_hash = xchan_hash where channel_id = %d limit 1",
+ intval($importer_uid)
+ );
+
+ if(! $r)
+ return;
+
+ $importer = $r[0];
+
+ logger("onepoll: poll: ({$contact['id']}) IMPORTER: {$importer['xchan_name']}, CONTACT: {$contact['xchan_name']}");
+
+ $last_update = ((($contact['abook_updated'] === $contact['abook_created']) || ($contact['abook_updated'] === NULL_DATE))
+ ? datetime_convert('UTC','UTC','now - 7 days')
+ : datetime_convert('UTC','UTC',$contact['abook_updated'] . ' - 2 days')
+ );
+
+ if($contact['xchan_network'] === 'rss') {
+ logger('onepoll: processing feed ' . $contact['xchan_name'], LOGGER_DEBUG);
+ handle_feed($importer['channel_id'],$contact_id,$contact['xchan_hash']);
+ q("update abook set abook_connected = '%s' where abook_id = %d",
+ dbesc(datetime_convert()),
+ intval($contact['abook_id'])
+ );
+ return;
+ }
+
+ if($contact['xchan_network'] !== 'zot')
+ return;
+
+ // update permissions
+
+ $x = zot_refresh($contact,$importer);
+
+ $responded = false;
+ $updated = datetime_convert();
+ $connected = datetime_convert();
+ if(! $x) {
+ // mark for death by not updating abook_connected, this is caught in include/poller.php
+ q("update abook set abook_updated = '%s' where abook_id = %d",
+ dbesc($updated),
+ intval($contact['abook_id'])
+ );
+ }
+ else {
+ q("update abook set abook_updated = '%s', abook_connected = '%s' where abook_id = %d",
+ dbesc($updated),
+ dbesc($connected),
+ intval($contact['abook_id'])
+ );
+ $responded = true;
+ }
+
+ if(! $responded)
+ return;
+
+ if($contact['xchan_connurl']) {
+ $fetch_feed = true;
+ $x = null;
+
+ if(! ($contact['abook_their_perms'] & PERMS_R_STREAM ))
+ $fetch_feed = false;
+
+ if($fetch_feed) {
+
+ $feedurl = str_replace('/poco/','/zotfeed/',$contact['xchan_connurl']);
+ $feedurl .= '?f=&mindate=' . urlencode($last_update);
+
+ $x = z_fetch_url($feedurl);
+
+ logger('feed_update: ' . print_r($x,true), LOGGER_DATA);
+
+ }
+
+ if(($x) && ($x['success'])) {
+ $total = 0;
+ logger('onepoll: feed update ' . $contact['xchan_name'] . ' ' . $feedurl);
+
+ $j = json_decode($x['body'],true);
+ if($j['success'] && $j['messages']) {
+ foreach($j['messages'] as $message) {
+ $results = process_delivery(array('hash' => $contact['xchan_hash']), get_item_elements($message),
+ array(array('hash' => $importer['xchan_hash'])), false);
+ logger('onepoll: feed_update: process_delivery: ' . print_r($results,true), LOGGER_DATA);
+ $total ++;
+ }
+ logger("onepoll: $total messages processed");
+ }
+ }
+ }
+
+
+ // update the poco details for this connection
+
+ if($contact['xchan_connurl']) {
+ $r = q("SELECT xlink_id from xlink
+ where xlink_xchan = '%s' and xlink_updated > %s - INTERVAL %s and xlink_static = 0 limit 1",
+ intval($contact['xchan_hash']),
+ db_utcnow(), db_quoteinterval('1 DAY')
+ );
+ if(! $r) {
+ poco_load($contact['xchan_hash'],$contact['xchan_connurl']);
+ }
+ }
+
+ return;
+ }
+}
diff --git a/Zotlabs/Daemon/Poller.php b/Zotlabs/Daemon/Poller.php
new file mode 100644
index 000000000..75efbf8f7
--- /dev/null
+++ b/Zotlabs/Daemon/Poller.php
@@ -0,0 +1,202 @@
+<?php /** @file */
+
+namespace Zotlabs\Daemon;
+
+class Poller {
+
+ static public function run($argc,$argv) {
+
+ $maxsysload = intval(get_config('system','maxloadavg'));
+ if($maxsysload < 1)
+ $maxsysload = 50;
+ if(function_exists('sys_getloadavg')) {
+ $load = sys_getloadavg();
+ if(intval($load[0]) > $maxsysload) {
+ logger('system: load ' . $load . ' too high. Poller deferred to next scheduled run.');
+ return;
+ }
+ }
+
+ $interval = intval(get_config('system','poll_interval'));
+ if(! $interval)
+ $interval = ((get_config('system','delivery_interval') === false) ? 3 : intval(get_config('system','delivery_interval')));
+
+ // Check for a lockfile. If it exists, but is over an hour old, it's stale. Ignore it.
+ $lockfile = 'store/[data]/poller';
+ if((file_exists($lockfile)) && (filemtime($lockfile) > (time() - 3600))
+ && (! get_config('system','override_poll_lockfile'))) {
+ logger("poller: Already running");
+ return;
+ }
+
+ // Create a lockfile. Needs two vars, but $x doesn't need to contain anything.
+ file_put_contents($lockfile, $x);
+
+ logger('poller: start');
+
+ $manual_id = 0;
+ $generation = 0;
+
+ $force = false;
+ $restart = false;
+
+ if(($argc > 1) && ($argv[1] == 'force'))
+ $force = true;
+
+ if(($argc > 1) && ($argv[1] == 'restart')) {
+ $restart = true;
+ $generation = intval($argv[2]);
+ if(! $generation)
+ killme();
+ }
+
+ if(($argc > 1) && intval($argv[1])) {
+ $manual_id = intval($argv[1]);
+ $force = true;
+ }
+
+
+ $sql_extra = (($manual_id) ? " AND abook_id = " . intval($manual_id) . " " : "");
+
+ reload_plugins();
+
+ $d = datetime_convert();
+
+ // Only poll from those with suitable relationships
+
+ $abandon_sql = (($abandon_days)
+ ? sprintf(" AND account_lastlog > %s - INTERVAL %s ", db_utcnow(), db_quoteinterval(intval($abandon_days).' DAY'))
+ : ''
+ );
+
+ $randfunc = db_getfunc('RAND');
+
+ $contacts = q("SELECT * FROM abook LEFT JOIN xchan on abook_xchan = xchan_hash
+ LEFT JOIN account on abook_account = account_id
+ where abook_self = 0
+ $sql_extra
+ AND (( account_flags = %d ) OR ( account_flags = %d )) $abandon_sql ORDER BY $randfunc",
+ intval(ACCOUNT_OK),
+ intval(ACCOUNT_UNVERIFIED) // FIXME
+
+ );
+
+ if($contacts) {
+
+ foreach($contacts as $contact) {
+
+ $update = false;
+
+ $t = $contact['abook_updated'];
+ $c = $contact['abook_connected'];
+
+ if(intval($contact['abook_feed'])) {
+ $min = service_class_fetch($contact['abook_channel'],'minimum_feedcheck_minutes');
+ if(! $min)
+ $min = intval(get_config('system','minimum_feedcheck_minutes'));
+ if(! $min)
+ $min = 60;
+ $x = datetime_convert('UTC','UTC',"now - $min minutes");
+ if($c < $x) {
+ Master::Summon(array('Onepoll',$contact['abook_id']));
+ if($interval)
+ @time_sleep_until(microtime(true) + (float) $interval);
+ }
+ continue;
+ }
+
+
+ if($contact['xchan_network'] !== 'zot')
+ continue;
+
+ if($c == $t) {
+ if(datetime_convert('UTC','UTC', 'now') > datetime_convert('UTC','UTC', $t . " + 1 day"))
+ $update = true;
+ }
+ else {
+
+ // if we've never connected with them, start the mark for death countdown from now
+
+ if($c == NULL_DATE) {
+ $r = q("update abook set abook_connected = '%s' where abook_id = %d",
+ dbesc(datetime_convert()),
+ intval($contact['abook_id'])
+ );
+ $c = datetime_convert();
+ $update = true;
+ }
+
+ // He's dead, Jim
+
+ if(strcmp(datetime_convert('UTC','UTC', 'now'),datetime_convert('UTC','UTC', $c . " + 30 day")) > 0) {
+ $r = q("update abook set abook_archived = 1 where abook_id = %d",
+ intval($contact['abook_id'])
+ );
+ $update = false;
+ continue;
+ }
+
+ if(intval($contact['abook_archived'])) {
+ $update = false;
+ continue;
+ }
+
+ // might be dead, so maybe don't poll quite so often
+
+ // recently deceased, so keep up the regular schedule for 3 days
+
+ if((strcmp(datetime_convert('UTC','UTC', 'now'),datetime_convert('UTC','UTC', $c . " + 3 day")) > 0)
+ && (strcmp(datetime_convert('UTC','UTC', 'now'),datetime_convert('UTC','UTC', $t . " + 1 day")) > 0))
+ $update = true;
+
+ // After that back off and put them on a morphine drip
+
+ if(strcmp(datetime_convert('UTC','UTC', 'now'),datetime_convert('UTC','UTC', $t . " + 2 day")) > 0) {
+ $update = true;
+ }
+
+ }
+
+ if(intval($contact['abook_pending']) || intval($contact['abook_archived']) || intval($contact['abook_ignored']) || intval($contact['abook_blocked']))
+ continue;
+
+ if((! $update) && (! $force))
+ continue;
+
+ Master::Summon(array('Onepoll',$contact['abook_id']));
+ if($interval)
+ @time_sleep_until(microtime(true) + (float) $interval);
+
+ }
+ }
+
+ if($dirmode == DIRECTORY_MODE_SECONDARY || $dirmode == DIRECTORY_MODE_PRIMARY) {
+ $r = q("SELECT u.ud_addr, u.ud_id, u.ud_last FROM updates AS u INNER JOIN (SELECT ud_addr, max(ud_id) AS ud_id FROM updates WHERE ( ud_flags & %d ) = 0 AND ud_addr != '' AND ( ud_last = '%s' OR ud_last > %s - INTERVAL %s ) GROUP BY ud_addr) AS s ON s.ud_id = u.ud_id ",
+ intval(UPDATE_FLAGS_UPDATED),
+ dbesc(NULL_DATE),
+ db_utcnow(), db_quoteinterval('7 DAY')
+ );
+ if($r) {
+ foreach($r as $rr) {
+
+ // If they didn't respond when we attempted before, back off to once a day
+ // After 7 days we won't bother anymore
+
+ if($rr['ud_last'] != NULL_DATE)
+ if($rr['ud_last'] > datetime_convert('UTC','UTC', 'now - 1 day'))
+ continue;
+ Master::Summon(array('Onedirsync',$rr['ud_id']));
+ if($interval)
+ @time_sleep_until(microtime(true) + (float) $interval);
+ }
+ }
+ }
+
+ set_config('system','lastpoll',datetime_convert());
+
+ //All done - clear the lockfile
+ @unlink($lockfile);
+
+ return;
+ }
+}
diff --git a/Zotlabs/Daemon/Queue.php b/Zotlabs/Daemon/Queue.php
new file mode 100644
index 000000000..27306589d
--- /dev/null
+++ b/Zotlabs/Daemon/Queue.php
@@ -0,0 +1,90 @@
+<?php /** @file */
+
+namespace Zotlabs\Daemon;
+
+require_once('include/queue_fn.php');
+require_once('include/zot.php');
+
+class Queue {
+
+ static public function run($argc,$argv) {
+
+ require_once('include/items.php');
+ require_once('include/bbcode.php');
+
+ if(argc() > 1)
+ $queue_id = argv(1);
+ else
+ $queue_id = 0;
+
+ logger('queue: start');
+
+ // delete all queue items more than 3 days old
+ // but first mark these sites dead if we haven't heard from them in a month
+
+ $r = q("select outq_posturl from outq where outq_created < %s - INTERVAL %s",
+ db_utcnow(), db_quoteinterval('3 DAY')
+ );
+ if($r) {
+ foreach($r as $rr) {
+ $site_url = '';
+ $h = parse_url($rr['outq_posturl']);
+ $desturl = $h['scheme'] . '://' . $h['host'] . (($h['port']) ? ':' . $h['port'] : '');
+ q("update site set site_dead = 1 where site_dead = 0 and site_url = '%s' and site_update < %s - INTERVAL %s",
+ dbesc($desturl),
+ db_utcnow(), db_quoteinterval('1 MONTH')
+ );
+ }
+ }
+
+ $r = q("DELETE FROM outq WHERE outq_created < %s - INTERVAL %s",
+ db_utcnow(), db_quoteinterval('3 DAY')
+ );
+
+ if($queue_id) {
+ $r = q("SELECT * FROM outq WHERE outq_hash = '%s' LIMIT 1",
+ dbesc($queue_id)
+ );
+ }
+ else {
+
+ // For the first 12 hours we'll try to deliver every 15 minutes
+ // After that, we'll only attempt delivery once per hour.
+ // This currently only handles the default queue drivers ('zot' or '') which we will group by posturl
+ // so that we don't start off a thousand deliveries for a couple of dead hubs.
+ // The zot driver will deliver everything destined for a single hub once contact is made (*if* contact is made).
+ // Other drivers will have to do something different here and may need their own query.
+
+ // Note: this requires some tweaking as new posts to long dead hubs once a day will keep them in the
+ // "every 15 minutes" category. We probably need to prioritise them when inserted into the queue
+ // or just prior to this query based on recent and long-term delivery history. If we have good reason to believe
+ // 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')
+ );
+ }
+ if(! $r)
+ return;
+
+ foreach($r as $rr) {
+ queue_deliver($rr);
+ }
+ }
+}
diff --git a/Zotlabs/Daemon/Ratenotif.php b/Zotlabs/Daemon/Ratenotif.php
new file mode 100644
index 000000000..1cba5e26d
--- /dev/null
+++ b/Zotlabs/Daemon/Ratenotif.php
@@ -0,0 +1,113 @@
+<?php
+
+namespace Zotlabs\Daemon;
+
+require_once('include/zot.php');
+require_once('include/queue_fn.php');
+
+
+class Ratenotif {
+
+ static public function run($argc,$argv) {
+
+ require_once("datetime.php");
+ require_once('include/items.php');
+
+ if($argc < 3)
+ return;
+
+
+ logger('ratenotif: invoked: ' . print_r($argv,true), LOGGER_DEBUG);
+
+ $cmd = $argv[1];
+
+ $item_id = $argv[2];
+
+
+ if($cmd === 'rating') {
+ $r = q("select * from xlink where xlink_id = %d and xlink_static = 1 limit 1",
+ intval($item_id)
+ );
+ if(! $r) {
+ logger('rating not found');
+ return;
+ }
+
+ $encoded_item = array(
+ 'type' => 'rating',
+ 'encoding' => 'zot',
+ 'target' => $r[0]['xlink_link'],
+ 'rating' => intval($r[0]['xlink_rating']),
+ 'rating_text' => $r[0]['xlink_rating_text'],
+ 'signature' => $r[0]['xlink_sig'],
+ 'edited' => $r[0]['xlink_updated']
+ );
+ }
+
+ $channel = channelx_by_hash($r[0]['xlink_xchan']);
+ if(! $channel) {
+ logger('no channel');
+ return;
+ }
+
+
+ $primary = get_directory_primary();
+
+ if(! $primary)
+ return;
+
+
+ $interval = ((get_config('system','delivery_interval') !== false)
+ ? intval(get_config('system','delivery_interval')) : 2 );
+
+ $deliveries_per_process = intval(get_config('system','delivery_batch_count'));
+
+ if($deliveries_per_process <= 0)
+ $deliveries_per_process = 1;
+
+ $deliver = array();
+
+ $x = z_fetch_url($primary . '/regdir');
+ if($x['success']) {
+ $j = json_decode($x['body'],true);
+ if($j && $j['success'] && is_array($j['directories'])) {
+
+ foreach($j['directories'] as $h) {
+ if($h == z_root())
+ continue;
+
+ $hash = random_string();
+ $n = zot_build_packet($channel,'notify',null,null,$hash);
+
+ queue_insert(array(
+ 'hash' => $hash,
+ 'account_id' => $channel['channel_account_id'],
+ 'channel_id' => $channel['channel_id'],
+ 'posturl' => $h . '/post',
+ 'notify' => $n,
+ 'msg' => json_encode($encoded_item)
+ ));
+
+ $deliver[] = $hash;
+
+ if(count($deliver) >= $deliveries_per_process) {
+ Master::Summon(array('Deliver',$deliver));
+ $deliver = array();
+ if($interval)
+ @time_sleep_until(microtime(true) + (float) $interval);
+ }
+ }
+
+ // catch any stragglers
+
+ if(count($deliver)) {
+ Master::Summon(array('Deliver',$deliver));
+ }
+ }
+ }
+
+ logger('ratenotif: complete.');
+ return;
+
+ }
+}
diff --git a/Zotlabs/Extend/Hook.php b/Zotlabs/Extend/Hook.php
index 713165faf..fc1e95367 100644
--- a/Zotlabs/Extend/Hook.php
+++ b/Zotlabs/Extend/Hook.php
@@ -10,7 +10,7 @@ class Hook {
$function = serialize($function);
}
- $r = q("SELECT * FROM `hook` WHERE `hook` = '%s' AND `file` = '%s' AND `function` = '%s' and priority = %d and hook_version = %d LIMIT 1",
+ $r = q("SELECT * FROM `hook` WHERE `hook` = '%s' AND `file` = '%s' AND `fn` = '%s' and priority = %d and hook_version = %d LIMIT 1",
dbesc($hook),
dbesc($file),
dbesc($function),
@@ -23,13 +23,13 @@ class Hook {
// To aid in upgrade and transition, remove old settings for any registered hooks that match in all respects except
// for priority or hook_version
- $r = q("DELETE FROM `hook` where `hook` = '%s' and `file` = '%s' and `function` = '%s'",
+ $r = q("DELETE FROM `hook` where `hook` = '%s' and `file` = '%s' and `fn` = '%s'",
dbesc($hook),
dbesc($file),
dbesc($function)
);
- $r = q("INSERT INTO `hook` (`hook`, `file`, `function`, `priority`, `hook_version`) VALUES ( '%s', '%s', '%s', %d, %d )",
+ $r = q("INSERT INTO `hook` (`hook`, `file`, `fn`, `priority`, `hook_version`) VALUES ( '%s', '%s', '%s', %d, %d )",
dbesc($hook),
dbesc($file),
dbesc($function),
@@ -44,7 +44,7 @@ class Hook {
if(is_array($function)) {
$function = serialize($function);
}
- $r = q("DELETE FROM hook WHERE hook = '%s' AND `file` = '%s' AND `function` = '%s' and priority = %d and hook_version = %d",
+ $r = q("DELETE FROM hook WHERE hook = '%s' AND `file` = '%s' AND `fn` = '%s' and priority = %d and hook_version = %d",
dbesc($hook),
dbesc($file),
dbesc($function),
diff --git a/Zotlabs/Lib/AConfig.php b/Zotlabs/Lib/AConfig.php
new file mode 100644
index 000000000..24ec97dfa
--- /dev/null
+++ b/Zotlabs/Lib/AConfig.php
@@ -0,0 +1,25 @@
+<?php
+
+namespace Zotlabs\Lib;
+
+// account configuration storage is built on top of the under-utilised xconfig
+
+class AConfig {
+
+ static public function Load($account_id) {
+ return XConfig::Load('a_' . $account_id);
+ }
+
+ static public function Get($account_id,$family,$key) {
+ return XConfig::Get('a_' . $account_id,$family,$key);
+ }
+
+ static public function Set($account_id,$family,$key,$value) {
+ return XConfig::Get('a_' . $account_id,$family,$key,$value);
+ }
+
+ static public function Delete($account_id,$family,$key) {
+ return XConfig::Delete('a_' . $account_id,$family,$key);
+ }
+
+}
diff --git a/Zotlabs/Lib/AbConfig.php b/Zotlabs/Lib/AbConfig.php
new file mode 100644
index 000000000..f2d6522b9
--- /dev/null
+++ b/Zotlabs/Lib/AbConfig.php
@@ -0,0 +1,73 @@
+<?php
+
+namespace Zotlabs\Lib;
+
+
+class AbConfig {
+
+ static public function Load($chash,$xhash) {
+ $r = q("select * from abconfig where chan = '%s' and xchan = '%s'",
+ dbesc($chash),
+ dbesc($xhash)
+ );
+ return $r;
+ }
+
+
+ static public function Get($chash,$xhash,$family,$key) {
+ $r = q("select * from abconfig where chan = '%s' and xchan = '%s' and cat = '%s' and k = '%s' limit 1",
+ dbesc($chash),
+ dbesc($xhash),
+ dbesc($family),
+ dbesc($key)
+ );
+ if($r) {
+ return ((preg_match('|^a:[0-9]+:{.*}$|s', $r[0]['v'])) ? unserialize($r[0]['v']) : $r[0]['v']);
+ }
+ return false;
+ }
+
+
+ static public function Set($chash,$xhash,$family,$key,$value) {
+
+ $dbvalue = ((is_array($value)) ? serialize($value) : $value);
+ $dbvalue = ((is_bool($dbvalue)) ? intval($dbvalue) : $dbvalue);
+
+ if(self::Get($chash,$xhash,$family,$key) === false) {
+ $r = q("insert into abconfig ( chan, xchan, cat, k, v ) values ( '%s', '%s', '%s', '%s', '%s' ) ",
+ dbesc($chash),
+ dbesc($xhash),
+ dbesc($family),
+ dbesc($key),
+ dbesc($dbvalue)
+ );
+ }
+ else {
+ $r = q("update abconfig set v = '%s' where chan = '%s' and xchan = '%s' and cat = '%s' and k = '%s' ",
+ dbesc($dbvalue),
+ dbesc($chash),
+ dbesc($xhash),
+ dbesc($family),
+ dbesc($key)
+ );
+ }
+
+ if($r)
+ return $value;
+ return false;
+ }
+
+
+ static public function Delete($chash,$xhash,$family,$key) {
+
+ $r = q("delete from abconfig where chan = '%s' and xchan = '%s' and cat = '%s' and k = '%s' ",
+ dbesc($chash),
+ dbesc($xhash),
+ dbesc($family),
+ dbesc($key)
+ );
+
+ return $r;
+ }
+
+} \ No newline at end of file
diff --git a/Zotlabs/Lib/Apps.php b/Zotlabs/Lib/Apps.php
new file mode 100644
index 000000000..20556212a
--- /dev/null
+++ b/Zotlabs/Lib/Apps.php
@@ -0,0 +1,708 @@
+<?php /** @file */
+
+namespace Zotlabs\Lib;
+
+/**
+ * Apps
+ *
+ */
+
+require_once('include/plugin.php');
+require_once('include/channel.php');
+
+
+class Apps {
+
+ static public $installed_system_apps = null;
+
+ static public function get_system_apps($translate = true) {
+
+ $ret = array();
+ if(is_dir('apps'))
+ $files = glob('apps/*.apd');
+ else
+ $files = glob('app/*.apd');
+ if($files) {
+ foreach($files as $f) {
+ $x = self::parse_app_description($f,$translate);
+ if($x) {
+ $ret[] = $x;
+ }
+ }
+ }
+ $files = glob('addon/*/*.apd');
+ if($files) {
+ foreach($files as $f) {
+ $n = basename($f,'.apd');
+ if(plugin_is_installed($n)) {
+ $x = self::parse_app_description($f,$translate);
+ if($x) {
+ $ret[] = $x;
+ }
+ }
+ }
+ }
+
+ return $ret;
+
+ }
+
+
+ static public function import_system_apps() {
+ if(! local_channel())
+ 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())
+ );
+
+ if($apps) {
+ foreach($apps as $app) {
+ $id = self::check_install_system_app($app);
+ // $id will be boolean true or false to install an app, or an integer id to update an existing app
+ if($id === false)
+ continue;
+ if($id !== true) {
+ // if we already installed this app, but it changed, preserve any categories we created
+ $s = '';
+ $r = q("select * from term where otype = %d and oid = d",
+ intval(TERM_OBJ_APP),
+ intval($id)
+ );
+ if($r) {
+ foreach($r as $t) {
+ if($s)
+ $s .= ',';
+ $s .= $t['term'];
+ }
+ $app['categories'] = $s;
+ }
+ }
+ $app['uid'] = local_channel();
+ $app['guid'] = hash('whirlpool',$app['name']);
+ $app['system'] = 1;
+ self::app_install(local_channel(),$app);
+ }
+ }
+ }
+
+ /**
+ * Install the system app if no system apps have been installed, or if a new system app
+ * is discovered, or if the version of a system app changes.
+ */
+
+ static public function check_install_system_app($app) {
+ if((! is_array(self::$installed_system_apps)) || (! count(self::$installed_system_apps))) {
+ return true;
+ }
+ $notfound = true;
+ foreach(self::$installed_system_apps as $iapp) {
+ if($iapp['app_id'] == hash('whirlpool',$app['name'])) {
+ $notfound = false;
+ if($iapp['app_version'] != $app['version']) {
+ return intval($iapp['app_id']);
+ }
+ }
+ }
+ return $notfound;
+ }
+
+
+ static public function app_name_compare($a,$b) {
+ return strcmp($a['name'],$b['name']);
+ }
+
+
+ static public function parse_app_description($f,$translate = true) {
+ $ret = array();
+
+ $baseurl = z_root();
+ $channel = \App::get_channel();
+ $address = (($channel) ? $channel['channel_address'] : '');
+
+ //future expansion
+
+ $observer = \App::get_observer();
+
+
+ $lines = @file($f);
+ if($lines) {
+ foreach($lines as $x) {
+ if(preg_match('/^([a-zA-Z].*?):(.*?)$/ism',$x,$matches)) {
+ $ret[$matches[1]] = trim(str_replace(array('$baseurl','$nick'),array($baseurl,$address),$matches[2]));
+ }
+ }
+ }
+
+
+ if(! $ret['photo'])
+ $ret['photo'] = $baseurl . '/' . get_default_profile_photo(80);
+
+ $ret['type'] = 'system';
+
+ foreach($ret as $k => $v) {
+ if(strpos($v,'http') === 0)
+ $ret[$k] = zid($v);
+ }
+
+ if(array_key_exists('desc',$ret))
+ $ret['desc'] = str_replace(array('\'','"'),array('&#39;','&dquot;'),$ret['desc']);
+
+ if(array_key_exists('target',$ret))
+ $ret['target'] = str_replace(array('\'','"'),array('&#39;','&dquot;'),$ret['target']);
+
+ if(array_key_exists('version',$ret))
+ $ret['version'] = str_replace(array('\'','"'),array('&#39;','&dquot;'),$ret['version']);
+
+
+ if(array_key_exists('requires',$ret)) {
+ $requires = explode(',',$ret['requires']);
+ foreach($requires as $require) {
+ $require = trim(strtolower($require));
+ switch($require) {
+ case 'nologin':
+ if(local_channel())
+ unset($ret);
+ break;
+ case 'admin':
+ if(! is_site_admin())
+ unset($ret);
+ break;
+ case 'local_channel':
+ if(! local_channel())
+ unset($ret);
+ break;
+ case 'public_profile':
+ if(! is_public_profile())
+ unset($ret);
+ break;
+ case 'observer':
+ if(! $observer)
+ unset($ret);
+ break;
+ default:
+ if(! (local_channel() && feature_enabled(local_channel(),$require)))
+ unset($ret);
+ break;
+
+ }
+ }
+ }
+ if($ret) {
+ if($translate)
+ self::translate_system_apps($ret);
+ return $ret;
+ }
+ return false;
+ }
+
+
+ static public function translate_system_apps(&$arr) {
+ $apps = array(
+ 'Site Admin' => t('Site Admin'),
+ 'Bug Report' => t('Bug Report'),
+ 'View Bookmarks' => t('View Bookmarks'),
+ 'My Chatrooms' => t('My Chatrooms'),
+ 'Connections' => t('Connections'),
+ 'Firefox Share' => t('Firefox Share'),
+ 'Remote Diagnostics' => t('Remote Diagnostics'),
+ 'Suggest Channels' => t('Suggest Channels'),
+ 'Login' => t('Login'),
+ 'Channel Manager' => t('Channel Manager'),
+ 'Grid' => t('Grid'),
+ 'Settings' => t('Settings'),
+ 'Files' => t('Files'),
+ 'Webpages' => t('Webpages'),
+ 'Wiki' => t('Wiki'),
+ 'Channel Home' => t('Channel Home'),
+ 'View Profile' => t('View Profile'),
+ 'Photos' => t('Photos'),
+ 'Events' => t('Events'),
+ 'Directory' => t('Directory'),
+ 'Help' => t('Help'),
+ 'Mail' => t('Mail'),
+ 'Mood' => t('Mood'),
+ 'Poke' => t('Poke'),
+ 'Chat' => t('Chat'),
+ 'Search' => t('Search'),
+ 'Probe' => t('Probe'),
+ 'Suggest' => t('Suggest'),
+ 'Random Channel' => t('Random Channel'),
+ 'Invite' => t('Invite'),
+ 'Features' => t('Features'),
+ 'Language' => t('Language'),
+ 'Post' => t('Post'),
+ 'Profile Photo' => t('Profile Photo')
+ );
+
+ if(array_key_exists($arr['name'],$apps))
+ $arr['name'] = $apps[$arr['name']];
+
+ }
+
+
+ // papp is a portable app
+
+ static public function app_render($papp,$mode = 'view') {
+
+ /**
+ * modes:
+ * view: normal mode for viewing an app via bbcode from a conversation or page
+ * provides install/update button if you're logged in locally
+ * 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
+ */
+
+ $installed = false;
+
+ if(! $papp)
+ return;
+
+ if(! $papp['photo'])
+ $papp['photo'] = z_root() . '/' . get_default_profile_photo(80);
+
+ self::translate_system_apps($papp);
+
+ $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($k === 'desc')
+ $papp['desc'] = str_replace(array('\'','"'),array('&#39;','&dquot;'),$papp['desc']);
+
+ if($k === 'requires') {
+ $requires = explode(',',$v);
+ foreach($requires as $require) {
+ $require = trim(strtolower($require));
+ switch($require) {
+ case 'nologin':
+ if(local_channel())
+ return '';
+ break;
+ case 'admin':
+ if(! is_site_admin())
+ return '';
+ break;
+ case 'local_channel':
+ if(! local_channel())
+ return '';
+ break;
+ case 'public_profile':
+ if(! is_public_profile())
+ return '';
+ break;
+ case 'observer':
+ $observer = \App::get_observer();
+ if(! $observer)
+ return '';
+ break;
+ default:
+ if(! (local_channel() && feature_enabled(local_channel(),$require)))
+ return '';
+ break;
+
+ }
+ }
+ }
+ }
+
+ $hosturl = '';
+
+ if(local_channel()) {
+ $installed = self::app_installed(local_channel(),$papp);
+ $hosturl = z_root() . '/';
+ }
+ elseif(remote_channel()) {
+ $observer = \App::get_observer();
+ if($observer && $observer['xchan_network'] === 'zot') {
+ // some folks might have xchan_url redirected offsite, use the connurl
+ $x = parse_url($observer['xchan_connurl']);
+ if($x) {
+ $hosturl = $x['scheme'] . '://' . $x['host'] . '/';
+ }
+ }
+ }
+
+ $install_action = (($installed) ? t('Update') : t('Install'));
+
+ return replace_macros(get_markup_template('app.tpl'),array(
+ '$app' => $papp,
+ '$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') : '')
+ ));
+ }
+
+ static public function app_install($uid,$app) {
+ $app['uid'] = $uid;
+
+ if(self::app_installed($uid,$app))
+ $x = self::app_update($app);
+ else
+ $x = self::app_store($app);
+
+ if($x['success']) {
+ $r = q("select * from app where app_id = '%s' and app_channel = %d limit 1",
+ dbesc($x['app_id']),
+ intval($uid)
+ );
+ if($r) {
+ if(! $r[0]['app_system']) {
+ if($app['categories'] && (! $app['term'])) {
+ $r[0]['term'] = q("select * from term where otype = %d and oid = d",
+ intval(TERM_OBJ_APP),
+ intval($r[0]['id'])
+ );
+ build_sync_packet($uid,array('app' => $r[0]));
+ }
+ }
+ }
+ return $x['app_id'];
+ }
+ return false;
+ }
+
+ static public function app_destroy($uid,$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) {
+ $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));
+ }
+ }
+ }
+ }
+
+
+ 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",
+ dbesc((array_key_exists('guid',$app)) ? $app['guid'] : ''),
+ dbesc((array_key_exists('version',$app)) ? $app['version'] : ''),
+ intval($uid)
+ );
+ return(($r) ? true : false);
+
+ }
+
+
+ static public function app_list($uid, $deleted = false, $cat = '') {
+ if($deleted)
+ $sql_extra = " and app_deleted = 1 ";
+ else
+ $sql_extra = " and app_deleted = 0 ";
+
+ if($cat) {
+ $r = q("select oid from term where otype = %d and term = '%s'",
+ intval(TERM_OBJ_APP),
+ dbesc($cat)
+ );
+ if(! $r)
+ return $r;
+ $sql_extra .= " and app.id in ( ";
+ $s = '';
+ foreach($r as $rr) {
+ if($s)
+ $s .= ',';
+ $s .= intval($rr['oid']);
+ }
+ $sql_extra .= $s . ') ';
+ }
+
+ $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'])
+ $r[$x]['type'] = 'personal';
+ $r[$x]['term'] = q("select * from term where otype = %d and oid = %d",
+ intval(TERM_OBJ_APP),
+ intval($r[$x]['id'])
+ );
+ }
+ }
+ return($r);
+ }
+
+
+ static public function app_decode($s) {
+ $x = base64_decode(str_replace(array('<br />',"\r","\n",' '),array('','','',''),$s));
+ return json_decode($x,true);
+ }
+
+
+ static public function app_store($arr) {
+
+ // logger('app_store: ' . print_r($arr,true));
+
+ $darray = array();
+ $ret = array('success' => false);
+
+ $darray['app_url'] = ((x($arr,'url')) ? $arr['url'] : '');
+ $darray['app_channel'] = ((x($arr,'uid')) ? $arr['uid'] : 0);
+
+ if((! $darray['app_url']) || (! $darray['app_channel']))
+ return $ret;
+
+ if($arr['photo'] && ! strstr($arr['photo'],z_root())) {
+ $x = import_xchan_photo($arr['photo'],get_observer_hash(),true);
+ $arr['photo'] = $x[1];
+ }
+
+
+ $darray['app_id'] = ((x($arr,'guid')) ? $arr['guid'] : random_string(). '.' . \App::get_hostname());
+ $darray['app_sig'] = ((x($arr,'sig')) ? $arr['sig'] : '');
+ $darray['app_author'] = ((x($arr,'author')) ? $arr['author'] : get_observer_hash());
+ $darray['app_name'] = ((x($arr,'name')) ? escape_tags($arr['name']) : t('Unknown'));
+ $darray['app_desc'] = ((x($arr,'desc')) ? escape_tags($arr['desc']) : '');
+ $darray['app_photo'] = ((x($arr,'photo')) ? $arr['photo'] : z_root() . '/' . get_default_profile_photo(80));
+ $darray['app_version'] = ((x($arr,'version')) ? escape_tags($arr['version']) : '');
+ $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_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 )",
+ dbesc($darray['app_id']),
+ dbesc($darray['app_sig']),
+ dbesc($darray['app_author']),
+ dbesc($darray['app_name']),
+ dbesc($darray['app_desc']),
+ dbesc($darray['app_url']),
+ dbesc($darray['app_photo']),
+ dbesc($darray['app_version']),
+ intval($darray['app_channel']),
+ dbesc($darray['app_addr']),
+ dbesc($darray['app_price']),
+ dbesc($darray['app_page']),
+ dbesc($darray['app_requires']),
+ dbesc($created),
+ dbesc($created),
+ intval($darray['app_system']),
+ intval($darray['app_deleted'])
+ );
+ if($r) {
+ $ret['success'] = true;
+ $ret['app_id'] = $darray['app_id'];
+ }
+ if($arr['categories']) {
+ $x = q("select id from app where app_id = '%s' and app_channel = %d limit 1",
+ dbesc($darray['app_id']),
+ intval($darray['app_channel'])
+ );
+ $y = explode(',',$arr['categories']);
+ if($y) {
+ foreach($y as $t) {
+ $t = trim($t);
+ if($t) {
+ store_item_tag($darray['app_channel'],$x[0]['id'],TERM_OBJ_APP,TERM_CATEGORY,escape_tags($t),escape_tags(z_root() . '/apps/?f=&cat=' . escape_tags($t)));
+ }
+ }
+ }
+ }
+
+ return $ret;
+ }
+
+
+ static public function app_update($arr) {
+
+ $darray = array();
+ $ret = array('success' => false);
+
+ $darray['app_url'] = ((x($arr,'url')) ? $arr['url'] : '');
+ $darray['app_channel'] = ((x($arr,'uid')) ? $arr['uid'] : 0);
+ $darray['app_id'] = ((x($arr,'guid')) ? $arr['guid'] : 0);
+
+ if((! $darray['app_url']) || (! $darray['app_channel']) || (! $darray['app_id']))
+ return $ret;
+
+ if($arr['photo'] && ! strstr($arr['photo'],z_root())) {
+ $x = import_xchan_photo($arr['photo'],get_observer_hash(),true);
+ $arr['photo'] = $x[1];
+ }
+
+ $darray['app_sig'] = ((x($arr,'sig')) ? $arr['sig'] : '');
+ $darray['app_author'] = ((x($arr,'author')) ? $arr['author'] : get_observer_hash());
+ $darray['app_name'] = ((x($arr,'name')) ? escape_tags($arr['name']) : t('Unknown'));
+ $darray['app_desc'] = ((x($arr,'desc')) ? escape_tags($arr['desc']) : '');
+ $darray['app_photo'] = ((x($arr,'photo')) ? $arr['photo'] : z_root() . '/' . get_default_profile_photo(80));
+ $darray['app_version'] = ((x($arr,'version')) ? escape_tags($arr['version']) : '');
+ $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_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",
+ dbesc($darray['app_sig']),
+ dbesc($darray['app_author']),
+ dbesc($darray['app_name']),
+ dbesc($darray['app_desc']),
+ dbesc($darray['app_url']),
+ dbesc($darray['app_photo']),
+ dbesc($darray['app_version']),
+ dbesc($darray['app_addr']),
+ dbesc($darray['app_price']),
+ dbesc($darray['app_page']),
+ dbesc($darray['app_requires']),
+ dbesc($edited),
+ intval($darray['app_system']),
+ intval($darray['app_deleted']),
+ dbesc($darray['app_id']),
+ intval($darray['app_channel'])
+ );
+ if($r) {
+ $ret['success'] = true;
+ $ret['app_id'] = $darray['app_id'];
+ }
+
+ $x = q("select id from app where app_id = '%s' and app_channel = %d limit 1",
+ dbesc($darray['app_id']),
+ intval($darray['app_channel'])
+ );
+ if($x) {
+ q("delete from term where otype = %d and oid = %d",
+ intval(TERM_OBJ_APP),
+ intval($x[0]['id'])
+ );
+ if($arr['categories']) {
+ $y = explode(',',$arr['categories']);
+ if($y) {
+ foreach($y as $t) {
+ $t = trim($t);
+ if($t) {
+ store_item_tag($darray['app_channel'],$x[0]['id'],TERM_OBJ_APP,TERM_CATEGORY,escape_tags($t),escape_tags(z_root() . '/apps/?f=&cat=' . escape_tags($t)));
+ }
+ }
+ }
+ }
+ }
+
+ return $ret;
+
+ }
+
+
+ static public function app_encode($app,$embed = false) {
+
+ $ret = array();
+
+ $ret['type'] = 'personal';
+
+ if($app['app_id'])
+ $ret['guid'] = $app['app_id'];
+
+ if($app['app_id'])
+ $ret['guid'] = $app['app_id'];
+
+ if($app['app_sig'])
+ $ret['sig'] = $app['app_sig'];
+
+ if($app['app_author'])
+ $ret['author'] = $app['app_author'];
+
+ if($app['app_name'])
+ $ret['name'] = $app['app_name'];
+
+ if($app['app_desc'])
+ $ret['desc'] = $app['app_desc'];
+
+ if($app['app_url'])
+ $ret['url'] = $app['app_url'];
+
+ if($app['app_photo'])
+ $ret['photo'] = $app['app_photo'];
+
+ if($app['app_version'])
+ $ret['version'] = $app['app_version'];
+
+ if($app['app_addr'])
+ $ret['addr'] = $app['app_addr'];
+
+ if($app['app_price'])
+ $ret['price'] = $app['app_price'];
+
+ if($app['app_page'])
+ $ret['page'] = $app['app_page'];
+
+ if($app['app_requires'])
+ $ret['requires'] = $app['app_requires'];
+
+ if($app['app_system'])
+ $ret['system'] = $app['app_system'];
+
+ if($app['app_deleted'])
+ $ret['deleted'] = $app['app_deleted'];
+
+ if($app['term']) {
+ $s = '';
+ foreach($app['term'] as $t) {
+ if($s)
+ $s .= ',';
+ $s .= $t['term'];
+ }
+ $ret['categories'] = $s;
+ }
+
+
+ if(! $embed)
+ return $ret;
+
+ if(array_key_exists('categories',$ret))
+ unset($ret['categories']);
+
+ $j = json_encode($ret);
+ return '[app]' . chunk_split(base64_encode($j),72,"\n") . '[/app]';
+
+ }
+
+
+ static public function papp_encode($papp) {
+ return chunk_split(base64_encode(json_encode($papp)),72,"\n");
+
+ }
+
+}
+
+
diff --git a/Zotlabs/Lib/Chatroom.php b/Zotlabs/Lib/Chatroom.php
new file mode 100644
index 000000000..e1a9a10b3
--- /dev/null
+++ b/Zotlabs/Lib/Chatroom.php
@@ -0,0 +1,267 @@
+<?php
+namespace Zotlabs\Lib;
+
+/**
+ * @brief Chat related functions.
+ */
+
+
+
+class Chatroom {
+ /**
+ * @brief Creates a chatroom.
+ *
+ * @param array $channel
+ * @param array $arr
+ * @return An associative array containing:
+ * - success: A boolean
+ * - message: (optional) A string
+ */
+
+ static public function create($channel, $arr) {
+
+ $ret = array('success' => false);
+
+ $name = trim($arr['name']);
+ if(! $name) {
+ $ret['message'] = t('Missing room name');
+ return $ret;
+ }
+
+ $r = q("select cr_id from chatroom where cr_uid = %d and cr_name = '%s' limit 1",
+ intval($channel['channel_id']),
+ dbesc($name)
+ );
+ if($r) {
+ $ret['message'] = t('Duplicate room name');
+ return $ret;
+ }
+
+ $r = q("select count(cr_id) as total from chatroom where cr_aid = %d",
+ intval($channel['channel_account_id'])
+ );
+ if($r)
+ $limit = service_class_fetch($channel['channel_id'], 'chatrooms');
+
+ if(($r) && ($limit !== false) && ($r[0]['total'] >= $limit)) {
+ $ret['message'] = upgrade_message();
+ return $ret;
+ }
+
+ if(! array_key_exists('expire', $arr))
+ $arr['expire'] = 120; // minutes, e.g. 2 hours
+
+ $created = datetime_convert();
+
+ $x = q("insert into chatroom ( cr_aid, cr_uid, cr_name, cr_created, cr_edited, cr_expire, allow_cid, allow_gid, deny_cid, deny_gid )
+ values ( %d, %d , '%s', '%s', '%s', %d, '%s', '%s', '%s', '%s' ) ",
+ intval($channel['channel_account_id']),
+ intval($channel['channel_id']),
+ dbesc($name),
+ dbesc($created),
+ dbesc($created),
+ intval($arr['expire']),
+ dbesc($arr['allow_cid']),
+ dbesc($arr['allow_gid']),
+ dbesc($arr['deny_cid']),
+ dbesc($arr['deny_gid'])
+ );
+
+ if($x)
+ $ret['success'] = true;
+
+ return $ret;
+ }
+
+
+ static public function destroy($channel,$arr) {
+
+ $ret = array('success' => false);
+
+ if(intval($arr['cr_id']))
+ $sql_extra = " and cr_id = " . intval($arr['cr_id']) . " ";
+ elseif(trim($arr['cr_name']))
+ $sql_extra = " and cr_name = '" . protect_sprintf(dbesc(trim($arr['cr_name']))) . "' ";
+ else {
+ $ret['message'] = t('Invalid room specifier.');
+ return $ret;
+ }
+
+ $r = q("select * from chatroom where cr_uid = %d $sql_extra limit 1",
+ intval($channel['channel_id'])
+ );
+ if(! $r) {
+ $ret['message'] = t('Invalid room specifier.');
+ return $ret;
+ }
+
+ build_sync_packet($channel['channel_id'],array('chatroom' => $r));
+
+ q("delete from chatroom where cr_id = %d",
+ intval($r[0]['cr_id'])
+ );
+ if($r[0]['cr_id']) {
+ q("delete from chatpresence where cp_room = %d",
+ intval($r[0]['cr_id'])
+ );
+ q("delete from chat where chat_room = %d",
+ intval($r[0]['cr_id'])
+ );
+ }
+
+ $ret['success'] = true;
+ return $ret;
+ }
+
+
+ static public function enter($observer_xchan, $room_id, $status, $client) {
+
+ if(! $room_id || ! $observer_xchan)
+ return;
+
+ $r = q("select * from chatroom where cr_id = %d limit 1",
+ intval($room_id)
+ );
+ if(! $r) {
+ notice( t('Room not found.') . EOL);
+ return false;
+ }
+ require_once('include/security.php');
+ $sql_extra = permissions_sql($r[0]['cr_uid']);
+
+ $x = q("select * from chatroom where cr_id = %d and cr_uid = %d $sql_extra limit 1",
+ intval($room_id),
+ intval($r[0]['cr_uid'])
+ );
+ if(! $x) {
+ notice( t('Permission denied.') . EOL);
+ return false;
+ }
+
+ $limit = service_class_fetch($r[0]['cr_uid'], 'chatters_inroom');
+ if($limit !== false) {
+ $y = q("select count(*) as total from chatpresence where cp_room = %d",
+ intval($room_id)
+ );
+ if($y && $y[0]['total'] > $limit) {
+ notice( t('Room is full') . EOL);
+ return false;
+ }
+ }
+
+ if(intval($x[0]['cr_expire'])) {
+ $r = q("delete from chat where created < %s - INTERVAL %s and chat_room = %d",
+ db_utcnow(),
+ db_quoteinterval( intval($x[0]['cr_expire']) . ' MINUTE' ),
+ intval($x[0]['cr_id'])
+ );
+ }
+
+ $r = q("select * from chatpresence where cp_xchan = '%s' and cp_room = %d limit 1",
+ dbesc($observer_xchan),
+ intval($room_id)
+ );
+ if($r) {
+ q("update chatpresence set cp_last = '%s' where cp_id = %d and cp_client = '%s'",
+ dbesc(datetime_convert()),
+ intval($r[0]['cp_id']),
+ dbesc($client)
+ );
+ return true;
+ }
+
+ $r = q("insert into chatpresence ( cp_room, cp_xchan, cp_last, cp_status, cp_client )
+ values ( %d, '%s', '%s', '%s', '%s' )",
+ intval($room_id),
+ dbesc($observer_xchan),
+ dbesc(datetime_convert()),
+ dbesc($status),
+ dbesc($client)
+ );
+
+ return $r;
+ }
+
+
+ function leave($observer_xchan, $room_id, $client) {
+ if(! $room_id || ! $observer_xchan)
+ return;
+
+ $r = q("select * from chatpresence where cp_xchan = '%s' and cp_room = %d and cp_client = '%s' limit 1",
+ dbesc($observer_xchan),
+ intval($room_id),
+ dbesc($client)
+ );
+ if($r) {
+ q("delete from chatpresence where cp_id = %d",
+ intval($r[0]['cp_id'])
+ );
+ }
+
+ return true;
+ }
+
+
+ static public function roomlist($uid) {
+ require_once('include/security.php');
+ $sql_extra = permissions_sql($uid);
+
+ $r = q("select allow_cid, allow_gid, deny_cid, deny_gid, cr_name, cr_expire, cr_id, count(cp_id) as cr_inroom from chatroom left join chatpresence on cr_id = cp_room where cr_uid = %d $sql_extra group by cr_name, cr_id order by cr_name",
+ intval($uid)
+ );
+
+ return $r;
+ }
+
+ static public function list_count($uid) {
+ require_once('include/security.php');
+ $sql_extra = permissions_sql($uid);
+
+ $r = q("select count(*) as total from chatroom where cr_uid = %d $sql_extra",
+ intval($uid)
+ );
+
+ return $r[0]['total'];
+ }
+
+ /**
+ * create a chat message via API.
+ * It is the caller's responsibility to enter the room.
+ */
+
+ static public function message($uid, $room_id, $xchan, $text) {
+
+ $ret = array('success' => false);
+
+ if(! $text)
+ return;
+
+ $sql_extra = permissions_sql($uid);
+
+ $r = q("select * from chatroom where cr_uid = %d and cr_id = %d $sql_extra",
+ intval($uid),
+ intval($room_id)
+ );
+ if(! $r)
+ return $ret;
+
+ $arr = array(
+ 'chat_room' => $room_id,
+ 'chat_xchan' => $xchan,
+ 'chat_text' => $text
+ );
+
+ call_hooks('chat_message', $arr);
+
+ $x = q("insert into chat ( chat_room, chat_xchan, created, chat_text )
+ values( %d, '%s', '%s', '%s' )",
+ intval($room_id),
+ dbesc($xchan),
+ dbesc(datetime_convert()),
+ dbesc($arr['chat_text'])
+ );
+
+ $ret['success'] = true;
+ return $ret;
+ }
+}
diff --git a/Zotlabs/Lib/Config.php b/Zotlabs/Lib/Config.php
new file mode 100644
index 000000000..d4ee1aeda
--- /dev/null
+++ b/Zotlabs/Lib/Config.php
@@ -0,0 +1,166 @@
+<?php /** @file */
+
+namespace Zotlabs\Lib;
+
+
+class Config {
+
+ /**
+ * @brief Loads the hub's configuration from database to a cached storage.
+ *
+ * Retrieve a category ($family) of config variables from database to a cached
+ * storage in the global App::$config[$family].
+ *
+ * @param string $family
+ * The category of the configuration value
+ */
+
+ static public function Load($family) {
+ if(! array_key_exists($family, \App::$config))
+ \App::$config[$family] = array();
+
+ if(! array_key_exists('config_loaded', \App::$config[$family])) {
+ $r = q("SELECT * FROM config WHERE cat = '%s'", dbesc($family));
+ if($r !== false) {
+ if($r) {
+ foreach($r as $rr) {
+ $k = $rr['k'];
+ \App::$config[$family][$k] = $rr['v'];
+ }
+ }
+ \App::$config[$family]['config_loaded'] = true;
+ }
+ }
+ }
+
+ /**
+ * @brief Sets a configuration value for the hub.
+ *
+ * Stores a config value ($value) in the category ($family) under the key ($key).
+ *
+ * @param string $family
+ * The category of the configuration value
+ * @param string $key
+ * The configuration key to set
+ * @param mixed $value
+ * The value to store in the configuration
+ * @return mixed
+ * Return the set value, or false if the database update failed
+ */
+
+ static public function Set($family,$key,$value) {
+ // manage array value
+ $dbvalue = ((is_array($value)) ? serialize($value) : $value);
+ $dbvalue = ((is_bool($dbvalue)) ? intval($dbvalue) : $dbvalue);
+
+ if(get_config($family, $key) === false || (! self::get_from_storage($family, $key))) {
+ $ret = q("INSERT INTO config ( cat, k, v ) VALUES ( '%s', '%s', '%s' ) ",
+ dbesc($family),
+ dbesc($key),
+ dbesc($dbvalue)
+ );
+ if($ret) {
+ \App::$config[$family][$key] = $value;
+ $ret = $value;
+ }
+ return $ret;
+ }
+
+ $ret = q("UPDATE config SET v = '%s' WHERE cat = '%s' AND k = '%s'",
+ dbesc($dbvalue),
+ dbesc($family),
+ dbesc($key)
+ );
+
+ if($ret) {
+ \App::$config[$family][$key] = $value;
+ $ret = $value;
+ }
+ return $ret;
+
+ }
+
+ /**
+ * @brief Get a particular config variable given the category name ($family)
+ * and a key.
+ *
+ * Get a particular config variable from the given category ($family) and the
+ * $key from a cached storage in App::$config[$family]. If a key is found in the
+ * DB but does not exist in local config cache, pull it into the cache so we
+ * do not have to hit the DB again for this item.
+ *
+ * Returns false if not set.
+ *
+ * @param string $family
+ * The category of the configuration value
+ * @param string $key
+ * The configuration key to query
+ * @return mixed Return value or false on error or if not set
+ */
+
+ static public function Get($family,$key) {
+ if((! array_key_exists($family, \App::$config)) || (! array_key_exists('config_loaded', \App::$config[$family])))
+ self::Load($family);
+
+ if(array_key_exists('config_loaded', \App::$config[$family])) {
+ if(! array_key_exists($key, \App::$config[$family])) {
+ return false;
+ }
+ return ((! is_array(\App::$config[$family][$key])) && (preg_match('|^a:[0-9]+:{.*}$|s', \App::$config[$family][$key]))
+ ? unserialize(\App::$config[$family][$key])
+ : \App::$config[$family][$key]
+ );
+ }
+
+ return false;
+ }
+
+ /**
+ * @brief Deletes the given key from the hub's configuration database.
+ *
+ * Removes the configured value from the stored cache in App::$config[$family]
+ * and removes it from the database.
+ *
+ * @param string $family
+ * The category of the configuration value
+ * @param string $key
+ * The configuration key to delete
+ * @return mixed
+ */
+
+ static public function Delete($family,$key) {
+
+ $ret = false;
+
+ if(array_key_exists($family, \App::$config) && array_key_exists($key, \App::$config[$family]))
+ unset(\App::$config[$family][$key]);
+ $ret = q("DELETE FROM config WHERE cat = '%s' AND k = '%s'",
+ dbesc($family),
+ dbesc($key)
+ );
+ return $ret;
+ }
+
+
+ /**
+ * @brief Returns a value directly from the database configuration storage.
+ *
+ * This function queries directly the database and bypasses the chached storage
+ * from get_config($family, $key).
+ *
+ * @param string $family
+ * The category of the configuration value
+ * @param string $key
+ * The configuration key to query
+ * @return mixed
+ */
+
+ static private function get_from_storage($family,$key) {
+ $ret = q("SELECT * FROM config WHERE cat = '%s' AND k = '%s' LIMIT 1",
+ dbesc($family),
+ dbesc($key)
+ );
+ return $ret;
+ }
+
+}
diff --git a/Zotlabs/Lib/Enotify.php b/Zotlabs/Lib/Enotify.php
new file mode 100644
index 000000000..56c717468
--- /dev/null
+++ b/Zotlabs/Lib/Enotify.php
@@ -0,0 +1,685 @@
+<?php
+
+namespace Zotlabs\Lib;
+
+/**
+ * @brief File with functions and a class for generating system and email notifications.
+ */
+
+
+class Enotify {
+
+ /**
+ * @brief
+ *
+ * @param array $params an assoziative array with:
+ * * \e string \b from_xchan sender xchan hash
+ * * \e string \b to_xchan recipient xchan hash
+ * * \e array \b item an assoziative array
+ * * \e int \b type one of the NOTIFY_* constants from boot.php
+ * * \e string \b link
+ * * \e string \b parent_mid
+ * * \e string \b otype
+ * * \e string \b verb
+ * * \e string \b activity
+ */
+
+
+ static public function submit($params) {
+
+ logger('notification: entry', LOGGER_DEBUG);
+
+ // throw a small amount of entropy into the system to breakup duplicates arriving at the same precise instant.
+ usleep(mt_rand(0, 10000));
+
+ if ($params['from_xchan']) {
+ $x = q("select * from xchan where xchan_hash = '%s' limit 1",
+ dbesc($params['from_xchan'])
+ );
+ }
+ if ($params['to_xchan']) {
+ $y = q("select channel.*, account.* from channel left join account on channel_account_id = account_id
+ where channel_hash = '%s' and channel_removed = 0 limit 1",
+ dbesc($params['to_xchan'])
+ );
+ }
+ if ($x & $y) {
+ $sender = $x[0];
+ $recip = $y[0];
+ } else {
+ logger('notification: no sender or recipient.');
+ logger('sender: ' . $params['from_xchan']);
+ logger('recip: ' . $params['to_xchan']);
+ return;
+ }
+
+ // from here on everything is in the recipients language
+
+ push_lang($recip['account_language']); // should probably have a channel language
+
+ $banner = t('$Projectname Notification');
+ $product = t('$projectname'); // PLATFORM_NAME;
+ $siteurl = z_root();
+ $thanks = t('Thank You,');
+ $sitename = get_config('system','sitename');
+ $site_admin = sprintf( t('%s Administrator'), $sitename);
+
+ $sender_name = $product;
+ $hostname = \App::get_hostname();
+ if(strpos($hostname,':'))
+ $hostname = substr($hostname,0,strpos($hostname,':'));
+
+ // Do not translate 'noreply' as it must be a legal 7-bit email address
+ $sender_email = 'noreply' . '@' . $hostname;
+
+ $additional_mail_header = "";
+
+ if(array_key_exists('item', $params)) {
+ require_once('include/conversation.php');
+ // if it's a normal item...
+ if (array_key_exists('verb', $params['item'])) {
+ // localize_item() alters the original item so make a copy first
+ $i = $params['item'];
+ logger('calling localize');
+ localize_item($i);
+ $title = $i['title'];
+ $body = $i['body'];
+ $private = (($i['item_private']) || intval($i['item_obscured']));
+ }
+ else {
+ $title = $params['item']['title'];
+ $body = $params['item']['body'];
+ }
+ }
+ else {
+ $title = $body = '';
+ }
+
+
+ // e.g. "your post", "David's photo", etc.
+ $possess_desc = t('%s <!item_type!>');
+
+ if ($params['type'] == NOTIFY_MAIL) {
+ logger('notification: mail');
+ $subject = sprintf( t('[Hubzilla:Notify] New mail received at %s'),$sitename);
+
+ $preamble = sprintf( t('%1$s, %2$s sent you a new private message at %3$s.'),$recip['channel_name'], $sender['xchan_name'],$sitename);
+ $epreamble = sprintf( t('%1$s sent you %2$s.'),'[zrl=' . $sender['xchan_url'] . ']' . $sender['xchan_name'] . '[/zrl]', '[zrl=$itemlink]' . t('a private message') . '[/zrl]');
+ $sitelink = t('Please visit %s to view and/or reply to your private messages.');
+ $tsitelink = sprintf( $sitelink, $siteurl . '/mail/' . $params['item']['id'] );
+ $hsitelink = sprintf( $sitelink, '<a href="' . $siteurl . '/mail/' . $params['item']['id'] . '">' . $sitename . '</a>');
+ $itemlink = $siteurl . '/mail/' . $params['item']['id'];
+ }
+
+ if ($params['type'] == NOTIFY_COMMENT) {
+// logger("notification: params = " . print_r($params, true), LOGGER_DEBUG);
+
+ $itemlink = $params['link'];
+
+ // ignore like/unlike activity on posts - they probably require a sepearate notification preference
+
+ if (array_key_exists('item',$params) && (! visible_activity($params['item'])))
+ return;
+
+ $parent_mid = $params['parent_mid'];
+
+ // Check to see if there was already a notify for this post.
+ // If so don't create a second notification
+
+ $p = null;
+ $p = q("select id from notify where link = '%s' and uid = %d limit 1",
+ dbesc($params['link']),
+ intval($recip['channel_id'])
+ );
+ if ($p) {
+ logger('notification: comment already notified');
+ pop_lang();
+ return;
+ }
+
+
+ // if it's a post figure out who's post it is.
+
+ $p = null;
+
+ if($params['otype'] === 'item' && $parent_mid) {
+ $p = q("select * from item where mid = '%s' and uid = %d limit 1",
+ dbesc($parent_mid),
+ intval($recip['channel_id'])
+ );
+ }
+
+ xchan_query($p);
+
+
+ $item_post_type = item_post_type($p[0]);
+// $private = $p[0]['item_private'];
+ $parent_id = $p[0]['id'];
+
+ $parent_item = $p[0];
+
+ //$possess_desc = str_replace('<!item_type!>',$possess_desc);
+
+ // "a post"
+ $dest_str = sprintf(t('%1$s, %2$s commented on [zrl=%3$s]a %4$s[/zrl]'),
+ $recip['channel_name'],
+ '[zrl=' . $sender['xchan_url'] . ']' . $sender['xchan_name'] . '[/zrl]',
+ $itemlink,
+ $item_post_type);
+
+ // "George Bull's post"
+ if($p)
+ $dest_str = sprintf(t('%1$s, %2$s commented on [zrl=%3$s]%4$s\'s %5$s[/zrl]'),
+ $recip['channel_name'],
+ '[zrl=' . $sender['xchan_url'] . ']' . $sender['xchan_name'] . '[/zrl]',
+ $itemlink,
+ $p[0]['author']['xchan_name'],
+ $item_post_type);
+
+ // "your post"
+ if($p[0]['owner']['xchan_name'] == $p[0]['author']['xchan_name'] && intval($p[0]['item_wall']))
+ $dest_str = sprintf(t('%1$s, %2$s commented on [zrl=%3$s]your %4$s[/zrl]'),
+ $recip['channel_name'],
+ '[zrl=' . $sender['xchan_url'] . ']' . $sender['xchan_name'] . '[/zrl]',
+ $itemlink,
+ $item_post_type);
+
+ // Some mail softwares relies on subject field for threading.
+ // So, we cannot have different subjects for notifications of the same thread.
+ // Before this we have the name of the replier on the subject rendering
+ // differents subjects for messages on the same thread.
+
+ $subject = sprintf( t('[Hubzilla:Notify] Comment to conversation #%1$d by %2$s'), $parent_id, $sender['xchan_name']);
+ $preamble = sprintf( t('%1$s, %2$s commented on an item/conversation you have been following.'), $recip['channel_name'], $sender['xchan_name']);
+ $epreamble = $dest_str;
+
+ $sitelink = t('Please visit %s to view and/or reply to the conversation.');
+ $tsitelink = sprintf( $sitelink, $siteurl );
+ $hsitelink = sprintf( $sitelink, '<a href="' . $siteurl . '">' . $sitename . '</a>');
+ }
+
+ if($params['type'] == NOTIFY_WALL) {
+ $subject = sprintf( t('[Hubzilla:Notify] %s posted to your profile wall') , $sender['xchan_name']);
+
+ $preamble = sprintf( t('%1$s, %2$s posted to your profile wall at %3$s') , $recip['channel_name'], $sender['xchan_name'], $sitename);
+
+ $epreamble = sprintf( t('%1$s, %2$s posted to [zrl=%3$s]your wall[/zrl]') ,
+ $recip['channel_name'],
+ '[zrl=' . $sender['xchan_url'] . ']' . $sender['xchan_name'] . '[/zrl]',
+ $params['link']);
+
+ $sitelink = t('Please visit %s to view and/or reply to the conversation.');
+ $tsitelink = sprintf( $sitelink, $siteurl );
+ $hsitelink = sprintf( $sitelink, '<a href="' . $siteurl . '">' . $sitename . '</a>');
+ $itemlink = $params['link'];
+ }
+
+ if ($params['type'] == NOTIFY_TAGSELF) {
+
+ $p = null;
+ $p = q("select id from notify where link = '%s' and uid = %d limit 1",
+ dbesc($params['link']),
+ intval($recip['channel_id'])
+ );
+ if ($p) {
+ logger('enotify: tag: already notified about this post');
+ pop_lang();
+ return;
+ }
+
+ $subject = sprintf( t('[Hubzilla:Notify] %s tagged you') , $sender['xchan_name']);
+ $preamble = sprintf( t('%1$s, %2$s tagged you at %3$s') , $recip['channel_name'], $sender['xchan_name'], $sitename);
+ $epreamble = sprintf( t('%1$s, %2$s [zrl=%3$s]tagged you[/zrl].') ,
+ $recip['channel_name'],
+ '[zrl=' . $sender['xchan_url'] . ']' . $sender['xchan_name'] . '[/zrl]',
+ $params['link']);
+
+ $sitelink = t('Please visit %s to view and/or reply to the conversation.');
+ $tsitelink = sprintf( $sitelink, $siteurl );
+ $hsitelink = sprintf( $sitelink, '<a href="' . $siteurl . '">' . $sitename . '</a>');
+ $itemlink = $params['link'];
+ }
+
+ if ($params['type'] == NOTIFY_POKE) {
+ $subject = sprintf( t('[Hubzilla:Notify] %1$s poked you') , $sender['xchan_name']);
+ $preamble = sprintf( t('%1$s, %2$s poked you at %3$s') , $recip['channel_name'], $sender['xchan_name'], $sitename);
+ $epreamble = sprintf( t('%1$s, %2$s [zrl=%2$s]poked you[/zrl].') ,
+ $recip['channel_name'],
+ '[zrl=' . $sender['xchan_url'] . ']' . $sender['xchan_name'] . '[/zrl]',
+ $params['link']);
+
+ $subject = str_replace('poked', t($params['activity']), $subject);
+ $preamble = str_replace('poked', t($params['activity']), $preamble);
+ $epreamble = str_replace('poked', t($params['activity']), $epreamble);
+
+ $sitelink = t('Please visit %s to view and/or reply to the conversation.');
+ $tsitelink = sprintf( $sitelink, $siteurl );
+ $hsitelink = sprintf( $sitelink, '<a href="' . $siteurl . '">' . $sitename . '</a>');
+ $itemlink = $params['link'];
+ }
+
+ if ($params['type'] == NOTIFY_TAGSHARE) {
+ $subject = sprintf( t('[Hubzilla:Notify] %s tagged your post') , $sender['xchan_name']);
+ $preamble = sprintf( t('%1$s, %2$s tagged your post at %3$s') , $recip['channel_name'],$sender['xchan_name'], $sitename);
+ $epreamble = sprintf( t('%1$s, %2$s tagged [zrl=%3$s]your post[/zrl]') ,
+ $recip['channel_name'],
+ '[zrl=' . $sender['xchan_url'] . ']' . $sender['xchan_name'] . '[/zrl]',
+ $itemlink);
+
+ $sitelink = t('Please visit %s to view and/or reply to the conversation.');
+ $tsitelink = sprintf( $sitelink, $siteurl );
+ $hsitelink = sprintf( $sitelink, '<a href="' . $siteurl . '">' . $sitename . '</a>');
+ $itemlink = $params['link'];
+ }
+
+ if ($params['type'] == NOTIFY_INTRO) {
+ $subject = sprintf( t('[Hubzilla:Notify] Introduction received'));
+ $preamble = sprintf( t('%1$s, you\'ve received an new connection request from \'%2$s\' at %3$s'), $recip['channel_name'], $sender['xchan_name'], $sitename);
+ $epreamble = sprintf( t('%1$s, you\'ve received [zrl=%2$s]a new connection request[/zrl] from %3$s.'),
+ $recip['channel_name'],
+ $siteurl . '/connections/ifpending',
+ '[zrl=' . $sender['xchan_url'] . ']' . $sender['xchan_name'] . '[/zrl]');
+ $body = sprintf( t('You may visit their profile at %s'),$sender['xchan_url']);
+
+ $sitelink = t('Please visit %s to approve or reject the connection request.');
+ $tsitelink = sprintf( $sitelink, $siteurl . '/connections/ifpending');
+ $hsitelink = sprintf( $sitelink, '<a href="' . $siteurl . '/connections/ifpending">' . $sitename . '</a>');
+ $itemlink = $params['link'];
+ }
+
+ if ($params['type'] == NOTIFY_SUGGEST) {
+ $subject = sprintf( t('[Hubzilla:Notify] Friend suggestion received'));
+ $preamble = sprintf( t('%1$s, you\'ve received a friend suggestion from \'%2$s\' at %3$s'), $recip['channel_name'], $sender['xchan_name'], $sitename);
+ $epreamble = sprintf( t('%1$s, you\'ve received [zrl=%2$s]a friend suggestion[/zrl] for %3$s from %4$s.'),
+ $recip['channel_name'],
+ $itemlink,
+ '[zrl=' . $params['item']['url'] . ']' . $params['item']['name'] . '[/zrl]',
+ '[zrl=' . $sender['xchan_url'] . ']' . $sender['xchan_name'] . '[/zrl]');
+
+ $body = t('Name:') . ' ' . $params['item']['name'] . "\n";
+ $body .= t('Photo:') . ' ' . $params['item']['photo'] . "\n";
+ $body .= sprintf( t('You may visit their profile at %s'),$params['item']['url']);
+
+ $sitelink = t('Please visit %s to approve or reject the suggestion.');
+ $tsitelink = sprintf( $sitelink, $siteurl );
+ $hsitelink = sprintf( $sitelink, '<a href="' . $siteurl . '">' . $sitename . '</a>');
+ $itemlink = $params['link'];
+ }
+
+ if ($params['type'] == NOTIFY_CONFIRM) {
+ // ?
+ }
+
+ if ($params['type'] == NOTIFY_SYSTEM) {
+ // ?
+ }
+
+ $h = array(
+ 'params' => $params,
+ 'subject' => $subject,
+ 'preamble' => $preamble,
+ 'epreamble' => $epreamble,
+ 'body' => $body,
+ 'sitelink' => $sitelink,
+ 'sitename' => $sitename,
+ 'tsitelink' => $tsitelink,
+ 'hsitelink' => $hsitelink,
+ 'itemlink' => $itemlink,
+ 'sender' => $sender,
+ 'recipient' => $recip
+ );
+
+ call_hooks('enotify', $h);
+
+ $subject = $h['subject'];
+ $preamble = $h['preamble'];
+ $epreamble = $h['epreamble'];
+ $body = $h['body'];
+ $sitelink = $h['sitelink'];
+ $tsitelink = $h['tsitelink'];
+ $hsitelink = $h['hsitelink'];
+ $itemlink = $h['itemlink'];
+
+
+ require_once('include/html2bbcode.php');
+
+ do {
+ $dups = false;
+ $hash = random_string();
+ $r = q("SELECT `id` FROM `notify` WHERE `hash` = '%s' LIMIT 1",
+ dbesc($hash));
+ if ($r)
+ $dups = true;
+ } while ($dups === true);
+
+
+ $datarray = array();
+ $datarray['hash'] = $hash;
+ $datarray['sender_hash'] = $sender['xchan_hash'];
+ $datarray['xname'] = $sender['xchan_name'];
+ $datarray['url'] = $sender['xchan_url'];
+ $datarray['photo'] = $sender['xchan_photo_s'];
+ $datarray['created'] = datetime_convert();
+ $datarray['aid'] = $recip['channel_account_id'];
+ $datarray['uid'] = $recip['channel_id'];
+ $datarray['link'] = $itemlink;
+ $datarray['parent'] = $parent_mid;
+ $datarray['parent_item'] = $parent_item;
+ $datarray['ntype'] = $params['type'];
+ $datarray['verb'] = $params['verb'];
+ $datarray['otype'] = $params['otype'];
+ $datarray['abort'] = false;
+
+ $datarray['item'] = $params['item'];
+
+ call_hooks('enotify_store', $datarray);
+
+ if ($datarray['abort']) {
+ pop_lang();
+ return;
+ }
+
+
+ // create notification entry in DB
+ $seen = 0;
+
+ // Mark some notifications as seen right away
+ // Note! The notification have to be created, because they are used to send emails
+ // So easiest solution to hide them from Notices is to mark them as seen right away.
+ // Another option would be to not add them to the DB, and change how emails are handled (probably would be better that way)
+ $always_show_in_notices = get_pconfig($recip['channel_id'],'system','always_show_in_notices');
+ if (!$always_show_in_notices) {
+ if (($params['type'] == NOTIFY_WALL) || ($params['type'] == NOTIFY_MAIL) || ($params['type'] == NOTIFY_INTRO)) {
+ $seen = 1;
+ }
+ }
+
+ $r = q("insert into notify (hash,xname,url,photo,created,aid,uid,link,parent,seen,ntype,verb,otype)
+ values('%s','%s','%s','%s','%s',%d,%d,'%s','%s',%d,%d,'%s','%s')",
+ dbesc($datarray['hash']),
+ dbesc($datarray['xname']),
+ dbesc($datarray['url']),
+ dbesc($datarray['photo']),
+ dbesc($datarray['created']),
+ intval($datarray['aid']),
+ intval($datarray['uid']),
+ dbesc($datarray['link']),
+ dbesc($datarray['parent']),
+ intval($seen),
+ intval($datarray['ntype']),
+ dbesc($datarray['verb']),
+ dbesc($datarray['otype'])
+ );
+
+ $r = q("select id from notify where hash = '%s' and uid = %d limit 1",
+ dbesc($hash),
+ intval($recip['channel_id'])
+ );
+ if ($r) {
+ $notify_id = $r[0]['id'];
+ } else {
+ logger('notification not found.');
+ pop_lang();
+ return;
+ }
+
+ $itemlink = z_root() . '/notify/view/' . $notify_id;
+ $msg = str_replace('$itemlink',$itemlink,$epreamble);
+
+ // wretched hack, but we don't want to duplicate all the preamble variations and we also don't want to screw up a translation
+
+ if ((\App::$language === 'en' || (! \App::$language)) && strpos($msg,', '))
+ $msg = substr($msg,strpos($msg,', ')+1);
+
+ $r = q("update notify set msg = '%s' where id = %d and uid = %d",
+ dbesc($msg),
+ intval($notify_id),
+ intval($datarray['uid'])
+ );
+
+ // send email notification if notification preferences permit
+
+ require_once('bbcode.php');
+ if ((intval($recip['channel_notifyflags']) & intval($params['type'])) || $params['type'] == NOTIFY_SYSTEM) {
+
+ logger('notification: sending notification email');
+
+ $hn = get_pconfig($recip['channel_id'],'system','email_notify_host');
+ if($hn && (! stristr(\App::get_hostname(),$hn))) {
+ // this isn't the email notification host
+ pop_lang();
+ return;
+ }
+
+ $textversion = strip_tags(html_entity_decode(bbcode(stripslashes(str_replace(array("\\r", "\\n"), array( "", "\n"), $body))),ENT_QUOTES,'UTF-8'));
+
+ $htmlversion = bbcode(stripslashes(str_replace(array("\\r","\\n"), array("","<br />\n"),$body)));
+
+
+ // use $_SESSION['zid_override'] to force zid() to use
+ // the recipient address instead of the current observer
+
+ $_SESSION['zid_override'] = $recip['channel_address'] . '@' . \App::get_hostname();
+ $_SESSION['zrl_override'] = z_root() . '/channel/' . $recip['channel_address'];
+
+ $textversion = zidify_links($textversion);
+ $htmlversion = zidify_links($htmlversion);
+
+ // unset when done to revert to normal behaviour
+
+ unset($_SESSION['zid_override']);
+ unset($_SESSION['zrl_override']);
+
+ $datarray = array();
+ $datarray['banner'] = $banner;
+ $datarray['product'] = $product;
+ $datarray['preamble'] = $preamble;
+ $datarray['sitename'] = $sitename;
+ $datarray['siteurl'] = $siteurl;
+ $datarray['type'] = $params['type'];
+ $datarray['parent'] = $params['parent_mid'];
+ $datarray['source_name'] = $sender['xchan_name'];
+ $datarray['source_link'] = $sender['xchan_url'];
+ $datarray['source_photo'] = $sender['xchan_photo_s'];
+ $datarray['uid'] = $recip['channel_id'];
+ $datarray['username'] = $recip['channel_name'];
+ $datarray['hsitelink'] = $hsitelink;
+ $datarray['tsitelink'] = $tsitelink;
+ $datarray['hitemlink'] = '<a href="' . $itemlink . '">' . $itemlink . '</a>';
+ $datarray['titemlink'] = $itemlink;
+ $datarray['thanks'] = $thanks;
+ $datarray['site_admin'] = $site_admin;
+ $datarray['title'] = stripslashes($title);
+ $datarray['htmlversion'] = $htmlversion;
+ $datarray['textversion'] = $textversion;
+ $datarray['subject'] = $subject;
+ $datarray['headers'] = $additional_mail_header;
+ $datarray['email_secure'] = false;
+
+ call_hooks('enotify_mail', $datarray);
+
+ // Default to private - don't disclose message contents over insecure channels (such as email)
+ // Might be interesting to use GPG,PGP,S/MIME encryption instead
+ // but we'll save that for a clever plugin developer to implement
+
+ $private_activity = false;
+
+ if (! $datarray['email_secure']) {
+ switch ($params['type']) {
+ case NOTIFY_WALL:
+ case NOTIFY_TAGSELF:
+ case NOTIFY_POKE:
+ case NOTIFY_COMMENT:
+ if (! $private)
+ break;
+ $private_activity = true;
+ case NOTIFY_MAIL:
+ $datarray['textversion'] = $datarray['htmlversion'] = $datarray['title'] = '';
+ $datarray['subject'] = preg_replace('/' . preg_quote(t('[Hubzilla:Notify]')) . '/','$0*',$datarray['subject']);
+ break;
+ default:
+ break;
+ }
+ }
+
+ if ($private_activity
+ && intval(get_pconfig($datarray['uid'], 'system', 'ignore_private_notifications'))) {
+
+ pop_lang();
+ return;
+ }
+
+ // load the template for private message notifications
+ $tpl = get_markup_template('email_notify_html.tpl');
+ $email_html_body = replace_macros($tpl,array(
+ '$banner' => $datarray['banner'],
+ '$notify_icon' => \Zotlabs\Lib\System::get_notify_icon(),
+ '$product' => $datarray['product'],
+ '$preamble' => $datarray['preamble'],
+ '$sitename' => $datarray['sitename'],
+ '$siteurl' => $datarray['siteurl'],
+ '$source_name' => $datarray['source_name'],
+ '$source_link' => $datarray['source_link'],
+ '$source_photo' => $datarray['source_photo'],
+ '$username' => $datarray['to_name'],
+ '$hsitelink' => $datarray['hsitelink'],
+ '$hitemlink' => $datarray['hitemlink'],
+ '$thanks' => $datarray['thanks'],
+ '$site_admin' => $datarray['site_admin'],
+ '$title' => $datarray['title'],
+ '$htmlversion' => $datarray['htmlversion'],
+ ));
+
+ // load the template for private message notifications
+ $tpl = get_markup_template('email_notify_text.tpl');
+ $email_text_body = replace_macros($tpl, array(
+ '$banner' => $datarray['banner'],
+ '$product' => $datarray['product'],
+ '$preamble' => $datarray['preamble'],
+ '$sitename' => $datarray['sitename'],
+ '$siteurl' => $datarray['siteurl'],
+ '$source_name' => $datarray['source_name'],
+ '$source_link' => $datarray['source_link'],
+ '$source_photo' => $datarray['source_photo'],
+ '$username' => $datarray['to_name'],
+ '$tsitelink' => $datarray['tsitelink'],
+ '$titemlink' => $datarray['titemlink'],
+ '$thanks' => $datarray['thanks'],
+ '$site_admin' => $datarray['site_admin'],
+ '$title' => $datarray['title'],
+ '$textversion' => $datarray['textversion'],
+ ));
+
+// logger('text: ' . $email_text_body);
+
+ // use the EmailNotification library to send the message
+
+ self::send(array(
+ 'fromName' => $sender_name,
+ 'fromEmail' => $sender_email,
+ 'replyTo' => $sender_email,
+ 'toEmail' => $recip['account_email'],
+ 'messageSubject' => $datarray['subject'],
+ 'htmlVersion' => $email_html_body,
+ 'textVersion' => $email_text_body,
+ 'additionalMailHeader' => $datarray['headers'],
+ ));
+ }
+
+ pop_lang();
+
+}
+
+
+ /**
+ * @brief Send a multipart/alternative message with Text and HTML versions.
+ *
+ * @param array $params an assoziative array with:
+ * * \e string \b fromName name of the sender
+ * * \e string \b fromEmail email of the sender
+ * * \e string \b replyTo replyTo address to direct responses
+ * * \e string \b toEmail destination email address
+ * * \e string \b messageSubject subject of the message
+ * * \e string \b htmlVersion html version of the message
+ * * \e string \b textVersion text only version of the message
+ * * \e string \b additionalMailHeader additions to the smtp mail header
+ */
+ static public function send($params) {
+
+ $fromName = email_header_encode(html_entity_decode($params['fromName'],ENT_QUOTES,'UTF-8'),'UTF-8');
+ $messageSubject = email_header_encode(html_entity_decode($params['messageSubject'],ENT_QUOTES,'UTF-8'),'UTF-8');
+
+ // generate a mime boundary
+ $mimeBoundary = rand(0, 9) . "-"
+ .rand(10000000000, 9999999999) . "-"
+ .rand(10000000000, 9999999999) . "=:"
+ .rand(10000, 99999);
+
+ // generate a multipart/alternative message header
+ $messageHeader =
+ $params['additionalMailHeader'] .
+ "From: $fromName <{$params['fromEmail']}>\n" .
+ "Reply-To: $fromName <{$params['replyTo']}>\n" .
+ "MIME-Version: 1.0\n" .
+ "Content-Type: multipart/alternative; boundary=\"{$mimeBoundary}\"";
+
+ // assemble the final multipart message body with the text and html types included
+ $textBody = chunk_split(base64_encode($params['textVersion']));
+ $htmlBody = chunk_split(base64_encode($params['htmlVersion']));
+
+ $multipartMessageBody =
+ "--" . $mimeBoundary . "\n" . // plain text section
+ "Content-Type: text/plain; charset=UTF-8\n" .
+ "Content-Transfer-Encoding: base64\n\n" .
+ $textBody . "\n" .
+ "--" . $mimeBoundary . "\n" . // text/html section
+ "Content-Type: text/html; charset=UTF-8\n" .
+ "Content-Transfer-Encoding: base64\n\n" .
+ $htmlBody . "\n" .
+ "--" . $mimeBoundary . "--\n"; // message ending
+
+ // send the message
+ $res = mail(
+ $params['toEmail'], // send to address
+ $messageSubject, // subject
+ $multipartMessageBody, // message body
+ $messageHeader // message headers
+ );
+ logger("notification: enotify::send returns " . $res, LOGGER_DEBUG);
+ }
+
+ static public function format($item) {
+
+ $ret = '';
+
+ require_once('include/conversation.php');
+
+ // Call localize_item with the "brief" flag to get a one line status for activities.
+ // This should set $item['localized'] to indicate we have a brief summary.
+
+ localize_item($item);
+
+ if($item_localize) {
+ $itemem_text = $item['localize'];
+ }
+ else {
+ $itemem_text = (($item['item_thread_top'])
+ ? t('created a new post')
+ : sprintf( t('commented on %s\'s post'), $item['owner']['xchan_name']));
+ }
+
+ // convert this logic into a json array just like the system notifications
+
+ return array(
+ 'notify_link' => $item['llink'],
+ 'name' => $item['author']['xchan_name'],
+ 'url' => $item['author']['xchan_url'],
+ 'photo' => $item['author']['xchan_photo_s'],
+ 'when' => relative_date($item['created']),
+ 'class' => (intval($item['item_unseen']) ? 'notify-unseen' : 'notify-seen'),
+ 'message' => strip_tags(bbcode($itemem_text))
+ );
+
+ }
+
+}
diff --git a/Zotlabs/Lib/IConfig.php b/Zotlabs/Lib/IConfig.php
new file mode 100644
index 000000000..28c9ab58e
--- /dev/null
+++ b/Zotlabs/Lib/IConfig.php
@@ -0,0 +1,165 @@
+<?php
+
+namespace Zotlabs\Lib;
+
+
+
+class IConfig {
+
+ static public function Load(&$item) {
+ return;
+ }
+
+ static public function Get(&$item, $family, $key) {
+
+ $is_item = false;
+
+ if(is_array($item)) {
+ $is_item = true;
+ if((! array_key_exists('iconfig',$item)) || (! is_array($item['iconfig'])))
+ $item['iconfig'] = array();
+
+ if(array_key_exists('item_id',$item))
+ $iid = $item['item_id'];
+ else
+ $iid = $item['id'];
+ }
+ elseif(intval($item))
+ $iid = $item;
+
+ if(! $iid)
+ return false;
+
+ if(is_array($item) && array_key_exists('iconfig',$item) && is_array($item['iconfig'])) {
+ foreach($item['iconfig'] as $c) {
+ if($c['iid'] == $iid && $c['cat'] == $family && $c['k'] == $key)
+ return $c['v'];
+ }
+ }
+
+ $r = q("select * from iconfig where iid = %d and cat = '%s' and k = '%s' limit 1",
+ intval($iid),
+ dbesc($family),
+ dbesc($key)
+ );
+ if($r) {
+ $r[0]['v'] = ((preg_match('|^a:[0-9]+:{.*}$|s',$r[0]['v'])) ? unserialize($r[0]['v']) : $r[0]['v']);
+ if($is_item)
+ $item['iconfig'][] = $r[0];
+ return $r[0]['v'];
+ }
+ return false;
+
+ }
+
+ /**
+ * IConfig::Set(&$item, $family, $key, $value, $sharing = false);
+ *
+ * $item - item array or item id. If passed an array the iconfig meta information is
+ * added to the item structure (which will need to be saved with item_store eventually).
+ * If passed an id, the DB is updated, but may not be federated and/or cloned.
+ * $family - namespace of meta variable
+ * $key - key of meta variable
+ * $value - value of meta variable
+ * $sharing - boolean (default false); if true the meta information is propagated with the item
+ * to other sites/channels, mostly useful when $item is an array and has not yet been stored/delivered.
+ * If the meta information is added after delivery and you wish it to be shared, it may be necessary to
+ * alter the item edited timestamp and invoke the delivery process on the updated item. The edited
+ * timestamp needs to be altered in order to trigger an item_store_update() at the receiving end.
+ */
+
+
+ static public function Set(&$item, $family, $key, $value, $sharing = false) {
+
+ $dbvalue = ((is_array($value)) ? serialize($value) : $value);
+ $dbvalue = ((is_bool($dbvalue)) ? intval($dbvalue) : $dbvalue);
+
+ $is_item = false;
+ $idx = null;
+
+ if(is_array($item)) {
+ $is_item = true;
+ if((! array_key_exists('iconfig',$item)) || (! is_array($item['iconfig'])))
+ $item['iconfig'] = array();
+ elseif($item['iconfig']) {
+ for($x = 0; $x < count($item['iconfig']); $x ++) {
+ if($item['iconfig'][$x]['cat'] == $family && $item['iconfig'][$x]['k'] == $key) {
+ $idx = $x;
+ }
+ }
+ }
+ $entry = array('cat' => $family, 'k' => $key, 'v' => $value, 'sharing' => $sharing);
+
+ if(is_null($idx))
+ $item['iconfig'][] = $entry;
+ else
+ $item['iconfig'][$idx] = $entry;
+ return $value;
+ }
+
+ if(intval($item))
+ $iid = intval($item);
+
+ if(! $iid)
+ return false;
+
+ if(self::Get($item, $family, $key) === false) {
+ $r = q("insert into iconfig( iid, cat, k, v, sharing ) values ( %d, '%s', '%s', '%s', %d ) ",
+ intval($iid),
+ dbesc($family),
+ dbesc($key),
+ dbesc($dbvalue),
+ intval($sharing)
+ );
+ }
+ else {
+ $r = q("update iconfig set v = '%s', sharing = %d where iid = %d and cat = '%s' and k = '%s' ",
+ dbesc($dbvalue),
+ intval($sharing),
+ intval($iid),
+ dbesc($family),
+ dbesc($key)
+ );
+ }
+
+ if(! $r)
+ return false;
+
+ return $value;
+ }
+
+
+
+ static public function Delete(&$item, $family, $key) {
+
+
+ $is_item = false;
+ $idx = null;
+
+ if(is_array($item)) {
+ $is_item = true;
+ if(is_array($item['iconfig'])) {
+ for($x = 0; $x < count($item['iconfig']); $x ++) {
+ if($item['iconfig'][$x]['cat'] == $family && $item['iconfig'][$x]['k'] == $key) {
+ unset($item['iconfig'][$x]);
+ }
+ }
+ }
+ return true;
+ }
+
+ if(intval($item))
+ $iid = intval($item);
+
+ if(! $iid)
+ return false;
+
+ return q("delete from iconfig where iid = %d and cat = '%s' and k = '%s' ",
+ intval($iid),
+ dbesc($family),
+ dbesc($key)
+ );
+
+ }
+
+} \ No newline at end of file
diff --git a/Zotlabs/Lib/PConfig.php b/Zotlabs/Lib/PConfig.php
new file mode 100644
index 000000000..195321375
--- /dev/null
+++ b/Zotlabs/Lib/PConfig.php
@@ -0,0 +1,189 @@
+<?php /** @file */
+
+namespace Zotlabs\Lib;
+
+
+class PConfig {
+
+ /**
+ * @brief Loads all configuration values of a channel into a cached storage.
+ *
+ * All configuration values of the given channel are stored in global cache
+ * which is available under the global variable App::$config[$uid].
+ *
+ * @param string $uid
+ * The channel_id
+ * @return void|false Nothing or false if $uid is false
+ */
+
+ static public function Load($uid) {
+ if($uid === false)
+ return false;
+
+ if(! array_key_exists($uid, \App::$config))
+ \App::$config[$uid] = array();
+
+ $r = q("SELECT * FROM pconfig WHERE uid = %d",
+ intval($uid)
+ );
+
+ if($r) {
+ foreach($r as $rr) {
+ $k = $rr['k'];
+ $c = $rr['cat'];
+ if(! array_key_exists($c, \App::$config[$uid])) {
+ \App::$config[$uid][$c] = array();
+ \App::$config[$uid][$c]['config_loaded'] = true;
+ }
+ \App::$config[$uid][$c][$k] = $rr['v'];
+ }
+ }
+ }
+
+ /**
+ * @brief Get a particular channel's config variable given the category name
+ * ($family) and a key.
+ *
+ * Get a particular channel's config value from the given category ($family)
+ * and the $key from a cached storage in App::$config[$uid].
+ *
+ * Returns false if not set.
+ *
+ * @param string $uid
+ * The channel_id
+ * @param string $family
+ * The category of the configuration value
+ * @param string $key
+ * The configuration key to query
+ * @param boolean $instore (deprecated, without function)
+ * @return mixed Stored value or false if it does not exist
+ */
+
+ static public function Get($uid,$family,$key,$instore = false) {
+
+ if($uid === false)
+ return false;
+
+ if(! array_key_exists($uid, \App::$config))
+ self::Load($uid);
+
+ if((! array_key_exists($family, \App::$config[$uid])) || (! array_key_exists($key, \App::$config[$uid][$family])))
+ return false;
+
+ return ((! is_array(\App::$config[$uid][$family][$key])) && (preg_match('|^a:[0-9]+:{.*}$|s', \App::$config[$uid][$family][$key]))
+ ? unserialize(\App::$config[$uid][$family][$key])
+ : \App::$config[$uid][$family][$key]
+ );
+
+ }
+
+ /**
+ * @brief Sets a configuration value for a channel.
+ *
+ * Stores a config value ($value) in the category ($family) under the key ($key)
+ * for the channel_id $uid.
+ *
+ * @param string $uid
+ * The channel_id
+ * @param string $family
+ * The category of the configuration value
+ * @param string $key
+ * The configuration key to set
+ * @param string $value
+ * The value to store
+ * @return mixed Stored $value or false
+ */
+
+ static public function Set($uid, $family, $key, $value) {
+
+ // this catches subtle errors where this function has been called
+ // with local_channel() when not logged in (which returns false)
+ // and throws an error in array_key_exists below.
+ // we provide a function backtrace in the logs so that we can find
+ // and fix the calling function.
+
+ if($uid === false) {
+ btlogger('UID is FALSE!', LOGGER_NORMAL, LOG_ERR);
+ return;
+ }
+
+ // manage array value
+ $dbvalue = ((is_array($value)) ? serialize($value) : $value);
+ $dbvalue = ((is_bool($dbvalue)) ? intval($dbvalue) : $dbvalue);
+
+ if(get_pconfig($uid, $family, $key) === false) {
+ if(! array_key_exists($uid, \App::$config))
+ \App::$config[$uid] = array();
+ if(! array_key_exists($family, \App::$config[$uid]))
+ \App::$config[$uid][$family] = array();
+
+ $ret = q("INSERT INTO pconfig ( uid, cat, k, v ) VALUES ( %d, '%s', '%s', '%s' ) ",
+ intval($uid),
+ dbesc($family),
+ dbesc($key),
+ dbesc($dbvalue)
+ );
+
+ }
+ else {
+
+ $ret = q("UPDATE pconfig SET v = '%s' WHERE uid = %d and cat = '%s' AND k = '%s'",
+ dbesc($dbvalue),
+ intval($uid),
+ dbesc($family),
+ dbesc($key)
+ );
+
+ }
+
+ // keep a separate copy for all variables which were
+ // set in the life of this page. We need this to
+ // synchronise channel clones.
+
+ if(! array_key_exists('transient', \App::$config[$uid]))
+ \App::$config[$uid]['transient'] = array();
+ if(! array_key_exists($family, \App::$config[$uid]['transient']))
+ \App::$config[$uid]['transient'][$family] = array();
+
+ \App::$config[$uid][$family][$key] = $value;
+ \App::$config[$uid]['transient'][$family][$key] = $value;
+
+ if($ret)
+ return $value;
+
+ return $ret;
+ }
+
+
+ /**
+ * @brief Deletes the given key from the channel's configuration.
+ *
+ * Removes the configured value from the stored cache in App::$config[$uid]
+ * and removes it from the database.
+ *
+ * @param string $uid
+ * The channel_id
+ * @param string $family
+ * The category of the configuration value
+ * @param string $key
+ * The configuration key to delete
+ * @return mixed
+ */
+
+ static public function Delete($uid, $family, $key) {
+
+ $ret = false;
+
+ if(array_key_exists($key, \App::$config[$uid][$family]))
+ unset(\App::$config[$uid][$family][$key]);
+ $ret = q("DELETE FROM pconfig WHERE uid = %d AND cat = '%s' AND k = '%s'",
+ intval($uid),
+ dbesc($family),
+ dbesc($key)
+ );
+
+ return $ret;
+ }
+
+}
+ \ No newline at end of file
diff --git a/Zotlabs/Lib/ProtoDriver.php b/Zotlabs/Lib/ProtoDriver.php
new file mode 100644
index 000000000..daf887dbb
--- /dev/null
+++ b/Zotlabs/Lib/ProtoDriver.php
@@ -0,0 +1,19 @@
+<?php /** @file */
+
+namespace Zotlabs\Lib;
+
+/*
+ * Abstraction class for dealing with alternate networks (which of course do not exist, hence the abstraction)
+ */
+
+
+abstract class ProtoDriver {
+ abstract protected function discover($channel,$location);
+ abstract protected function deliver($item,$channel,$recipients);
+ abstract protected function collect($channel,$connection);
+ abstract protected function change_permissions($permissions,$channel,$recipient);
+ abstract protected function acknowledge_permissions($permissions,$channel,$recipient);
+ abstract protected function deliver_private($item,$channel,$recipients);
+ abstract protected function collect_private($channel,$connection);
+
+}
diff --git a/Zotlabs/Project/System.php b/Zotlabs/Lib/System.php
index f61313da0..c52a90338 100644
--- a/Zotlabs/Project/System.php
+++ b/Zotlabs/Lib/System.php
@@ -1,11 +1,11 @@
<?php
-namespace Zotlabs\Project;
+namespace Zotlabs\Lib;
class System {
static public function get_platform_name() {
- if(is_array(\App::$config) && is_array(\App::$config['system']) && \App::$config['system']['platform_name'])
+ if(is_array(\App::$config) && is_array(\App::$config['system']) && array_key_exists('platform_name',\App::$config['system']))
return \App::$config['system']['platform_name'];
return PLATFORM_NAME;
}
@@ -45,7 +45,7 @@ class System {
static public function get_server_role() {
if(UNO)
return 'basic';
- return 'advanced';
+ return 'pro';
}
static public function get_std_version() {
diff --git a/Zotlabs/Lib/ThreadItem.php b/Zotlabs/Lib/ThreadItem.php
new file mode 100644
index 000000000..f724ac95d
--- /dev/null
+++ b/Zotlabs/Lib/ThreadItem.php
@@ -0,0 +1,780 @@
+<?php /** @file */
+
+namespace Zotlabs\Lib;
+
+require_once('include/text.php');
+
+/**
+ * A thread item
+ */
+
+class ThreadItem {
+
+ public $data = array();
+ private $template = 'conv_item.tpl';
+ private $comment_box_template = 'comment_item.tpl';
+ private $commentable = false;
+ // list of supported reaction emojis - a site can over-ride this via config system.reactions
+ private $reactions = ['1f60a','1f44f','1f37e','1f48b','1f61e','2665','1f606','1f62e','1f634','1f61c','1f607','1f608'];
+ private $toplevel = false;
+ private $children = array();
+ private $parent = null;
+ private $conversation = null;
+ private $redirect_url = null;
+ private $owner_url = '';
+ private $owner_photo = '';
+ private $owner_name = '';
+ private $wall_to_wall = false;
+ private $threaded = false;
+ private $visiting = false;
+ private $channel = null;
+ private $display_mode = 'normal';
+
+
+ public function __construct($data) {
+
+ $this->data = $data;
+ $this->toplevel = ($this->get_id() == $this->get_data_value('parent'));
+
+ // Prepare the children
+ if(count($data['children'])) {
+ foreach($data['children'] as $item) {
+
+ /*
+ * Only add those that will be displayed
+ */
+
+ if((! visible_activity($item)) || array_key_exists('author_blocked',$item)) {
+ continue;
+ }
+
+ $child = new ThreadItem($item);
+ $this->add_child($child);
+ }
+ }
+
+ // allow a site to configure the order and content of the reaction emoji list
+ if($this->toplevel) {
+ $x = get_config('system','reactions');
+ if($x && is_array($x) && count($x)) {
+ $this->reactions = $x;
+ }
+ }
+ }
+
+ /**
+ * Get data in a form usable by a conversation template
+ *
+ * Returns:
+ * _ The data requested on success
+ * _ false on failure
+ */
+
+ public function get_template_data($conv_responses, $thread_level=1) {
+
+ $result = array();
+
+ $item = $this->get_data();
+
+ $commentww = '';
+ $sparkle = '';
+ $buttons = '';
+ $dropping = false;
+ $star = false;
+ $isstarred = "unstarred fa-star-o";
+ $indent = '';
+ $osparkle = '';
+ $total_children = $this->count_descendants();
+ $unseen_comments = (($item['real_uid']) ? 0 : $this->count_unseen_descendants());
+
+ $conv = $this->get_conversation();
+ $observer = $conv->get_observer();
+
+ $lock = ((($item['item_private'] == 1) || (($item['uid'] == local_channel()) && (strlen($item['allow_cid']) || strlen($item['allow_gid'])
+ || strlen($item['deny_cid']) || strlen($item['deny_gid']))))
+ ? t('Private Message')
+ : false);
+ $shareable = ((($conv->get_profile_owner() == local_channel() && local_channel()) && ($item['item_private'] != 1)) ? true : false);
+
+ // allow an exemption for sharing stuff from your private feeds
+ if($item['author']['xchan_network'] === 'rss')
+ $shareable = true;
+
+ $mode = $conv->get_mode();
+
+ if(local_channel() && $observer['xchan_hash'] === $item['author_xchan'])
+ $edpost = array(z_root()."/editpost/".$item['id'], t("Edit"));
+ else
+ $edpost = false;
+
+
+ if($observer['xchan_hash'] == $this->get_data_value('author_xchan')
+ || $observer['xchan_hash'] == $this->get_data_value('owner_xchan')
+ || $this->get_data_value('uid') == local_channel())
+ $dropping = true;
+
+
+ if(array_key_exists('real_uid',$item)) {
+ $edpost = false;
+ $dropping = false;
+ }
+
+
+ if($dropping) {
+ $drop = array(
+ 'dropping' => $dropping,
+ 'delete' => t('Delete'),
+ );
+ }
+// FIXME
+ if($observer_is_pageowner) {
+ $multidrop = array(
+ 'select' => t('Select'),
+ );
+ }
+
+ $filer = ((($conv->get_profile_owner() == local_channel()) && (! array_key_exists('real_uid',$item))) ? t("Save to Folder") : false);
+
+ $profile_avatar = $item['author']['xchan_photo_m'];
+ $profile_link = chanlink_url($item['author']['xchan_url']);
+ $profile_name = $item['author']['xchan_name'];
+
+ $location = format_location($item);
+ $isevent = false;
+ $attend = null;
+ $canvote = false;
+
+ // process action responses - e.g. like/dislike/attend/agree/whatever
+ $response_verbs = array('like');
+ if(feature_enabled($conv->get_profile_owner(),'dislike'))
+ $response_verbs[] = 'dislike';
+ if($item['obj_type'] === ACTIVITY_OBJ_EVENT) {
+ $response_verbs[] = 'attendyes';
+ $response_verbs[] = 'attendno';
+ $response_verbs[] = 'attendmaybe';
+ if($this->is_commentable()) {
+ $isevent = true;
+ $attend = array( t('I will attend'), t('I will not attend'), t('I might attend'));
+ }
+ }
+
+ $consensus = (intval($item['item_consensus']) ? true : false);
+ if($consensus) {
+ $response_verbs[] = 'agree';
+ $response_verbs[] = 'disagree';
+ $response_verbs[] = 'abstain';
+ if($this->is_commentable()) {
+ $conlabels = array( t('I agree'), t('I disagree'), t('I abstain'));
+ $canvote = true;
+ }
+ }
+
+ if(! feature_enabled($conv->get_profile_owner(),'dislike'))
+ unset($conv_responses['dislike']);
+
+ $responses = get_responses($conv_responses,$response_verbs,$this,$item);
+
+ $like_count = ((x($conv_responses['like'],$item['mid'])) ? $conv_responses['like'][$item['mid']] : '');
+ $like_list = ((x($conv_responses['like'],$item['mid'])) ? $conv_responses['like'][$item['mid'] . '-l'] : '');
+ if (count($like_list) > MAX_LIKERS) {
+ $like_list_part = array_slice($like_list, 0, MAX_LIKERS);
+ array_push($like_list_part, '<a href="#" data-toggle="modal" data-target="#likeModal-' . $this->get_id() . '"><b>' . t('View all') . '</b></a>');
+ } else {
+ $like_list_part = '';
+ }
+ $like_button_label = tt('Like','Likes',$like_count,'noun');
+
+ if (feature_enabled($conv->get_profile_owner(),'dislike')) {
+ $dislike_count = ((x($conv_responses['dislike'],$item['mid'])) ? $conv_responses['dislike'][$item['mid']] : '');
+ $dislike_list = ((x($conv_responses['dislike'],$item['mid'])) ? $conv_responses['dislike'][$item['mid'] . '-l'] : '');
+ $dislike_button_label = tt('Dislike','Dislikes',$dislike_count,'noun');
+ if (count($dislike_list) > MAX_LIKERS) {
+ $dislike_list_part = array_slice($dislike_list, 0, MAX_LIKERS);
+ array_push($dislike_list_part, '<a href="#" data-toggle="modal" data-target="#dislikeModal-' . $this->get_id() . '"><b>' . t('View all') . '</b></a>');
+ } else {
+ $dislike_list_part = '';
+ }
+ }
+
+ $showlike = ((x($conv_responses['like'],$item['mid'])) ? format_like($conv_responses['like'][$item['mid']],$conv_responses['like'][$item['mid'] . '-l'],'like',$item['mid']) : '');
+ $showdislike = ((x($conv_responses['dislike'],$item['mid']) && feature_enabled($conv->get_profile_owner(),'dislike'))
+ ? format_like($conv_responses['dislike'][$item['mid']],$conv_responses['dislike'][$item['mid'] . '-l'],'dislike',$item['mid']) : '');
+
+ /*
+ * We should avoid doing this all the time, but it depends on the conversation mode
+ * And the conv mode may change when we change the conv, or it changes its mode
+ * Maybe we should establish a way to be notified about conversation changes
+ */
+
+ $this->check_wall_to_wall();
+
+ if($this->is_toplevel()) {
+ // FIXME check this permission
+ if(($conv->get_profile_owner() == local_channel()) && (! array_key_exists('real_uid',$item))) {
+
+// FIXME we don't need all this stuff, some can be done in the template
+
+ $star = array(
+ 'do' => t("Add Star"),
+ 'undo' => t("Remove Star"),
+ 'toggle' => t("Toggle Star Status"),
+ 'classdo' => (intval($item['item_starred']) ? "hidden" : ""),
+ 'classundo' => (intval($item['item_starred']) ? "" : "hidden"),
+ 'isstarred' => (intval($item['item_starred']) ? "starred fa-star" : "unstarred fa-star-o"),
+ 'starred' => t('starred'),
+ );
+
+ }
+ }
+ else {
+ $indent = 'comment';
+ }
+
+
+ $verified = (intval($item['item_verified']) ? t('Message signature validated') : '');
+ $forged = ((($item['sig']) && (! intval($item['item_verified']))) ? t('Message signature incorrect') : '');
+ $unverified = '' ; // (($this->is_wall_to_wall() && (! intval($item['item_verified']))) ? t('Message cannot be verified') : '');
+
+
+
+ // FIXME - check this permission
+ if($conv->get_profile_owner() == local_channel()) {
+ $tagger = array(
+ 'tagit' => t("Add Tag"),
+ 'classtagger' => "",
+ );
+ }
+
+ $has_bookmarks = false;
+ if(is_array($item['term'])) {
+ foreach($item['term'] as $t) {
+ if(!UNO && $t['type'] == TERM_BOOKMARK)
+ $has_bookmarks = true;
+ }
+ }
+
+ $has_event = false;
+ if(($item['obj_type'] === ACTIVITY_OBJ_EVENT) && $conv->get_profile_owner() == local_channel())
+ $has_event = true;
+
+ if($this->is_commentable()) {
+ $like = array( t("I like this \x28toggle\x29"), t("like"));
+ $dislike = array( t("I don't like this \x28toggle\x29"), t("dislike"));
+ }
+
+ if ($shareable)
+ $share = array( t('Share This'), t('share'));
+
+ $dreport = '';
+
+ $keep_reports = intval(get_config('system','expire_delivery_reports'));
+ if($keep_reports === 0)
+ $keep_reports = 30;
+
+ if((! get_config('system','disable_dreport')) && strcmp(datetime_convert('UTC','UTC',$item['created']),datetime_convert('UTC','UTC',"now - $keep_reports days")) > 0)
+ $dreport = t('Delivery Report');
+
+ if(strcmp(datetime_convert('UTC','UTC',$item['created']),datetime_convert('UTC','UTC','now - 12 hours')) > 0)
+ $indent .= ' shiny';
+
+
+ localize_item($item);
+
+ $body = prepare_body($item,true);
+
+ // $viewthread (below) is only valid in list mode. If this is a channel page, build the thread viewing link
+ // since we can't depend on llink or plink pointing to the right local location.
+
+ $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'];
+
+ $comment_count_txt = sprintf( tt('%d comment','%d comments',$total_children),$total_children );
+ $list_unseen_txt = (($unseen_comments) ? sprintf('%d unseen',$unseen_comments) : '');
+
+
+
+
+
+ $children = $this->get_children();
+
+ $has_tags = (($body['tags'] || $body['categories'] || $body['mentions'] || $body['attachments'] || $body['folders']) ? true : false);
+
+ $tmp_item = array(
+ 'template' => $this->get_template(),
+ 'mode' => $mode,
+ 'type' => implode("",array_slice(explode("/",$item['verb']),-1)),
+ 'body' => $body['html'],
+ 'tags' => $body['tags'],
+ 'categories' => $body['categories'],
+ 'mentions' => $body['mentions'],
+ 'attachments' => $body['attachments'],
+ 'folders' => $body['folders'],
+ 'text' => strip_tags($body['html']),
+ 'id' => $this->get_id(),
+ 'mid' => $item['mid'],
+ 'isevent' => $isevent,
+ 'attend' => $attend,
+ 'consensus' => $consensus,
+ 'conlabels' => $conlabels,
+ 'canvote' => $canvote,
+ 'linktitle' => sprintf( t('View %s\'s profile - %s'), $profile_name, $item['author']['xchan_addr']),
+ 'olinktitle' => sprintf( t('View %s\'s profile - %s'), $this->get_owner_name(), $item['owner']['xchan_addr']),
+ 'llink' => $item['llink'],
+ 'viewthread' => $viewthread,
+ 'to' => t('to'),
+ 'via' => t('via'),
+ 'wall' => t('Wall-to-Wall'),
+ 'vwall' => t('via Wall-To-Wall:'),
+ 'profile_url' => $profile_link,
+ 'item_photo_menu' => item_photo_menu($item),
+ 'dreport' => $dreport,
+ 'name' => $profile_name,
+ 'thumb' => $profile_avatar,
+ 'osparkle' => $osparkle,
+ 'sparkle' => $sparkle,
+ 'title' => $item['title'],
+ 'title_tosource' => get_pconfig($conv->get_profile_owner(),'system','title_tosource'),
+ 'ago' => relative_date($item['created']),
+ 'app' => $item['app'],
+ 'str_app' => sprintf( t('from %s'), $item['app']),
+ 'isotime' => datetime_convert('UTC', date_default_timezone_get(), $item['created'], 'c'),
+ 'localtime' => datetime_convert('UTC', date_default_timezone_get(), $item['created'], 'r'),
+ 'editedtime' => (($item['edited'] != $item['created']) ? sprintf( t('last edited: %s'), datetime_convert('UTC', date_default_timezone_get(), $item['edited'], 'r')) : ''),
+ 'expiretime' => (($item['expires'] !== NULL_DATE) ? sprintf( t('Expires: %s'), datetime_convert('UTC', date_default_timezone_get(), $item['expires'], 'r')):''),
+ 'lock' => $lock,
+ 'verified' => $verified,
+ 'unverified' => $unverified,
+ 'forged' => $forged,
+ 'location' => $location,
+ 'indent' => $indent,
+ 'owner_url' => $this->get_owner_url(),
+ 'owner_photo' => $this->get_owner_photo(),
+ 'owner_name' => $this->get_owner_name(),
+ 'photo' => $body['photo'],
+ 'event' => $body['event'],
+ 'has_tags' => $has_tags,
+ 'reactions' => $this->reactions,
+// Item toolbar buttons
+ 'emojis' => (($this->is_toplevel() && $this->is_commentable() && feature_enabled($conv->get_profile_owner(),'emojis')) ? '1' : ''),
+ 'like' => $like,
+ 'dislike' => ((feature_enabled($conv->get_profile_owner(),'dislike')) ? $dislike : ''),
+ 'share' => $share,
+ 'rawmid' => $item['mid'],
+ 'plink' => get_plink($item),
+ 'edpost' => $edpost, // ((feature_enabled($conv->get_profile_owner(),'edit_posts')) ? $edpost : ''),
+ 'star' => ((feature_enabled($conv->get_profile_owner(),'star_posts')) ? $star : ''),
+ 'tagger' => ((feature_enabled($conv->get_profile_owner(),'commtag')) ? $tagger : ''),
+ 'filer' => ((feature_enabled($conv->get_profile_owner(),'filing')) ? $filer : ''),
+ 'bookmark' => (($conv->get_profile_owner() == local_channel() && local_channel() && $has_bookmarks) ? t('Save Bookmarks') : ''),
+ 'addtocal' => (($has_event) ? t('Add to Calendar') : ''),
+ 'drop' => $drop,
+ 'multidrop' => ((feature_enabled($conv->get_profile_owner(),'multi_delete')) ? $multidrop : ''),
+// end toolbar buttons
+
+ 'unseen_comments' => $unseen_comments,
+ 'comment_count' => $total_children,
+ 'comment_count_txt' => $comment_count_txt,
+ 'list_unseen_txt' => $list_unseen_txt,
+ 'markseen' => t('Mark all seen'),
+ 'responses' => $responses,
+ 'like_count' => $like_count,
+ 'like_list' => $like_list,
+ 'like_list_part' => $like_list_part,
+ 'like_button_label' => $like_button_label,
+ 'like_modal_title' => t('Likes','noun'),
+ 'dislike_modal_title' => t('Dislikes','noun'),
+ 'dislike_count' => ((feature_enabled($conv->get_profile_owner(),'dislike')) ? $dislike_count : ''),
+ 'dislike_list' => ((feature_enabled($conv->get_profile_owner(),'dislike')) ? $dislike_list : ''),
+ 'dislike_list_part' => ((feature_enabled($conv->get_profile_owner(),'dislike')) ? $dislike_list_part : ''),
+ 'dislike_button_label' => ((feature_enabled($conv->get_profile_owner(),'dislike')) ? $dislike_button_label : ''),
+ 'modal_dismiss' => t('Close'),
+ 'showlike' => $showlike,
+ 'showdislike' => $showdislike,
+ 'comment' => $this->get_comment_box($indent),
+ 'previewing' => ($conv->is_preview() ? ' preview ' : ''),
+ 'wait' => t('Please wait'),
+ 'thread_level' => $thread_level
+ );
+
+ $arr = array('item' => $item, 'output' => $tmp_item);
+ call_hooks('display_item', $arr);
+
+ $result = $arr['output'];
+
+ $result['children'] = array();
+ $nb_children = count($children);
+
+ $visible_comments = get_config('system','expanded_comments');
+ if($visible_comments === false)
+ $visible_comments = 3;
+
+ if(($this->get_display_mode() === 'normal') && ($nb_children > 0)) {
+ foreach($children as $child) {
+ $result['children'][] = $child->get_template_data($conv_responses, $thread_level + 1);
+ }
+ // Collapse
+ if(($nb_children > $visible_comments) || ($thread_level > 1)) {
+ $result['children'][0]['comment_firstcollapsed'] = true;
+ $result['children'][0]['num_comments'] = $comment_count_txt;
+ $result['children'][0]['hide_text'] = t('[+] show all');
+ if($thread_level > 1) {
+ $result['children'][$nb_children - 1]['comment_lastcollapsed'] = true;
+ }
+ else {
+ $result['children'][$nb_children - ($visible_comments + 1)]['comment_lastcollapsed'] = true;
+ }
+ }
+ }
+
+ $result['private'] = $item['item_private'];
+ $result['toplevel'] = ($this->is_toplevel() ? 'toplevel_item' : '');
+
+ if($this->is_threaded()) {
+ $result['flatten'] = false;
+ $result['threaded'] = true;
+ }
+ else {
+ $result['flatten'] = true;
+ $result['threaded'] = false;
+ }
+
+ return $result;
+ }
+
+ public function get_id() {
+ return $this->get_data_value('id');
+ }
+
+ public function get_display_mode() {
+ return $this->display_mode;
+ }
+
+ public function set_display_mode($mode) {
+ $this->display_mode = $mode;
+ }
+
+ public function is_threaded() {
+ return $this->threaded;
+ }
+
+ public function set_commentable($val) {
+ $this->commentable = $val;
+ foreach($this->get_children() as $child)
+ $child->set_commentable($val);
+ }
+
+ public function is_commentable() {
+ return $this->commentable;
+ }
+
+ /**
+ * Add a child item
+ */
+ public function add_child($item) {
+ $item_id = $item->get_id();
+ if(!$item_id) {
+ logger('[ERROR] Item::add_child : Item has no ID!!', LOGGER_DEBUG);
+ return false;
+ }
+ if($this->get_child($item->get_id())) {
+ logger('[WARN] Item::add_child : Item already exists ('. $item->get_id() .').', LOGGER_DEBUG);
+ return false;
+ }
+ /*
+ * Only add what will be displayed
+ */
+
+ if(activity_match($item->get_data_value('verb'),ACTIVITY_LIKE) || activity_match($item->get_data_value('verb'),ACTIVITY_DISLIKE)) {
+ return false;
+ }
+
+ $item->set_parent($this);
+ $this->children[] = $item;
+ return end($this->children);
+ }
+
+ /**
+ * Get a child by its ID
+ */
+ public function get_child($id) {
+ foreach($this->get_children() as $child) {
+ if($child->get_id() == $id)
+ return $child;
+ }
+ return null;
+ }
+
+ /**
+ * Get all our children
+ */
+ public function get_children() {
+ return $this->children;
+ }
+
+ /**
+ * Set our parent
+ */
+ protected function set_parent($item) {
+ $parent = $this->get_parent();
+ if($parent) {
+ $parent->remove_child($this);
+ }
+ $this->parent = $item;
+ $this->set_conversation($item->get_conversation());
+ }
+
+ /**
+ * Remove our parent
+ */
+ protected function remove_parent() {
+ $this->parent = null;
+ $this->conversation = null;
+ }
+
+ /**
+ * Remove a child
+ */
+ public function remove_child($item) {
+ $id = $item->get_id();
+ foreach($this->get_children() as $key => $child) {
+ if($child->get_id() == $id) {
+ $child->remove_parent();
+ unset($this->children[$key]);
+ // Reindex the array, in order to make sure there won't be any trouble on loops using count()
+ $this->children = array_values($this->children);
+ return true;
+ }
+ }
+ logger('[WARN] Item::remove_child : Item is not a child ('. $id .').', LOGGER_DEBUG);
+ return false;
+ }
+
+ /**
+ * Get parent item
+ */
+ protected function get_parent() {
+ return $this->parent;
+ }
+
+ /**
+ * set conversation
+ */
+ public function set_conversation($conv) {
+ $previous_mode = ($this->conversation ? $this->conversation->get_mode() : '');
+
+ $this->conversation = $conv;
+
+ // Set it on our children too
+ foreach($this->get_children() as $child)
+ $child->set_conversation($conv);
+ }
+
+ /**
+ * get conversation
+ */
+ public function get_conversation() {
+ return $this->conversation;
+ }
+
+ /**
+ * Get raw data
+ *
+ * We shouldn't need this
+ */
+ public function get_data() {
+ return $this->data;
+ }
+
+ /**
+ * Get a data value
+ *
+ * Returns:
+ * _ value on success
+ * _ false on failure
+ */
+ public function get_data_value($name) {
+ if(!isset($this->data[$name])) {
+// logger('[ERROR] Item::get_data_value : Item has no value name "'. $name .'".', LOGGER_DEBUG);
+ return false;
+ }
+
+ return $this->data[$name];
+ }
+
+ /**
+ * Get template
+ */
+ public function get_template() {
+ return $this->template;
+ }
+
+
+ public function set_template($t) {
+ $this->template = $t;
+ }
+
+ /**
+ * Check if this is a toplevel post
+ */
+ private function is_toplevel() {
+ return $this->toplevel;
+ }
+
+ /**
+ * Count the total of our descendants
+ */
+ private function count_descendants() {
+ $children = $this->get_children();
+ $total = count($children);
+ if($total > 0) {
+ foreach($children as $child) {
+ $total += $child->count_descendants();
+ }
+ }
+ return $total;
+ }
+
+ private function count_unseen_descendants() {
+ $children = $this->get_children();
+ $total = count($children);
+ if($total > 0) {
+ $total = 0;
+ foreach($children as $child) {
+ if((! visible_activity($child->data)) || array_key_exists('author_blocked',$child->data)) {
+ continue;
+ }
+ if(intval($child->data['item_unseen']))
+ $total ++;
+ }
+ }
+ return $total;
+ }
+
+
+ /**
+ * Get the template for the comment box
+ */
+ private function get_comment_box_template() {
+ return $this->comment_box_template;
+ }
+
+ /**
+ * Get the comment box
+ *
+ * Returns:
+ * _ The comment box string (empty if no comment box)
+ * _ false on failure
+ */
+ private function get_comment_box($indent) {
+
+ if(!$this->is_toplevel() && !get_config('system','thread_allow')) {
+ return '';
+ }
+
+ $comment_box = '';
+ $conv = $this->get_conversation();
+
+// logger('Commentable conv: ' . $conv->is_commentable());
+
+ if(! $this->is_commentable())
+ return;
+
+ $template = get_markup_template($this->get_comment_box_template());
+
+ $observer = $conv->get_observer();
+
+ $qc = ((local_channel()) ? get_pconfig(local_channel(),'system','qcomment') : null);
+ $qcomment = (($qc) ? explode("\n",$qc) : null);
+
+ $arr = array('comment_buttons' => '','id' => $this->get_id());
+ call_hooks('comment_buttons',$arr);
+ $comment_buttons = $arr['comment_buttons'];
+
+
+ $comment_box = replace_macros($template,array(
+ '$return_path' => '',
+ '$threaded' => $this->is_threaded(),
+ '$jsreload' => '', //(($conv->get_mode() === 'display') ? $_SESSION['return_url'] : ''),
+ '$type' => (($conv->get_mode() === 'channel') ? 'wall-comment' : 'net-comment'),
+ '$id' => $this->get_id(),
+ '$parent' => $this->get_id(),
+ '$qcomment' => $qcomment,
+ '$comment_buttons' => $comment_buttons,
+ '$profile_uid' => $conv->get_profile_owner(),
+ '$mylink' => $observer['xchan_url'],
+ '$mytitle' => t('This is you'),
+ '$myphoto' => $observer['xchan_photo_s'],
+ '$comment' => t('Comment'),
+ '$submit' => t('Submit'),
+ '$edbold' => t('Bold'),
+ '$editalic' => t('Italic'),
+ '$eduline' => t('Underline'),
+ '$edquote' => t('Quote'),
+ '$edcode' => t('Code'),
+ '$edimg' => t('Image'),
+ '$edurl' => t('Insert Link'),
+ '$edvideo' => t('Video'),
+ '$preview' => t('Preview'), // ((feature_enabled($conv->get_profile_owner(),'preview')) ? t('Preview') : ''),
+ '$indent' => $indent,
+ '$feature_encrypt' => ((feature_enabled($conv->get_profile_owner(),'content_encrypt')) ? true : false),
+ '$encrypt' => t('Encrypt text'),
+ '$cipher' => $conv->get_cipher(),
+ '$sourceapp' => \App::$sourcename
+
+ ));
+
+ return $comment_box;
+ }
+
+ private function get_redirect_url() {
+ return $this->redirect_url;
+ }
+
+ /**
+ * Check if we are a wall to wall item and set the relevant properties
+ */
+ protected function check_wall_to_wall() {
+ $conv = $this->get_conversation();
+ $this->wall_to_wall = false;
+ $this->owner_url = '';
+ $this->owner_photo = '';
+ $this->owner_name = '';
+
+ if($conv->get_mode() === 'channel')
+ 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_photo = $this->data['owner']['xchan_photo_m'];
+ $this->owner_name = $this->data['owner']['xchan_name'];
+ $this->wall_to_wall = true;
+ }
+ }
+
+ private function is_wall_to_wall() {
+ return $this->wall_to_wall;
+ }
+
+ private function get_owner_url() {
+ return $this->owner_url;
+ }
+
+ private function get_owner_photo() {
+ return $this->owner_photo;
+ }
+
+ private function get_owner_name() {
+ return $this->owner_name;
+ }
+
+ private function is_visiting() {
+ return $this->visiting;
+ }
+
+
+
+
+}
+
diff --git a/Zotlabs/Lib/ThreadStream.php b/Zotlabs/Lib/ThreadStream.php
new file mode 100644
index 000000000..a6d4f8517
--- /dev/null
+++ b/Zotlabs/Lib/ThreadStream.php
@@ -0,0 +1,220 @@
+<?php /** @file */
+
+namespace Zotlabs\Lib;
+
+require_once('boot.php');
+require_once('include/text.php');
+require_once('include/items.php');
+
+/**
+ * A list of threads
+ *
+ */
+
+class ThreadStream {
+
+ private $threads = array();
+ private $mode = null;
+ private $observer = null;
+ private $writable = false;
+ private $commentable = false;
+ private $profile_owner = 0;
+ private $preview = false;
+ private $prepared_item = '';
+ private $cipher = 'aes256';
+
+ // $prepared_item is for use by alternate conversation structures such as photos
+ // wherein we've already prepared a top level item which doesn't look anything like
+ // a normal "post" item
+
+ public function __construct($mode, $preview, $prepared_item = '') {
+ $this->set_mode($mode);
+ $this->preview = $preview;
+ $this->prepared_item = $prepared_item;
+ $c = ((local_channel()) ? get_pconfig(local_channel(),'system','default_cipher') : '');
+ if($c)
+ $this->cipher = $c;
+ }
+
+ /**
+ * Set the mode we'll be displayed on
+ */
+ private function set_mode($mode) {
+ if($this->get_mode() == $mode)
+ return;
+
+ $this->observer = \App::get_observer();
+ $ob_hash = (($this->observer) ? $this->observer['xchan_hash'] : '');
+
+ switch($mode) {
+ case 'network':
+ $this->profile_owner = local_channel();
+ $this->writable = true;
+ break;
+ case 'channel':
+ $this->profile_owner = \App::$profile['profile_uid'];
+ $this->writable = perm_is_allowed($this->profile_owner,$ob_hash,'post_comments');
+ break;
+ case 'display':
+ // in this mode we set profile_owner after initialisation (from conversation()) and then
+ // pull some trickery which allows us to re-invoke this function afterward
+ // it's an ugly hack so FIXME
+ $this->writable = perm_is_allowed($this->profile_owner,$ob_hash,'post_comments');
+ break;
+ case 'page':
+ $this->profile_owner = \App::$profile['uid'];
+ $this->writable = perm_is_allowed($this->profile_owner,$ob_hash,'post_comments');
+ break;
+ default:
+ logger('[ERROR] Conversation::set_mode : Unhandled mode ('. $mode .').', LOGGER_DEBUG);
+ return false;
+ break;
+ }
+ $this->mode = $mode;
+ }
+
+ /**
+ * Get mode
+ */
+ public function get_mode() {
+ return $this->mode;
+ }
+
+ /**
+ * Check if page is writable
+ */
+ public function is_writable() {
+ return $this->writable;
+ }
+
+ public function is_commentable() {
+ return $this->commentable;
+ }
+
+ /**
+ * Check if page is a preview
+ */
+ public function is_preview() {
+ return $this->preview;
+ }
+
+ /**
+ * Get profile owner
+ */
+ public function get_profile_owner() {
+ return $this->profile_owner;
+ }
+
+ public function set_profile_owner($uid) {
+ $this->profile_owner = $uid;
+ $mode = $this->get_mode();
+ $this->mode = null;
+ $this->set_mode($mode);
+ }
+
+ public function get_observer() {
+ return $this->observer;
+ }
+
+ public function get_cipher() {
+ return $this->cipher;
+ }
+
+
+ /**
+ * Add a thread to the conversation
+ *
+ * Returns:
+ * _ The inserted item on success
+ * _ false on failure
+ */
+ public function add_thread($item) {
+ $item_id = $item->get_id();
+ if(!$item_id) {
+ logger('Item has no ID!!', LOGGER_DEBUG, LOG_ERR);
+ return false;
+ }
+ if($this->get_thread($item->get_id())) {
+ logger('Thread already exists ('. $item->get_id() .').', LOGGER_DEBUG, LOG_WARNING);
+ return false;
+ }
+
+ /*
+ * Only add things that will be displayed
+ */
+
+
+ if(($item->get_data_value('id') != $item->get_data_value('parent')) && (activity_match($item->get_data_value('verb'),ACTIVITY_LIKE) || activity_match($item->get_data_value('verb'),ACTIVITY_DISLIKE))) {
+ return false;
+ }
+
+ $item->set_commentable(false);
+ $ob_hash = (($this->observer) ? $this->observer['xchan_hash'] : '');
+
+ if(! comments_are_now_closed($item->get_data())) {
+ if(($item->get_data_value('author_xchan') === $ob_hash) || ($item->get_data_value('owner_xchan') === $ob_hash))
+ $item->set_commentable(true);
+
+ if(intval($item->get_data_value('item_nocomment'))) {
+ $item->set_commentable(false);
+ }
+ elseif(($this->observer) && (! $item->is_commentable())) {
+ if((array_key_exists('owner',$item->data)) && intval($item->data['owner']['abook_self']))
+ $item->set_commentable(perm_is_allowed($this->profile_owner,$this->observer['xchan_hash'],'post_comments'));
+ else
+ $item->set_commentable(can_comment_on_post($this->observer['xchan_hash'],$item->data));
+ }
+ }
+ require_once('include/channel.php');
+
+ $item->set_conversation($this);
+ $this->threads[] = $item;
+ return end($this->threads);
+ }
+
+ /**
+ * Get data in a form usable by a conversation template
+ *
+ * We should find a way to avoid using those arguments (at least most of them)
+ *
+ * Returns:
+ * _ The data requested on success
+ * _ false on failure
+ */
+ public function get_template_data($conv_responses) {
+ $result = array();
+
+ foreach($this->threads as $item) {
+
+ if(($item->get_data_value('id') == $item->get_data_value('parent')) && $this->prepared_item) {
+ $item_data = $this->prepared_item;
+ }
+ else {
+ $item_data = $item->get_template_data($conv_responses);
+ }
+ if(!$item_data) {
+ logger('Failed to get item template data ('. $item->get_id() .').', LOGGER_DEBUG, LOG_ERR);
+ return false;
+ }
+ $result[] = $item_data;
+ }
+
+ return $result;
+ }
+
+ /**
+ * Get a thread based on its item id
+ *
+ * Returns:
+ * _ The found item on success
+ * _ false on failure
+ */
+ private function get_thread($id) {
+ foreach($this->threads as $item) {
+ if($item->get_id() == $id)
+ return $item;
+ }
+
+ return false;
+ }
+}
diff --git a/Zotlabs/Lib/XConfig.php b/Zotlabs/Lib/XConfig.php
new file mode 100644
index 000000000..e28dcf559
--- /dev/null
+++ b/Zotlabs/Lib/XConfig.php
@@ -0,0 +1,160 @@
+<?php
+
+namespace Zotlabs\Lib;
+
+
+class XConfig {
+
+ /**
+ * @brief Loads a full xchan's configuration into a cached storage.
+ *
+ * All configuration values of the given observer hash are stored in global
+ * cache which is available under the global variable App::$config[$xchan].
+ *
+ * @param string $xchan
+ * The observer's hash
+ * @return void|false Returns false if xchan is not set
+ */
+
+ static public function Load($xchan) {
+
+ if(! $xchan)
+ return false;
+
+ if(! array_key_exists($xchan, \App::$config))
+ \App::$config[$xchan] = array();
+
+ $r = q("SELECT * FROM xconfig WHERE xchan = '%s'",
+ dbesc($xchan)
+ );
+
+ if($r) {
+ foreach($r as $rr) {
+ $k = $rr['k'];
+ $c = $rr['cat'];
+ if(! array_key_exists($c, \App::$config[$xchan])) {
+ \App::$config[$xchan][$c] = array();
+ \App::$config[$xchan][$c]['config_loaded'] = true;
+ }
+ \App::$config[$xchan][$c][$k] = $rr['v'];
+ }
+ }
+ }
+
+ /**
+ * @brief Get a particular observer's config variable given the category
+ * name ($family) and a key.
+ *
+ * Get a particular observer's config value from the given category ($family)
+ * and the $key from a cached storage in App::$config[$xchan].
+ *
+ * Returns false if not set.
+ *
+ * @param string $xchan
+ * The observer's hash
+ * @param string $family
+ * The category of the configuration value
+ * @param string $key
+ * The configuration key to query
+ * @return mixed Stored $value or false if it does not exist
+ */
+
+ static public function Get($xchan, $family, $key) {
+
+ if(! $xchan)
+ return false;
+
+ if(! array_key_exists($xchan, \App::$config))
+ load_xconfig($xchan);
+
+ if((! array_key_exists($family, \App::$config[$xchan])) || (! array_key_exists($key, \App::$config[$xchan][$family])))
+ return false;
+
+ return ((! is_array(\App::$config[$xchan][$family][$key])) && (preg_match('|^a:[0-9]+:{.*}$|s', \App::$config[$xchan][$family][$key]))
+ ? unserialize(\App::$config[$xchan][$family][$key])
+ : \App::$config[$xchan][$family][$key]
+ );
+ }
+
+ /**
+ * @brief Sets a configuration value for an observer.
+ *
+ * Stores a config value ($value) in the category ($family) under the key ($key)
+ * for the observer's $xchan hash.
+ *
+ *
+ * @param string $xchan
+ * The observer's hash
+ * @param string $family
+ * The category of the configuration value
+ * @param string $key
+ * The configuration key to set
+ * @param string $value
+ * The value to store
+ * @return mixed Stored $value or false
+ */
+
+ static public function Set($xchan, $family, $key, $value) {
+
+ // manage array value
+ $dbvalue = ((is_array($value)) ? serialize($value) : $value);
+ $dbvalue = ((is_bool($dbvalue)) ? intval($dbvalue) : $dbvalue);
+
+ if(self::Get($xchan, $family, $key) === false) {
+ if(! array_key_exists($xchan, \App::$config))
+ \App::$config[$xchan] = array();
+ if(! array_key_exists($family, \App::$config[$xchan]))
+ \App::$config[$xchan][$family] = array();
+
+ $ret = q("INSERT INTO xconfig ( xchan, cat, k, v ) VALUES ( '%s', '%s', '%s', '%s' ) ",
+ dbesc($xchan),
+ dbesc($family),
+ dbesc($key),
+ dbesc($dbvalue)
+ );
+ }
+ else {
+ $ret = q("UPDATE xconfig SET v = '%s' WHERE xchan = '%s' and cat = '%s' AND k = '%s'",
+ dbesc($dbvalue),
+ dbesc($xchan),
+ dbesc($family),
+ dbesc($key)
+ );
+ }
+
+ App::$config[$xchan][$family][$key] = $value;
+
+ if($ret)
+ return $value;
+ return $ret;
+ }
+
+ /**
+ * @brief Deletes the given key from the observer's config.
+ *
+ * Removes the configured value from the stored cache in App::$config[$xchan]
+ * and removes it from the database.
+ *
+ * @param string $xchan
+ * The observer's hash
+ * @param string $family
+ * The category of the configuration value
+ * @param string $key
+ * The configuration key to delete
+ * @return mixed
+ */
+
+ static public function Delete($xchan, $family, $key) {
+
+ if(x(\App::$config[$xchan][$family], $key))
+ unset(\App::$config[$xchan][$family][$key]);
+ $ret = q("DELETE FROM xconfig WHERE xchan = '%s' AND cat = '%s' AND k = '%s'",
+ dbesc($xchan),
+ dbesc($family),
+ dbesc($key)
+ );
+
+ return $ret;
+ }
+
+} \ No newline at end of file
diff --git a/Zotlabs/Lib/ZotDriver.php b/Zotlabs/Lib/ZotDriver.php
new file mode 100644
index 000000000..e14cc7f35
--- /dev/null
+++ b/Zotlabs/Lib/ZotDriver.php
@@ -0,0 +1,30 @@
+<?php /** @file */
+
+namespace Zotlabs\Lib;
+
+
+class ZotDriver extends ProtoDriver {
+
+ protected function discover($channel,$location) {
+
+ }
+ protected function deliver($item,$channel,$recipients) {
+
+ }
+ protected function collect($channel,$connection) {
+
+ }
+ protected function change_permissions($permissions,$channel,$recipient) {
+
+ }
+ protected function acknowledge_permissions($permissions,$channel,$recipient) {
+
+ }
+ protected function deliver_private($item,$channel,$recipients) {
+
+ }
+ protected function collect_private($channel,$connection) {
+
+ }
+
+}
diff --git a/Zotlabs/Module/Acl.php b/Zotlabs/Module/Acl.php
index 5c14ab599..2bc4ba62d 100644
--- a/Zotlabs/Module/Acl.php
+++ b/Zotlabs/Module/Acl.php
@@ -53,30 +53,32 @@ class Acl extends \Zotlabs\Web\Controller {
if ($type=='' || $type=='g'){
- $r = q("SELECT `groups`.`id`, `groups`.`hash`, `groups`.`name`
+ $r = q("SELECT `groups`.`id`, `groups`.`hash`, `groups`.`gname`
FROM `groups`,`group_member`
WHERE `groups`.`deleted` = 0 AND `groups`.`uid` = %d
AND `group_member`.`gid`=`groups`.`id`
$sql_extra
GROUP BY `groups`.`id`
- ORDER BY `groups`.`name`
+ ORDER BY `groups`.`gname`
LIMIT %d OFFSET %d",
intval(local_channel()),
intval($count),
intval($start)
);
-
- foreach($r as $g){
- // logger('acl: group: ' . $g['name'] . ' members: ' . group_get_members_xchan($g['id']));
- $groups[] = array(
- "type" => "g",
- "photo" => "images/twopeople.png",
- "name" => $g['name'],
- "id" => $g['id'],
- "xid" => $g['hash'],
- "uids" => group_get_members_xchan($g['id']),
- "link" => ''
- );
+
+ if($r) {
+ foreach($r as $g){
+ // logger('acl: group: ' . $g['gname'] . ' members: ' . group_get_members_xchan($g['id']));
+ $groups[] = array(
+ "type" => "g",
+ "photo" => "images/twopeople.png",
+ "name" => $g['gname'],
+ "id" => $g['id'],
+ "xid" => $g['hash'],
+ "uids" => group_get_members_xchan($g['id']),
+ "link" => ''
+ );
+ }
}
}
@@ -204,7 +206,7 @@ class Acl extends \Zotlabs\Web\Controller {
else
$r = array();
- if(count($r)) {
+ if($r) {
foreach($r as $g){
// remove RSS feeds from ACLs - they are inaccessible
@@ -260,7 +262,7 @@ class Acl extends \Zotlabs\Web\Controller {
// logger('navbar_complete');
- if((get_config('system','block_public')) && (! local_channel()) && (! remote_channel())) {
+ if(observer_prohibited()) {
return;
}
diff --git a/Zotlabs/Module/Admin.php b/Zotlabs/Module/Admin.php
index e2e6146f8..085d13fd7 100644
--- a/Zotlabs/Module/Admin.php
+++ b/Zotlabs/Module/Admin.php
@@ -32,8 +32,8 @@ class Admin extends \Zotlabs\Web\Controller {
case 'site':
$this->admin_page_site_post($a);
break;
- case 'users':
- $this->admin_page_users_post($a);
+ case 'accounts':
+ $this->admin_page_accounts_post($a);
break;
case 'channels':
$this->admin_page_channels_post($a);
@@ -127,8 +127,8 @@ class Admin extends \Zotlabs\Web\Controller {
case 'site':
$o = $this->admin_page_site($a);
break;
- case 'users':
- $o = $this->admin_page_users($a);
+ case 'accounts':
+ $o = $this->admin_page_accounts($a);
break;
case 'channels':
$o = $this->admin_page_channels($a);
@@ -872,20 +872,20 @@ class Admin extends \Zotlabs\Web\Controller {
}
/**
- * @brief Handle POST actions on users admin page.
+ * @brief Handle POST actions on accounts admin page.
*
* This function is called when on the admin user/account page the form was
* submitted to handle multiple operations at once. If one of the icons next
- * to an entry are pressed the function admin_page_users() will handle this.
+ * to an entry are pressed the function admin_page_accounts() will handle this.
*
* @param App $a
*/
- function admin_page_users_post($a) {
+ function admin_page_accounts_post($a) {
$pending = ( x($_POST, 'pending') ? $_POST['pending'] : array() );
$users = ( x($_POST, 'user') ? $_POST['user'] : array() );
$blocked = ( x($_POST, 'blocked') ? $_POST['blocked'] : array() );
- check_form_security_token_redirectOnErr('/admin/users', 'admin_users');
+ check_form_security_token_redirectOnErr('/admin/accounts', 'admin_accounts');
// change to switch structure?
// account block/unblock button was submitted
@@ -901,8 +901,7 @@ class Admin extends \Zotlabs\Web\Controller {
notice( sprintf( tt("%s account blocked/unblocked", "%s account blocked/unblocked", count($users)), count($users)) );
}
// account delete button was submitted
- if (x($_POST, 'page_users_delete')) {
- require_once('include/Contact.php');
+ if (x($_POST, 'page_accounts_delete')) {
foreach ($users as $uid){
account_remove($uid, true, false);
}
@@ -921,20 +920,20 @@ class Admin extends \Zotlabs\Web\Controller {
}
}
- goaway(z_root() . '/admin/users' );
+ goaway(z_root() . '/admin/accounts' );
}
/**
- * @brief Generate users admin page and handle single item operations.
+ * @brief Generate accounts admin page and handle single item operations.
*
- * This function generates the users/account admin page and handles the actions
+ * This function generates the accounts/account admin page and handles the actions
* if an icon next to an entry was clicked. If several items were selected and
- * the form was submitted it is handled by the function admin_page_users_post().
+ * the form was submitted it is handled by the function admin_page_accounts_post().
*
* @param App &$a
* @return string
*/
- function admin_page_users(&$a){
+ function admin_page_accounts(&$a){
if (argc() > 2) {
$uid = argv(3);
$account = q("SELECT * FROM account WHERE account_id = %d",
@@ -943,15 +942,14 @@ class Admin extends \Zotlabs\Web\Controller {
if (! $account) {
notice( t('Account not found') . EOL);
- goaway(z_root() . '/admin/users' );
+ goaway(z_root() . '/admin/accounts' );
}
- check_form_security_token_redirectOnErr('/admin/users', 'admin_users', 't');
+ check_form_security_token_redirectOnErr('/admin/accounts', 'admin_accounts', 't');
switch (argv(2)){
case 'delete':
// delete user
- require_once('include/Contact.php');
account_remove($uid,true,false);
notice( sprintf(t("Account '%s' deleted"), $account[0]['account_email']) . EOL);
@@ -974,7 +972,7 @@ class Admin extends \Zotlabs\Web\Controller {
break;
}
- goaway(z_root() . '/admin/users' );
+ goaway(z_root() . '/admin/accounts' );
}
/* get pending */
@@ -982,7 +980,7 @@ class Admin extends \Zotlabs\Web\Controller {
intval(ACCOUNT_PENDING)
);
- /* get users */
+ /* get accounts */
$total = q("SELECT count(*) as total FROM account");
if (count($total)) {
@@ -990,22 +988,20 @@ class Admin extends \Zotlabs\Web\Controller {
\App::set_pager_itemspage(100);
}
-
- // We'll still need to link email addresses to admin/users/channels or some such, but this bit doesn't exist yet.
- // That's where we need to be doing last post/channel flags/etc, not here.
-
$serviceclass = (($_REQUEST['class']) ? " and account_service_class = '" . dbesc($_REQUEST['class']) . "' " : '');
+
+ $key = (($_REQUEST['key']) ? dbesc($_REQUEST['key']) : 'account_id');
+ $dir = 'asc';
+ if(array_key_exists('dir',$_REQUEST))
+ $dir = ((intval($_REQUEST['dir'])) ? 'asc' : 'desc');
+
+ $base = z_root() . '/admin/accounts?f=';
+ $odir = (($dir === 'asc') ? '0' : '1');
- $order = " order by account_email asc ";
- if($_REQUEST['order'] === 'expires')
- $order = " order by account_expires desc ";
- if($_REQUEST['order'] === 'created')
- $order = " order by account_created desc ";
-
- $users = q("SELECT `account_id` , `account_email`, `account_lastlog`, `account_created`, `account_expires`, " . "`account_service_class`, ( account_flags & %d )>0 as `blocked`, " .
+ $users = q("SELECT `account_id` , `account_email`, `account_lastlog`, `account_created`, `account_expires`, " . "`account_service_class`, ( account_flags & %d ) > 0 as `blocked`, " .
"(SELECT %s FROM channel as ch " .
"WHERE ch.channel_account_id = ac.account_id and ch.channel_removed = 0 ) as `channels` " .
- "FROM account as ac where true $serviceclass $order limit %d offset %d ",
+ "FROM account as ac where true $serviceclass order by $key $dir limit %d offset %d ",
intval(ACCOUNT_BLOCKED),
db_concat('ch.channel_address', ' '),
intval(\App::$pager['itemspage']),
@@ -1028,14 +1024,14 @@ class Admin extends \Zotlabs\Web\Controller {
// }
// $users = array_map("_setup_users", $users);
- $t = get_markup_template('admin_users.tpl');
+ $t = get_markup_template('admin_accounts.tpl');
$o = replace_macros($t, array(
// strings //
'$title' => t('Administration'),
- '$page' => t('Users'),
+ '$page' => t('Accounts'),
'$submit' => t('Submit'),
'$select_all' => t('select all'),
- '$h_pending' => t('User registrations waiting for confirm'),
+ '$h_pending' => t('Registrations waiting for confirm'),
'$th_pending' => array( t('Request date'), t('Email') ),
'$no_pending' => t('No registrations.'),
'$approve' => t('Approve'),
@@ -1043,14 +1039,22 @@ class Admin extends \Zotlabs\Web\Controller {
'$delete' => t('Delete'),
'$block' => t('Block'),
'$unblock' => t('Unblock'),
-
- '$h_users' => t('Users'),
- '$th_users' => array( t('ID'), t('Email'), t('All Channels'), t('Register date'), t('Last login'), t('Expires'), t('Service Class')),
+ '$odir' => $odir,
+ '$base' => $base,
+ '$h_users' => t('Accounts'),
+ '$th_users' => array(
+ [ t('ID'), 'account_id' ],
+ [ t('Email'), 'account_email' ],
+ [ t('All Channels'), 'channels' ],
+ [ t('Register date'), 'account_created' ],
+ [ t('Last login'), 'account_lastlog' ],
+ [ t('Expires'), 'account_expires' ],
+ [ t('Service Class'), 'account_service_class'] ),
'$confirm_delete_multi' => t('Selected accounts will be deleted!\n\nEverything these accounts had posted on this site will be permanently deleted!\n\nAre you sure?'),
'$confirm_delete' => t('The account {0} will be deleted!\n\nEverything this account has posted on this site will be permanently deleted!\n\nAre you sure?'),
- '$form_security_token' => get_form_security_token("admin_users"),
+ '$form_security_token' => get_form_security_token("admin_accounts"),
// values //
'$baseurl' => z_root(),
@@ -1082,7 +1086,7 @@ class Admin extends \Zotlabs\Web\Controller {
intval(PAGE_CENSORED),
intval( $uid )
);
- proc_run('php','include/directory.php',$uid,'nopush');
+ \Zotlabs\Daemon\Master::Summon(array('Directory',$uid,'nopush'));
}
notice( sprintf( tt("%s channel censored/uncensored", "%s channels censored/uncensored", count($channels)), count($channels)) );
}
@@ -1096,7 +1100,6 @@ class Admin extends \Zotlabs\Web\Controller {
notice( sprintf( tt("%s channel code allowed/disallowed", "%s channels code allowed/disallowed", count($channels)), count($channels)) );
}
if (x($_POST,'page_channels_delete')){
- require_once("include/Contact.php");
foreach($channels as $uid){
channel_remove($uid,true);
}
@@ -1128,7 +1131,6 @@ class Admin extends \Zotlabs\Web\Controller {
case "delete":{
check_form_security_token_redirectOnErr('/admin/channels', 'admin_channels', 't');
// delete channel
- require_once("include/Contact.php");
channel_remove($uid,true);
notice( sprintf(t("Channel '%s' deleted"), $channel[0]['channel_name']) . EOL);
@@ -1141,7 +1143,7 @@ class Admin extends \Zotlabs\Web\Controller {
intval($pflags),
intval( $uid )
);
- proc_run('php','include/directory.php',$uid,'nopush');
+ \Zotlabs\Daemon\Master::Summon(array('Directory',$uid,'nopush'));
notice( sprintf( (($pflags & PAGE_CENSORED) ? t("Channel '%s' censored"): t("Channel '%s' uncensored")) , $channel[0]['channel_name'] . ' (' . $channel[0]['channel_address'] . ')' ) . EOL);
}; break;
@@ -1162,6 +1164,17 @@ class Admin extends \Zotlabs\Web\Controller {
}
goaway(z_root() . '/admin/channels' );
}
+
+
+ $key = (($_REQUEST['key']) ? dbesc($_REQUEST['key']) : 'channel_id');
+ $dir = 'asc';
+ if(array_key_exists('dir',$_REQUEST))
+ $dir = ((intval($_REQUEST['dir'])) ? 'asc' : 'desc');
+
+ $base = z_root() . '/admin/channels?f=';
+ $odir = (($dir === 'asc') ? '0' : '1');
+
+
/* get channels */
@@ -1170,14 +1183,12 @@ class Admin extends \Zotlabs\Web\Controller {
\App::set_pager_total($total[0]['total']);
\App::set_pager_itemspage(100);
}
-
- $order = " order by channel_name asc ";
-
- $channels = q("SELECT * from channel where channel_removed = 0 and channel_system = 0 $order limit %d offset %d ",
+
+ $channels = q("SELECT * from channel where channel_removed = 0 and channel_system = 0 order by $key $dir limit %d offset %d ",
intval(\App::$pager['itemspage']),
intval(\App::$pager['start'])
);
-
+
if($channels) {
for($x = 0; $x < count($channels); $x ++) {
if($channels[$x]['channel_pageflags'] & PAGE_CENSORED)
@@ -1205,7 +1216,12 @@ class Admin extends \Zotlabs\Web\Controller {
'$code' => t('Allow Code'),
'$uncode' => t('Disallow Code'),
'$h_channels' => t('Channel'),
- '$th_channels' => array( t('UID'), t('Name'), t('Address')),
+ '$base' => $base,
+ '$odir' => $odir,
+ '$th_channels' => array(
+ [ t('UID'), 'channel_id' ],
+ [ t('Name'), 'channel_name' ],
+ [ t('Address'), 'channel_address' ]),
'$confirm_delete_multi' => t('Selected channels will be deleted!\n\nEverything that was posted in these channels on this site will be permanently deleted!\n\nAre you sure?'),
'$confirm_delete' => t('The channel {0} will be deleted!\n\nEverything that was posted in this channel on this site will be permanently deleted!\n\nAre you sure?'),
@@ -1295,7 +1311,7 @@ class Admin extends \Zotlabs\Web\Controller {
$admin_form = '';
- $r = q("select * from addon where plugin_admin = 1 and name = '%s' limit 1",
+ $r = q("select * from addon where plugin_admin = 1 and aname = '%s' limit 1",
dbesc($plugin)
);
@@ -1408,7 +1424,9 @@ class Admin extends \Zotlabs\Web\Controller {
'$plugins' => $plugins,
'$disabled' => t('Disabled - version incompatibility'),
'$form_security_token' => get_form_security_token('admin_plugins'),
- '$addrepo' => t('Add Plugin Repo'),
+ '$managerepos' => t('Manage Repos'),
+ '$installedtitle' => t('Installed Plugin Repositories'),
+ '$addnewrepotitle' => t('Install a New Plugin Repository'),
'$expandform' => false,
'$form' => $admin_plugins_add_repo_form,
'$newRepoModal' => $newRepoModal,
@@ -1423,13 +1441,15 @@ class Admin extends \Zotlabs\Web\Controller {
function listAddonRepos() {
$addonrepos = [];
$addonDir = __DIR__ . '/../../extend/addon/';
- if ($handle = opendir($addonDir)) {
- while (false !== ($entry = readdir($handle))) {
- if ($entry != "." && $entry != "..") {
- $addonrepos[] = $entry;
+ if(is_dir($addonDir)) {
+ if ($handle = opendir($addonDir)) {
+ while (false !== ($entry = readdir($handle))) {
+ if ($entry != "." && $entry != "..") {
+ $addonrepos[] = $entry;
+ }
}
+ closedir($handle);
}
- closedir($handle);
}
return $addonrepos;
}
@@ -1718,7 +1738,7 @@ class Admin extends \Zotlabs\Web\Controller {
// name, label, value, help string, extra data...
'$debugging' => array('debugging', t("Debugging"),get_config('system','debugging'), ""),
- '$logfile' => array('logfile', t("Log file"), get_config('system','logfile'), t("Must be writable by web server. Relative to your Red top-level directory.")),
+ '$logfile' => array('logfile', t("Log file"), get_config('system','logfile'), t("Must be writable by web server. Relative to your top-level webserver directory.")),
'$loglevel' => array('loglevel', t("Log level"), get_config('system','loglevel'), "", $log_choices),
'$form_security_token' => get_form_security_token('admin_logs'),
@@ -1733,7 +1753,7 @@ class Admin extends \Zotlabs\Web\Controller {
} else {
json_return_and_die(array('message' => 'No repo name provided.', 'success' => false));
}
- $extendDir = __DIR__ . '/../../store/git/sys/extend';
+ $extendDir = __DIR__ . '/../../store/[data]/git/sys/extend';
$addonDir = $extendDir . '/addon';
if (!file_exists($extendDir)) {
if (!mkdir($extendDir, 0770, true)) {
@@ -1746,7 +1766,7 @@ class Admin extends \Zotlabs\Web\Controller {
}
}
}
- $repoDir = __DIR__ . '/../../store/git/sys/extend/addon/' . $repoName;
+ $repoDir = __DIR__ . '/../../store/[data]/git/sys/extend/addon/' . $repoName;
if (!is_dir($repoDir)) {
logger('Repo directory does not exist: ' . $repoDir);
json_return_and_die(array('message' => 'Invalid addon repo.', 'success' => false));
@@ -1758,6 +1778,18 @@ class Admin extends \Zotlabs\Web\Controller {
$git = new GitRepo('sys', null, false, $repoName, $repoDir);
try {
if ($git->pull()) {
+ $files = array_diff(scandir($repoDir), array('.', '..'));
+ foreach ($files as $file) {
+ if (is_dir($repoDir . '/' . $file) && $file !== '.git') {
+ $source = '../extend/addon/' . $repoName . '/' . $file;
+ $target = realpath(__DIR__ . '/../../addon/') . '/' . $file;
+ unlink($target);
+ if (!symlink($source, $target)) {
+ logger('Error linking addons to /addon');
+ json_return_and_die(array('message' => 'Error linking addons to /addon', 'success' => false));
+ }
+ }
+ }
json_return_and_die(array('message' => 'Repo updated.', 'success' => true));
} else {
json_return_and_die(array('message' => 'Error updating addon repo.', 'success' => false));
@@ -1771,7 +1803,7 @@ class Admin extends \Zotlabs\Web\Controller {
} else {
json_return_and_die(array('message' => 'No repo name provided.', 'success' => false));
}
- $extendDir = __DIR__ . '/../../store/git/sys/extend';
+ $extendDir = __DIR__ . '/../../store/[data]/git/sys/extend';
$addonDir = $extendDir . '/addon';
if (!file_exists($extendDir)) {
if (!mkdir($extendDir, 0770, true)) {
@@ -1784,7 +1816,7 @@ class Admin extends \Zotlabs\Web\Controller {
}
}
}
- $repoDir = __DIR__ . '/../../store/git/sys/extend/addon/' . $repoName;
+ $repoDir = __DIR__ . '/../../store/[data]/git/sys/extend/addon/' . $repoName;
if (!is_dir($repoDir)) {
logger('Repo directory does not exist: ' . $repoDir);
json_return_and_die(array('message' => 'Invalid addon repo.', 'success' => false));
@@ -1804,7 +1836,7 @@ class Admin extends \Zotlabs\Web\Controller {
if (array_key_exists('repoURL', $_REQUEST)) {
require __DIR__ . '/../../library/PHPGit.autoload.php'; // Load PHPGit dependencies
$repoURL = $_REQUEST['repoURL'];
- $extendDir = __DIR__ . '/../../store/git/sys/extend';
+ $extendDir = __DIR__ . '/../../store/[data]/git/sys/extend';
$addonDir = $extendDir . '/addon';
if (!file_exists($extendDir)) {
if (!mkdir($extendDir, 0770, true)) {
@@ -1832,7 +1864,7 @@ class Admin extends \Zotlabs\Web\Controller {
json_return_and_die(array('message' => 'Invalid git repo', 'success' => false));
}
$repoDir = $addonDir . '/' . $repoName;
- $tempRepoBaseDir = __DIR__ . '/../../store/git/sys/temp/';
+ $tempRepoBaseDir = __DIR__ . '/../../store/[data]/git/sys/temp/';
$tempAddonDir = $tempRepoBaseDir . $repoName;
if (!is_writable($addonDir) || !is_writable($tempAddonDir)) {
@@ -1866,9 +1898,9 @@ class Admin extends \Zotlabs\Web\Controller {
if (array_key_exists('repoURL', $_REQUEST)) {
require __DIR__ . '/../../library/PHPGit.autoload.php'; // Load PHPGit dependencies
$repoURL = $_REQUEST['repoURL'];
- $extendDir = __DIR__ . '/../../store/git/sys/extend';
+ $extendDir = __DIR__ . '/../../store/[data]/git/sys/extend';
$addonDir = $extendDir . '/addon';
- $tempAddonDir = __DIR__ . '/../../store/git/sys/temp';
+ $tempAddonDir = __DIR__ . '/../../store/[data]/git/sys/temp';
if (!file_exists($extendDir)) {
if (!mkdir($extendDir, 0770, true)) {
logger('Error creating extend folder: ' . $extendDir);
@@ -1880,6 +1912,12 @@ class Admin extends \Zotlabs\Web\Controller {
}
}
}
+ if (!is_dir($tempAddonDir)) {
+ if (!mkdir($tempAddonDir, 0770, true)) {
+ logger('Error creating temp plugin repo folder: ' . $tempAddonDir);
+ json_return_and_die(array('message' => 'Error creating temp plugin repo folder: ' . $tempAddonDir, 'success' => false));
+ }
+ }
$repoName = null;
if (array_key_exists('repoName', $_REQUEST) && $_REQUEST['repoName'] !== '') {
$repoName = $_REQUEST['repoName'];
diff --git a/Zotlabs/Module/Api.php b/Zotlabs/Module/Api.php
index 3e7f23b6c..e4744c29f 100644
--- a/Zotlabs/Module/Api.php
+++ b/Zotlabs/Module/Api.php
@@ -107,7 +107,7 @@ class Api extends \Zotlabs\Web\Controller {
$r = q("SELECT `clients`.*
FROM `clients`, `tokens`
WHERE `clients`.`client_id`=`tokens`.`client_id`
- AND `tokens`.`id`='%s' AND `tokens`.`scope`='request'",
+ AND `tokens`.`id`='%s' AND `tokens`.`auth_scope`='request'",
dbesc($token));
if (!count($r))
diff --git a/Zotlabs/Module/Appman.php b/Zotlabs/Module/Appman.php
index ba2a64f35..a200e986a 100644
--- a/Zotlabs/Module/Appman.php
+++ b/Zotlabs/Module/Appman.php
@@ -2,8 +2,9 @@
namespace Zotlabs\Module;
-require_once('include/apps.php');
+//require_once('include/apps.php');
+use \Zotlabs\Lib as Zlib;
class Appman extends \Zotlabs\Web\Controller {
@@ -30,16 +31,16 @@ class Appman extends \Zotlabs\Web\Controller {
'categories' => escape_tags($_REQUEST['categories'])
);
- $_REQUEST['appid'] = app_install(local_channel(),$arr);
+ $_REQUEST['appid'] = Zlib\Apps::app_install(local_channel(),$arr);
- if(app_installed(local_channel(),$arr))
+ if(Zlib\Apps::app_installed(local_channel(),$arr))
info( t('App installed.') . EOL);
return;
}
- $papp = app_decode($_POST['papp']);
+ $papp = Zlib\Apps::app_decode($_POST['papp']);
if(! is_array($papp)) {
notice( t('Malformed app.') . EOL);
@@ -47,13 +48,13 @@ class Appman extends \Zotlabs\Web\Controller {
}
if($_POST['install']) {
- app_install(local_channel(),$papp);
- if(app_installed(local_channel(),$papp))
+ Zlib\Apps::app_install(local_channel(),$papp);
+ if(Zlib\Apps::app_installed(local_channel(),$papp))
info( t('App installed.') . EOL);
}
if($_POST['delete']) {
- app_destroy(local_channel(),$papp);
+ Zlib\Apps::app_destroy(local_channel(),$papp);
}
if($_POST['edit']) {
@@ -100,7 +101,7 @@ class Appman extends \Zotlabs\Web\Controller {
}
}
- $embed = array('embed', t('Embed code'), app_encode($app,true),'', 'onclick="this.select();"');
+ $embed = array('embed', t('Embed code'), Zlib\Apps::app_encode($app,true),'', 'onclick="this.select();"');
}
diff --git a/Zotlabs/Module/Apps.php b/Zotlabs/Module/Apps.php
index 33259b319..4bdec4573 100644
--- a/Zotlabs/Module/Apps.php
+++ b/Zotlabs/Module/Apps.php
@@ -1,8 +1,9 @@
<?php
namespace Zotlabs\Module;
-require_once('include/apps.php');
+//require_once('include/apps.php');
+use \Zotlabs\Lib as Zlib;
class Apps extends \Zotlabs\Web\Controller {
@@ -19,25 +20,25 @@ class Apps extends \Zotlabs\Web\Controller {
if(local_channel()) {
- import_system_apps();
+ Zlib\Apps::import_system_apps();
$syslist = array();
- $list = app_list(local_channel(), false, $_GET['cat']);
+ $list = Zlib\Apps::app_list(local_channel(), false, $_GET['cat']);
if($list) {
foreach($list as $x) {
- $syslist[] = app_encode($x);
+ $syslist[] = Zlib\Apps::app_encode($x);
}
}
- translate_system_apps($syslist);
+ Zlib\Apps::translate_system_apps($syslist);
}
else
- $syslist = get_system_apps(true);
+ $syslist = Zlib\Apps::get_system_apps(true);
- usort($syslist,'app_name_compare');
+ usort($syslist,'Zotlabs\\Lib\\Apps::app_name_compare');
// logger('apps: ' . print_r($syslist,true));
foreach($syslist as $app) {
- $apps[] = app_render($app,$mode);
+ $apps[] = Zlib\Apps::app_render($app,$mode);
}
return replace_macros(get_markup_template('myapps.tpl'), array(
diff --git a/Zotlabs/Module/Attach.php b/Zotlabs/Module/Attach.php
index 8948b66d7..de941d52c 100644
--- a/Zotlabs/Module/Attach.php
+++ b/Zotlabs/Module/Attach.php
@@ -40,7 +40,7 @@ class Attach extends \Zotlabs\Web\Controller {
header('Content-disposition: attachment; filename="' . $r['data']['filename'] . '"');
if(intval($r['data']['os_storage'])) {
- $fname = dbunescbin($r['data']['data']);
+ $fname = dbunescbin($r['data']['content']);
if(strpos($fname,'store') !== false)
$istream = fopen($fname,'rb');
else
@@ -53,7 +53,7 @@ class Attach extends \Zotlabs\Web\Controller {
}
}
else
- echo dbunescbin($r['data']['data']);
+ echo dbunescbin($r['data']['content']);
killme();
}
diff --git a/Zotlabs/Module/Blocks.php b/Zotlabs/Module/Blocks.php
index ed702befb..32650a090 100644
--- a/Zotlabs/Module/Blocks.php
+++ b/Zotlabs/Module/Blocks.php
@@ -1,7 +1,7 @@
<?php
namespace Zotlabs\Module;
-require_once('include/identity.php');
+require_once('include/channel.php');
require_once('include/conversation.php');
require_once('include/acl_selectors.php');
diff --git a/Zotlabs/Module/Cal.php b/Zotlabs/Module/Cal.php
index 958ce5aa6..1da42684d 100644
--- a/Zotlabs/Module/Cal.php
+++ b/Zotlabs/Module/Cal.php
@@ -6,14 +6,12 @@ require_once('include/bbcode.php');
require_once('include/datetime.php');
require_once('include/event.php');
require_once('include/items.php');
-require_once('include/Contact.php');
-
class Cal extends \Zotlabs\Web\Controller {
function init() {
- if((get_config('system','block_public')) && (! local_channel()) && (! remote_channel())) {
+ if(observer_prohibited()) {
return;
}
@@ -47,13 +45,12 @@ class Cal extends \Zotlabs\Web\Controller {
- function get() {
+ function get() {
- if((get_config('system','block_public')) && (! local_channel()) && (! remote_channel())) {
+ if(observer_prohibited()) {
return;
}
-
-
+
$channel = null;
if(argc() > 1) {
@@ -94,7 +91,7 @@ class Cal extends \Zotlabs\Web\Controller {
$mode = 'view';
$y = 0;
$m = 0;
- $ignored = ((x($_REQUEST,'ignored')) ? " and ignored = " . intval($_REQUEST['ignored']) . " " : '');
+ $ignored = ((x($_REQUEST,'ignored')) ? " and dismissed = " . intval($_REQUEST['ignored']) . " " : '');
// logger('args: ' . print_r(\App::$argv,true));
@@ -149,7 +146,7 @@ class Cal extends \Zotlabs\Web\Controller {
$ftext = datetime_convert('UTC',$tz,$fdt);
$ftext = substr($ftext,0,14) . "00:00";
- $type = ((x($orig_event)) ? $orig_event['type'] : 'event');
+ $type = ((x($orig_event)) ? $orig_event['etype'] : 'event');
$f = get_config('system','event_input_format');
if(! $f)
@@ -160,7 +157,7 @@ class Cal extends \Zotlabs\Web\Controller {
$show_bd = perm_is_allowed($channel['channel_id'], get_observer_hash(), 'view_contacts');
if(! $show_bd) {
- $sql_extra .= " and event.type != 'birthday' ";
+ $sql_extra .= " and event.etype != 'birthday' ";
}
@@ -228,8 +225,8 @@ class Cal extends \Zotlabs\Web\Controller {
$r = q("SELECT event.*, item.plink, item.item_flags, item.author_xchan, item.owner_xchan
from event left join item on event_hash = resource_id
where resource_type = 'event' and event.uid = %d $ignored
- AND (( adjust = 0 AND ( finish >= '%s' or nofinish = 1 ) AND start <= '%s' )
- OR ( adjust = 1 AND ( finish >= '%s' or nofinish = 1 ) AND start <= '%s' )) $sql_extra ",
+ AND (( adjust = 0 AND ( dtend >= '%s' or nofinish = 1 ) AND dtstart <= '%s' )
+ OR ( adjust = 1 AND ( dtend >= '%s' or nofinish = 1 ) AND dtstart <= '%s' )) $sql_extra ",
intval($channel['channel_id']),
dbesc($start),
dbesc($finish),
@@ -250,7 +247,7 @@ class Cal extends \Zotlabs\Web\Controller {
if($r) {
foreach($r as $rr) {
- $j = (($rr['adjust']) ? datetime_convert('UTC',date_default_timezone_get(),$rr['start'], 'j') : datetime_convert('UTC','UTC',$rr['start'],'j'));
+ $j = (($rr['adjust']) ? datetime_convert('UTC',date_default_timezone_get(),$rr['dtstart'], 'j') : datetime_convert('UTC','UTC',$rr['dtstart'],'j'));
if(! x($links,$j))
$links[$j] = z_root() . '/' . \App::$cmd . '#link-' . $j;
}
@@ -265,15 +262,15 @@ class Cal extends \Zotlabs\Web\Controller {
foreach($r as $rr) {
- $j = (($rr['adjust']) ? datetime_convert('UTC',date_default_timezone_get(),$rr['start'], 'j') : datetime_convert('UTC','UTC',$rr['start'],'j'));
- $d = (($rr['adjust']) ? datetime_convert('UTC',date_default_timezone_get(),$rr['start'], $fmt) : datetime_convert('UTC','UTC',$rr['start'],$fmt));
+ $j = (($rr['adjust']) ? datetime_convert('UTC',date_default_timezone_get(),$rr['dtstart'], 'j') : datetime_convert('UTC','UTC',$rr['dtstart'],'j'));
+ $d = (($rr['adjust']) ? datetime_convert('UTC',date_default_timezone_get(),$rr['dtstart'], $fmt) : datetime_convert('UTC','UTC',$rr['dtstart'],$fmt));
$d = day_translate($d);
- $start = (($rr['adjust']) ? datetime_convert('UTC',date_default_timezone_get(),$rr['start'], 'c') : datetime_convert('UTC','UTC',$rr['start'],'c'));
+ $start = (($rr['adjust']) ? datetime_convert('UTC',date_default_timezone_get(),$rr['dtstart'], 'c') : datetime_convert('UTC','UTC',$rr['dtstart'],'c'));
if ($rr['nofinish']){
$end = null;
} else {
- $end = (($rr['adjust']) ? datetime_convert('UTC',date_default_timezone_get(),$rr['finish'], 'c') : datetime_convert('UTC','UTC',$rr['finish'],'c'));
+ $end = (($rr['adjust']) ? datetime_convert('UTC',date_default_timezone_get(),$rr['dtend'], 'c') : datetime_convert('UTC','UTC',$rr['dtend'],'c'));
}
diff --git a/Zotlabs/Module/Channel.php b/Zotlabs/Module/Channel.php
index f55705442..29bfcbc3c 100644
--- a/Zotlabs/Module/Channel.php
+++ b/Zotlabs/Module/Channel.php
@@ -13,353 +13,355 @@ require_once('include/PermissionDescription.php');
class Channel extends \Zotlabs\Web\Controller {
-function init() {
-
- $which = null;
- if(argc() > 1)
- $which = argv(1);
- if(! $which) {
- if(local_channel()) {
- $channel = \App::get_channel();
- if($channel && $channel['channel_address'])
- $which = $channel['channel_address'];
+ function init() {
+
+ $which = null;
+ if(argc() > 1)
+ $which = argv(1);
+ if(! $which) {
+ if(local_channel()) {
+ $channel = \App::get_channel();
+ if($channel && $channel['channel_address'])
+ $which = $channel['channel_address'];
+ }
+ }
+ if(! $which) {
+ notice( t('You must be logged in to see this page.') . EOL );
+ return;
}
- }
- if(! $which) {
- notice( t('You must be logged in to see this page.') . EOL );
- return;
- }
- $profile = 0;
- $channel = \App::get_channel();
+ $profile = 0;
+ $channel = \App::get_channel();
- if((local_channel()) && (argc() > 2) && (argv(2) === 'view')) {
- $which = $channel['channel_address'];
- $profile = argv(1);
- }
+ if((local_channel()) && (argc() > 2) && (argv(2) === 'view')) {
+ $which = $channel['channel_address'];
+ $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" ;
+ \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" ;
-// 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" ;
+ // 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
+ // Run profile_load() here to make sure the theme is set before
+ // we start loading content
- profile_load($a,$which,$profile);
+ profile_load($a,$which,$profile);
-}
+ }
-function get($update = 0, $load = false) {
+ function get($update = 0, $load = false) {
- if($load)
- $_SESSION['loadtime'] = datetime_convert();
+ if($load)
+ $_SESSION['loadtime'] = datetime_convert();
- $checkjs = new \Zotlabs\Web\CheckJS(1);
+ $checkjs = new \Zotlabs\Web\CheckJS(1);
- $category = $datequery = $datequery2 = '';
+ $category = $datequery = $datequery2 = '';
- $mid = ((x($_REQUEST,'mid')) ? $_REQUEST['mid'] : '');
+ $mid = ((x($_REQUEST,'mid')) ? $_REQUEST['mid'] : '');
- $datequery = ((x($_GET,'dend') && is_a_date_arg($_GET['dend'])) ? notags($_GET['dend']) : '');
- $datequery2 = ((x($_GET,'dbegin') && is_a_date_arg($_GET['dbegin'])) ? notags($_GET['dbegin']) : '');
+ $datequery = ((x($_GET,'dend') && is_a_date_arg($_GET['dend'])) ? notags($_GET['dend']) : '');
+ $datequery2 = ((x($_GET,'dbegin') && is_a_date_arg($_GET['dbegin'])) ? notags($_GET['dbegin']) : '');
- if(get_config('system','block_public') && (! get_account_id()) && (! remote_channel())) {
+ if(observer_prohibited(true)) {
return login();
- }
+ }
- $category = ((x($_REQUEST,'cat')) ? $_REQUEST['cat'] : '');
- $hashtags = ((x($_REQUEST,'tag')) ? $_REQUEST['tag'] : '');
+ $category = ((x($_REQUEST,'cat')) ? $_REQUEST['cat'] : '');
+ $hashtags = ((x($_REQUEST,'tag')) ? $_REQUEST['tag'] : '');
- $groups = array();
+ $groups = array();
- $o = '';
+ $o = '';
- if($update) {
- // Ensure we've got a profile owner if updating.
- \App::$profile['profile_uid'] = \App::$profile_uid = $update;
- }
- else {
- if(\App::$profile['profile_uid'] == local_channel()) {
- nav_set_selected('home');
+ if($update) {
+ // Ensure we've got a profile owner if updating.
+ \App::$profile['profile_uid'] = \App::$profile_uid = $update;
+ }
+ else {
+ if(\App::$profile['profile_uid'] == local_channel()) {
+ nav_set_selected('home');
+ }
}
- }
- $is_owner = (((local_channel()) && (\App::$profile['profile_uid'] == local_channel())) ? true : false);
+ $is_owner = (((local_channel()) && (\App::$profile['profile_uid'] == local_channel())) ? true : false);
- $channel = \App::get_channel();
- $observer = \App::get_observer();
- $ob_hash = (($observer) ? $observer['xchan_hash'] : '');
+ $channel = \App::get_channel();
+ $observer = \App::get_observer();
+ $ob_hash = (($observer) ? $observer['xchan_hash'] : '');
- $perms = get_all_perms(\App::$profile['profile_uid'],$ob_hash);
+ $perms = get_all_perms(\App::$profile['profile_uid'],$ob_hash);
- if(! $perms['view_stream']) {
+ if(! $perms['view_stream']) {
// We may want to make the target of this redirect configurable
if($perms['view_profile']) {
notice( t('Insufficient permissions. Request redirected to profile page.') . EOL);
goaway (z_root() . "/profile/" . \App::$profile['channel_address']);
}
- notice( t('Permission denied.') . EOL);
- return;
- }
+ notice( t('Permission denied.') . EOL);
+ return;
+ }
- if(! $update) {
+ if(! $update) {
- $o .= profile_tabs($a, $is_owner, \App::$profile['channel_address']);
+ $o .= profile_tabs($a, $is_owner, \App::$profile['channel_address']);
- $o .= common_friends_visitor_widget(\App::$profile['profile_uid']);
+ $o .= common_friends_visitor_widget(\App::$profile['profile_uid']);
- if($channel && $is_owner) {
- $channel_acl = array(
- 'allow_cid' => $channel['channel_allow_cid'],
- 'allow_gid' => $channel['channel_allow_gid'],
- 'deny_cid' => $channel['channel_deny_cid'],
- 'deny_gid' => $channel['channel_deny_gid']
- );
- }
- else
- $channel_acl = array();
-
-
- if($perms['post_wall']) {
-
- $x = array(
- 'is_owner' => $is_owner,
- 'allow_location' => ((($is_owner || $observer) && (intval(get_pconfig(\App::$profile['profile_uid'],'system','use_browser_location')))) ? true : false),
- 'default_location' => (($is_owner) ? \App::$profile['channel_location'] : ''),
- 'nickname' => \App::$profile['channel_address'],
- 'lockstate' => (((strlen(\App::$profile['channel_allow_cid'])) || (strlen(\App::$profile['channel_allow_gid'])) || (strlen(\App::$profile['channel_deny_cid'])) || (strlen(\App::$profile['channel_deny_gid']))) ? 'lock' : 'unlock'),
- 'acl' => (($is_owner) ? populate_acl($channel_acl,true, \PermissionDescription::fromGlobalPermission('view_stream'), get_post_aclDialogDescription(), 'acl_dialog_post') : ''),
- 'showacl' => (($is_owner) ? 'yes' : ''),
- 'bang' => '',
- 'visitor' => (($is_owner || $observer) ? true : false),
- 'profile_uid' => \App::$profile['profile_uid'],
- 'editor_autocomplete' => true,
- 'bbco_autocomplete' => 'bbcode',
- 'bbcode' => true
- );
-
- $o .= status_editor($a,$x);
- }
+ if($channel && $is_owner) {
+ $channel_acl = array(
+ 'allow_cid' => $channel['channel_allow_cid'],
+ 'allow_gid' => $channel['channel_allow_gid'],
+ 'deny_cid' => $channel['channel_deny_cid'],
+ 'deny_gid' => $channel['channel_deny_gid']
+ );
+ }
+ else
+ $channel_acl = array();
+
+
+ if($perms['post_wall']) {
+
+ $x = array(
+ 'is_owner' => $is_owner,
+ 'allow_location' => ((($is_owner || $observer) && (intval(get_pconfig(\App::$profile['profile_uid'],'system','use_browser_location')))) ? true : false),
+ 'default_location' => (($is_owner) ? \App::$profile['channel_location'] : ''),
+ 'nickname' => \App::$profile['channel_address'],
+ 'lockstate' => (((strlen(\App::$profile['channel_allow_cid'])) || (strlen(\App::$profile['channel_allow_gid'])) || (strlen(\App::$profile['channel_deny_cid'])) || (strlen(\App::$profile['channel_deny_gid']))) ? 'lock' : 'unlock'),
+ 'acl' => (($is_owner) ? populate_acl($channel_acl,true, \PermissionDescription::fromGlobalPermission('view_stream'), get_post_aclDialogDescription(), 'acl_dialog_post') : ''),
+ 'showacl' => (($is_owner) ? 'yes' : ''),
+ 'bang' => '',
+ 'visitor' => (($is_owner || $observer) ? true : false),
+ 'profile_uid' => \App::$profile['profile_uid'],
+ 'editor_autocomplete' => true,
+ 'bbco_autocomplete' => 'bbcode',
+ 'bbcode' => true
+ );
+
+ $o .= status_editor($a,$x);
+ }
- }
+ }
- /**
- * Get permissions SQL - if $remote_contact is true, our remote user has been pre-verified and we already have fetched his/her groups
- */
+ /**
+ * Get permissions SQL - if $remote_contact is true, our remote user has been pre-verified and we already have fetched his/her groups
+ */
- $item_normal = item_normal();
- $sql_extra = item_permissions_sql(\App::$profile['profile_uid']);
+ $item_normal = item_normal();
+ $sql_extra = item_permissions_sql(\App::$profile['profile_uid']);
- if(get_pconfig(\App::$profile['profile_uid'],'system','channel_list_mode') && (! $mid))
- $page_mode = 'list';
- else
- $page_mode = 'client';
+ if(get_pconfig(\App::$profile['profile_uid'],'system','channel_list_mode') && (! $mid))
+ $page_mode = 'list';
+ else
+ $page_mode = 'client';
- $abook_uids = " and abook.abook_channel = " . intval(\App::$profile['profile_uid']) . " ";
+ $abook_uids = " and abook.abook_channel = " . intval(\App::$profile['profile_uid']) . " ";
- $simple_update = (($update) ? " AND item_unseen = 1 " : '');
+ $simple_update = (($update) ? " AND item_unseen = 1 " : '');
- \App::$page['htmlhead'] .= "\r\n" . '<link rel="alternate" type="application/json+oembed" href="' . z_root() . '/oep?f=&url=' . urlencode(z_root() . '/' . \App::$query_string) . '" 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::$query_string) . '" title="oembed" />' . "\r\n";
- if($update && $_SESSION['loadtime'])
- $simple_update = " AND (( item_unseen = 1 AND item.changed > '" . datetime_convert('UTC','UTC',$_SESSION['loadtime']) . "' ) OR item.changed > '" . datetime_convert('UTC','UTC',$_SESSION['loadtime']) . "' ) ";
- if($load)
- $simple_update = '';
-
- if(($update) && (! $load)) {
-
- if ($mid) {
- $r = q("SELECT parent AS item_id from item where mid like '%s' and uid = %d $item_normal
- AND item_wall = 1 AND item_unseen = 1 $sql_extra limit 1",
- dbesc($mid . '%'),
- intval(\App::$profile['profile_uid'])
- );
- } else {
- $r = q("SELECT distinct parent AS `item_id`, created from item
- left join abook on ( item.owner_xchan = abook.abook_xchan $abook_uids )
- WHERE uid = %d $item_normal
- AND item_wall = 1 $simple_update
- AND (abook.abook_blocked = 0 or abook.abook_flags is null)
- $sql_extra
- ORDER BY created DESC",
- intval(\App::$profile['profile_uid'])
- );
- $_SESSION['loadtime'] = datetime_convert();
- }
-
- }
- else {
-
- if(x($category)) {
- $sql_extra .= protect_sprintf(term_query('item', $category, TERM_CATEGORY));
- }
- if(x($hashtags)) {
- $sql_extra .= protect_sprintf(term_query('item', $hashtags, TERM_HASHTAG, TERM_COMMUNITYTAG));
- }
-
- if($datequery) {
- $sql_extra2 .= protect_sprintf(sprintf(" AND item.created <= '%s' ", dbesc(datetime_convert(date_default_timezone_get(),'',$datequery))));
- }
- if($datequery2) {
- $sql_extra2 .= protect_sprintf(sprintf(" AND item.created >= '%s' ", dbesc(datetime_convert(date_default_timezone_get(),'',$datequery2))));
- }
+ if($update && $_SESSION['loadtime'])
+ $simple_update = " AND (( item_unseen = 1 AND item.changed > '" . datetime_convert('UTC','UTC',$_SESSION['loadtime']) . "' ) OR item.changed > '" . datetime_convert('UTC','UTC',$_SESSION['loadtime']) . "' ) ";
+ if($load)
+ $simple_update = '';
- $itemspage = get_pconfig(local_channel(),'system','itemspage');
- \App::set_pager_itemspage(((intval($itemspage)) ? $itemspage : 20));
- $pager_sql = sprintf(" LIMIT %d OFFSET %d ", intval(\App::$pager['itemspage']), intval(\App::$pager['start']));
+ if(($update) && (! $load)) {
- if($load || ($checkjs->disabled())) {
- if ($mid) {
- $r = q("SELECT parent AS item_id from item where mid = '%s' and uid = %d $item_normal
- AND item_wall = 1 $sql_extra limit 1",
- dbesc($mid),
+ if($mid) {
+ $r = q("SELECT parent AS item_id from item where mid like '%s' and uid = %d $item_normal
+ AND item_wall = 1 AND item_unseen = 1 $sql_extra limit 1",
+ dbesc($mid . '%'),
intval(\App::$profile['profile_uid'])
);
- if (! $r) {
- notice( t('Permission denied.') . EOL);
- }
-
- } else {
- $r = q("SELECT distinct id AS item_id, created FROM item
- left join abook on item.author_xchan = abook.abook_xchan
+ }
+ else {
+ $r = q("SELECT distinct parent AS `item_id`, created from item
+ left join abook on ( item.owner_xchan = abook.abook_xchan $abook_uids )
WHERE uid = %d $item_normal
- AND item_wall = 1 and item_thread_top = 1
- AND (abook_blocked = 0 or abook.abook_flags is null)
- $sql_extra $sql_extra2
- ORDER BY created DESC $pager_sql ",
+ AND item_wall = 1 $simple_update
+ AND (abook.abook_blocked = 0 or abook.abook_flags is null)
+ $sql_extra
+ ORDER BY created DESC",
intval(\App::$profile['profile_uid'])
);
+ $_SESSION['loadtime'] = datetime_convert();
}
+
}
else {
- $r = array();
- }
- }
- if($r) {
+ if(x($category)) {
+ $sql_extra .= protect_sprintf(term_query('item', $category, TERM_CATEGORY));
+ }
+ if(x($hashtags)) {
+ $sql_extra .= protect_sprintf(term_query('item', $hashtags, TERM_HASHTAG, TERM_COMMUNITYTAG));
+ }
- $parents_str = ids_to_querystr($r,'item_id');
-
- $items = q("SELECT `item`.*, `item`.`id` AS `item_id`
- FROM `item`
- WHERE `item`.`uid` = %d $item_normal
- AND `item`.`parent` IN ( %s )
- $sql_extra ",
- intval(\App::$profile['profile_uid']),
- dbesc($parents_str)
- );
-
- xchan_query($items);
- $items = fetch_post_tags($items, true);
- $items = conv_sort($items,'created');
-
- if ($load && $mid && (! count($items))) {
- // This will happen if we don't have sufficient permissions
- // to view the parent item (or the item itself if it is toplevel)
- notice( t('Permission denied.') . EOL);
+ if($datequery) {
+ $sql_extra2 .= protect_sprintf(sprintf(" AND item.created <= '%s' ", dbesc(datetime_convert(date_default_timezone_get(),'',$datequery))));
+ }
+ if($datequery2) {
+ $sql_extra2 .= protect_sprintf(sprintf(" AND item.created >= '%s' ", dbesc(datetime_convert(date_default_timezone_get(),'',$datequery2))));
+ }
+
+ $itemspage = get_pconfig(local_channel(),'system','itemspage');
+ \App::set_pager_itemspage(((intval($itemspage)) ? $itemspage : 20));
+ $pager_sql = sprintf(" LIMIT %d OFFSET %d ", intval(\App::$pager['itemspage']), intval(\App::$pager['start']));
+
+ if($load || ($checkjs->disabled())) {
+ if($mid) {
+ $r = q("SELECT parent AS item_id from item where mid = '%s' and uid = %d $item_normal
+ AND item_wall = 1 $sql_extra limit 1",
+ dbesc($mid),
+ intval(\App::$profile['profile_uid'])
+ );
+ if (! $r) {
+ notice( t('Permission denied.') . EOL);
+ }
+
+ }
+ else {
+ $r = q("SELECT distinct id AS item_id, created FROM item
+ left join abook on item.author_xchan = abook.abook_xchan
+ WHERE uid = %d $item_normal
+ AND item_wall = 1 and item_thread_top = 1
+ AND (abook_blocked = 0 or abook.abook_flags is null)
+ $sql_extra $sql_extra2
+ ORDER BY created DESC $pager_sql ",
+ intval(\App::$profile['profile_uid'])
+ );
+ }
+ }
+ else {
+ $r = array();
+ }
}
- } else {
- $items = array();
- }
+ if($r) {
- if((! $update) && (! $load)) {
-
- // This is ugly, but we can't pass the profile_uid through the session to the ajax updater,
- // because browser prefetching might change it on us. We have to deliver it with the page.
-
- $maxheight = get_pconfig(\App::$profile['profile_uid'],'system','channel_divmore_height');
- if(! $maxheight)
- $maxheight = 400;
-
- $o .= '<div id="live-channel"></div>' . "\r\n";
- $o .= "<script> var profile_uid = " . \App::$profile['profile_uid']
- . "; var netargs = '?f='; var profile_page = " . \App::$pager['page']
- . "; divmore_height = " . intval($maxheight) . "; </script>\r\n";
-
- \App::$page['htmlhead'] .= replace_macros(get_markup_template("build_query.tpl"),array(
- '$baseurl' => z_root(),
- '$pgtype' => 'channel',
- '$uid' => ((\App::$profile['profile_uid']) ? \App::$profile['profile_uid'] : '0'),
- '$gid' => '0',
- '$cid' => '0',
- '$cmin' => '0',
- '$cmax' => '0',
- '$star' => '0',
- '$liked' => '0',
- '$conv' => '0',
- '$spam' => '0',
- '$nouveau' => '0',
- '$wall' => '1',
- '$fh' => '0',
- '$page' => ((\App::$pager['page'] != 1) ? \App::$pager['page'] : 1),
- '$search' => '',
- '$order' => '',
- '$list' => ((x($_REQUEST,'list')) ? intval($_REQUEST['list']) : 0),
- '$file' => '',
- '$cats' => (($category) ? $category : ''),
- '$tags' => (($hashtags) ? $hashtags : ''),
- '$mid' => $mid,
- '$verb' => '',
- '$dend' => $datequery,
- '$dbegin' => $datequery2
- ));
+ $parents_str = ids_to_querystr($r,'item_id');
+
+ $items = q("SELECT `item`.*, `item`.`id` AS `item_id`
+ FROM `item`
+ WHERE `item`.`uid` = %d $item_normal
+ AND `item`.`parent` IN ( %s )
+ $sql_extra ",
+ intval(\App::$profile['profile_uid']),
+ dbesc($parents_str)
+ );
+ xchan_query($items);
+ $items = fetch_post_tags($items, true);
+ $items = conv_sort($items,'created');
- }
+ if($load && $mid && (! count($items))) {
+ // This will happen if we don't have sufficient permissions
+ // to view the parent item (or the item itself if it is toplevel)
+ notice( t('Permission denied.') . EOL);
+ }
- $update_unseen = '';
+ }
+ else {
+ $items = array();
+ }
- if($page_mode === 'list') {
+ if((! $update) && (! $load)) {
+
+ // This is ugly, but we can't pass the profile_uid through the session to the ajax updater,
+ // because browser prefetching might change it on us. We have to deliver it with the page.
+
+ $maxheight = get_pconfig(\App::$profile['profile_uid'],'system','channel_divmore_height');
+ if(! $maxheight)
+ $maxheight = 400;
+
+ $o .= '<div id="live-channel"></div>' . "\r\n";
+ $o .= "<script> var profile_uid = " . \App::$profile['profile_uid']
+ . "; var netargs = '?f='; var profile_page = " . \App::$pager['page']
+ . "; divmore_height = " . intval($maxheight) . "; </script>\r\n";
+
+ \App::$page['htmlhead'] .= replace_macros(get_markup_template("build_query.tpl"),array(
+ '$baseurl' => z_root(),
+ '$pgtype' => 'channel',
+ '$uid' => ((\App::$profile['profile_uid']) ? \App::$profile['profile_uid'] : '0'),
+ '$gid' => '0',
+ '$cid' => '0',
+ '$cmin' => '0',
+ '$cmax' => '0',
+ '$star' => '0',
+ '$liked' => '0',
+ '$conv' => '0',
+ '$spam' => '0',
+ '$nouveau' => '0',
+ '$wall' => '1',
+ '$fh' => '0',
+ '$page' => ((\App::$pager['page'] != 1) ? \App::$pager['page'] : 1),
+ '$search' => '',
+ '$order' => '',
+ '$list' => ((x($_REQUEST,'list')) ? intval($_REQUEST['list']) : 0),
+ '$file' => '',
+ '$cats' => (($category) ? $category : ''),
+ '$tags' => (($hashtags) ? $hashtags : ''),
+ '$mid' => $mid,
+ '$verb' => '',
+ '$dend' => $datequery,
+ '$dbegin' => $datequery2
+ ));
- /**
- * in "list mode", only mark the parent item and any like activities as "seen".
- * We won't distinguish between comment likes and post likes. The important thing
- * is that the number of unseen comments will be accurate. The SQL to separate the
- * comment likes could also get somewhat hairy.
- */
- if($parents_str) {
- $update_unseen = " AND ( id IN ( " . dbesc($parents_str) . " )";
- $update_unseen .= " OR ( parent IN ( " . dbesc($parents_str) . " ) AND verb in ( '" . dbesc(ACTIVITY_LIKE) . "','" . dbesc(ACTIVITY_DISLIKE) . "' ))) ";
- }
- }
- else {
- if($parents_str) {
- $update_unseen = " AND parent IN ( " . dbesc($parents_str) . " )";
}
- }
- if($is_owner && $update_unseen) {
- $r = q("UPDATE item SET item_unseen = 0 where item_unseen = 1 and item_wall = 1 AND uid = %d $update_unseen",
- intval(local_channel())
- );
- }
+ $update_unseen = '';
+ if($page_mode === 'list') {
- if($checkjs->disabled()) {
- $o .= conversation($a,$items,'channel',$update,'traditional');
- } else {
- $o .= conversation($a,$items,'channel',$update,$page_mode);
- }
+ /**
+ * in "list mode", only mark the parent item and any like activities as "seen".
+ * We won't distinguish between comment likes and post likes. The important thing
+ * is that the number of unseen comments will be accurate. The SQL to separate the
+ * comment likes could also get somewhat hairy.
+ */
- if((! $update) || ($checkjs->disabled())) {
- $o .= alt_pager($a,count($items));
- if ($mid && $items[0]['title'])
- \App::$page['title'] = $items[0]['title'] . " - " . \App::$page['title'];
- }
+ if($parents_str) {
+ $update_unseen = " AND ( id IN ( " . dbesc($parents_str) . " )";
+ $update_unseen .= " OR ( parent IN ( " . dbesc($parents_str) . " ) AND verb in ( '" . dbesc(ACTIVITY_LIKE) . "','" . dbesc(ACTIVITY_DISLIKE) . "' ))) ";
+ }
+ }
+ else {
+ if($parents_str) {
+ $update_unseen = " AND parent IN ( " . dbesc($parents_str) . " )";
+ }
+ }
+
+ if($is_owner && $update_unseen) {
+ $r = q("UPDATE item SET item_unseen = 0 where item_unseen = 1 and item_wall = 1 AND uid = %d $update_unseen",
+ intval(local_channel())
+ );
+ }
- if($mid)
- $o .= '<div id="content-complete"></div>';
- return $o;
-}
+ if($checkjs->disabled()) {
+ $o .= conversation($a,$items,'channel',$update,'traditional');
+ }
+ else {
+ $o .= conversation($a,$items,'channel',$update,$page_mode);
+ }
+ if((! $update) || ($checkjs->disabled())) {
+ $o .= alt_pager($a,count($items));
+ if ($mid && $items[0]['title'])
+ \App::$page['title'] = $items[0]['title'] . " - " . \App::$page['title'];
+ }
+ if($mid)
+ $o .= '<div id="content-complete"></div>';
+
+ return $o;
+ }
} \ No newline at end of file
diff --git a/Zotlabs/Module/Chanview.php b/Zotlabs/Module/Chanview.php
index f70444816..c6dd07eb7 100644
--- a/Zotlabs/Module/Chanview.php
+++ b/Zotlabs/Module/Chanview.php
@@ -1,10 +1,8 @@
<?php
namespace Zotlabs\Module;
-require_once('include/Contact.php');
require_once('include/zot.php');
-
class Chanview extends \Zotlabs\Web\Controller {
function get() {
@@ -62,18 +60,15 @@ class Chanview extends \Zotlabs\Web\Controller {
}
if($_REQUEST['address']) {
- $ret = zot_finger($_REQUEST['address'],null);
- if($ret['success']) {
- $j = json_decode($ret['body'],true);
- if($j)
- import_xchan($j);
+ $j = \Zotlabs\Zot\Finger::run($_REQUEST['address'],null);
+ if($j['success']) {
+ import_xchan($j);
$r = q("select * from xchan where xchan_addr = '%s' limit 1",
dbesc($_REQUEST['address'])
);
if($r)
\App::$poi = $r[0];
}
-
}
}
diff --git a/Zotlabs/Module/Chat.php b/Zotlabs/Module/Chat.php
index 9508ed3de..026e8369a 100644
--- a/Zotlabs/Module/Chat.php
+++ b/Zotlabs/Module/Chat.php
@@ -1,9 +1,11 @@
-<?php
-namespace Zotlabs\Module; /** @file */
+<?php /** @file */
+
+namespace Zotlabs\Module;
+
-require_once('include/chat.php');
require_once('include/bookmarks.php');
+use \Zotlabs\Lib as Zlib;
class Chat extends \Zotlabs\Web\Controller {
@@ -41,7 +43,7 @@ class Chat extends \Zotlabs\Web\Controller {
}
- function post() {
+ function post() {
if($_POST['room_name'])
$room = strip_tags(trim($_POST['room_name']));
@@ -54,7 +56,7 @@ class Chat extends \Zotlabs\Web\Controller {
if($_POST['action'] === 'drop') {
logger('delete chatroom');
- chatroom_destroy($channel,array('cr_name' => $room));
+ Zlib\Chatroom::destroy($channel,array('cr_name' => $room));
goaway(z_root() . '/chat/' . $channel['channel_address']);
}
@@ -67,7 +69,7 @@ class Chat extends \Zotlabs\Web\Controller {
if(intval($arr['expire']) < 0)
$arr['expire'] = 0;
- chatroom_create($channel,$arr);
+ Zlib\Chatroom::create($channel,$arr);
$x = q("select * from chatroom where cr_name = '%s' and cr_uid = %d limit 1",
dbesc($room),
@@ -87,7 +89,7 @@ class Chat extends \Zotlabs\Web\Controller {
}
- function get() {
+ function get() {
if(local_channel())
$channel = \App::get_channel();
@@ -105,7 +107,7 @@ class Chat extends \Zotlabs\Web\Controller {
}
if((argc() > 3) && intval(argv(2)) && (argv(3) === 'leave')) {
- chatroom_leave($observer,argv(2),$_SERVER['REMOTE_ADDR']);
+ Zlib\Chatroom::leave($observer,argv(2),$_SERVER['REMOTE_ADDR']);
goaway(z_root() . '/channel/' . argv(1));
}
@@ -158,7 +160,7 @@ class Chat extends \Zotlabs\Web\Controller {
$room_id = intval(argv(2));
$bookmark_link = get_bookmark_link($ob);
- $x = chatroom_enter($observer,$room_id,'online',$_SERVER['REMOTE_ADDR']);
+ $x = Zlib\Chatroom::enter($observer,$room_id,'online',$_SERVER['REMOTE_ADDR']);
if(! $x)
return;
$x = q("select * from chatroom where cr_id = %d and cr_uid = %d $sql_extra limit 1",
@@ -238,10 +240,10 @@ class Chat extends \Zotlabs\Web\Controller {
));
}
- $rooms = chatroom_list(\App::$profile['profile_uid']);
+ $rooms = Zlib\Chatroom::roomlist(\App::$profile['profile_uid']);
$o .= replace_macros(get_markup_template('chatrooms.tpl'), array(
- '$header' => sprintf( t('%1$s\'s Chatrooms'), \App::$profile['name']),
+ '$header' => sprintf( t('%1$s\'s Chatrooms'), \App::$profile['fullname']),
'$name' => t('Name'),
'$baseurl' => z_root(),
'$nickname' => \App::$profile['channel_address'],
diff --git a/Zotlabs/Module/Chatsvc.php b/Zotlabs/Module/Chatsvc.php
index a9bc97301..6a28a7c4d 100644
--- a/Zotlabs/Module/Chatsvc.php
+++ b/Zotlabs/Module/Chatsvc.php
@@ -1,14 +1,16 @@
-<?php
-namespace Zotlabs\Module; /** @file */
+<?php /** @file */
+
+namespace Zotlabs\Module;
require_once('include/security.php');
+use \Zotlabs\Lib as Zlib;
class Chatsvc extends \Zotlabs\Web\Controller {
function init() {
- //logger('chatsvc');
+ //logger('chatsvc');
$ret = array('success' => false);
@@ -27,7 +29,7 @@ class Chatsvc extends \Zotlabs\Web\Controller {
}
- function post() {
+ function post() {
$ret = array('success' => false);
@@ -65,7 +67,7 @@ class Chatsvc extends \Zotlabs\Web\Controller {
json_return_and_die($ret);
}
- function get() {
+ function get() {
$status = strip_tags($_REQUEST['status']);
$room_id = intval(\App::$data['chat']['room_id']);
diff --git a/Zotlabs/Module/Cloud.php b/Zotlabs/Module/Cloud.php
index f3767e3f0..b691475ce 100644
--- a/Zotlabs/Module/Cloud.php
+++ b/Zotlabs/Module/Cloud.php
@@ -100,9 +100,12 @@ class Cloud extends \Zotlabs\Web\Controller {
// require_once('\Zotlabs\Storage/QuotaPlugin.php');
// $server->addPlugin(new \Zotlabs\Storage\\QuotaPlugin($auth));
+ ob_start();
// All we need to do now, is to fire up the server
$server->exec();
-
+
+ ob_end_flush();
+
killme();
}
diff --git a/Zotlabs/Module/Connect.php b/Zotlabs/Module/Connect.php
index 6ef3577d7..f68e0baac 100644
--- a/Zotlabs/Module/Connect.php
+++ b/Zotlabs/Module/Connect.php
@@ -2,7 +2,7 @@
namespace Zotlabs\Module; /** @file */
-require_once('include/Contact.php');
+
require_once('include/contact_widgets.php');
require_once('include/items.php');
@@ -47,7 +47,8 @@ class Connect extends \Zotlabs\Web\Controller {
intval(PAGE_PREMIUM),
intval(local_channel())
);
- proc_run('php','include/notifier.php','refresh_all',\App::$data['channel']['channel_id']);
+
+ \Zotlabs\Daemon\Master::Summon(array('Notifier','refresh_all',\App::$data['channel']['channel_id']));
}
set_pconfig(\App::$data['channel']['channel_id'],'system','selltext',$text);
// reload the page completely to get fresh data
diff --git a/Zotlabs/Module/Connections.php b/Zotlabs/Module/Connections.php
index 564f4e527..a412d16ae 100644
--- a/Zotlabs/Module/Connections.php
+++ b/Zotlabs/Module/Connections.php
@@ -1,9 +1,9 @@
<?php
namespace Zotlabs\Module;
-require_once('include/Contact.php');
+
require_once('include/socgraph.php');
-require_once('include/contact_selectors.php');
+require_once('include/selectors.php');
require_once('include/group.php');
require_once('include/contact_widgets.php');
require_once('include/zot.php');
diff --git a/Zotlabs/Module/Connedit.php b/Zotlabs/Module/Connedit.php
index a1268510d..33deac4c8 100644
--- a/Zotlabs/Module/Connedit.php
+++ b/Zotlabs/Module/Connedit.php
@@ -7,9 +7,9 @@ namespace Zotlabs\Module;
*
*/
-require_once('include/Contact.php');
+
require_once('include/socgraph.php');
-require_once('include/contact_selectors.php');
+require_once('include/selectors.php');
require_once('include/group.php');
require_once('include/contact_widgets.php');
require_once('include/zot.php');
@@ -176,7 +176,7 @@ class Connedit extends \Zotlabs\Web\Controller {
$record = $z[0]['xlink_id'];
}
if($record) {
- proc_run('php','include/ratenotif.php','rating',$record);
+ \Zotlabs\Daemon\Master::Summon(array('Ratenotif','rating',$record));
}
}
@@ -230,7 +230,7 @@ class Connedit extends \Zotlabs\Web\Controller {
if(\App::$poi && \App::$poi['abook_my_perms'] != $abook_my_perms
&& (! intval(\App::$poi['abook_self']))) {
- proc_run('php', 'include/notifier.php', (($new_friend) ? 'permission_create' : 'permission_update'), $contact_id);
+ \Zotlabs\Daemon\Master::Summon(array('Notifier', (($new_friend) ? 'permission_create' : 'permission_update'), $contact_id));
}
if($new_friend) {
@@ -270,7 +270,7 @@ class Connedit extends \Zotlabs\Web\Controller {
array('rel' => 'photo', 'type' => \App::$poi['xchan_photo_mimetype'], 'href' => \App::$poi['xchan_photo_l'])
),
);
- $xarr['object'] = json_encode($obj);
+ $xarr['obj'] = json_encode($obj);
$xarr['obj_type'] = ACTIVITY_OBJ_PERSON;
$xarr['body'] = '[zrl=' . $channel['xchan_url'] . ']' . $channel['xchan_name'] . '[/zrl]' . ' ' . t('is now connected to') . ' ' . '[zrl=' . \App::$poi['xchan_url'] . ']' . \App::$poi['xchan_name'] . '[/zrl]';
@@ -283,7 +283,7 @@ class Connedit extends \Zotlabs\Web\Controller {
// pull in a bit of content if there is any to pull in
- proc_run('php','include/onepoll.php',$contact_id);
+ \Zotlabs\Daemon\Master::Summon(array('Onepoll',$contact_id));
}
@@ -414,7 +414,7 @@ class Connedit extends \Zotlabs\Web\Controller {
if($cmd === 'update') {
// pull feed and consume it, which should subscribe to the hub.
- proc_run('php',"include/poller.php","$contact_id");
+ \Zotlabs\Daemon\Master::Summon(array('Poller',$contact_id));
goaway(z_root() . '/connedit/' . $contact_id);
}
@@ -427,7 +427,7 @@ class Connedit extends \Zotlabs\Web\Controller {
else {
// if you are on a different network we'll force a refresh of the connection basic info
- proc_run('php','include/notifier.php','permission_update',$contact_id);
+ Zotlabs\Daemon\Master::Summon(array('Notifier','permission_update',$contact_id));
}
goaway(z_root() . '/connedit/' . $contact_id);
}
@@ -485,7 +485,6 @@ class Connedit extends \Zotlabs\Web\Controller {
if($cmd === 'drop') {
- require_once('include/Contact.php');
// FIXME
// We need to send either a purge or a refresh packet to the other side (the channel being unfriended).
@@ -583,8 +582,6 @@ class Connedit extends \Zotlabs\Web\Controller {
if(intval($contact['abook_self']))
$self = true;
- require_once('include/contact_selectors.php');
-
$tpl = get_markup_template("abook_edit.tpl");
if(feature_enabled(local_channel(),'affinity')) {
diff --git a/Zotlabs/Module/Contactgroup.php b/Zotlabs/Module/Contactgroup.php
index 497442ff4..bbe56b4ad 100644
--- a/Zotlabs/Module/Contactgroup.php
+++ b/Zotlabs/Module/Contactgroup.php
@@ -41,10 +41,10 @@ class Contactgroup extends \Zotlabs\Web\Controller {
if($change) {
if(in_array($change,$preselected)) {
- group_rmv_member(local_channel(),$group['name'],$change);
+ group_rmv_member(local_channel(),$group['gname'],$change);
}
else {
- group_add_member(local_channel(),$group['name'],$change);
+ group_add_member(local_channel(),$group['gname'],$change);
}
}
}
diff --git a/Zotlabs/Module/Cover_photo.php b/Zotlabs/Module/Cover_photo.php
index be27a99ef..a72c3389f 100644
--- a/Zotlabs/Module/Cover_photo.php
+++ b/Zotlabs/Module/Cover_photo.php
@@ -8,7 +8,7 @@ namespace Zotlabs\Module;
*/
require_once('include/photo/photo_driver.php');
-require_once('include/identity.php');
+require_once('include/channel.php');
@@ -80,7 +80,7 @@ class Cover_photo extends \Zotlabs\Web\Controller {
$profile = $r[0];
}
- $r = q("SELECT * FROM photo WHERE resource_id = '%s' AND uid = %d AND scale = 0 LIMIT 1",
+ $r = q("SELECT * FROM photo WHERE resource_id = '%s' AND uid = %d AND imgscale = 0 LIMIT 1",
dbesc($image_id),
intval(local_channel())
);
@@ -88,9 +88,9 @@ class Cover_photo extends \Zotlabs\Web\Controller {
if($r) {
$base_image = $r[0];
- $base_image['data'] = (($r[0]['os_storage']) ? @file_get_contents($base_image['data']) : dbunescbin($base_image['data']));
+ $base_image['content'] = (($r[0]['os_storage']) ? @file_get_contents($base_image['content']) : dbunescbin($base_image['content']));
- $im = photo_factory($base_image['data'], $base_image['type']);
+ $im = photo_factory($base_image['content'], $base_image['mimetype']);
if($im->is_valid()) {
// We are scaling and cropping the relative pixel locations to the original photo instead of the
@@ -99,7 +99,7 @@ class Cover_photo extends \Zotlabs\Web\Controller {
// First load the scaled photo to check its size. (Should probably pass this in the post form and save
// a query.)
- $g = q("select width, height from photo where resource_id = '%s' and uid = %d and scale = 3",
+ $g = q("select width, height from photo where resource_id = '%s' and uid = %d and imgscale = 3",
dbesc($image_id),
intval(local_channel())
);
@@ -133,26 +133,26 @@ class Cover_photo extends \Zotlabs\Web\Controller {
$p = array('aid' => $aid, 'uid' => local_channel(), 'resource_id' => $base_image['resource_id'],
'filename' => $base_image['filename'], 'album' => t('Cover Photos'));
- $p['scale'] = 7;
+ $p['imgscale'] = 7;
$p['photo_usage'] = PHOTO_COVER;
$r1 = $im->save($p);
$im->doScaleImage(850,310);
- $p['scale'] = 8;
+ $p['imgscale'] = 8;
$r2 = $im->save($p);
$im->doScaleImage(425,160);
- $p['scale'] = 9;
+ $p['imgscale'] = 9;
$r3 = $im->save($p);
if($r1 === false || $r2 === false || $r3 === false) {
// if one failed, delete them all so we can start over.
notice( t('Image resize failed.') . EOL );
- $x = q("delete from photo where resource_id = '%s' and uid = %d and scale >= 7 ",
+ $x = q("delete from photo where resource_id = '%s' and uid = %d and imgscale >= 7 ",
dbesc($base_image['resource_id']),
local_channel()
);
@@ -183,7 +183,7 @@ class Cover_photo extends \Zotlabs\Web\Controller {
logger('attach_store: ' . print_r($res,true));
if($res && intval($res['data']['is_photo'])) {
- $i = q("select * from photo where resource_id = '%s' and uid = %d and scale = 0",
+ $i = q("select * from photo where resource_id = '%s' and uid = %d and imgscale = 0",
dbesc($hash),
intval(local_channel())
);
@@ -195,10 +195,10 @@ class Cover_photo extends \Zotlabs\Web\Controller {
$os_storage = false;
foreach($i as $ii) {
- $smallest = intval($ii['scale']);
+ $smallest = intval($ii['imgscale']);
$os_storage = intval($ii['os_storage']);
- $imagedata = $ii['data'];
- $filetype = $ii['type'];
+ $imagedata = $ii['content'];
+ $filetype = $ii['mimetype'];
}
}
@@ -224,10 +224,10 @@ class Cover_photo extends \Zotlabs\Web\Controller {
$arr['obj_type'] = ACTIVITY_OBJ_PHOTO;
$arr['verb'] = ACTIVITY_UPDATE;
- $arr['object'] = json_encode(array(
+ $arr['obj'] = json_encode(array(
'type' => $arr['obj_type'],
'id' => z_root() . '/photo/' . $photo['resource_id'] . '-7',
- 'link' => array('rel' => 'photo', 'type' => $photo['type'], 'href' => z_root() . '/photo/' . $photo['resource_id'] . '-7')
+ 'link' => array('rel' => 'photo', 'type' => $photo['mimetype'], 'href' => z_root() . '/photo/' . $photo['resource_id'] . '-7')
));
if($profile && stripos($profile['gender'],t('female')) !== false)
@@ -295,7 +295,7 @@ class Cover_photo extends \Zotlabs\Web\Controller {
$resource_id = argv(2);
- $r = q("SELECT id, album, scale FROM photo WHERE uid = %d AND resource_id = '%s' ORDER BY scale ASC",
+ $r = q("SELECT id, album, imgscale FROM photo WHERE uid = %d AND resource_id = '%s' ORDER BY imgscale ASC",
intval(local_channel()),
dbesc($resource_id)
);
@@ -305,11 +305,11 @@ class Cover_photo extends \Zotlabs\Web\Controller {
}
$havescale = false;
foreach($r as $rr) {
- if($rr['scale'] == 7)
+ if($rr['imgscale'] == 7)
$havescale = true;
}
- $r = q("SELECT `data`, `type`, resource_id, os_storage FROM photo WHERE id = %d and uid = %d limit 1",
+ $r = q("SELECT `content`, `mimetype`, resource_id, os_storage FROM photo WHERE id = %d and uid = %d limit 1",
intval($r[0]['id']),
intval(local_channel())
@@ -320,15 +320,15 @@ class Cover_photo extends \Zotlabs\Web\Controller {
}
if(intval($r[0]['os_storage']))
- $data = @file_get_contents($r[0]['data']);
+ $data = @file_get_contents($r[0]['content']);
else
- $data = dbunescbin($r[0]['data']);
+ $data = dbunescbin($r[0]['content']);
- $ph = photo_factory($data, $r[0]['type']);
+ $ph = photo_factory($data, $r[0]['mimetype']);
$smallest = 0;
if($ph->is_valid()) {
// go ahead as if we have just uploaded a new photo to crop
- $i = q("select resource_id, scale from photo where resource_id = '%s' and uid = %d and scale = 0",
+ $i = q("select resource_id, imgscale from photo where resource_id = '%s' and uid = %d and imgscale = 0",
dbesc($r[0]['resource_id']),
intval(local_channel())
);
@@ -336,7 +336,7 @@ class Cover_photo extends \Zotlabs\Web\Controller {
if($i) {
$hash = $i[0]['resource_id'];
foreach($i as $ii) {
- $smallest = intval($ii['scale']);
+ $smallest = intval($ii['imgscale']);
}
}
}
diff --git a/Zotlabs/Module/Dav.php b/Zotlabs/Module/Dav.php
index 549c992cc..2fddabe19 100644
--- a/Zotlabs/Module/Dav.php
+++ b/Zotlabs/Module/Dav.php
@@ -64,6 +64,7 @@ class Dav extends \Zotlabs\Web\Controller {
$auth = new \Zotlabs\Storage\BasicAuth();
+ $auth->setRealm(ucfirst(\Zotlabs\Lib\System::get_platform_name()) . 'WebDAV');
// $authBackend = new \Sabre\DAV\Auth\Backend\BasicCallBack(function($userName,$password) {
// if(account_verify_password($userName,$password))
diff --git a/Zotlabs/Module/Directory.php b/Zotlabs/Module/Directory.php
index b8bac53bb..560038ffc 100644
--- a/Zotlabs/Module/Directory.php
+++ b/Zotlabs/Module/Directory.php
@@ -57,9 +57,9 @@ class Directory extends \Zotlabs\Web\Controller {
}
}
- function get() {
+ function get() {
- if((get_config('system','block_public')) && (! local_channel()) && (! remote_channel())) {
+ if(observer_prohibited()) {
notice( t('Public access denied.') . EOL);
return;
}
diff --git a/Zotlabs/Module/Display.php b/Zotlabs/Module/Display.php
index 2a5a04a2a..c1a0d84bc 100644
--- a/Zotlabs/Module/Display.php
+++ b/Zotlabs/Module/Display.php
@@ -7,17 +7,13 @@ class Display extends \Zotlabs\Web\Controller {
function get($update = 0, $load = false) {
- // logger("mod-display: update = $update load = $load");
-
-
$checkjs = new \Zotlabs\Web\CheckJS(1);
-
if($load)
$_SESSION['loadtime'] = datetime_convert();
- if(intval(get_config('system','block_public')) && (! local_channel()) && (! remote_channel())) {
+ if(observer_prohibited()) {
notice( t('Public access denied.') . EOL);
return;
}
@@ -185,7 +181,7 @@ class Display extends \Zotlabs\Web\Controller {
if($load || ($checkjs->disabled())) {
$r = null;
- require_once('include/identity.php');
+ require_once('include/channel.php');
$sys = get_sys_channel();
$sysid = $sys['channel_id'];
@@ -233,7 +229,7 @@ class Display extends \Zotlabs\Web\Controller {
elseif($update && !$load) {
$r = null;
- require_once('include/identity.php');
+ require_once('include/channel.php');
$sys = get_sys_channel();
$sysid = $sys['channel_id'];
diff --git a/Zotlabs/Module/Editblock.php b/Zotlabs/Module/Editblock.php
index a79962033..fb86557f2 100644
--- a/Zotlabs/Module/Editblock.php
+++ b/Zotlabs/Module/Editblock.php
@@ -1,7 +1,7 @@
<?php
namespace Zotlabs\Module;
-require_once('include/identity.php');
+require_once('include/channel.php');
require_once('include/acl_selectors.php');
require_once('include/conversation.php');
diff --git a/Zotlabs/Module/Editlayout.php b/Zotlabs/Module/Editlayout.php
index c5b50235a..5028882d2 100644
--- a/Zotlabs/Module/Editlayout.php
+++ b/Zotlabs/Module/Editlayout.php
@@ -1,7 +1,7 @@
<?php
namespace Zotlabs\Module;
-require_once('include/identity.php');
+require_once('include/channel.php');
require_once('include/acl_selectors.php');
require_once('include/conversation.php');
diff --git a/Zotlabs/Module/Editpost.php b/Zotlabs/Module/Editpost.php
index 43edf2c00..da859de3e 100644
--- a/Zotlabs/Module/Editpost.php
+++ b/Zotlabs/Module/Editpost.php
@@ -87,11 +87,11 @@ class Editpost extends \Zotlabs\Web\Controller {
'hide_location' => true,
'mimetype' => $itm[0]['mimetype'],
'ptyp' => $itm[0]['obj_type'],
- 'body' => undo_post_tagging($itm[0]['body']),
+ 'body' => htmlspecialchars_decode(undo_post_tagging($itm[0]['body']),ENT_COMPAT),
'post_id' => $post_id,
'defloc' => $channel['channel_location'],
'visitor' => true,
- 'title' => htmlspecialchars($itm[0]['title'],ENT_COMPAT,'UTF-8'),
+ 'title' => htmlspecialchars_decode($itm[0]['title'],ENT_COMPAT),
'category' => $category,
'showacl' => false,
'profile_uid' => $owner_uid,
diff --git a/Zotlabs/Module/Editwebpage.php b/Zotlabs/Module/Editwebpage.php
index c2346c53b..1b5c320a0 100644
--- a/Zotlabs/Module/Editwebpage.php
+++ b/Zotlabs/Module/Editwebpage.php
@@ -1,7 +1,7 @@
<?php
namespace Zotlabs\Module;
-require_once('include/identity.php');
+require_once('include/channel.php');
require_once('include/acl_selectors.php');
require_once('include/conversation.php');
require_once('include/PermissionDescription.php');
diff --git a/Zotlabs/Module/Events.php b/Zotlabs/Module/Events.php
index 9519ca11b..3f3f9fb4c 100644
--- a/Zotlabs/Module/Events.php
+++ b/Zotlabs/Module/Events.php
@@ -171,7 +171,7 @@ class Events extends \Zotlabs\Web\Controller {
foreach($cats as $cat) {
$post_tags[] = array(
'uid' => $profile_uid,
- 'type' => TERM_CATEGORY,
+ 'ttype' => TERM_CATEGORY,
'otype' => TERM_OBJ_POST,
'term' => trim($cat),
'url' => $channel['xchan_url'] . '?f=&cat=' . urlencode(trim($cat))
@@ -180,12 +180,12 @@ class Events extends \Zotlabs\Web\Controller {
}
$datarray = array();
- $datarray['start'] = $start;
- $datarray['finish'] = $finish;
+ $datarray['dtstart'] = $start;
+ $datarray['dtend'] = $finish;
$datarray['summary'] = $summary;
$datarray['description'] = $desc;
$datarray['location'] = $location;
- $datarray['type'] = $type;
+ $datarray['etype'] = $type;
$datarray['adjust'] = $adjust;
$datarray['nofinish'] = $nofinish;
$datarray['uid'] = local_channel();
@@ -232,7 +232,7 @@ class Events extends \Zotlabs\Web\Controller {
}
if($share)
- proc_run('php',"include/notifier.php","event","$item_id");
+ \Zotlabs\Daemon\Master::Summon(array('Notifier','event',$item_id));
}
@@ -269,14 +269,14 @@ class Events extends \Zotlabs\Web\Controller {
nav_set_selected('all_events');
if((argc() > 2) && (argv(1) === 'ignore') && intval(argv(2))) {
- $r = q("update event set ignore = 1 where id = %d and uid = %d",
+ $r = q("update event set dismissed = 1 where id = %d and uid = %d",
intval(argv(2)),
intval(local_channel())
);
}
if((argc() > 2) && (argv(1) === 'unignore') && intval(argv(2))) {
- $r = q("update event set ignore = 0 where id = %d and uid = %d",
+ $r = q("update event set dismissed = 0 where id = %d and uid = %d",
intval(argv(2)),
intval(local_channel())
);
@@ -301,7 +301,7 @@ class Events extends \Zotlabs\Web\Controller {
$mode = 'view';
$y = 0;
$m = 0;
- $ignored = ((x($_REQUEST,'ignored')) ? " and ignored = " . intval($_REQUEST['ignored']) . " " : '');
+ $ignored = ((x($_REQUEST,'ignored')) ? " and dismissed = " . intval($_REQUEST['ignored']) . " " : '');
// logger('args: ' . print_r(\App::$argv,true));
@@ -358,9 +358,9 @@ class Events extends \Zotlabs\Web\Controller {
if(x($_REQUEST,'summary')) $orig_event['summary'] = $_REQUEST['summary'];
if(x($_REQUEST,'description')) $orig_event['description'] = $_REQUEST['description'];
if(x($_REQUEST,'location')) $orig_event['location'] = $_REQUEST['location'];
- if(x($_REQUEST,'start')) $orig_event['start'] = $_REQUEST['start'];
- if(x($_REQUEST,'finish')) $orig_event['finish'] = $_REQUEST['finish'];
- if(x($_REQUEST,'type')) $orig_event['type'] = $_REQUEST['type'];
+ if(x($_REQUEST,'start')) $orig_event['dtstart'] = $_REQUEST['start'];
+ if(x($_REQUEST,'finish')) $orig_event['dtend'] = $_REQUEST['finish'];
+ if(x($_REQUEST,'type')) $orig_event['etype'] = $_REQUEST['type'];
*/
$n_checked = ((x($orig_event) && $orig_event['nofinish']) ? ' checked="checked" ' : '');
@@ -380,9 +380,9 @@ class Events extends \Zotlabs\Web\Controller {
if($orig_event['event_xchan'])
$sh_checked .= ' disabled="disabled" ';
- $sdt = ((x($orig_event)) ? $orig_event['start'] : 'now');
+ $sdt = ((x($orig_event)) ? $orig_event['dtstart'] : 'now');
- $fdt = ((x($orig_event)) ? $orig_event['finish'] : '+1 hour');
+ $fdt = ((x($orig_event)) ? $orig_event['dtend'] : '+1 hour');
$tz = date_default_timezone_get();
if(x($orig_event))
@@ -406,7 +406,7 @@ class Events extends \Zotlabs\Web\Controller {
$ftext = datetime_convert('UTC',$tz,$fdt);
$ftext = substr($ftext,0,14) . "00:00";
- $type = ((x($orig_event)) ? $orig_event['type'] : 'event');
+ $type = ((x($orig_event)) ? $orig_event['etype'] : 'event');
$f = get_config('system','event_input_format');
if(! $f)
@@ -536,8 +536,8 @@ class Events extends \Zotlabs\Web\Controller {
);
} elseif($export) {
$r = q("SELECT * from event where uid = %d
- AND (( `adjust` = 0 AND ( `finish` >= '%s' or nofinish = 1 ) AND `start` <= '%s' )
- OR ( `adjust` = 1 AND ( `finish` >= '%s' or nofinish = 1 ) AND `start` <= '%s' )) ",
+ AND (( `adjust` = 0 AND ( `dtend` >= '%s' or nofinish = 1 ) AND `dtstart` <= '%s' )
+ OR ( `adjust` = 1 AND ( `dtend` >= '%s' or nofinish = 1 ) AND `dtstart` <= '%s' )) ",
intval(local_channel()),
dbesc($start),
dbesc($finish),
@@ -554,8 +554,8 @@ class Events extends \Zotlabs\Web\Controller {
$r = q("SELECT event.*, item.plink, item.item_flags, item.author_xchan, item.owner_xchan
from event left join item on event_hash = resource_id
where resource_type = 'event' and event.uid = %d $ignored
- AND (( adjust = 0 AND ( finish >= '%s' or nofinish = 1 ) AND start <= '%s' )
- OR ( adjust = 1 AND ( finish >= '%s' or nofinish = 1 ) AND start <= '%s' )) ",
+ AND (( adjust = 0 AND ( dtend >= '%s' or nofinish = 1 ) AND dtstart <= '%s' )
+ OR ( adjust = 1 AND ( dtend >= '%s' or nofinish = 1 ) AND dtstart <= '%s' )) ",
intval(local_channel()),
dbesc($start),
dbesc($finish),
@@ -576,7 +576,7 @@ class Events extends \Zotlabs\Web\Controller {
if($r) {
foreach($r as $rr) {
- $j = (($rr['adjust']) ? datetime_convert('UTC',date_default_timezone_get(),$rr['start'], 'j') : datetime_convert('UTC','UTC',$rr['start'],'j'));
+ $j = (($rr['adjust']) ? datetime_convert('UTC',date_default_timezone_get(),$rr['dtstart'], 'j') : datetime_convert('UTC','UTC',$rr['dtstart'],'j'));
if(! x($links,$j))
$links[$j] = z_root() . '/' . \App::$cmd . '#link-' . $j;
}
@@ -591,15 +591,15 @@ class Events extends \Zotlabs\Web\Controller {
foreach($r as $rr) {
- $j = (($rr['adjust']) ? datetime_convert('UTC',date_default_timezone_get(),$rr['start'], 'j') : datetime_convert('UTC','UTC',$rr['start'],'j'));
- $d = (($rr['adjust']) ? datetime_convert('UTC',date_default_timezone_get(),$rr['start'], $fmt) : datetime_convert('UTC','UTC',$rr['start'],$fmt));
+ $j = (($rr['adjust']) ? datetime_convert('UTC',date_default_timezone_get(),$rr['dtstart'], 'j') : datetime_convert('UTC','UTC',$rr['dtstart'],'j'));
+ $d = (($rr['adjust']) ? datetime_convert('UTC',date_default_timezone_get(),$rr['dtstart'], $fmt) : datetime_convert('UTC','UTC',$rr['dtstart'],$fmt));
$d = day_translate($d);
- $start = (($rr['adjust']) ? datetime_convert('UTC',date_default_timezone_get(),$rr['start'], 'c') : datetime_convert('UTC','UTC',$rr['start'],'c'));
+ $start = (($rr['adjust']) ? datetime_convert('UTC',date_default_timezone_get(),$rr['dtstart'], 'c') : datetime_convert('UTC','UTC',$rr['dtstart'],'c'));
if ($rr['nofinish']){
$end = null;
} else {
- $end = (($rr['adjust']) ? datetime_convert('UTC',date_default_timezone_get(),$rr['finish'], 'c') : datetime_convert('UTC','UTC',$rr['finish'],'c'));
+ $end = (($rr['adjust']) ? datetime_convert('UTC',date_default_timezone_get(),$rr['dtend'], 'c') : datetime_convert('UTC','UTC',$rr['dtend'],'c'));
}
diff --git a/Zotlabs/Module/Fbrowser.php b/Zotlabs/Module/Fbrowser.php
index eef3cb67d..c534e8f72 100644
--- a/Zotlabs/Module/Fbrowser.php
+++ b/Zotlabs/Module/Fbrowser.php
@@ -45,10 +45,10 @@ class Fbrowser extends \Zotlabs\Web\Controller {
$album = hex2bin(\App::$argv[2]);
$sql_extra = sprintf("AND `album` = '%s' ",dbesc($album));
$sql_extra2 = "";
- $path[]=array(z_root()."/fbrowser/image/".\App::$argv[2]."/", $album);
+ $path[]=array(z_root() . "/fbrowser/image/" . \App::$argv[2] . "/", $album);
}
- $r = q("SELECT `resource_id`, `id`, `filename`, type, min(`scale`) AS `hiq`,max(`scale`) AS `loq`, `description`
+ $r = q("SELECT `resource_id`, `id`, `filename`, type, min(`imgscale`) AS `hiq`,max(`imgscale`) AS `loq`, `description`
FROM `photo` WHERE `uid` = %d $sql_extra
GROUP BY `resource_id` $sql_extra2",
intval(local_channel())
diff --git a/Zotlabs/Module/Feed.php b/Zotlabs/Module/Feed.php
index 9d33ba2c3..47871eafb 100644
--- a/Zotlabs/Module/Feed.php
+++ b/Zotlabs/Module/Feed.php
@@ -31,7 +31,7 @@ class Feed extends \Zotlabs\Web\Controller {
$channel = $r[0];
- if((intval(get_config('system','block_public'))) && (! get_account_id()))
+ if(observer_prohibited(true))
killme();
logger('mod_feed: public feed request from ' . $_SERVER['REMOTE_ADDR'] . ' for ' . $channel['channel_address']);
diff --git a/Zotlabs/Module/Filer.php b/Zotlabs/Module/Filer.php
index 607d088db..6a57cdb2a 100644
--- a/Zotlabs/Module/Filer.php
+++ b/Zotlabs/Module/Filer.php
@@ -39,7 +39,7 @@ class Filer extends \Zotlabs\Web\Controller {
}
else {
$filetags = array();
- $r = q("select distinct(term) from term where uid = %d and type = %d order by term asc",
+ $r = q("select distinct(term) from term where uid = %d and ttype = %d order by term asc",
intval(local_channel()),
intval(TERM_FILE)
);
diff --git a/Zotlabs/Module/Filerm.php b/Zotlabs/Module/Filerm.php
index eb9a42c1e..cbf6a118d 100644
--- a/Zotlabs/Module/Filerm.php
+++ b/Zotlabs/Module/Filerm.php
@@ -22,7 +22,7 @@ class Filerm extends \Zotlabs\Web\Controller {
logger('filerm: tag ' . $term . ' item ' . $item_id);
if($item_id && strlen($term)) {
- $r = q("delete from term where uid = %d and type = %d and oid = %d and term = '%s'",
+ $r = q("delete from term where uid = %d and ttype = %d and oid = %d and term = '%s'",
intval(local_channel()),
intval(($category) ? TERM_CATEGORY : TERM_FILE),
intval($item_id),
diff --git a/Zotlabs/Module/Follow.php b/Zotlabs/Module/Follow.php
index 1701328bf..1df382a89 100644
--- a/Zotlabs/Module/Follow.php
+++ b/Zotlabs/Module/Follow.php
@@ -53,14 +53,13 @@ class Follow extends \Zotlabs\Web\Controller {
// If we can view their stream, pull in some posts
if(($result['abook']['abook_their_perms'] & PERMS_R_STREAM) || ($result['abook']['xchan_network'] === 'rss'))
- proc_run('php','include/onepoll.php',$result['abook']['abook_id']);
+ \Zotlabs\Daemon\Master::Summon(array('Onepoll',$result['abook']['abook_id']));
goaway(z_root() . '/connedit/' . $result['abook']['abook_id'] . '?f=&follow=1');
}
- function get() {
-
+ function get() {
if(! local_channel()) {
return login();
}
diff --git a/Zotlabs/Module/Fsuggest.php b/Zotlabs/Module/Fsuggest.php
deleted file mode 100644
index 143fd34e1..000000000
--- a/Zotlabs/Module/Fsuggest.php
+++ /dev/null
@@ -1,117 +0,0 @@
-<?php
-namespace Zotlabs\Module;
-
-
-
-class Fsuggest extends \Zotlabs\Web\Controller {
-
- function post() {
-
- if(! local_channel()) {
- return;
- }
-
- if(\App::$argc != 2)
- return;
-
- $contact_id = intval(\App::$argv[1]);
-
- $r = q("SELECT * FROM `contact` WHERE `id` = %d AND `uid` = %d LIMIT 1",
- intval($contact_id),
- intval(local_channel())
- );
- if(! count($r)) {
- notice( t('Contact not found.') . EOL);
- return;
- }
- $contact = $r[0];
-
- $new_contact = intval($_POST['suggest']);
-
- $hash = random_string();
-
- $note = escape_tags(trim($_POST['note']));
-
- if($new_contact) {
- $r = q("SELECT * FROM `contact` WHERE `id` = %d AND `uid` = %d LIMIT 1",
- intval($new_contact),
- intval(local_channel())
- );
- if(count($r)) {
-
- $x = q("INSERT INTO `fsuggest` ( `uid`,`cid`,`name`,`url`,`request`,`photo`,`note`,`created`)
- VALUES ( %d, %d, '%s','%s','%s','%s','%s','%s')",
- intval(local_channel()),
- intval($contact_id),
- dbesc($r[0]['name']),
- dbesc($r[0]['url']),
- dbesc($r[0]['request']),
- dbesc($r[0]['photo']),
- dbesc($hash),
- dbesc(datetime_convert())
- );
- $r = q("SELECT `id` FROM `fsuggest` WHERE `note` = '%s' AND `uid` = %d LIMIT 1",
- dbesc($hash),
- intval(local_channel())
- );
- if(count($r)) {
- $fsuggest_id = $r[0]['id'];
- q("UPDATE `fsuggest` SET `note` = '%s' WHERE `id` = %d AND `uid` = %d",
- dbesc($note),
- intval($fsuggest_id),
- intval(local_channel())
- );
- proc_run('php', 'include/notifier.php', 'suggest' , $fsuggest_id);
- }
-
- info( t('Friend suggestion sent.') . EOL);
- }
-
- }
-
-
- }
-
-
-
- function get() {
-
- require_once('include/acl_selectors.php');
-
- if(! local_channel()) {
- notice( t('Permission denied.') . EOL);
- return;
- }
-
- if(\App::$argc != 2)
- return;
-
- $contact_id = intval(\App::$argv[1]);
-
- $r = q("SELECT * FROM `contact` WHERE `id` = %d AND `uid` = %d LIMIT 1",
- intval($contact_id),
- intval(local_channel())
- );
- if(! count($r)) {
- notice( t('Contact not found.') . EOL);
- return;
- }
- $contact = $r[0];
-
- $o = '<h3>' . t('Suggest Friends') . '</h3>';
-
- $o .= '<div id="fsuggest-desc" >' . sprintf( t('Suggest a friend for %s'), $contact['name']) . '</div>';
-
- $o .= '<form id="fsuggest-form" action="fsuggest/' . $contact_id . '" method="post" >';
-
- // FIXME contact_selector deprecated, removed
- // $o .= contact_selector('suggest','suggest-select', false,
- // array('size' => 4, 'exclude' => $contact_id, 'networks' => 'DFRN_ONLY', 'single' => true));
-
-
- $o .= '<div id="fsuggest-submit-wrapper"><input id="fsuggest-submit" type="submit" name="submit" value="' . t('Submit') . '" /></div>';
- $o .= '</form>';
-
- return $o;
- }
-}
diff --git a/Zotlabs/Module/Getfile.php b/Zotlabs/Module/Getfile.php
index 6999e77e8..09d761887 100644
--- a/Zotlabs/Module/Getfile.php
+++ b/Zotlabs/Module/Getfile.php
@@ -21,7 +21,6 @@ namespace Zotlabs\Module;
-require_once('include/Contact.php');
require_once('include/attach.php');
diff --git a/Zotlabs/Module/Group.php b/Zotlabs/Module/Group.php
index 144797baf..254ee6ef2 100644
--- a/Zotlabs/Module/Group.php
+++ b/Zotlabs/Module/Group.php
@@ -47,8 +47,8 @@ class Group extends \Zotlabs\Web\Controller {
$groupname = notags(trim($_POST['groupname']));
$public = intval($_POST['public']);
- if((strlen($groupname)) && (($groupname != $group['name']) || ($public != $group['visible']))) {
- $r = q("UPDATE `groups` SET `name` = '%s', visible = %d WHERE `uid` = %d AND `id` = %d",
+ if((strlen($groupname)) && (($groupname != $group['gname']) || ($public != $group['visible']))) {
+ $r = q("UPDATE `groups` SET `gname` = '%s', visible = %d WHERE `uid` = %d AND `id` = %d",
dbesc($groupname),
intval($public),
intval(local_channel()),
@@ -106,7 +106,7 @@ class Group extends \Zotlabs\Web\Controller {
intval(local_channel())
);
if($r)
- $result = group_rmv(local_channel(),$r[0]['name']);
+ $result = group_rmv(local_channel(),$r[0]['gname']);
if($result)
info( t('Privacy group removed.') . EOL);
else
@@ -156,10 +156,10 @@ class Group extends \Zotlabs\Web\Controller {
if($change) {
if(in_array($change,$preselected)) {
- group_rmv_member(local_channel(),$group['name'],$change);
+ group_rmv_member(local_channel(),$group['gname'],$change);
}
else {
- group_add_member(local_channel(),$group['name'],$change);
+ group_add_member(local_channel(),$group['gname'],$change);
}
$members = group_get_members($group['id']);
@@ -181,7 +181,7 @@ class Group extends \Zotlabs\Web\Controller {
$context = $context + array(
'$title' => t('Privacy group editor'),
- '$gname' => array('groupname',t('Privacy group name: '),$group['name'], ''),
+ '$gname' => array('groupname',t('Privacy group name: '),$group['gname'], ''),
'$gid' => $group['id'],
'$drop' => $drop_txt,
'$public' => array('public',t('Members are visible to other channels'), $group['visible'], ''),
@@ -209,7 +209,7 @@ class Group extends \Zotlabs\Web\Controller {
$groupeditor['members'][] = micropro($member,true,'mpgroup', $textmode);
}
else
- group_rmv_member(local_channel(),$group['name'],$member['xchan_hash']);
+ group_rmv_member(local_channel(),$group['gname'],$member['xchan_hash']);
}
$r = q("SELECT abook.*, xchan.* FROM `abook` left join xchan on abook_xchan = xchan_hash WHERE `abook_channel` = %d AND abook_self = 0 and abook_blocked = 0 and abook_pending = 0 and xchan_deleted = 0 order by xchan_name asc",
diff --git a/Zotlabs/Module/Help.php b/Zotlabs/Module/Help.php
index 4842c56c6..cc46c550b 100644
--- a/Zotlabs/Module/Help.php
+++ b/Zotlabs/Module/Help.php
@@ -37,7 +37,7 @@ class Help extends \Zotlabs\Web\Controller {
$path = trim(substr($dirname,4),'/');
$o .= '<li><a href="help/' . (($path) ? $path . '/' : '') . $fname . '" >' . ucwords(str_replace('_',' ',notags($fname))) . '</a><br />' .
- str_replace('$Projectname',\Zotlabs\Project\System::get_platform_name(),substr($rr['text'],0,200)) . '...<br /><br /></li>';
+ str_replace('$Projectname',\Zotlabs\Lib\System::get_platform_name(),substr($rr['text'],0,200)) . '...<br /><br /></li>';
}
$o .= '</ul>';
diff --git a/Zotlabs/Module/Import.php b/Zotlabs/Module/Import.php
index dadbf8ff1..122e27e90 100644
--- a/Zotlabs/Module/Import.php
+++ b/Zotlabs/Module/Import.php
@@ -4,9 +4,9 @@ namespace Zotlabs\Module;
// Import a channel, either by direct file upload or via
// connection to original server.
-require_once('include/Contact.php');
+
require_once('include/zot.php');
-require_once('include/identity.php');
+require_once('include/channel.php');
require_once('include/import.php');
@@ -408,8 +408,12 @@ class Import extends \Zotlabs\Web\Controller {
$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'];
+ $group['uid'] = $channel['channel_id'];
dbesc_array($group);
$r = dbq("INSERT INTO groups (`"
. implode("`, `", array_keys($group))
@@ -496,11 +500,11 @@ class Import extends \Zotlabs\Web\Controller {
// send out refresh requests
// notify old server that it may no longer be primary.
- proc_run('php','include/notifier.php','location',$channel['channel_id']);
+ \Zotlabs\Daemon\Master::Summon(array('Notifier','location',$channel['channel_id']));
// This will indirectly perform a refresh_all *and* update the directory
- proc_run('php', 'include/directory.php', $channel['channel_id']);
+ \Zotlabs\Daemon\Master::Summon(array('Directory', $channel['channel_id']));
notice( t('Import completed.') . EOL);
diff --git a/Zotlabs/Module/Item.php b/Zotlabs/Module/Item.php
index 93570fdec..2601feb0a 100644
--- a/Zotlabs/Module/Item.php
+++ b/Zotlabs/Module/Item.php
@@ -17,10 +17,10 @@ namespace Zotlabs\Module;
*/
require_once('include/crypto.php');
-require_once('include/enotify.php');
require_once('include/items.php');
require_once('include/attach.php');
+use \Zotlabs\Lib as Zlib;
class Item extends \Zotlabs\Web\Controller {
@@ -56,7 +56,7 @@ class Item extends \Zotlabs\Web\Controller {
$remote_xchan = $remote_observer = false;
$profile_uid = ((x($_REQUEST,'profile_uid')) ? intval($_REQUEST['profile_uid']) : 0);
- require_once('include/identity.php');
+ require_once('include/channel.php');
$sys = get_sys_channel();
if($sys && $profile_uid && ($sys['channel_id'] == $profile_uid) && is_site_admin()) {
$uid = intval($sys['channel_id']);
@@ -581,7 +581,7 @@ class Item extends \Zotlabs\Web\Controller {
if($success['replaced']) {
$post_tags[] = array(
'uid' => $profile_uid,
- 'type' => $success['termtype'],
+ 'ttype' => $success['termtype'],
'otype' => TERM_OBJ_POST,
'term' => $success['term'],
'url' => $success['url']
@@ -666,7 +666,7 @@ class Item extends \Zotlabs\Web\Controller {
foreach($cats as $cat) {
$post_tags[] = array(
'uid' => $profile_uid,
- 'type' => TERM_CATEGORY,
+ 'ttype' => TERM_CATEGORY,
'otype' => TERM_OBJ_POST,
'term' => trim($cat),
'url' => $owner_xchan['xchan_url'] . '?f=&cat=' . urlencode(trim($cat))
@@ -676,7 +676,7 @@ class Item extends \Zotlabs\Web\Controller {
if($orig_post) {
// preserve original tags
- $t = q("select * from term where oid = %d and otype = %d and uid = %d and type in ( %d, %d, %d )",
+ $t = q("select * from term where oid = %d and otype = %d and uid = %d and ttype in ( %d, %d, %d )",
intval($orig_post['id']),
intval(TERM_OBJ_POST),
intval($profile_uid),
@@ -688,7 +688,7 @@ class Item extends \Zotlabs\Web\Controller {
foreach($t as $t1) {
$post_tags[] = array(
'uid' => $profile_uid,
- 'type' => $t1['type'],
+ 'ttype' => $t1['type'],
'otype' => TERM_OBJ_POST,
'term' => $t1['term'],
'url' => $t1['url'],
@@ -901,7 +901,7 @@ class Item extends \Zotlabs\Web\Controller {
}
}
if(! $nopush)
- proc_run('php', "include/notifier.php", 'edit_post', $post_id);
+ \Zotlabs\Daemon\Master::Summon(array('Notifier', 'edit_post', $post_id));
if((x($_REQUEST,'return')) && strlen($return_path)) {
logger('return: ' . $return_path);
@@ -925,7 +925,7 @@ class Item extends \Zotlabs\Web\Controller {
// otherwise it will happen during delivery
if(($datarray['owner_xchan'] != $datarray['author_xchan']) && (intval($parent_item['item_wall']))) {
- notification(array(
+ Zlib\Enotify::submit(array(
'type' => NOTIFY_COMMENT,
'from_xchan' => $datarray['author_xchan'],
'to_xchan' => $datarray['owner_xchan'],
@@ -943,7 +943,7 @@ class Item extends \Zotlabs\Web\Controller {
$parent = $post_id;
if(($datarray['owner_xchan'] != $datarray['author_xchan']) && ($datarray['item_type'] == ITEM_TYPE_POST)) {
- notification(array(
+ Zlib\Enotify::submit(array(
'type' => NOTIFY_WALL,
'from_xchan' => $datarray['author_xchan'],
'to_xchan' => $datarray['owner_xchan'],
@@ -1008,7 +1008,7 @@ class Item extends \Zotlabs\Web\Controller {
call_hooks('post_local_end', $datarray);
if(! $nopush)
- proc_run('php', 'include/notifier.php', $notify_type, $post_id);
+ \Zotlabs\Daemon\Master::Summon(array('Notifier', $notify_type, $post_id));
logger('post_complete');
diff --git a/Zotlabs/Module/Layouts.php b/Zotlabs/Module/Layouts.php
index 8a7207fc2..9b9fc22f3 100644
--- a/Zotlabs/Module/Layouts.php
+++ b/Zotlabs/Module/Layouts.php
@@ -1,7 +1,7 @@
<?php
namespace Zotlabs\Module;
-require_once('include/identity.php');
+require_once('include/channel.php');
require_once('include/conversation.php');
require_once('include/acl_selectors.php');
diff --git a/Zotlabs/Module/Like.php b/Zotlabs/Module/Like.php
index ac8791950..1ca37d646 100644
--- a/Zotlabs/Module/Like.php
+++ b/Zotlabs/Module/Like.php
@@ -346,7 +346,7 @@ class Like extends \Zotlabs\Web\Controller {
// drop_item was not done interactively, so we need to invoke the notifier
// in order to push the changes to connections
- proc_run('php','include/notifier.php','drop',$rr['id']);
+ \Zotlabs\Daemon\Master::Summon(array('Notifier','drop',$rr['id']));
}
@@ -483,7 +483,7 @@ class Like extends \Zotlabs\Web\Controller {
$arr['verb'] = $activity;
$arr['obj_type'] = $objtype;
- $arr['object'] = $object;
+ $arr['obj'] = $object;
if($target) {
$arr['tgt_type'] = $tgttype;
@@ -531,7 +531,7 @@ class Like extends \Zotlabs\Web\Controller {
}
- proc_run('php',"include/notifier.php","like","$post_id");
+ \Zotlabs\Daemon\Master::Summon(array('Notifier','like',$post_id));
if($interactive) {
notice( t('Action completed.') . EOL);
diff --git a/Zotlabs/Module/Linkinfo.php b/Zotlabs/Module/Linkinfo.php
index ef34bb465..e1a3a6abe 100644
--- a/Zotlabs/Module/Linkinfo.php
+++ b/Zotlabs/Module/Linkinfo.php
@@ -115,7 +115,7 @@ class Linkinfo extends \Zotlabs\Web\Controller {
// If this is a Red site, use zrl rather than url so they get zids sent to them by default
- if( x($siteinfo,'generator') && (strpos($siteinfo['generator'], \Zotlabs\Project\System::get_platform_name() . ' ') === 0))
+ if( x($siteinfo,'generator') && (strpos($siteinfo['generator'], \Zotlabs\Lib\System::get_platform_name() . ' ') === 0))
$template = str_replace('url','zrl',$template);
if($siteinfo["title"] == "") {
diff --git a/Zotlabs/Module/Lockview.php b/Zotlabs/Module/Lockview.php
index 0df0dd4da..4776e1c56 100644
--- a/Zotlabs/Module/Lockview.php
+++ b/Zotlabs/Module/Lockview.php
@@ -88,10 +88,10 @@ class Lockview extends \Zotlabs\Web\Controller {
stringify_array_elms($deny_users,true);
if(count($allowed_groups)) {
- $r = q("SELECT name FROM `groups` WHERE hash IN ( " . implode(', ', $allowed_groups) . " )");
+ $r = q("SELECT gname FROM `groups` WHERE hash IN ( " . implode(', ', $allowed_groups) . " )");
if($r)
foreach($r as $rr)
- $l[] = '<li><b>' . $rr['name'] . '</b></li>';
+ $l[] = '<li><b>' . $rr['gname'] . '</b></li>';
}
if(count($allowed_users)) {
$r = q("SELECT xchan_name FROM xchan WHERE xchan_hash IN ( " . implode(', ',$allowed_users) . " )");
@@ -100,10 +100,10 @@ class Lockview extends \Zotlabs\Web\Controller {
$l[] = '<li>' . $rr['xchan_name'] . '</li>';
}
if(count($deny_groups)) {
- $r = q("SELECT name FROM `groups` WHERE hash IN ( " . implode(', ', $deny_groups) . " )");
+ $r = q("SELECT gname FROM `groups` WHERE hash IN ( " . implode(', ', $deny_groups) . " )");
if($r)
foreach($r as $rr)
- $l[] = '<li><b><strike>' . $rr['name'] . '</strike></b></li>';
+ $l[] = '<li><b><strike>' . $rr['gname'] . '</strike></b></li>';
}
if(count($deny_users)) {
$r = q("SELECT xchan_name FROM xchan WHERE xchan_hash IN ( " . implode(', ', $deny_users) . " )");
diff --git a/Zotlabs/Module/Locs.php b/Zotlabs/Module/Locs.php
index 4b5d58df5..4b1e3ffe2 100644
--- a/Zotlabs/Module/Locs.php
+++ b/Zotlabs/Module/Locs.php
@@ -34,7 +34,7 @@ class Locs extends \Zotlabs\Web\Controller {
dbesc($channel['channel_hash'])
);
- proc_run('php','include/notifier.php','location',$channel['channel_id']);
+ \Zotlabs\Daemon\Master::Summon(array('Notifier','location',$channel['channel_id']));
return;
}
}
@@ -72,7 +72,7 @@ class Locs extends \Zotlabs\Web\Controller {
intval($hubloc_id),
dbesc($channel['channel_hash'])
);
- proc_run('php','include/notifier.php','location',$channel['channel_id']);
+ \Zotlabs\Daemon\Master::Summon(array('Notifier','location',$channel['channel_id']));
return;
}
}
@@ -91,7 +91,7 @@ class Locs extends \Zotlabs\Web\Controller {
$channel = \App::get_channel();
if($_REQUEST['sync']) {
- proc_run('php','include/notifier.php','location',$channel['channel_id']);
+ \Zotlabs\Daemon\Master::Summon(array('Notifier','location',$channel['channel_id']));
info( t('Syncing locations') . EOL);
goaway(z_root() . '/locs');
}
diff --git a/Zotlabs/Module/Magic.php b/Zotlabs/Module/Magic.php
index 63db4a317..6798f72a9 100644
--- a/Zotlabs/Module/Magic.php
+++ b/Zotlabs/Module/Magic.php
@@ -47,11 +47,9 @@ class Magic extends \Zotlabs\Web\Controller {
*
*/
- $ret = zot_finger((($addr) ? $addr : '[system]@' . $parsed['host']),null);
- if($ret['success']) {
- $j = json_decode($ret['body'],true);
- if($j)
- import_xchan($j);
+ $j = \Zotlabs\Zot\Finger::run((($addr) ? $addr : '[system]@' . $parsed['host']),null);
+ if($j['success']) {
+ import_xchan($j);
// Now try again
diff --git a/Zotlabs/Module/Mail.php b/Zotlabs/Module/Mail.php
index 35cb3b9bf..aae7585c4 100644
--- a/Zotlabs/Module/Mail.php
+++ b/Zotlabs/Module/Mail.php
@@ -5,7 +5,7 @@ require_once('include/acl_selectors.php');
require_once('include/message.php');
require_once('include/zot.php');
require_once("include/bbcode.php");
-require_once('include/Contact.php');
+
@@ -32,17 +32,16 @@ class Mail extends \Zotlabs\Web\Controller {
if(! $recipient) {
$channel = \App::get_channel();
- $ret = zot_finger($rstr,$channel);
+ $j = \Zotlabs\Zot\Finger::run($rstr,$channel);
- if(! $ret['success']) {
+ if(! $j['success']) {
notice( t('Unable to lookup recipient.') . EOL);
return;
}
- $j = json_decode($ret['body'],true);
logger('message_post: lookup: ' . $url . ' ' . print_r($j,true));
- if(! ($j['success'] && $j['guid'])) {
+ if(! $j['guid']) {
notice( t('Unable to communicate with requested channel.'));
return;
}
@@ -173,7 +172,7 @@ class Mail extends \Zotlabs\Web\Controller {
build_sync_packet(local_channel(),array('mail' => encode_mail($x[0],true)));
}
- proc_run('php','include/notifier.php','mail',intval(argv(3)));
+ \Zotlabs\Daemon\Master::Summon(array('Notifier','mail',intval(argv(3))));
if($r) {
info( t('Message recalled.') . EOL );
@@ -306,11 +305,6 @@ class Mail extends \Zotlabs\Web\Controller {
else
\App::$poi = $messages[0]['to'];
- // require_once('include/Contact.php');
-
- // \App::set_widget('mail_conversant',vcard_from_xchan(\App::$poi,$get_observer_hash,'mail'));
-
-
$tpl = get_markup_template('msg-header.tpl');
\App::$page['htmlhead'] .= replace_macros($tpl, array(
diff --git a/Zotlabs/Module/Manage.php b/Zotlabs/Module/Manage.php
index 5ae79dbb2..4ca044c4a 100644
--- a/Zotlabs/Module/Manage.php
+++ b/Zotlabs/Module/Manage.php
@@ -93,9 +93,9 @@ class Manage extends \Zotlabs\Web\Controller {
$channels[$x]['mail'] = intval($mails[0]['total']);
- $events = q("SELECT type, start, adjust FROM `event`
- WHERE `event`.`uid` = %d AND start < '%s' AND start > '%s' and `ignore` = 0
- ORDER BY `start` ASC ",
+ $events = q("SELECT etype, dtstart, adjust FROM `event`
+ WHERE `event`.`uid` = %d AND dtstart < '%s' AND dtstart > '%s' and `dismissed` = 0
+ ORDER BY `dtstart` ASC ",
intval($channels[$x]['channel_id']),
dbesc(datetime_convert('UTC', date_default_timezone_get(), 'now + 7 days')),
dbesc(datetime_convert('UTC', date_default_timezone_get(), 'now - 1 days'))
@@ -108,14 +108,14 @@ class Manage extends \Zotlabs\Web\Controller {
$str_now = datetime_convert('UTC', date_default_timezone_get(), 'now', 'Y-m-d');
foreach($events as $e) {
$bd = false;
- if($e['type'] === 'birthday') {
+ if($e['etype'] === 'birthday') {
$channels[$x]['birthdays'] ++;
$bd = true;
}
else {
$channels[$x]['events'] ++;
}
- if(datetime_convert('UTC', ((intval($e['adjust'])) ? date_default_timezone_get() : 'UTC'), $e['start'], 'Y-m-d') === $str_now) {
+ if(datetime_convert('UTC', ((intval($e['adjust'])) ? date_default_timezone_get() : 'UTC'), $e['dtstart'], 'Y-m-d') === $str_now) {
$channels[$x]['all_events_today'] ++;
if($bd)
$channels[$x]['birthdays_today'] ++;
diff --git a/Zotlabs/Module/Menu.php b/Zotlabs/Module/Menu.php
index 9ada63911..e98053f8c 100644
--- a/Zotlabs/Module/Menu.php
+++ b/Zotlabs/Module/Menu.php
@@ -2,7 +2,7 @@
namespace Zotlabs\Module;
require_once('include/menu.php');
-require_once('include/identity.php');
+require_once('include/channel.php');
class Menu extends \Zotlabs\Web\Controller {
diff --git a/Zotlabs/Module/Message.php b/Zotlabs/Module/Message.php
index 58a138899..ea2127a1d 100644
--- a/Zotlabs/Module/Message.php
+++ b/Zotlabs/Module/Message.php
@@ -5,8 +5,6 @@ require_once('include/acl_selectors.php');
require_once('include/message.php');
require_once('include/zot.php');
require_once("include/bbcode.php");
-require_once('include/Contact.php');
-
class Message extends \Zotlabs\Web\Controller {
diff --git a/Zotlabs/Module/Mood.php b/Zotlabs/Module/Mood.php
index b1007fd06..d1bd44526 100644
--- a/Zotlabs/Module/Mood.php
+++ b/Zotlabs/Module/Mood.php
@@ -97,7 +97,7 @@ class Mood extends \Zotlabs\Web\Controller {
$item_id = $post['item_id'];
if($item_id) {
- proc_run('php',"include/notifier.php","activity", $item_id);
+ \Zotlabs\Daemon\Master::Summon(array('Notifier','activity', $item_id));
}
call_hooks('post_local_end', $arr);
diff --git a/Zotlabs/Module/Network.php b/Zotlabs/Module/Network.php
index c88258a78..87ed326e2 100644
--- a/Zotlabs/Module/Network.php
+++ b/Zotlabs/Module/Network.php
@@ -223,7 +223,7 @@ class Network extends \Zotlabs\Web\Controller {
if($x) {
$title = replace_macros(get_markup_template("section_title.tpl"),array(
- '$title' => t('Privacy group: ') . $x['name']
+ '$title' => t('Privacy group: ') . $x['gname']
));
}
@@ -385,7 +385,7 @@ class Network extends \Zotlabs\Web\Controller {
$abook_uids = " and abook.abook_channel = " . local_channel() . " ";
if($firehose && (! get_config('system','disable_discover_tab'))) {
- require_once('include/identity.php');
+ require_once('include/channel.php');
$sys = get_sys_channel();
$uids = " and item.uid = " . intval($sys['channel_id']) . " ";
\App::$data['firehose'] = intval($sys['channel_id']);
diff --git a/Zotlabs/Module/New_channel.php b/Zotlabs/Module/New_channel.php
index 3dca1b0b4..30d7c83c6 100644
--- a/Zotlabs/Module/New_channel.php
+++ b/Zotlabs/Module/New_channel.php
@@ -1,7 +1,7 @@
<?php
namespace Zotlabs\Module;
-require_once('include/identity.php');
+require_once('include/channel.php');
require_once('include/permissions.php');
diff --git a/Zotlabs/Module/Notifications.php b/Zotlabs/Module/Notifications.php
index d51d2861c..9da28a360 100644
--- a/Zotlabs/Module/Notifications.php
+++ b/Zotlabs/Module/Notifications.php
@@ -80,18 +80,18 @@ class Notifications extends \Zotlabs\Web\Controller {
$not_tpl = get_markup_template('notify.tpl');
require_once('include/bbcode.php');
- $r = q("SELECT * from notify where uid = %d and seen = 0 order by date desc",
+ $r = q("SELECT * from notify where uid = %d and seen = 0 order by created desc",
intval(local_channel())
);
- if (count($r) > 0) {
+ if ($r > 0) {
$notifications_available =1;
foreach ($r as $it) {
$notif_content .= replace_macros($not_tpl,array(
'$item_link' => z_root().'/notify/view/'. $it['id'],
'$item_image' => $it['photo'],
'$item_text' => strip_tags(bbcode($it['msg'])),
- '$item_when' => relative_date($it['date'])
+ '$item_when' => relative_date($it['created'])
));
}
} else {
diff --git a/Zotlabs/Module/Notify.php b/Zotlabs/Module/Notify.php
index 227491145..f592f6f37 100644
--- a/Zotlabs/Module/Notify.php
+++ b/Zotlabs/Module/Notify.php
@@ -39,7 +39,7 @@ class Notify extends \Zotlabs\Web\Controller {
$not_tpl = get_markup_template('notify.tpl');
require_once('include/bbcode.php');
- $r = q("SELECT * from notify where uid = %d and seen = 0 order by date desc",
+ $r = q("SELECT * from notify where uid = %d and seen = 0 order by created desc",
intval(local_channel())
);
@@ -49,7 +49,7 @@ class Notify extends \Zotlabs\Web\Controller {
'$item_link' => z_root().'/notify/view/'. $it['id'],
'$item_image' => $it['photo'],
'$item_text' => strip_tags(bbcode($it['msg'])),
- '$item_when' => relative_date($it['date'])
+ '$item_when' => relative_date($it['created'])
));
}
}
diff --git a/Zotlabs/Module/Oep.php b/Zotlabs/Module/Oep.php
index 638ea7e2d..dc0547a42 100644
--- a/Zotlabs/Module/Oep.php
+++ b/Zotlabs/Module/Oep.php
@@ -181,8 +181,8 @@ class Oep extends \Zotlabs\Web\Controller {
function oep_profile_reply($args) {
- require_once('include/identity.php');
- require_once('include/Contact.php');
+ require_once('include/channel.php');
+
$url = $args['url'];
if(preg_match('#//(.*?)/(.*?)/(.*?)(/|\?|&|$)#',$url,$matches)) {
@@ -249,7 +249,7 @@ class Oep extends \Zotlabs\Web\Controller {
$sql_extra = permissions_sql($c[0]['channel_id']);
- $p = q("select resource_id from photo where album = '%s' and uid = %d and scale = 0 $sql_extra order by created desc limit 1",
+ $p = q("select resource_id from photo where album = '%s' and uid = %d and imgscale = 0 $sql_extra order by created desc limit 1",
dbesc($res),
intval($c[0]['channel_id'])
);
@@ -258,7 +258,7 @@ class Oep extends \Zotlabs\Web\Controller {
$res = $p[0]['resource_id'];
- $r = q("select height, width, scale, resource_id from photo where uid = %d and resource_id = '%s' $sql_extra order by scale asc",
+ $r = q("select height, width, imgscale, resource_id from photo where uid = %d and resource_id = '%s' $sql_extra order by imgscale asc",
intval($c[0]['channel_id']),
dbesc($res)
);
@@ -276,7 +276,7 @@ class Oep extends \Zotlabs\Web\Controller {
if($foundres) {
$ret['type'] = 'link';
- $ret['thumbnail_url'] = z_root() . '/photo/' . '/' . $rr['resource_id'] . '-' . $rr['scale'];
+ $ret['thumbnail_url'] = z_root() . '/photo/' . '/' . $rr['resource_id'] . '-' . $rr['imgscale'];
$ret['thumbnail_width'] = $rr['width'];
$ret['thumbnail_height'] = $rr['height'];
}
@@ -310,7 +310,7 @@ class Oep extends \Zotlabs\Web\Controller {
$sql_extra = permissions_sql($c[0]['channel_id']);
- $p = q("select resource_id from photo where uid = %d and scale = 0 $sql_extra order by created desc limit 1",
+ $p = q("select resource_id from photo where uid = %d and imgscale = 0 $sql_extra order by created desc limit 1",
intval($c[0]['channel_id'])
);
if(! $p)
@@ -318,7 +318,7 @@ class Oep extends \Zotlabs\Web\Controller {
$res = $p[0]['resource_id'];
- $r = q("select height, width, scale, resource_id from photo where uid = %d and resource_id = '%s' $sql_extra order by scale asc",
+ $r = q("select height, width, imgscale, resource_id from photo where uid = %d and resource_id = '%s' $sql_extra order by imgscale asc",
intval($c[0]['channel_id']),
dbesc($res)
);
@@ -336,7 +336,7 @@ class Oep extends \Zotlabs\Web\Controller {
if($foundres) {
$ret['type'] = 'link';
- $ret['thumbnail_url'] = z_root() . '/photo/' . '/' . $rr['resource_id'] . '-' . $rr['scale'];
+ $ret['thumbnail_url'] = z_root() . '/photo/' . '/' . $rr['resource_id'] . '-' . $rr['imgscale'];
$ret['thumbnail_width'] = $rr['width'];
$ret['thumbnail_height'] = $rr['height'];
}
@@ -372,7 +372,7 @@ class Oep extends \Zotlabs\Web\Controller {
$sql_extra = permissions_sql($c[0]['channel_id']);
- $r = q("select height, width, scale, resource_id from photo where uid = %d and resource_id = '%s' $sql_extra order by scale asc",
+ $r = q("select height, width, imgscale, resource_id from photo where uid = %d and resource_id = '%s' $sql_extra order by imgscale asc",
intval($c[0]['channel_id']),
dbesc($res)
);
@@ -390,7 +390,7 @@ class Oep extends \Zotlabs\Web\Controller {
if($foundres) {
$ret['type'] = 'link';
- $ret['thumbnail_url'] = z_root() . '/photo/' . '/' . $rr['resource_id'] . '-' . $rr['scale'];
+ $ret['thumbnail_url'] = z_root() . '/photo/' . '/' . $rr['resource_id'] . '-' . $rr['imgscale'];
$ret['thumbnail_width'] = $rr['width'];
$ret['thumbnail_height'] = $rr['height'];
}
diff --git a/Zotlabs/Module/Photo.php b/Zotlabs/Module/Photo.php
index 408688886..92c9ac3c0 100644
--- a/Zotlabs/Module/Photo.php
+++ b/Zotlabs/Module/Photo.php
@@ -57,14 +57,14 @@ class Photo extends \Zotlabs\Web\Controller {
$uid = $person;
- $r = q("SELECT * FROM photo WHERE scale = %d AND uid = %d AND photo_usage = %d LIMIT 1",
+ $r = q("SELECT * FROM photo WHERE imgscale = %d AND uid = %d AND photo_usage = %d LIMIT 1",
intval($resolution),
intval($uid),
intval(PHOTO_PROFILE)
);
if(count($r)) {
- $data = dbunescbin($r[0]['data']);
- $mimetype = $r[0]['type'];
+ $data = dbunescbin($r[0]['content']);
+ $mimetype = $r[0]['mimetype'];
}
if(intval($r[0]['os_storage']))
$data = file_get_contents($data);
@@ -113,7 +113,7 @@ class Photo extends \Zotlabs\Web\Controller {
// If using resolution 1, make sure it exists before proceeding:
if ($resolution == 1)
{
- $r = q("SELECT uid FROM photo WHERE resource_id = '%s' AND scale = %d LIMIT 1",
+ $r = q("SELECT uid FROM photo WHERE resource_id = '%s' AND imgscale = %d LIMIT 1",
dbesc($photo),
intval($resolution)
);
@@ -121,7 +121,7 @@ class Photo extends \Zotlabs\Web\Controller {
$resolution = 2;
}
- $r = q("SELECT uid FROM photo WHERE resource_id = '%s' AND scale = %d LIMIT 1",
+ $r = q("SELECT uid FROM photo WHERE resource_id = '%s' AND imgscale = %d LIMIT 1",
dbesc($photo),
intval($resolution)
);
@@ -133,14 +133,14 @@ class Photo extends \Zotlabs\Web\Controller {
// Now we'll see if we can access the photo
- $r = q("SELECT * FROM photo WHERE resource_id = '%s' AND scale = %d $sql_extra LIMIT 1",
+ $r = q("SELECT * FROM photo WHERE resource_id = '%s' AND imgscale = %d $sql_extra LIMIT 1",
dbesc($photo),
intval($resolution)
);
if($r && $allowed) {
- $data = dbunescbin($r[0]['data']);
- $mimetype = $r[0]['type'];
+ $data = dbunescbin($r[0]['content']);
+ $mimetype = $r[0]['mimetype'];
if(intval($r[0]['os_storage']))
$data = file_get_contents($data);
}
@@ -154,7 +154,7 @@ class Photo extends \Zotlabs\Web\Controller {
// they won't have the photo link, so there's a reasonable chance that the person
// might be able to obtain permission to view it.
- $r = q("SELECT * FROM `photo` WHERE `resource_id` = '%s' AND `scale` = %d LIMIT 1",
+ $r = q("SELECT * FROM `photo` WHERE `resource_id` = '%s' AND `imgscale` = %d LIMIT 1",
dbesc($photo),
intval($resolution)
);
diff --git a/Zotlabs/Module/Photos.php b/Zotlabs/Module/Photos.php
index 1659350a5..1bdc23897 100644
--- a/Zotlabs/Module/Photos.php
+++ b/Zotlabs/Module/Photos.php
@@ -1,12 +1,12 @@
<?php
namespace Zotlabs\Module;
+
require_once('include/photo/photo_driver.php');
require_once('include/photos.php');
require_once('include/items.php');
require_once('include/acl_selectors.php');
require_once('include/bbcode.php');
require_once('include/security.php');
-require_once('include/Contact.php');
require_once('include/attach.php');
require_once('include/text.php');
require_once('include/PermissionDescription.php');
@@ -18,7 +18,7 @@ class Photos extends \Zotlabs\Web\Controller {
function init() {
- if((get_config('system','block_public')) && (! local_channel()) && (! remote_channel())) {
+ if(observer_prohibited()) {
return;
}
@@ -255,13 +255,13 @@ class Photos extends \Zotlabs\Web\Controller {
( (intval($_POST['rotate']) == 1) || (intval($_POST['rotate']) == 2) )) {
logger('rotate');
- $r = q("select * from photo where `resource_id` = '%s' and uid = %d and scale = 0 limit 1",
+ $r = q("select * from photo where `resource_id` = '%s' and uid = %d and imgscale = 0 limit 1",
dbesc($resource_id),
intval($page_owner_uid)
);
if(count($r)) {
- $d = (($r[0]['os_storage']) ? @file_get_contents($r[0]['data']) : dbunescbin($r[0]['data']));
- $ph = photo_factory($d, $r[0]['type']);
+ $d = (($r[0]['os_storage']) ? @file_get_contents($r[0]['content']) : dbunescbin($r[0]['content']));
+ $ph = photo_factory($d, $r[0]['mimetype']);
if($ph->is_valid()) {
$rotate_deg = ( (intval($_POST['rotate']) == 1) ? 270 : 90 );
$ph->rotate($rotate_deg);
@@ -270,9 +270,9 @@ class Photos extends \Zotlabs\Web\Controller {
$height = $ph->getHeight();
if(intval($r[0]['os_storage'])) {
- @file_put_contents($r[0]['data'],$ph->imageString());
- $data = $r[0]['data'];
- $fsize = @filesize($r[0]['data']);
+ @file_put_contents($r[0]['content'],$ph->imageString());
+ $data = $r[0]['content'];
+ $fsize = @filesize($r[0]['content']);
q("update attach set filesize = %d where hash = '%s' and uid = %d limit 1",
intval($fsize),
dbesc($resource_id),
@@ -284,7 +284,7 @@ class Photos extends \Zotlabs\Web\Controller {
$fsize = strlen($data);
}
- $x = q("update photo set data = '%s', `size` = %d, height = %d, width = %d where `resource_id` = '%s' and uid = %d and scale = 0",
+ $x = q("update photo set content = '%s', filesize = %d, height = %d, width = %d where `resource_id` = '%s' and uid = %d and imgscale = 0",
dbescbin($data),
intval($fsize),
intval($height),
@@ -299,7 +299,7 @@ class Photos extends \Zotlabs\Web\Controller {
$width = $ph->getWidth();
$height = $ph->getHeight();
- $x = q("update photo set data = '%s', height = %d, width = %d where `resource_id` = '%s' and uid = %d and scale = 1",
+ $x = q("update photo set content = '%s', height = %d, width = %d where `resource_id` = '%s' and uid = %d and imgscale = 1",
dbescbin($ph->imageString()),
intval($height),
intval($width),
@@ -314,7 +314,7 @@ class Photos extends \Zotlabs\Web\Controller {
$width = $ph->getWidth();
$height = $ph->getHeight();
- $x = q("update photo set data = '%s', height = %d, width = %d where `resource_id` = '%s' and uid = %d and scale = 2",
+ $x = q("update photo set content = '%s', height = %d, width = %d where `resource_id` = '%s' and uid = %d and imgscale = 2",
dbescbin($ph->imageString()),
intval($height),
intval($width),
@@ -329,7 +329,7 @@ class Photos extends \Zotlabs\Web\Controller {
$width = $ph->getWidth();
$height = $ph->getHeight();
- $x = q("update photo set data = '%s', height = %d, width = %d where `resource_id` = '%s' and uid = %d and scale = 3",
+ $x = q("update photo set content = '%s', height = %d, width = %d where `resource_id` = '%s' and uid = %d and imgscale = 3",
dbescbin($ph->imageString()),
intval($height),
intval($width),
@@ -340,12 +340,12 @@ class Photos extends \Zotlabs\Web\Controller {
}
}
- $p = q("SELECT type, is_nsfw, description, resource_id, scale, allow_cid, allow_gid, deny_cid, deny_gid FROM photo WHERE resource_id = '%s' AND uid = %d ORDER BY scale DESC",
+ $p = q("SELECT mimetype, is_nsfw, description, resource_id, imgscale, allow_cid, allow_gid, deny_cid, deny_gid FROM photo WHERE resource_id = '%s' AND uid = %d ORDER BY imgscale DESC",
dbesc($resource_id),
intval($page_owner_uid)
);
if($p) {
- $ext = $phototypes[$p[0]['type']];
+ $ext = $phototypes[$p[0]['mimetype']];
$r = q("UPDATE `photo` SET `description` = '%s', `allow_cid` = '%s', `allow_gid` = '%s', `deny_cid` = '%s', `deny_gid` = '%s' WHERE `resource_id` = '%s' AND `uid` = %d",
dbesc($desc),
@@ -440,7 +440,7 @@ class Photos extends \Zotlabs\Web\Controller {
if($success['replaced']) {
$post_tags[] = array(
'uid' => $profile_uid,
- 'type' => $success['termtype'],
+ 'ttype' => $success['termtype'],
'otype' => TERM_OBJ_POST,
'term' => $success['term'],
'url' => $success['url']
@@ -510,7 +510,7 @@ class Photos extends \Zotlabs\Web\Controller {
- function get() {
+ function get() {
// URLs:
// photos/name
@@ -518,7 +518,7 @@ class Photos extends \Zotlabs\Web\Controller {
// photos/name/image/xxxxx
- if((get_config('system','block_public')) && (! local_channel()) && (! remote_channel())) {
+ if(observer_prohibited()) {
notice( t('Public access denied.') . EOL);
return;
}
@@ -611,7 +611,7 @@ class Photos extends \Zotlabs\Web\Controller {
/* Show space usage */
- $r = q("select sum(size) as total from photo where aid = %d and scale = 0 ",
+ $r = q("select sum(filesize) as total from photo where aid = %d and imgscale = 0 ",
intval(\App::$data['channel']['channel_account_id'])
);
@@ -704,8 +704,8 @@ class Photos extends \Zotlabs\Web\Controller {
\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(`scale`) AS `scale` FROM `photo` WHERE `uid` = %d AND `album` = '%s'
- AND `scale` <= 4 and photo_usage IN ( %d, %d ) and is_nsfw = %d $sql_extra GROUP BY `resource_id`",
+ $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`",
intval($owner_uid),
dbesc($album),
intval(PHOTO_NORMAL),
@@ -725,9 +725,9 @@ class Photos extends \Zotlabs\Web\Controller {
$order = 'DESC';
- $r = q("SELECT p.resource_id, p.id, p.filename, p.type, p.scale, p.description, p.created FROM photo p INNER JOIN
- (SELECT resource_id, max(scale) scale FROM photo WHERE uid = %d AND album = '%s' AND scale <= 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.scale = ph.scale)
+ $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)
ORDER BY created $order LIMIT %d OFFSET %d",
intval($owner_uid),
dbesc($album),
@@ -777,7 +777,7 @@ class Photos extends \Zotlabs\Web\Controller {
else
$twist = 'rotright';
- $ext = $phototypes[$rr['type']];
+ $ext = $phototypes[$rr['mimetype']];
$imgalt_e = $rr['filename'];
$desc_e = $rr['description'];
@@ -790,7 +790,7 @@ class Photos extends \Zotlabs\Web\Controller {
'twist' => ' ' . $twist . rand(2,4),
'link' => $imagelink,
'title' => t('View Photo'),
- 'src' => z_root() . '/photo/' . $rr['resource_id'] . '-' . $rr['scale'] . '.' .$ext,
+ 'src' => z_root() . '/photo/' . $rr['resource_id'] . '-' . $rr['imgscale'] . '.' .$ext,
'alt' => $imgalt_e,
'desc'=> $desc_e,
'ext' => $ext,
@@ -852,8 +852,8 @@ class Photos extends \Zotlabs\Web\Controller {
// fetch image, item containing image, then comments
- $ph = q("SELECT id,aid,uid,xchan,resource_id,created,edited,title,`description`,album,filename,`type`,height,width,`size`,scale,photo_usage,is_nsfw,allow_cid,allow_gid,deny_cid,deny_gid FROM `photo` WHERE `uid` = %d AND `resource_id` = '%s'
- $sql_extra ORDER BY `scale` ASC ",
+ $ph = q("SELECT id,aid,uid,xchan,resource_id,created,edited,title,`description`,album,filename,mimetype,height,width,filesize,imgscale,photo_usage,is_nsfw,allow_cid,allow_gid,deny_cid,deny_gid FROM `photo` WHERE `uid` = %d AND `resource_id` = '%s'
+ $sql_extra ORDER BY `imgscale` ASC ",
intval($owner_uid),
dbesc($datum)
);
@@ -884,7 +884,7 @@ class Photos extends \Zotlabs\Web\Controller {
$order = 'DESC';
- $prvnxt = q("SELECT `resource_id` FROM `photo` WHERE `album` = '%s' AND `uid` = %d AND `scale` = 0
+ $prvnxt = q("SELECT `resource_id` FROM `photo` WHERE `album` = '%s' AND `uid` = %d AND `imgscale` = 0
$sql_extra ORDER BY `created` $order ",
dbesc($ph[0]['album']),
intval($owner_uid)
@@ -911,7 +911,7 @@ class Photos extends \Zotlabs\Web\Controller {
if(count($ph) == 1)
$hires = $lores = $ph[0];
if(count($ph) > 1) {
- if($ph[1]['scale'] == 2) {
+ if($ph[1]['imgscale'] == 2) {
// original is 640 or less, we can display it directly
$hires = $lores = $ph[0];
}
@@ -949,9 +949,9 @@ class Photos extends \Zotlabs\Web\Controller {
$prevlink = array($prevlink, t('Previous'));
$photo = array(
- 'href' => z_root() . '/photo/' . $hires['resource_id'] . '-' . $hires['scale'] . '.' . $phototypes[$hires['type']],
+ 'href' => z_root() . '/photo/' . $hires['resource_id'] . '-' . $hires['imgscale'] . '.' . $phototypes[$hires['mimetype']],
'title'=> t('View Full Size'),
- 'src' => z_root() . '/photo/' . $lores['resource_id'] . '-' . $lores['scale'] . '.' . $phototypes[$lores['type']] . '?f=&_u=' . datetime_convert('','','','ymdhis')
+ 'src' => z_root() . '/photo/' . $lores['resource_id'] . '-' . $lores['imgscale'] . '.' . $phototypes[$lores['mimetype']] . '?f=&_u=' . datetime_convert('','','','ymdhis')
);
if($nextlink)
@@ -1277,28 +1277,25 @@ class Photos extends \Zotlabs\Web\Controller {
\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(`scale`) AS `scale` FROM `photo` WHERE `uid` = %d AND `album` != '%s' AND `album` != '%s'
+ $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']),
- dbesc('Contact Photos'),
- dbesc( t('Contact Photos')),
intval(PHOTO_NORMAL),
intval(PHOTO_PROFILE),
intval($unsafe)
);
- if(count($r)) {
+ if($r) {
\App::set_pager_total(count($r));
\App::set_pager_itemspage(60);
}
- $r = q("SELECT p.resource_id, p.id, p.filename, p.type, p.album, p.scale, p.created FROM photo p INNER JOIN
- (SELECT resource_id, max(scale) scale FROM photo
- WHERE uid=%d AND album != '%s' AND album != '%s'
- 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.scale = ph.scale) ORDER by p.created DESC LIMIT %d OFFSET %d",
+ $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
+ WHERE uid = %d 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)
+ ORDER by p.created DESC LIMIT %d OFFSET %d",
intval(\App::$data['channel']['channel_id']),
- dbesc('Contact Photos'),
- dbesc( t('Contact Photos')),
intval(PHOTO_NORMAL),
intval(PHOTO_PROFILE),
intval($unsafe),
@@ -1309,14 +1306,14 @@ class Photos extends \Zotlabs\Web\Controller {
$photos = array();
- if(count($r)) {
+ if($r) {
$twist = 'rotright';
foreach($r as $rr) {
if($twist == 'rotright')
$twist = 'rotleft';
else
$twist = 'rotright';
- $ext = $phototypes[$rr['type']];
+ $ext = $phototypes[$rr['mimetype']];
if(\App::get_template_engine() === 'internal') {
$alt_e = template_escape($rr['filename']);
@@ -1332,7 +1329,7 @@ class Photos extends \Zotlabs\Web\Controller {
'twist' => ' ' . $twist . rand(2,4),
'link' => z_root() . '/photos/' . \App::$data['channel']['channel_address'] . '/image/' . $rr['resource_id'],
'title' => t('View Photo'),
- 'src' => z_root() . '/photo/' . $rr['resource_id'] . '-' . ((($rr['scale']) == 6) ? 4 : $rr['scale']) . '.' . $ext,
+ 'src' => z_root() . '/photo/' . $rr['resource_id'] . '-' . ((($rr['imgscale']) == 6) ? 4 : $rr['imgscale']) . '.' . $ext,
'alt' => $alt_e,
'album' => array(
'link' => z_root() . '/photos/' . \App::$data['channel']['channel_address'] . '/album/' . bin2hex($rr['album']),
diff --git a/Zotlabs/Module/Ping.php b/Zotlabs/Module/Ping.php
index bea4a08b7..5cbf45daa 100644
--- a/Zotlabs/Module/Ping.php
+++ b/Zotlabs/Module/Ping.php
@@ -1,12 +1,13 @@
<?php
namespace Zotlabs\Module;
+
/**
* @file mod/ping.php
*
*/
require_once('include/bbcode.php');
-require_once('include/notify.php');
+
/**
* @brief do several updates when pinged.
@@ -172,7 +173,7 @@ class Ping extends \Zotlabs\Web\Controller {
);
break;
case 'all_events':
- $r = q("update event set `ignore` = 1 where `ignore` = 0 and uid = %d AND start < '%s' AND start > '%s' ",
+ $r = q("update event set `dimissed` = 1 where `dismissed` = 0 and uid = %d AND dtstart < '%s' AND dtstart > '%s' ",
intval(local_channel()),
dbesc(datetime_convert('UTC', date_default_timezone_get(), 'now + ' . intval($evdays) . ' days')),
dbesc(datetime_convert('UTC', date_default_timezone_get(), 'now - 1 days'))
@@ -208,17 +209,17 @@ class Ping extends \Zotlabs\Web\Controller {
);
if($t && intval($t[0]['total']) > 49) {
$z = q("select * from notify where uid = %d
- and seen = 0 order by date desc limit 50",
+ and seen = 0 order by created desc limit 50",
intval(local_channel())
);
}
else {
$z1 = q("select * from notify where uid = %d
- and seen = 0 order by date desc limit 50",
+ and seen = 0 order by created desc limit 50",
intval(local_channel())
);
$z2 = q("select * from notify where uid = %d
- and seen = 1 order by date desc limit %d",
+ and seen = 1 order by created desc limit %d",
intval(local_channel()),
intval(50 - intval($t[0]['total']))
);
@@ -229,10 +230,10 @@ class Ping extends \Zotlabs\Web\Controller {
foreach($z as $zz) {
$notifs[] = array(
'notify_link' => z_root() . '/notify/view/' . $zz['id'],
- 'name' => $zz['name'],
+ 'name' => $zz['xname'],
'url' => $zz['url'],
'photo' => $zz['photo'],
- 'when' => relative_date($zz['date']),
+ 'when' => relative_date($zz['created']),
'hclass' => (($zz['seen']) ? 'notify-seen' : 'notify-unseen'),
'message' => strip_tags(bbcode($zz['msg']))
);
@@ -285,7 +286,7 @@ class Ping extends \Zotlabs\Web\Controller {
foreach($r as $item) {
if((argv(1) === 'home') && (! intval($item['item_wall'])))
continue;
- $result[] = format_notification($item);
+ $result[] = \Zotlabs\Lib\Enotify::format($item);
}
}
// logger('ping (network||home): ' . print_r($result, true), LOGGER_DATA);
@@ -324,9 +325,9 @@ class Ping extends \Zotlabs\Web\Controller {
$result = array();
$r = q("SELECT * FROM event left join xchan on event_xchan = xchan_hash
- WHERE `event`.`uid` = %d AND start < '%s' AND start > '%s' and `ignore` = 0
- and type in ( 'event', 'birthday' )
- ORDER BY `start` DESC LIMIT 1000",
+ WHERE `event`.`uid` = %d AND dtstart < '%s' AND dtstart > '%s' and `dismissed` = 0
+ and etype in ( 'event', 'birthday' )
+ ORDER BY `dtstart` DESC LIMIT 1000",
intval(local_channel()),
dbesc(datetime_convert('UTC', date_default_timezone_get(), 'now + ' . intval($evdays) . ' days')),
dbesc(datetime_convert('UTC', date_default_timezone_get(), 'now - 1 days'))
@@ -335,14 +336,14 @@ class Ping extends \Zotlabs\Web\Controller {
if($r) {
foreach($r as $rr) {
if($rr['adjust'])
- $md = datetime_convert('UTC', date_default_timezone_get(), $rr['start'], 'Y/m');
+ $md = datetime_convert('UTC', date_default_timezone_get(), $rr['dtstart'], 'Y/m');
else
- $md = datetime_convert('UTC', 'UTC', $rr['start'], 'Y/m');
+ $md = datetime_convert('UTC', 'UTC', $rr['dtstart'], 'Y/m');
- $strt = datetime_convert('UTC', (($rr['adjust']) ? date_default_timezone_get() : 'UTC'), $rr['start']);
+ $strt = datetime_convert('UTC', (($rr['adjust']) ? date_default_timezone_get() : 'UTC'), $rr['dtstart']);
$today = ((substr($strt, 0, 10) === datetime_convert('UTC', date_default_timezone_get(), 'now', 'Y-m-d')) ? true : false);
- $when = day_translate(datetime_convert('UTC', (($rr['adjust']) ? date_default_timezone_get() : 'UTC'), $rr['start'], $bd_format)) . (($today) ? ' ' . t('[today]') : '');
+ $when = day_translate(datetime_convert('UTC', (($rr['adjust']) ? date_default_timezone_get() : 'UTC'), $rr['dtstart'], $bd_format)) . (($today) ? ' ' . t('[today]') : '');
$result[] = array(
'notify_link' => z_root() . '/events', // FIXME this takes you to an edit page and it may not be yours, we really want to just view the single event --> '/events/event/' . $rr['event_hash'],
@@ -442,10 +443,10 @@ class Ping extends \Zotlabs\Web\Controller {
$t5 = dba_timer();
if($vnotify & (VNOTIFY_EVENT|VNOTIFY_EVENTTODAY|VNOTIFY_BIRTHDAY)) {
- $events = q("SELECT type, start, adjust FROM `event`
- WHERE `event`.`uid` = %d AND start < '%s' AND start > '%s' and `ignore` = 0
- and type in ( 'event', 'birthday' )
- ORDER BY `start` ASC ",
+ $events = q("SELECT etype, dtstart, adjust FROM `event`
+ WHERE `event`.`uid` = %d AND dtstart < '%s' AND dtstart > '%s' and `dismissed` = 0
+ and etype in ( 'event', 'birthday' )
+ ORDER BY `dtstart` ASC ",
intval(local_channel()),
dbesc(datetime_convert('UTC', date_default_timezone_get(), 'now + ' . intval($evdays) . ' days')),
dbesc(datetime_convert('UTC', date_default_timezone_get(), 'now - 1 days'))
@@ -458,14 +459,14 @@ class Ping extends \Zotlabs\Web\Controller {
$str_now = datetime_convert('UTC', date_default_timezone_get(), 'now', 'Y-m-d');
foreach($events as $x) {
$bd = false;
- if($x['type'] === 'birthday') {
+ if($x['etype'] === 'birthday') {
$result['birthdays'] ++;
$bd = true;
}
else {
$result['events'] ++;
}
- if(datetime_convert('UTC', ((intval($x['adjust'])) ? date_default_timezone_get() : 'UTC'), $x['start'], 'Y-m-d') === $str_now) {
+ if(datetime_convert('UTC', ((intval($x['adjust'])) ? date_default_timezone_get() : 'UTC'), $x['dtstart'], 'Y-m-d') === $str_now) {
$result['all_events_today'] ++;
if($bd)
$result['birthdays_today'] ++;
diff --git a/Zotlabs/Module/Poke.php b/Zotlabs/Module/Poke.php
index 123ecbc7b..cf8d83023 100644
--- a/Zotlabs/Module/Poke.php
+++ b/Zotlabs/Module/Poke.php
@@ -115,7 +115,7 @@ class Poke extends \Zotlabs\Web\Controller {
),
);
- $arr['object'] = json_encode($obj);
+ $arr['obj'] = json_encode($obj);
$arr['item_origin'] = 1;
$arr['item_wall'] = 1;
diff --git a/Zotlabs/Module/Prate.php b/Zotlabs/Module/Prate.php
index 65bbcca9a..2a8539ed0 100644
--- a/Zotlabs/Module/Prate.php
+++ b/Zotlabs/Module/Prate.php
@@ -85,7 +85,7 @@ class Prate extends \Zotlabs\Web\Controller {
$record = $z[0]['xlink_id'];
}
if($record) {
- proc_run('php','include/ratenotif.php','rating',$record);
+ \Zotlabs\Daemon\Master::Summon(array('Ratenotif','rating',$record));
}
json_return_and_die(array('result' => true));;
diff --git a/Zotlabs/Module/Probe.php b/Zotlabs/Module/Probe.php
index 79abe9819..dda792131 100644
--- a/Zotlabs/Module/Probe.php
+++ b/Zotlabs/Module/Probe.php
@@ -20,17 +20,17 @@ class Probe extends \Zotlabs\Web\Controller {
$channel = \App::get_channel();
$addr = trim($_GET['addr']);
$do_import = ((intval($_GET['import']) && is_site_admin()) ? true : false);
- $res = zot_finger($addr,$channel,false);
+
+ $j = \Zotlabs\Zot\Finger::run($addr,$channel,false);
+
+ // $res = zot_finger($addr,$channel,false);
+
$o .= '<pre>';
- if($res['success'])
- $j = json_decode($res['body'],true);
- else {
+ if(! $j['success']) {
$o .= sprintf( t('Fetching URL returns error: %1$s'),$res['error'] . "\r\n\r\n");
$o .= "<strong>https connection failed. Trying again with auto failover to http.</strong>\r\n\r\n";
- $res = zot_finger($addr,$channel,true);
- if($res['success'])
- $j = json_decode($res['body'],true);
- else
+ $j = \Zotlabs\Zot\Finger::run($addr,$channel,true);
+ if(! $j['success'])
$o .= sprintf( t('Fetching URL returns error: %1$s'),$res['error'] . "\r\n\r\n");
}
diff --git a/Zotlabs/Module/Profile.php b/Zotlabs/Module/Profile.php
index 04a64fe76..8bf358bc8 100644
--- a/Zotlabs/Module/Profile.php
+++ b/Zotlabs/Module/Profile.php
@@ -55,8 +55,8 @@ class Profile extends \Zotlabs\Web\Controller {
function get() {
- if(get_config('system','block_public') && (! get_account_id()) && (! remote_channel())) {
- return login();
+ if(observer_prohibited(true)) {
+ return login();
}
$groups = array();
diff --git a/Zotlabs/Module/Profile_photo.php b/Zotlabs/Module/Profile_photo.php
index 8f879503c..6129a7492 100644
--- a/Zotlabs/Module/Profile_photo.php
+++ b/Zotlabs/Module/Profile_photo.php
@@ -9,7 +9,7 @@ namespace Zotlabs\Module;
require_once('include/photo/photo_driver.php');
require_once('include/photos.php');
-require_once('include/identity.php');
+require_once('include/channel.php');
/* @brief Function for sync'ing permissions of profile-photos and their profile
*
@@ -93,7 +93,7 @@ class Profile_photo extends \Zotlabs\Web\Controller {
$srcW = $_POST['xfinal'] - $srcX;
$srcH = $_POST['yfinal'] - $srcY;
- $r = q("SELECT * FROM photo WHERE resource_id = '%s' AND uid = %d AND scale = %d LIMIT 1",
+ $r = q("SELECT * FROM photo WHERE resource_id = '%s' AND uid = %d AND imgscale = %d LIMIT 1",
dbesc($image_id),
dbesc(local_channel()),
intval($scale));
@@ -101,9 +101,9 @@ class Profile_photo extends \Zotlabs\Web\Controller {
if($r) {
$base_image = $r[0];
- $base_image['data'] = (($r[0]['os_storage']) ? @file_get_contents($base_image['data']) : dbunescbin($base_image['data']));
+ $base_image['content'] = (($r[0]['os_storage']) ? @file_get_contents($base_image['content']) : dbunescbin($base_image['content']));
- $im = photo_factory($base_image['data'], $base_image['type']);
+ $im = photo_factory($base_image['content'], $base_image['mimetype']);
if($im->is_valid()) {
$im->cropImage(300,$srcX,$srcY,$srcW,$srcH);
@@ -113,25 +113,25 @@ class Profile_photo extends \Zotlabs\Web\Controller {
$p = array('aid' => $aid, 'uid' => local_channel(), 'resource_id' => $base_image['resource_id'],
'filename' => $base_image['filename'], 'album' => t('Profile Photos'));
- $p['scale'] = 4;
+ $p['imgscale'] = 4;
$p['photo_usage'] = (($is_default_profile) ? PHOTO_PROFILE : PHOTO_NORMAL);
$r1 = $im->save($p);
$im->scaleImage(80);
- $p['scale'] = 5;
+ $p['imgscale'] = 5;
$r2 = $im->save($p);
$im->scaleImage(48);
- $p['scale'] = 6;
+ $p['imgscale'] = 6;
$r3 = $im->save($p);
if($r1 === false || $r2 === false || $r3 === false) {
// if one failed, delete them all so we can start over.
notice( t('Image resize failed.') . EOL );
- $x = q("delete from photo where resource_id = '%s' and uid = %d and scale >= 4 ",
+ $x = q("delete from photo where resource_id = '%s' and uid = %d and imgscale >= 4 ",
dbesc($base_image['resource_id']),
local_channel()
);
@@ -179,7 +179,7 @@ class Profile_photo extends \Zotlabs\Web\Controller {
info( t('Shift-reload the page or clear browser cache if the new photo does not display immediately.') . EOL);
// Update directory in background
- proc_run('php',"include/directory.php",$channel['channel_id']);
+ \Zotlabs\Daemon\Master::Summon(array('Directory',$channel['channel_id']));
// Now copy profile-permissions to pictures, to prevent privacyleaks by automatically created folder 'Profile Pictures'
@@ -208,7 +208,7 @@ class Profile_photo extends \Zotlabs\Web\Controller {
logger('attach_store: ' . print_r($res,true));
if($res && intval($res['data']['is_photo'])) {
- $i = q("select * from photo where resource_id = '%s' and uid = %d order by scale",
+ $i = q("select * from photo where resource_id = '%s' and uid = %d order by imgscale",
dbesc($hash),
intval(local_channel())
);
@@ -220,11 +220,11 @@ class Profile_photo extends \Zotlabs\Web\Controller {
$os_storage = false;
foreach($i as $ii) {
- if(intval($ii['scale']) < 2) {
- $smallest = intval($ii['scale']);
+ if(intval($ii['imgscale']) < 2) {
+ $smallest = intval($ii['imgscale']);
$os_storage = intval($ii['os_storage']);
- $imagedata = $ii['data'];
- $filetype = $ii['type'];
+ $imagedata = $ii['content'];
+ $filetype = $ii['mimetype'];
}
}
}
@@ -250,7 +250,7 @@ class Profile_photo extends \Zotlabs\Web\Controller {
*/
- function get() {
+ function get() {
if(! local_channel()) {
notice( t('Permission denied.') . EOL );
@@ -275,7 +275,7 @@ class Profile_photo extends \Zotlabs\Web\Controller {
$resource_id = argv(2);
- $r = q("SELECT id, album, scale FROM photo WHERE uid = %d AND resource_id = '%s' ORDER BY scale ASC",
+ $r = q("SELECT id, album, imgscale FROM photo WHERE uid = %d AND resource_id = '%s' ORDER BY imgscale ASC",
intval(local_channel()),
dbesc($resource_id)
);
@@ -285,7 +285,7 @@ class Profile_photo extends \Zotlabs\Web\Controller {
}
$havescale = false;
foreach($r as $rr) {
- if($rr['scale'] == 5)
+ if($rr['imgscale'] == 5)
$havescale = true;
}
@@ -311,11 +311,11 @@ class Profile_photo extends \Zotlabs\Web\Controller {
);
profile_photo_set_profile_perms(); //Reset default photo permissions to public
- proc_run('php','include/directory.php',local_channel());
+ \Zotlabs\Daemon\Master::Summon(array('Directory',local_channel()));
goaway(z_root() . '/profiles');
}
- $r = q("SELECT `data`, `type`, resource_id, os_storage FROM photo WHERE id = %d and uid = %d limit 1",
+ $r = q("SELECT content, mimetype, resource_id, os_storage FROM photo WHERE id = %d and uid = %d limit 1",
intval($r[0]['id']),
intval(local_channel())
@@ -326,15 +326,15 @@ class Profile_photo extends \Zotlabs\Web\Controller {
}
if(intval($r[0]['os_storage']))
- $data = @file_get_contents($r[0]['data']);
+ $data = @file_get_contents($r[0]['content']);
else
- $data = dbunescbin($r[0]['data']);
+ $data = dbunescbin($r[0]['content']);
- $ph = photo_factory($data, $r[0]['type']);
+ $ph = photo_factory($data, $r[0]['mimetype']);
$smallest = 0;
if($ph->is_valid()) {
// go ahead as if we have just uploaded a new photo to crop
- $i = q("select resource_id, scale from photo where resource_id = '%s' and uid = %d order by scale",
+ $i = q("select resource_id, imgscale from photo where resource_id = '%s' and uid = %d order by imgscale",
dbesc($r[0]['resource_id']),
intval(local_channel())
);
@@ -342,8 +342,8 @@ class Profile_photo extends \Zotlabs\Web\Controller {
if($i) {
$hash = $i[0]['resource_id'];
foreach($i as $ii) {
- if(intval($ii['scale']) < 2) {
- $smallest = intval($ii['scale']);
+ if(intval($ii['imgscale']) < 2) {
+ $smallest = intval($ii['imgscale']);
}
}
}
diff --git a/Zotlabs/Module/Profiles.php b/Zotlabs/Module/Profiles.php
index 72edf396f..06e5cfd7b 100644
--- a/Zotlabs/Module/Profiles.php
+++ b/Zotlabs/Module/Profiles.php
@@ -1,7 +1,8 @@
<?php
namespace Zotlabs\Module;
-require_once('include/identity.php');
+require_once('include/channel.php');
+require_once('include/selectors.php');
class Profiles extends \Zotlabs\Web\Controller {
@@ -66,16 +67,16 @@ class Profiles extends \Zotlabs\Web\Controller {
$name = t('Profile-') . ($num_profiles + 1);
- $r1 = q("SELECT `name`, `photo`, `thumb` FROM `profile` WHERE `uid` = %d AND `is_default` = 1 LIMIT 1",
+ $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` , `name`, `photo`, `thumb`)
+ $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]['name']),
+ dbesc($r1[0]['fullname']),
dbesc($r1[0]['photo']),
dbesc($r1[0]['thumb'])
);
@@ -276,14 +277,14 @@ class Profiles extends \Zotlabs\Web\Controller {
$name = escape_tags(trim($_POST['name']));
- if($orig[0]['name'] != $name) {
+ if($orig[0]['fullname'] != $name) {
$namechanged = true;
$v = validate_channelname($name);
if($v) {
notice($v);
$namechanged = false;
- $name = $orig[0]['name'];
+ $name = $orig[0]['fullname'];
}
}
@@ -349,7 +350,7 @@ class Profiles extends \Zotlabs\Web\Controller {
$withchanged = false;
if(strlen($with)) {
- if($with != strip_tags($orig[0]['with'])) {
+ if($with != strip_tags($orig[0]['partner'])) {
$withchanged = true;
$prf = '';
$lookup = $with;
@@ -381,7 +382,7 @@ class Profiles extends \Zotlabs\Web\Controller {
}
}
else
- $with = $orig[0]['with'];
+ $with = $orig[0]['partner'];
}
$profile_fields_basic = get_profile_fields_basic();
@@ -438,7 +439,7 @@ class Profiles extends \Zotlabs\Web\Controller {
$changes[] = t('Dislikes');
$value = $dislikes;
}
- if($work != $orig[0]['work']) {
+ if($work != $orig[0]['employment']) {
$changes[] = t('Work/Employment');
}
if($religion != $orig[0]['religion']) {
@@ -485,7 +486,7 @@ class Profiles extends \Zotlabs\Web\Controller {
$r = q("UPDATE `profile`
SET `profile_name` = '%s',
- `name` = '%s',
+ `fullname` = '%s',
`pdesc` = '%s',
`gender` = '%s',
`dob` = '%s',
@@ -495,7 +496,7 @@ class Profiles extends \Zotlabs\Web\Controller {
`postal_code` = '%s',
`country_name` = '%s',
`marital` = '%s',
- `with` = '%s',
+ `partner` = '%s',
`howlong` = '%s',
`sexual` = '%s',
`homepage` = '%s',
@@ -514,7 +515,7 @@ class Profiles extends \Zotlabs\Web\Controller {
`tv` = '%s',
`film` = '%s',
`romance` = '%s',
- `work` = '%s',
+ `employment` = '%s',
`education` = '%s',
`hide_friends` = %d
WHERE `id` = %d AND `uid` = %d",
@@ -584,13 +585,13 @@ class Profiles extends \Zotlabs\Web\Controller {
if($is_default) {
// reload the info for the sidebar widget - why does this not work?
profile_load($a,$channel['channel_address']);
- proc_run('php','include/directory.php',local_channel());
+ \Zotlabs\Daemon\Master::Summon(array('Directory',local_channel()));
}
}
}
- function get() {
+ function get() {
$o = '';
@@ -601,7 +602,7 @@ class Profiles extends \Zotlabs\Web\Controller {
return;
}
- require_once('include/identity.php');
+ require_once('include/channel.php');
$profile_fields_basic = get_profile_fields_basic();
$profile_fields_advanced = get_profile_fields_advanced();
@@ -625,12 +626,7 @@ class Profiles extends \Zotlabs\Web\Controller {
return;
}
- require_once('include/profile_selectors.php');
-
-
$editselect = 'none';
- // if(feature_enabled(local_channel(),'richtext'))
- // $editselect = 'textareas';
\App::$page['htmlhead'] .= replace_macros(get_markup_template('profed_head.tpl'), array(
'$baseurl' => z_root(),
@@ -714,7 +710,7 @@ class Profiles extends \Zotlabs\Web\Controller {
'$is_default' => $is_default,
'$default' => t('This is your default profile.') . EOL . translate_scope(map_scope($channel['channel_r_profile'])),
'$advanced' => $advanced,
- '$name' => array('name', t('Your full name'), $r[0]['name'], t('Required'), '*'),
+ '$name' => array('name', t('Your full name'), $r[0]['fullname'], t('Required'), '*'),
'$pdesc' => array('pdesc', t('Title/Description'), $r[0]['pdesc']),
'$dob' => dob($r[0]['dob']),
'$hide_friends' => $hide_friends,
@@ -727,7 +723,7 @@ class Profiles extends \Zotlabs\Web\Controller {
'$gender_min' => gender_selector_min($r[0]['gender']),
'$marital' => marital_selector($r[0]['marital']),
'$marital_min' => marital_selector_min($r[0]['marital']),
- '$with' => array('with', t("Who (if applicable)"), $r[0]['with'], t('Examples: cathy123, Cathy Williams, cathy@example.com')),
+ '$with' => array('with', t("Who (if applicable)"), $r[0]['partner'], t('Examples: cathy123, Cathy Williams, cathy@example.com')),
'$howlong' => array('howlong', t('Since (date)'), ($r[0]['howlong'] === NULL_DATE ? '' : datetime_convert('UTC',date_default_timezone_get(),$r[0]['howlong']))),
'$sexual' => sexpref_selector($r[0]['sexual']),
'$sexual_min' => sexpref_selector_min($r[0]['sexual']),
@@ -745,7 +741,7 @@ class Profiles extends \Zotlabs\Web\Controller {
'$film' => array('film', t('Film/Dance/Culture/Entertainment'), $r[0]['film']),
'$interest' => array('interest', t('Hobbies/Interests'), $r[0]['interest']),
'$romance' => array('romance',t('Love/Romance'), $r[0]['romance']),
- '$work' => array('work', t('Work/Employment'), $r[0]['work']),
+ '$work' => array('work', t('Work/Employment'), $r[0]['employment']),
'$education' => array('education', t('School/Education'), $r[0]['education']),
'$contact' => array('contact', t('Contact information and social networks'), $r[0]['contact']),
'$channels' => array('channels', t('My other channels'), $r[0]['channels']),
@@ -761,7 +757,7 @@ class Profiles extends \Zotlabs\Web\Controller {
$r = q("SELECT * FROM `profile` WHERE `uid` = %d",
local_channel());
- if(count($r)) {
+ if($r) {
$tpl = get_markup_template('profile_entry.tpl');
foreach($r as $rr) {
@@ -782,10 +778,7 @@ class Profiles extends \Zotlabs\Web\Controller {
'$cr_new' => t('Create New'),
'$cr_new_link' => 'profiles/new?t=' . get_form_security_token("profile_new"),
'$profiles' => $profiles
- ));
-
-
-
+ ));
}
return $o;
diff --git a/Zotlabs/Module/Profperm.php b/Zotlabs/Module/Profperm.php
index 94267aaac..33e9d1ece 100644
--- a/Zotlabs/Module/Profperm.php
+++ b/Zotlabs/Module/Profperm.php
@@ -1,7 +1,7 @@
<?php
namespace Zotlabs\Module;
-require_once('include/Contact.php');
+
require_once('include/photos.php');
diff --git a/Zotlabs/Module/Pubsites.php b/Zotlabs/Module/Pubsites.php
index 9313a3c5a..0dda08e6d 100644
--- a/Zotlabs/Module/Pubsites.php
+++ b/Zotlabs/Module/Pubsites.php
@@ -28,10 +28,11 @@ class Pubsites extends \Zotlabs\Web\Controller {
if($ret['success']) {
$j = json_decode($ret['body'],true);
if($j) {
- $o .= '<table class="table table-striped table-hover"><tr><td>' . t('Hub URL') . '</td><td>' . t('Access Type') . '</td><td>' . t('Registration Policy') . '</td><td colspan="2">' . t('Ratings') . '</td></tr>';
+ $o .= '<table class="table table-striped table-hover"><tr><td>' . t('Hub URL') . '</td><td>' . t('Access Type') . '</td><td>' . t('Registration Policy') . '</td><td>' . t('Stats') . '</td><td>' . t('Software') . '</td><td colspan="2">' . t('Ratings') . '</td></tr>';
if($j['sites']) {
foreach($j['sites'] as $jj) {
- if($jj['project'] !== \Zotlabs\Project\System::get_platform_name())
+ $m = parse_url($jj['url']);
+ if(strpos($jj['project'],\Zotlabs\Lib\System::get_platform_name()) === false)
continue;
$host = strtolower(substr($jj['url'],strpos($jj['url'],'://')+3));
$rate_links = ((local_channel()) ? '<td><a href="rate?f=&target=' . $host . '" class="btn-btn-default"><i class="fa fa-check-square-o"></i> ' . t('Rate') . '</a></td>' : '');
@@ -43,7 +44,7 @@ class Pubsites extends \Zotlabs\Web\Controller {
$location = '<br />&nbsp;';
}
$urltext = str_replace(array('https://'), '', $jj['url']);
- $o .= '<tr><td><a href="'. (($jj['sellpage']) ? $jj['sellpage'] : $jj['url'] . '/register' ) . '" ><i class="fa fa-link"></i> ' . $urltext . '</a>' . $location . '</td><td>' . $jj['access'] . '</td><td>' . $jj['register'] . '</td><td><a href="ratings/' . $host . '" class="btn-btn-default"><i class="fa fa-eye"></i> ' . t('View') . '</a></td>' . $rate_links . '</tr>';
+ $o .= '<tr><td><a href="'. (($jj['sellpage']) ? $jj['sellpage'] : $jj['url'] . '/register' ) . '" ><i class="fa fa-link"></i> ' . $urltext . '</a>' . $location . '</td><td>' . $jj['access'] . '</td><td>' . $jj['register'] . '</td><td>' . '<a target="stats" href="https://hubchart-tarine.rhcloud.com/hub.jsp?hubFqdn=' . $m['host'] . '"><i class="fa fa-area-chart"></i></a></td><td>' . ucwords($jj['project']) . '</td><td><a href="ratings/' . $host . '" class="btn-btn-default"><i class="fa fa-eye"></i> ' . t('View') . '</a></td>' . $rate_links . '</tr>';
}
}
diff --git a/Zotlabs/Module/Pubstream.php b/Zotlabs/Module/Pubstream.php
index adc16e6e6..312be7718 100644
--- a/Zotlabs/Module/Pubstream.php
+++ b/Zotlabs/Module/Pubstream.php
@@ -12,7 +12,7 @@ class Pubstream extends \Zotlabs\Web\Controller {
$_SESSION['loadtime'] = datetime_convert();
- if(get_config('system','block_public') && (! get_account_id()) && (! remote_channel())) {
+ if(observer_prohibited(true)) {
return login();
}
@@ -71,7 +71,7 @@ class Pubstream extends \Zotlabs\Web\Controller {
$pager_sql = sprintf(" LIMIT %d OFFSET %d ", intval(\App::$pager['itemspage']), intval(\App::$pager['start']));
}
- require_once('include/identity.php');
+ require_once('include/channel.php');
require_once('include/security.php');
if(get_config('system','site_firehose')) {
diff --git a/Zotlabs/Module/Randprof.php b/Zotlabs/Module/Randprof.php
index 86b25c22a..dc2e925fe 100644
--- a/Zotlabs/Module/Randprof.php
+++ b/Zotlabs/Module/Randprof.php
@@ -6,7 +6,6 @@ namespace Zotlabs\Module;
class Randprof extends \Zotlabs\Web\Controller {
function init() {
- require_once('include/Contact.php');
$x = random_profile();
if($x)
goaway(chanlink_url($x));
diff --git a/Zotlabs/Module/Rate.php b/Zotlabs/Module/Rate.php
index e2c05b6d4..da23b840e 100644
--- a/Zotlabs/Module/Rate.php
+++ b/Zotlabs/Module/Rate.php
@@ -102,14 +102,12 @@ class Rate extends \Zotlabs\Web\Controller {
}
if($record) {
- proc_run('php','include/ratenotif.php','rating',$record);
+ \Zotlabs\Daemon\Master::Summon(array('Ratenotif','rating',$record));
}
}
-
-
- function get() {
+ function get() {
if(! local_channel()) {
notice( t('Permission denied.') . EOL);
diff --git a/Zotlabs/Module/Ratings.php b/Zotlabs/Module/Ratings.php
index 802bbfec2..969fb5015 100644
--- a/Zotlabs/Module/Ratings.php
+++ b/Zotlabs/Module/Ratings.php
@@ -8,7 +8,7 @@ class Ratings extends \Zotlabs\Web\Controller {
function init() {
- if((get_config('system','block_public')) && (! local_channel()) && (! remote_channel())) {
+ if(observer_prohibited()) {
return;
}
@@ -80,9 +80,9 @@ class Ratings extends \Zotlabs\Web\Controller {
- function get() {
+ function get() {
- if((get_config('system','block_public')) && (! local_channel()) && (! remote_channel())) {
+ if(observer_prohibited()) {
notice( t('Public access denied.') . EOL);
return;
}
diff --git a/Zotlabs/Module/React.php b/Zotlabs/Module/React.php
new file mode 100644
index 000000000..ed4f87e7e
--- /dev/null
+++ b/Zotlabs/Module/React.php
@@ -0,0 +1,51 @@
+<?php
+
+namespace Zotlabs\Module;
+
+
+class React extends \Zotlabs\Web\Controller {
+
+ function get() {
+ if(! local_channel())
+ return;
+
+ $postid = $_REQUEST['postid'];
+
+ if(! $postid)
+ return;
+
+ $emoji = $_REQUEST['emoji'];
+ if($_REQUEST['emoji']) {
+
+ $i = q("select * from item where id = %d and uid = %d",
+ intval($postid),
+ intval(local_channel())
+ );
+
+ if(! $i)
+ return;
+
+ $channel = \App::get_channel();
+
+ $n = array();
+ $n['aid'] = $channel['channel_account_id'];
+ $n['uid'] = $channel['channel_id'];
+ $n['item_origin'] = true;
+ $n['parent'] = $postid;
+ $n['parent_mid'] = $i[0]['mid'];
+ $n['mid'] = item_message_id();
+ $n['verb'] = ACTIVITY_REACT . '#' . $emoji;
+ $n['body'] = "\n\n[zmg=32x32]" . z_root() . '/images/emoji/' . $emoji . '.png[/zmg]' . "\n\n";
+ $n['author_xchan'] = $channel['channel_hash'];
+
+ $x = item_store($n);
+ if($x['success']) {
+ $nid = $x['item_id'];
+ \Zotlabs\Daemon\Master::Summon(array('Notifier','like',$nid));
+ }
+
+ }
+
+ }
+
+} \ No newline at end of file
diff --git a/Zotlabs/Module/Regdir.php b/Zotlabs/Module/Regdir.php
index 65f8daf67..48a7cc16d 100644
--- a/Zotlabs/Module/Regdir.php
+++ b/Zotlabs/Module/Regdir.php
@@ -60,14 +60,11 @@ class Regdir extends \Zotlabs\Web\Controller {
json_return_and_die($result);
}
- $f = zot_finger('[system]@' . $m['host']);
- if($f['success']) {
- $j = json_decode($f['body'],true);
- if($j['success'] && $j['guid']) {
- $x = import_xchan($j);
- if($x['success']) {
- $result['success'] = true;
- }
+ $j = \Zotlabs\Zot\Finger::run('[system]@' . $m['host']);
+ if($j['success'] && $j['guid']) {
+ $x = import_xchan($j);
+ if($x['success']) {
+ $result['success'] = true;
}
}
diff --git a/Zotlabs/Module/Register.php b/Zotlabs/Module/Register.php
index ca3f33238..7cd1ee501 100644
--- a/Zotlabs/Module/Register.php
+++ b/Zotlabs/Module/Register.php
@@ -1,7 +1,7 @@
<?php
namespace Zotlabs\Module;
-require_once('include/identity.php');
+require_once('include/channel.php');
class Register extends \Zotlabs\Web\Controller {
diff --git a/Zotlabs/Module/Removeaccount.php b/Zotlabs/Module/Removeaccount.php
index da496dfad..39e06bb7f 100644
--- a/Zotlabs/Module/Removeaccount.php
+++ b/Zotlabs/Module/Removeaccount.php
@@ -36,17 +36,12 @@ class Removeaccount extends \Zotlabs\Web\Controller {
}
}
- require_once('include/Contact.php');
-
$global_remove = intval($_POST['global']);
- account_remove($account_id,true);
-
+ account_remove($account_id, 1 - $global_remove);
}
-
-
-
- function get() {
+
+ function get() {
if(! local_channel())
goaway(z_root());
diff --git a/Zotlabs/Module/Removeme.php b/Zotlabs/Module/Removeme.php
index 9b634672a..e611d8112 100644
--- a/Zotlabs/Module/Removeme.php
+++ b/Zotlabs/Module/Removeme.php
@@ -35,8 +35,6 @@ class Removeme extends \Zotlabs\Web\Controller {
}
}
- require_once('include/Contact.php');
-
$global_remove = intval($_POST['global']);
channel_remove(local_channel(),1 - $global_remove,true);
@@ -44,8 +42,7 @@ class Removeme extends \Zotlabs\Web\Controller {
}
-
- function get() {
+ function get() {
if(! local_channel())
goaway(z_root());
diff --git a/Zotlabs/Module/Rmagic.php b/Zotlabs/Module/Rmagic.php
index bcdbf6c90..26b0c46a6 100644
--- a/Zotlabs/Module/Rmagic.php
+++ b/Zotlabs/Module/Rmagic.php
@@ -24,7 +24,7 @@ class Rmagic extends \Zotlabs\Web\Controller {
}
}
- function post() {
+ function post() {
$address = trim($_REQUEST['address']);
@@ -34,13 +34,13 @@ class Rmagic extends \Zotlabs\Web\Controller {
try {
require_once('library/openid/openid.php');
- $openid = new LightOpenID(z_root());
+ $openid = new \LightOpenID(z_root());
$openid->identity = $address;
$openid->returnUrl = z_root() . '/openid';
$openid->required = array('namePerson/friendly', 'namePerson');
$openid->optional = array('namePerson/first','media/image/aspect11','media/image/default');
goaway($openid->authUrl());
- } catch (Exception $e) {
+ } catch (\Exception $e) {
notice( t('We encountered a problem while logging in with the OpenID you provided. Please check the correct spelling of the ID.').'<br /><br >'. t('The error message was:').' '.$e->getMessage());
}
@@ -82,7 +82,7 @@ class Rmagic extends \Zotlabs\Web\Controller {
}
- function get() {
+ function get() {
$o = replace_macros(get_markup_template('rmagic.tpl'),array(
'$title' => t('Remote Authentication'),
diff --git a/Zotlabs/Module/Rsd_xml.php b/Zotlabs/Module/Rsd_xml.php
index 06af39ad1..e5059834b 100644
--- a/Zotlabs/Module/Rsd_xml.php
+++ b/Zotlabs/Module/Rsd_xml.php
@@ -6,7 +6,7 @@ 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\Project\System::get_platform_name(),
+ '$project' => \Zotlabs\Lib\System::get_platform_name(),
'$baseurl' => z_root(),
'$apipath' => z_root() . '/api/'
));
diff --git a/Zotlabs/Module/Search.php b/Zotlabs/Module/Search.php
index 9941ebbd2..402a27d40 100644
--- a/Zotlabs/Module/Search.php
+++ b/Zotlabs/Module/Search.php
@@ -79,7 +79,7 @@ class Search extends \Zotlabs\Web\Controller {
return $o;
if($tag) {
- $sql_extra = sprintf(" AND `item`.`id` IN (select `oid` from term where otype = %d and type in ( %d , %d) and term = '%s') ",
+ $sql_extra = sprintf(" AND `item`.`id` IN (select `oid` from term where otype = %d and ttype in ( %d , %d) and term = '%s') ",
intval(TERM_OBJ_POST),
intval(TERM_HASHTAG),
intval(TERM_COMMUNITYTAG),
@@ -139,7 +139,7 @@ class Search extends \Zotlabs\Web\Controller {
$item_normal = item_normal();
$pub_sql = public_permissions_sql($observer_hash);
- require_once('include/identity.php');
+ require_once('include/channel.php');
$sys = get_sys_channel();
diff --git a/Zotlabs/Module/Search_ac.php b/Zotlabs/Module/Search_ac.php
index 78bcf374d..4e936d97b 100644
--- a/Zotlabs/Module/Search_ac.php
+++ b/Zotlabs/Module/Search_ac.php
@@ -46,7 +46,7 @@ class Search_ac extends \Zotlabs\Web\Controller {
}
}
- $r = q("select distinct term, tid, url from term where type in ( %d, %d ) $tag_sql_extra group by term order by term asc",
+ $r = q("select distinct term, tid, url from term where ttype in ( %d, %d ) $tag_sql_extra group by term order by term asc",
intval(TERM_HASHTAG),
intval(TERM_COMMUNITYTAG)
);
diff --git a/Zotlabs/Module/Settings.php b/Zotlabs/Module/Settings.php
index a6293e842..875004fae 100644
--- a/Zotlabs/Module/Settings.php
+++ b/Zotlabs/Module/Settings.php
@@ -78,7 +78,7 @@ class Settings extends \Zotlabs\Web\Controller {
$r = q("UPDATE clients SET
client_id='%s',
pw='%s',
- name='%s',
+ clname='%s',
redirect_uri='%s',
icon='%s',
uid=%d
@@ -91,7 +91,7 @@ class Settings extends \Zotlabs\Web\Controller {
intval(local_channel()),
dbesc($key));
} else {
- $r = q("INSERT INTO clients (client_id, pw, name, redirect_uri, icon, uid)
+ $r = q("INSERT INTO clients (client_id, pw, clname, redirect_uri, icon, uid)
VALUES ('%s','%s','%s','%s','%s',%d)",
dbesc($key),
dbesc($secret),
@@ -337,7 +337,7 @@ class Settings extends \Zotlabs\Web\Controller {
}
$hide_presence = 1 - (intval($role_permissions['online']));
if($role_permissions['default_collection']) {
- $r = q("select hash from groups where uid = %d and name = '%s' limit 1",
+ $r = q("select hash from groups where uid = %d and gname = '%s' limit 1",
intval(local_channel()),
dbesc( t('Friends') )
);
@@ -345,7 +345,7 @@ class Settings extends \Zotlabs\Web\Controller {
require_once('include/group.php');
group_add(local_channel(), t('Friends'));
group_add_member(local_channel(),t('Friends'),$channel['channel_hash']);
- $r = q("select hash from groups where uid = %d and name = '%s' limit 1",
+ $r = q("select hash from groups where uid = %d and gname = '%s' limit 1",
intval(local_channel()),
dbesc( t('Friends') )
);
@@ -483,7 +483,7 @@ class Settings extends \Zotlabs\Web\Controller {
if($username != $channel['channel_name']) {
$name_change = true;
- require_once('include/identity.php');
+ require_once('include/channel.php');
$err = validate_channelname($username);
if($err) {
notice($err);
@@ -537,13 +537,13 @@ class Settings extends \Zotlabs\Web\Controller {
dbesc(datetime_convert()),
dbesc($channel['channel_hash'])
);
- $r = q("update profile set name = '%s' where uid = %d and is_default = 1",
+ $r = q("update profile set fullname = '%s' where uid = %d and is_default = 1",
dbesc($username),
intval($channel['channel_id'])
);
}
- proc_run('php','include/directory.php',local_channel());
+ \Zotlabs\Daemon\Master::Summon(array('Directory',local_channel()));
build_sync_packet();
@@ -562,7 +562,7 @@ class Settings extends \Zotlabs\Web\Controller {
- function get() {
+ function get() {
$o = '';
nav_set_selected('settings');
@@ -615,7 +615,7 @@ class Settings extends \Zotlabs\Web\Controller {
'$title' => t('Add application'),
'$submit' => t('Update'),
'$cancel' => t('Cancel'),
- '$name' => array('name', t('Name'), $app['name'] , ''),
+ '$name' => array('name', t('Name'), $app['clname'] , ''),
'$key' => array('key', t('Consumer Key'), $app['client_id'], ''),
'$secret' => array('secret', t('Consumer Secret'), $app['pw'], ''),
'$redirect' => array('redirect', t('Redirect'), $app['redirect_uri'], ''),
@@ -1047,7 +1047,7 @@ class Settings extends \Zotlabs\Web\Controller {
'$h_prv' => t('Security and Privacy Settings'),
'$permissions_set' => $permissions_set,
- '$server_role' => \Zotlabs\Project\System::get_server_role(),
+ '$server_role' => \Zotlabs\Lib\System::get_server_role(),
'$perms_set_msg' => t('Your permissions are already configured. Click to view/adjust'),
'$hide_presence' => array('hide_presence', t('Hide my online presence'),$hide_presence, t('Prevents displaying in your profile that you are online'), $yes_no),
@@ -1062,11 +1062,11 @@ class Settings extends \Zotlabs\Web\Controller {
'$lbl_p2macro' => t('Advanced Privacy Settings'),
- '$expire' => array('expire',t('Expire other channel content after this many days'),$expire,sprintf( t('0 or blank to use the website limit. The website expires after %d days.'),intval($sys_expire))),
+ '$expire' => array('expire',t('Expire other channel content after this many days'),$expire, t('0 or blank to use the website limit.') . ' ' . ((intval($sys_expire)) ? sprintf( t('This website expires after %d days.'),intval($sys_expire)) : t('This website does not expire imported content.')) . ' ' . t('The website limit takes precedence if lower than your limit.')),
'$maxreq' => array('maxreq', t('Maximum Friend Requests/Day:'), intval($channel['channel_max_friend_req']) , t('May reduce spam activity')),
- '$permissions' => t('Default Post Permissions'),
+ '$permissions' => t('Default Post and Publish Permissions'),
'$permdesc' => t("\x28click to open/close\x29"),
- '$aclselect' => populate_acl($perm_defaults, false, \PermissionDescription::fromDescription(t('Use my default audience setting for the type of post'))),
+ '$aclselect' => populate_acl($perm_defaults, false, \PermissionDescription::fromDescription(t('Use my default audience setting for the type of object published'))),
'$suggestme' => $suggestme,
'$group_select' => $group_select,
'$role' => array('permissions_role' , t('Channel permissions category:'), $permissions_role, '', get_roles()),
diff --git a/Zotlabs/Module/Setup.php b/Zotlabs/Module/Setup.php
index f8c14951b..c4878e217 100644
--- a/Zotlabs/Module/Setup.php
+++ b/Zotlabs/Module/Setup.php
@@ -12,7 +12,6 @@ namespace Zotlabs\Module;
/**
* @brief Initialisation for the setup module.
*
- * @param[in,out] App &$a
*/
class Setup extends \Zotlabs\Web\Controller {
@@ -54,16 +53,15 @@ class Setup extends \Zotlabs\Web\Controller {
/**
* @brief Handle the actions of the different setup steps.
*
- * @param[in,out] App &$a
*/
- function post() {
- global $db;
+
+ function post() {
switch($this->install_wizard_pass) {
case 1:
case 2:
return;
- break; // just in case return don't return :)
+ // implied break;
case 3:
$urlpath = \App::get_path();
$dbhost = trim($_POST['dbhost']);
@@ -82,39 +80,15 @@ class Setup extends \Zotlabs\Web\Controller {
$siteurl = rtrim($siteurl,'/');
require_once('include/dba/dba_driver.php');
- unset($db);
- $db = dba_factory($dbhost, $dbport, $dbuser, $dbpass, $dbdata, $dbtype, true);
+
+ $db = \DBA::dba_factory($dbhost, $dbport, $dbuser, $dbpass, $dbdata, $dbtype, true);
- if(! $db->connected) {
- echo 'Database Connect failed: ' . $db->error;
+ if(! \DBA::$dba->connected) {
+ echo 'Database Connect failed: ' . DBA::$dba->error;
killme();
- \App::$data['db_conn_failed']=true;
}
- /*if(get_db_errno()) {
- unset($db);
- $db = dba_factory($dbhost, $dbport, $dbuser, $dbpass, '', true);
-
- if(! get_db_errno()) {
- $r = q("CREATE DATABASE '%s'",
- dbesc($dbdata)
- );
- if($r) {
- unset($db);
- $db = new dba($dbhost, $dbport, $dbuser, $dbpass, $dbdata, true);
- } else {
- \App::$data['db_create_failed']=true;
- }
- } else {
- \App::$data['db_conn_failed']=true;
- return;
- }
- }*/
- //if(get_db_errno()) {
-
- //}
-
return;
- break;
+ // implied break;
case 4:
$urlpath = \App::get_path();
$dbhost = notags(trim($_POST['dbhost']));
@@ -138,10 +112,12 @@ class Setup extends \Zotlabs\Web\Controller {
}
}
- // connect to db
- $db = dba_factory($dbhost, $dbport, $dbuser, $dbpass, $dbdata, $dbtype, true);
-
- if(! $db->connected) {
+ if(! \DBA::$dba->connected) {
+ // connect to db
+ $db = \DBA::dba_factory($dbhost, $dbport, $dbuser, $dbpass, $dbdata, $dbtype, true);
+ }
+
+ if(! \DBA::$dba->connected) {
echo 'CRITICAL: DB not connected.';
killme();
}
@@ -175,6 +151,8 @@ class Setup extends \Zotlabs\Web\Controller {
\App::$data['db_installed'] = true;
return;
+ // implied break;
+ default:
break;
}
}
@@ -191,11 +169,10 @@ class Setup extends \Zotlabs\Web\Controller {
*
* Depending on the state we are currently in it returns different content.
*
- * @param App &$a
* @return string parsed HTML output
*/
- function get() {
- global $db;
+
+ function get() {
$o = '';
$wizard_status = '';
@@ -228,7 +205,7 @@ class Setup extends \Zotlabs\Web\Controller {
$txt .= "<pre>".\App::$data['db_failed'] . "</pre>". EOL ;
$db_return_text .= $txt;
}
- if($db && $db->connected) {
+ if(\DBA::$dba && \DBA::$dba->connected) {
$r = q("SELECT COUNT(*) as `total` FROM `account`");
if($r && count($r) && $r[0]['total']) {
$tpl = get_markup_template('install.tpl');
@@ -407,8 +384,8 @@ class Setup extends \Zotlabs\Web\Controller {
function check_php(&$phpath, &$checks) {
$help = '';
- if(version_compare(PHP_VERSION, '5.4') < 0) {
- $help .= t('PHP version 5.4 or greater is required.');
+ if(version_compare(PHP_VERSION, '5.5') < 0) {
+ $help .= t('PHP version 5.5 or greater is required.');
$this->check_add($checks, t('PHP version'), false, false, $help);
}
@@ -598,7 +575,7 @@ class Setup extends \Zotlabs\Web\Controller {
if(! is_writable(TEMPLATE_BUILD_PATH) ) {
$status = false;
$help = t('Red uses the Smarty3 template engine to render its web views. Smarty3 compiles templates to PHP to speed up rendering.') .EOL;
- $help .= sprintf( t('In order to store these compiled templates, the web server needs to have write access to the directory %s under the Red top level folder.'), TEMPLATE_BUILD_PATH) . EOL;
+ $help .= sprintf( t('In order to store these compiled templates, the web server needs to have write access to the directory %s under the top level web folder.'), TEMPLATE_BUILD_PATH) . EOL;
$help .= t('Please ensure that the user that your web server runs as (e.g. www-data) has write access to this folder.').EOL;
$help .= sprintf( t('Note: as a security measure, you should give the web server write access to %s only--not the template files (.tpl) that it contains.'), TEMPLATE_BUILD_PATH) . EOL;
}
@@ -698,12 +675,12 @@ class Setup extends \Zotlabs\Web\Controller {
function load_database($db) {
- $str = file_get_contents($db->get_install_script());
+ $str = file_get_contents(\DBA::$dba->get_install_script());
$arr = explode(';',$str);
$errors = false;
foreach($arr as $a) {
if(strlen(trim($a))) {
- $r = @$db->q(trim($a));
+ $r = dbq(trim($a));
if(! $r) {
$errors .= t('Errors encountered creating database tables.') . $a . EOL;
}
@@ -734,7 +711,7 @@ class Setup extends \Zotlabs\Web\Controller {
set_config('system','curl_ssl_ciphers','ALL:!eNULL');
// Create a system channel
- require_once ('include/identity.php');
+ require_once ('include/channel.php');
create_sys_channel();
$baseurl = z_root();
diff --git a/Zotlabs/Module/Share.php b/Zotlabs/Module/Share.php
index 73db01657..fcc2486ba 100644
--- a/Zotlabs/Module/Share.php
+++ b/Zotlabs/Module/Share.php
@@ -48,7 +48,7 @@ class Share extends \Zotlabs\Web\Controller {
$is_photo = (($r[0]['obj_type'] === ACTIVITY_OBJ_PHOTO) ? true : false);
if($is_photo) {
- $object = json_decode($r[0]['object'],true);
+ $object = json_decode($r[0]['obj'],true);
$photo_bb = $object['body'];
}
diff --git a/Zotlabs/Module/Sharedwithme.php b/Zotlabs/Module/Sharedwithme.php
index 8eaa47dba..25bc7dba3 100644
--- a/Zotlabs/Module/Sharedwithme.php
+++ b/Zotlabs/Module/Sharedwithme.php
@@ -46,7 +46,7 @@ class Sharedwithme extends \Zotlabs\Web\Controller {
}
//list files
- $r = q("SELECT id, uid, object, item_unseen FROM item WHERE verb = '%s' AND obj_type = '%s' AND uid = %d AND owner_xchan != '%s'",
+ $r = q("SELECT id, uid, obj, item_unseen FROM item WHERE verb = '%s' AND obj_type = '%s' AND uid = %d AND owner_xchan != '%s'",
dbesc(ACTIVITY_POST),
dbesc(ACTIVITY_OBJ_FILE),
intval(local_channel()),
@@ -59,7 +59,7 @@ class Sharedwithme extends \Zotlabs\Web\Controller {
if($r) {
foreach($r as $rr) {
- $object = json_decode($rr['object'],true);
+ $object = json_decode($rr['obj'],true);
$item = array();
$item['id'] = $rr['id'];
diff --git a/Zotlabs/Module/Siteinfo.php b/Zotlabs/Module/Siteinfo.php
index c65277004..41f6e9f0b 100644
--- a/Zotlabs/Module/Siteinfo.php
+++ b/Zotlabs/Module/Siteinfo.php
@@ -16,10 +16,10 @@ class Siteinfo extends \Zotlabs\Web\Controller {
function get() {
if(! get_config('system','hidden_version_siteinfo')) {
- $version = sprintf( t('Version %s'), \Zotlabs\Project\System::get_project_version());
+ $version = sprintf( t('Version %s'), \Zotlabs\Lib\System::get_project_version());
if(@is_dir('.git') && function_exists('shell_exec')) {
$commit = @shell_exec('git log -1 --format="%h"');
- $tag = \Zotlabs\Project\System::get_std_version(); // @shell_exec('git describe --tags --abbrev=0');
+ $tag = \Zotlabs\Lib\System::get_std_version(); // @shell_exec('git describe --tags --abbrev=0');
}
if(! isset($commit) || strlen($commit) > 16)
$commit = '';
diff --git a/Zotlabs/Module/Subthread.php b/Zotlabs/Module/Subthread.php
index 16a011a40..0226664d7 100644
--- a/Zotlabs/Module/Subthread.php
+++ b/Zotlabs/Module/Subthread.php
@@ -144,7 +144,7 @@ class Subthread extends \Zotlabs\Web\Controller {
$arr['verb'] = $activity;
$arr['obj_type'] = $objtype;
- $arr['object'] = $obj;
+ $arr['obj'] = $obj;
$arr['allow_cid'] = $item['allow_cid'];
$arr['allow_gid'] = $item['allow_gid'];
diff --git a/Zotlabs/Module/Tagger.php b/Zotlabs/Module/Tagger.php
index 879cf3dbb..0a46cf56d 100644
--- a/Zotlabs/Module/Tagger.php
+++ b/Zotlabs/Module/Tagger.php
@@ -124,14 +124,14 @@ class Tagger extends \Zotlabs\Web\Controller {
$arr['tgt_type'] = $targettype;
$arr['target'] = $target;
$arr['obj_type'] = $objtype;
- $arr['object'] = $obj;
+ $arr['obj'] = $obj;
$arr['parent_mid'] = $item['mid'];
store_item_tag($item['uid'],$item['id'],TERM_OBJ_POST,TERM_COMMUNITYTAG,$term,$tagid);
$ret = post_activity_item($arr);
if($ret['success'])
- proc_run('php','include/notifier.php','tag',$ret['activity']['id']);
+ \Zotlabs\Daemon\Master::Summon(array('Notifier','tag',$ret['activity']['id']));
killme();
diff --git a/Zotlabs/Module/Tagrm.php b/Zotlabs/Module/Tagrm.php
index 81ae30aa5..42aa6e90f 100644
--- a/Zotlabs/Module/Tagrm.php
+++ b/Zotlabs/Module/Tagrm.php
@@ -54,7 +54,7 @@ class Tagrm extends \Zotlabs\Web\Controller {
- function get() {
+ function get() {
if(! local_channel()) {
goaway(z_root() . '/' . $_SESSION['photo_return']);
diff --git a/Zotlabs/Module/Tasks.php b/Zotlabs/Module/Tasks.php
index ab05f8be9..6d0a92d91 100644
--- a/Zotlabs/Module/Tasks.php
+++ b/Zotlabs/Module/Tasks.php
@@ -45,7 +45,7 @@ class Tasks extends \Zotlabs\Web\Controller {
if((argc() > 2) && (argv(1) === 'complete') && intval(argv(2))) {
$ret = array('success' => false);
- $r = q("select * from event where `type` = 'task' and uid = %d and id = %d limit 1",
+ $r = q("select * from event where `etype` = 'task' and uid = %d and id = %d limit 1",
intval(local_channel()),
intval(argv(2))
);
@@ -80,9 +80,9 @@ class Tasks extends \Zotlabs\Web\Controller {
$event['account'] = $channel['channel_account_id'];
$event['uid'] = $channel['channel_id'];
$event['event_xchan'] = $channel['channel_hash'];
- $event['type'] = 'task';
+ $event['etype'] = 'task';
$event['nofinish'] = true;
- $event['created'] = $event['edited'] = $event['start'] = datetime_convert();
+ $event['created'] = $event['edited'] = $event['dtstart'] = datetime_convert();
$event['adjust'] = 1;
$event['allow_cid'] = '<' . $channel['channel_hash'] . '>';
$event['summary'] = escape_tags($_REQUEST['summary']);
@@ -92,21 +92,13 @@ class Tasks extends \Zotlabs\Web\Controller {
else
$x = array('success' => false);
json_return_and_die($x);
- }
-
-
+ }
}
-
-
-
-
- function get() {
-
+ function get() {
if(! local_channel())
return;
-
-
+
return '';
}
}
diff --git a/Zotlabs/Module/Thing.php b/Zotlabs/Module/Thing.php
index e95ec53f6..65fc0588e 100644
--- a/Zotlabs/Module/Thing.php
+++ b/Zotlabs/Module/Thing.php
@@ -7,7 +7,7 @@ namespace Zotlabs\Module;
require_once('include/items.php');
require_once('include/security.php');
-require_once('include/contact_selectors.php');
+require_once('include/selectors.php');
require_once('include/acl_selectors.php');
@@ -26,7 +26,7 @@ class Thing extends \Zotlabs\Web\Controller {
$verb = escape_tags($_REQUEST['verb']);
$activity = intval($_REQUEST['activity']);
$profile_guid = escape_tags($_REQUEST['profile_assign']);
- $url = $_REQUEST['link'];
+ $url = $_REQUEST['url'];
$photo = $_REQUEST['img'];
$hash = random_string();
@@ -212,7 +212,7 @@ class Thing extends \Zotlabs\Web\Controller {
$arr['verb'] = $verb;
$arr['obj_type'] = $objtype;
- $arr['object'] = $obj;
+ $arr['obj'] = $obj;
if(! $profile['is_default']) {
$arr['item_private'] = true;
@@ -235,7 +235,7 @@ class Thing extends \Zotlabs\Web\Controller {
}
- function get() {
+ function get() {
// @FIXME one problem with things is we can't share them unless we provide the channel in the url
// so we can definitively lookup the owner.
diff --git a/Zotlabs/Module/Uexport.php b/Zotlabs/Module/Uexport.php
index ada7e0986..d48f96d76 100644
--- a/Zotlabs/Module/Uexport.php
+++ b/Zotlabs/Module/Uexport.php
@@ -11,7 +11,7 @@ class Uexport extends \Zotlabs\Web\Controller {
if(argc() > 1) {
$channel = \App::get_channel();
- require_once('include/identity.php');
+ require_once('include/channel.php');
if(argc() > 1 && intval(argv(1)) > 1900) {
$year = intval(argv(1));
diff --git a/Zotlabs/Module/Viewconnections.php b/Zotlabs/Module/Viewconnections.php
index 726ef043b..ea478f92a 100644
--- a/Zotlabs/Module/Viewconnections.php
+++ b/Zotlabs/Module/Viewconnections.php
@@ -1,23 +1,22 @@
<?php
namespace Zotlabs\Module;
-require_once('include/contact_selectors.php');
-require_once('include/Contact.php');
+require_once('include/selectors.php');
class Viewconnections extends \Zotlabs\Web\Controller {
function init() {
- if((get_config('system','block_public')) && (! local_channel()) && (! remote_channel())) {
+ if(observer_prohibited()) {
return;
}
if(argc() > 1)
profile_load($a,argv(1));
}
- function get() {
+ function get() {
- if((get_config('system','block_public')) && (! local_channel()) && (! remote_channel())) {
+ if(observer_prohibited()) {
notice( t('Public access denied.') . EOL);
return;
}
diff --git a/Zotlabs/Module/Wall_attach.php b/Zotlabs/Module/Wall_attach.php
index 5bdecfa75..9a1019ddb 100644
--- a/Zotlabs/Module/Wall_attach.php
+++ b/Zotlabs/Module/Wall_attach.php
@@ -2,7 +2,7 @@
namespace Zotlabs\Module;
require_once('include/attach.php');
-require_once('include/identity.php');
+require_once('include/channel.php');
require_once('include/photos.php');
diff --git a/Zotlabs/Module/Wall_upload.php b/Zotlabs/Module/Wall_upload.php
index fff3ed03a..3868cb14e 100644
--- a/Zotlabs/Module/Wall_upload.php
+++ b/Zotlabs/Module/Wall_upload.php
@@ -2,7 +2,7 @@
namespace Zotlabs\Module;
require_once('include/photo/photo_driver.php');
-require_once('include/identity.php');
+require_once('include/channel.php');
require_once('include/photos.php');
diff --git a/Zotlabs/Module/Webpages.php b/Zotlabs/Module/Webpages.php
index d8adb55b2..bb8d454c8 100644
--- a/Zotlabs/Module/Webpages.php
+++ b/Zotlabs/Module/Webpages.php
@@ -1,7 +1,7 @@
<?php
namespace Zotlabs\Module;
-require_once('include/identity.php');
+require_once('include/channel.php');
require_once('include/conversation.php');
require_once('include/acl_selectors.php');
require_once('include/PermissionDescription.php');
diff --git a/Zotlabs/Module/Wiki.php b/Zotlabs/Module/Wiki.php
new file mode 100644
index 000000000..1e6446904
--- /dev/null
+++ b/Zotlabs/Module/Wiki.php
@@ -0,0 +1,424 @@
+<?php
+
+namespace Zotlabs\Module;/** @file */
+
+class Wiki extends \Zotlabs\Web\Controller {
+
+ function init() {
+ // Determine which channel's wikis to display to the observer
+ $nick = null;
+ if (argc() > 1)
+ $nick = argv(1); // if the channel name is in the URL, use that
+ if (!$nick && local_channel()) { // if no channel name was provided, assume the current logged in channel
+ $channel = \App::get_channel();
+ if ($channel && $channel['channel_address']) {
+ $nick = $channel['channel_address'];
+ goaway(z_root() . '/wiki/' . $nick);
+ }
+ }
+ if (!$nick) {
+ notice(t('You must be logged in to see this page.') . EOL);
+ goaway('/login');
+ }
+ }
+
+ function get() {
+ require_once('include/wiki.php');
+ require_once('include/acl_selectors.php');
+ // 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;
+ $showCommitMsg = false;
+ $hidePageHistory = false;
+ $pageHistory = array();
+ $local_observer = null;
+ $resource_id = '';
+
+ // init() should have forced the URL to redirect to /wiki/channel so assume argc() > 1
+ $nick = argv(1);
+ $channel = get_channel_by_nick($nick); // The channel who owns the wikis being viewed
+ if(! $channel) {
+ notice('Invalid channel' . EOL);
+ goaway('/' . argv(0));
+ }
+ // Determine if the observer is the channel owner so the ACL dialog can be populated
+ if (local_channel() === intval($channel['channel_id'])) {
+ $local_observer = \App::get_channel();
+ $wiki_owner = true;
+
+ // Obtain the default permission settings of the channel
+ $channel_acl = array(
+ 'allow_cid' => $local_observer['channel_allow_cid'],
+ 'allow_gid' => $local_observer['channel_allow_gid'],
+ 'deny_cid' => $local_observer['channel_deny_cid'],
+ 'deny_gid' => $local_observer['channel_deny_gid']
+ );
+ // Initialize the ACL to the channel default permissions
+ $x = array(
+ 'lockstate' => (( $local_observer['channel_allow_cid'] ||
+ $local_observer['channel_allow_gid'] ||
+ $local_observer['channel_deny_cid'] ||
+ $local_observer['channel_deny_gid'])
+ ? 'lock' : 'unlock'),
+ 'acl' => populate_acl($channel_acl),
+ 'bang' => ''
+ );
+ } else {
+ // Not the channel owner
+ $channel_acl = $x = array();
+ }
+
+ switch (argc()) {
+ case 2:
+ // Configure page template
+ $wikiheader = t('Wiki Sandbox');
+ $content = '"# Wiki Sandbox\n\nContent you **edit** and **preview** here *will not be saved*."';
+ $hide_editor = false;
+ $showPageControls = false;
+ $showNewWikiButton = $wiki_owner;
+ $showNewPageButton = false;
+ $hidePageHistory = true;
+ $showCommitMsg = false;
+ 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');
+ 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($channel['channel_id'], $wikiUrlName);
+ if(!$w['resource_id']) {
+ notice('Wiki not found' . EOL);
+ goaway('/'.argv(0).'/'.argv(1));
+ }
+ $resource_id = $w['resource_id'];
+
+ if (!$wiki_owner) {
+ // Check for observer permissions
+ $observer_hash = get_observer_hash();
+ $perms = wiki_get_permissions($resource_id, intval($channel['channel_id']), $observer_hash);
+ if(!$perms['read']) {
+ notice('Permission denied.' . EOL);
+ goaway('/'.argv(0).'/'.argv(1));
+ }
+ if($perms['write']) {
+ $wiki_editor = true;
+ } else {
+ $wiki_editor = false;
+ }
+ } else {
+ $wiki_editor = true;
+ }
+ $wikiheader = urldecode($wikiUrlName) . ': ' . urldecode($pageUrlName); // show wiki name and page
+ $p = wiki_get_page_content(array('resource_id' => $resource_id, 'pageUrlName' => $pageUrlName));
+ if(!$p['success']) {
+ notice('Error retrieving page content' . EOL);
+ goaway('/'.argv(0).'/'.argv(1).'/'.$wikiUrlName);
+ }
+ $content = ($p['content'] !== '' ? $p['content'] : '"# New page\n"');
+ $hide_editor = false;
+ $showPageControls = $wiki_editor;
+ $showNewWikiButton = $wiki_owner;
+ $showNewPageButton = $wiki_editor;
+ $hidePageHistory = false;
+ $showCommitMsg = true;
+ $pageHistory = wiki_page_history(array('resource_id' => $resource_id, 'pageUrlName' => $pageUrlName));
+ break;
+ default: // Strip the extraneous URL components
+ goaway('/'.argv(0).'/'.argv(1).'/'.$wikiUrlName.'/'.$pageUrlName);
+ }
+ // Render the Markdown-formatted page content in HTML
+ require_once('library/markdown.php');
+
+ $o .= replace_macros(get_markup_template('wiki.tpl'),array(
+ '$wikiheader' => $wikiheader,
+ '$hideEditor' => $hide_editor,
+ '$showPageControls' => $showPageControls,
+ '$showNewWikiButton'=> $showNewWikiButton,
+ '$showNewPageButton'=> $showNewPageButton,
+ '$hidePageHistory' => $hidePageHistory,
+ '$showCommitMsg' => $showCommitMsg,
+ '$channel' => $channel['channel_address'],
+ '$resource_id' => $resource_id,
+ '$page' => $pageUrlName,
+ '$lockstate' => $x['lockstate'],
+ '$acl' => $x['acl'],
+ '$bang' => $x['bang'],
+ '$content' => $content,
+ '$renderedContent' => Markdown(json_decode($content)),
+ '$wikiName' => array('wikiName', t('Enter the name of your new wiki:'), '', ''),
+ '$pageName' => array('pageName', t('Enter the name of the new page:'), '', ''),
+ '$commitMsg' => array('commitMsg', '', '', '', '', 'placeholder="(optional) Enter a custom message when saving the page..."'),
+ '$pageHistory' => $pageHistory['history']
+ ));
+ head_add_js('library/ace/ace.js'); // Ace Code Editor
+ return $o;
+ }
+
+ function post() {
+ require_once('include/wiki.php');
+
+ // /wiki/channel/preview
+ // Render mardown-formatted text in HTML for preview
+ if((argc() > 2) && (argv(2) === 'preview')) {
+ $content = $_POST['content'];
+ require_once('library/markdown.php');
+ $html = purify_html(Markdown($content));
+ json_return_and_die(array('html' => $html, 'success' => true));
+ }
+
+ // Create a new wiki
+ // /wiki/channel/create/wiki
+ if ((argc() > 3) && (argv(2) === 'create') && (argv(3) === 'wiki')) {
+ $nick = argv(1);
+ $channel = get_channel_by_nick($nick);
+ // Determine if observer has permission to create wiki
+ $observer_hash = get_observer_hash();
+ // Only the channel owner can create a wiki, at least until we create a
+ // more detail permissions framework
+ if (local_channel() !== intval($channel['channel_id'])) {
+ goaway('/'.argv(0).'/'.$nick.'/');
+ }
+ $wiki = array();
+ // Generate new wiki info from input name
+ $wiki['rawName'] = $_POST['wikiName'];
+ $wiki['htmlName'] = escape_tags($_POST['wikiName']);
+ $wiki['urlName'] = urlencode($_POST['wikiName']);
+ if($wiki['urlName'] === '') {
+ notice('Error creating wiki. Invalid name.');
+ goaway('/wiki');
+ }
+ // Get ACL for permissions
+ $acl = new \Zotlabs\Access\AccessList($channel);
+ $acl->set_from_array($_POST);
+ $r = wiki_create_wiki($channel, $observer_hash, $wiki, $acl);
+ if ($r['success']) {
+ $homePage = wiki_create_page('Home', $r['item']['resource_id']);
+ if(!$homePage['success']) {
+ notice('Wiki created, but error creating Home page.');
+ goaway('/wiki/'.$nick.'/'.$wiki['urlName']);
+ }
+ goaway('/wiki/'.$nick.'/'.$wiki['urlName'].'/'.$homePage['page']['urlName']);
+ } else {
+ notice('Error creating wiki');
+ goaway('/wiki');
+ }
+ }
+
+ // Delete a wiki
+ if ((argc() > 3) && (argv(2) === 'delete') && (argv(3) === 'wiki')) {
+ $nick = argv(1);
+ $channel = get_channel_by_nick($nick);
+ // Only the channel owner can delete a wiki, at least until we create a
+ // more detail permissions framework
+ if (local_channel() !== intval($channel['channel_id'])) {
+ logger('Wiki delete permission denied.' . EOL);
+ json_return_and_die(array('message' => 'Wiki delete permission denied.', 'success' => false));
+ } else {
+ /*
+ $channel = get_channel_by_nick($nick);
+ $observer_hash = get_observer_hash();
+ // Figure out who the page owner is.
+ $perms = get_all_perms(intval($channel['channel_id']), $observer_hash);
+ // TODO: Create a new permission setting for wiki analogous to webpages. Until
+ // then, use webpage permissions
+ if (!$perms['write_pages']) {
+ logger('Wiki delete permission denied.' . EOL);
+ json_return_and_die(array('success' => false));
+ }
+ */
+ }
+ $resource_id = $_POST['resource_id'];
+ $deleted = wiki_delete_wiki($resource_id);
+ if ($deleted['success']) {
+ 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));
+ }
+ }
+
+ // Create a page
+ if ((argc() === 4) && (argv(2) === 'create') && (argv(3) === 'page')) {
+ $nick = argv(1);
+ $resource_id = $_POST['resource_id'];
+ // Determine if observer has permission to create a page
+ $channel = get_channel_by_nick($nick);
+ if (local_channel() !== intval($channel['channel_id'])) {
+ $observer_hash = get_observer_hash();
+ $perms = wiki_get_permissions($resource_id, intval($channel['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'])) === '') {
+ json_return_and_die(array('message' => 'Error creating page. Invalid name.', 'success' => false));
+ }
+ $page = wiki_create_page($name, $resource_id);
+ if ($page['success']) {
+ json_return_and_die(array('url' => '/'.argv(0).'/'.argv(1).'/'.$page['wiki']['urlName'].'/'.urlencode($page['page']['urlName']), 'success' => true));
+ } else {
+ logger('Error creating page');
+ json_return_and_die(array('message' => 'Error creating page.', 'success' => false));
+ }
+ }
+
+ // Fetch page list for a wiki
+ if ((argc() === 5) && (argv(2) === 'get') && (argv(3) === 'page') && (argv(4) === 'list')) {
+ $resource_id = $_POST['resource_id']; // resource_id for wiki in db
+ $channel = get_channel_by_nick(argv(1));
+ $observer_hash = get_observer_hash();
+ if (local_channel() !== intval($channel['channel_id'])) {
+ $perms = wiki_get_permissions($resource_id, intval($channel['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));
+ }
+ }
+ $page_list_html = widget_wiki_pages(array(
+ 'resource_id' => $resource_id,
+ 'refresh' => true,
+ 'channel' => argv(1)));
+ json_return_and_die(array('pages' => $page_list_html, 'message' => '', 'success' => true));
+ }
+
+ // Save a page
+ if ((argc() === 4) && (argv(2) === 'save') && (argv(3) === 'page')) {
+
+ $resource_id = $_POST['resource_id'];
+ $pageUrlName = $_POST['name'];
+ $pageHtmlName = escape_tags($_POST['name']);
+ $content = $_POST['content']; //Get new content
+ $commitMsg = $_POST['commitMsg'];
+ if ($commitMsg === '') {
+ $commitMsg = 'Updated ' . $pageHtmlName;
+ }
+ $nick = argv(1);
+ $channel = get_channel_by_nick($nick);
+ // Determine if observer has permission to save content
+ if (local_channel() !== intval($channel['channel_id'])) {
+ $observer_hash = get_observer_hash();
+ $perms = wiki_get_permissions($resource_id, intval($channel['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));
+ if($saved['success']) {
+ $ob = \App::get_observer();
+ $commit = wiki_git_commit(array(
+ 'commit_msg' => $commitMsg,
+ 'resource_id' => $resource_id,
+ 'observer' => $ob,
+ 'files' => array($pageUrlName.'.md')
+ ));
+ 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 {
+ json_return_and_die(array('message' => 'Error saving page', 'success' => false));
+ }
+ }
+
+ // Update page history
+ // /wiki/channel/history/page
+ if ((argc() === 4) && (argv(2) === 'history') && (argv(3) === 'page')) {
+
+ $resource_id = $_POST['resource_id'];
+ $pageUrlName = $_POST['name'];
+
+ $nick = argv(1);
+ $channel = get_channel_by_nick($nick);
+ // Determine if observer has permission to read content
+ if (local_channel() !== intval($channel['channel_id'])) {
+ $observer_hash = get_observer_hash();
+ $perms = wiki_get_permissions($resource_id, intval($channel['channel_id']), $observer_hash);
+ if(!$perms['read']) {
+ logger('Wiki read permission denied.' . EOL);
+ json_return_and_die(array('historyHTML' => '', 'message' => 'Permission denied.', 'success' => false));
+ }
+ }
+ $historyHTML = widget_wiki_page_history(array(
+ 'resource_id' => $resource_id,
+ 'pageUrlName' => $pageUrlName
+ ));
+ 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));
+ }
+ // Determine if observer has permission to delete pages
+ $nick = argv(1);
+ $channel = get_channel_by_nick($nick);
+ if (local_channel() !== intval($channel['channel_id'])) {
+ $observer_hash = get_observer_hash();
+ $perms = wiki_get_permissions($resource_id, intval($channel['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));
+ if($deleted['success']) {
+ $ob = \App::get_observer();
+ $commit = wiki_git_commit(array(
+ 'commit_msg' => 'Deleted ' . $pageHtmlName,
+ '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 {
+ 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
+ $nick = argv(1);
+ $channel = get_channel_by_nick($nick);
+ if (local_channel() !== intval($channel['channel_id'])) {
+ $observer_hash = get_observer_hash();
+ $perms = wiki_get_permissions($resource_id, intval($channel['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, 'observer' => \App::get_observer(), 'resource_id' => $resource_id, 'pageUrlName' => $pageUrlName));
+ if($reverted['success']) {
+ json_return_and_die(array('content' => $reverted['content'], 'message' => '', 'success' => true));
+ } else {
+ json_return_and_die(array('content' => '', 'message' => 'Error reverting page', 'success' => false));
+ }
+ }
+
+
+ //notice('You must be authenticated.');
+ json_return_and_die(array('message' => 'You must be authenticated.', 'success' => false));
+
+ }
+}
diff --git a/Zotlabs/Module/Zotfeed.php b/Zotlabs/Module/Zotfeed.php
index 28040149f..6b505c890 100644
--- a/Zotlabs/Module/Zotfeed.php
+++ b/Zotlabs/Module/Zotfeed.php
@@ -15,7 +15,7 @@ class Zotfeed extends \Zotlabs\Web\Controller {
if(! $mindate)
$mindate = datetime_convert('UTC','UTC', 'now - 14 days');
- if(get_config('system','block_public') && (! get_account_id()) && (! remote_channel())) {
+ if(observer_prohibited()) {
$result['message'] = 'Public access denied';
json_return_and_die($result);
}
@@ -45,8 +45,6 @@ class Zotfeed extends \Zotlabs\Web\Controller {
$result['messages'] = zot_feed($r[0]['channel_id'],$observer['xchan_hash'],array('mindate' => $mindate));
$result['success'] = true;
json_return_and_die($result);
-
-
}
}
diff --git a/Zotlabs/Render/Comanche.php b/Zotlabs/Render/Comanche.php
index 776874e35..1017ec6aa 100644
--- a/Zotlabs/Render/Comanche.php
+++ b/Zotlabs/Render/Comanche.php
@@ -8,7 +8,6 @@ require_once('include/widgets.php');
-
class Comanche {
@@ -95,7 +94,7 @@ class Comanche {
$cnt = preg_match_all("/\[region=(.*?)\](.*?)\[\/region\]/ism", $s, $matches, PREG_SET_ORDER);
if($cnt) {
foreach($matches as $mtch) {
- \App::$layout['region_' . $mtch[1]] = $this->region($mtch[2]);
+ \App::$layout['region_' . $mtch[1]] = $this->region($mtch[2],$mtch[1]);
}
}
}
@@ -320,7 +319,9 @@ class Comanche {
}
- function region($s) {
+ function region($s,$region_name) {
+
+ $s = str_replace('$region',$region_name,$s);
$matches = array();
diff --git a/Zotlabs/Render/SimpleTemplate.php b/Zotlabs/Render/SimpleTemplate.php
new file mode 100755
index 000000000..ff1bb5c3c
--- /dev/null
+++ b/Zotlabs/Render/SimpleTemplate.php
@@ -0,0 +1,310 @@
+<?php
+
+namespace Zotlabs\Render;
+
+define ("KEY_NOT_EXISTS", '^R_key_not_Exists^');
+
+class SimpleTemplate implements TemplateEngine {
+
+ static $name ="internal";
+
+ var $r;
+ var $search;
+ var $replace;
+ var $stack = array();
+ var $nodes = array();
+ var $done = false;
+ var $d = false;
+ var $lang = null;
+ var $debug=false;
+
+ private function _preg_error() {
+ switch(preg_last_error()) {
+ case PREG_INTERNAL_ERROR: echo('PREG_INTERNAL_ERROR'); break;
+ case PREG_BACKTRACK_LIMIT_ERROR: echo('PREG_BACKTRACK_LIMIT_ERROR'); break;
+ case PREG_RECURSION_LIMIT_ERROR: echo('PREG_RECURSION_LIMIT_ERROR'); break;
+ case PREG_BAD_UTF8_ERROR: echo('PREG_BAD_UTF8_ERROR'); break;
+// This is only valid for php > 5.3, not certain how to code around it for unit tests
+// case PREG_BAD_UTF8_OFFSET_ERROR: echo('PREG_BAD_UTF8_OFFSET_ERROR'); break;
+ default:
+ //die("Unknown preg error.");
+ return;
+ }
+ echo "<hr><pre>";
+ debug_print_backtrace();
+ die();
+ }
+
+ private function _push_stack() {
+ $this->stack[] = array($this->r, $this->nodes);
+ }
+
+ private function _pop_stack(){
+ list($this->r, $this->nodes) = array_pop($this->stack);
+ }
+
+ private function _get_var($name, $retNoKey=false) {
+ $keys = array_map('trim',explode(".",$name));
+ if ($retNoKey && !array_key_exists($keys[0], $this->r))
+ return KEY_NOT_EXISTS;
+
+ $val = $this->r;
+ foreach($keys as $k) {
+ $val = (isset($val[$k]) ? $val[$k] : null);
+ }
+
+ return template_escape($val);
+ }
+
+ /**
+ * IF node
+ * \code
+ * {{ if <$var> }}...[{{ else }} ...] {{ endif }}
+ * {{ if <$var>==<val|$var> }}...[{{ else }} ...]{{ endif }}
+ * {{ if <$var>!=<val|$var> }}...[{{ else }} ...]{{ endif }}
+ * \endcode
+ */
+ private function _replcb_if($args) {
+ if (strpos($args[2],"==")>0){
+ list($a,$b) = array_map("trim",explode("==",$args[2]));
+ $a = $this->_get_var($a);
+ if ($b[0]=="$") $b = $this->_get_var($b);
+ $val = ($a == $b);
+ } else if (strpos($args[2],"!=")>0){
+ list($a,$b) = array_map("trim", explode("!=",$args[2]));
+ $a = $this->_get_var($a);
+ if ($b[0]=="$") $b = $this->_get_var($b);
+ $val = ($a != $b);
+ } else {
+ $val = $this->_get_var($args[2]);
+ }
+ $x = preg_split("|{{ *else *}}|", $args[3]);
+
+ return ( ($val) ? $x[0] : (isset($x[1]) ? $x[1] : ""));
+ }
+
+ /**
+ * FOR node
+ * \code
+ * {{ for <$var> as $name }}...{{ endfor }}
+ * {{ for <$var> as $key=>$name }}...{{ endfor }}
+ * \endcode
+ */
+ private function _replcb_for($args) {
+ $m = array_map('trim', explode(" as ", $args[2]));
+ $x = explode("=>",$m[1]);
+ if (count($x) == 1) {
+ $varname = $x[0];
+ $keyname = "";
+ } else {
+ list($keyname, $varname) = $x;
+ }
+ if ($m[0]=="" || $varname=="" || is_null($varname)) die("template error: 'for ".$m[0]." as ".$varname."'") ;
+ //$vals = $this->r[$m[0]];
+ $vals = $this->_get_var($m[0]);
+ $ret="";
+ if (!is_array($vals)) return $ret;
+
+ foreach ($vals as $k=>$v){
+ $this->_push_stack();
+ $r = $this->r;
+ $r[$varname] = $v;
+ if ($keyname!='') $r[$keyname] = (($k === 0) ? '0' : $k);
+ $ret .= $this->replace($args[3], $r);
+ $this->_pop_stack();
+ }
+
+ return $ret;
+ }
+
+ /**
+ * INC node
+ * \code
+ * {{ inc <templatefile> [with $var1=$var2] }}{{ endinc }}
+ * \endcode
+ */
+ private function _replcb_inc($args) {
+ if (strpos($args[2],"with")) {
+ list($tplfile, $newctx) = array_map('trim', explode("with",$args[2]));
+ } else {
+ $tplfile = trim($args[2]);
+ $newctx = null;
+ }
+
+ if ($tplfile[0]=="$") $tplfile = $this->_get_var($tplfile);
+
+ $this->_push_stack();
+ $r = $this->r;
+ if (!is_null($newctx)) {
+ list($a,$b) = array_map('trim', explode("=",$newctx));
+ $r[$a] = $this->_get_var($b);
+ }
+ $this->nodes = Array();
+ $tpl = get_markup_template($tplfile);
+ $ret = $this->replace($tpl, $r);
+ $this->_pop_stack();
+
+ return $ret;
+ }
+
+ /**
+ * DEBUG node
+ * \code
+ * {{ debug $var [$var [$var [...]]] }}{{ enddebug }}
+ * \endcode
+ * replace node with <pre>var_dump($var, $var, ...);</pre>
+ */
+ private function _replcb_debug($args) {
+ $vars = array_map('trim', explode(" ",$args[2]));
+ $vars[] = $args[1];
+
+ $ret = "<pre>";
+ foreach ($vars as $var){
+ $ret .= htmlspecialchars(var_export( $this->_get_var($var), true ));
+ $ret .= "\n";
+ }
+ $ret .= "</pre>";
+
+ return $ret;
+ }
+
+ private function _replcb_node($m) {
+ $node = $this->nodes[$m[1]];
+ if (method_exists($this, "_replcb_".$node[1])){
+ $s = call_user_func(array($this, "_replcb_".$node[1]), $node);
+ } else {
+ $s = "";
+ }
+ $s = preg_replace_callback('/\|\|([0-9]+)\|\|/', array($this, "_replcb_node"), $s);
+
+ return $s;
+ }
+
+ private function _replcb($m) {
+ //var_dump(array_map('htmlspecialchars', $m));
+ $this->done = false;
+ $this->nodes[] = (array) $m;
+
+ return "||". (count($this->nodes)-1) ."||";
+ }
+
+ private function _build_nodes($s) {
+ $this->done = false;
+ while (!$this->done) {
+ $this->done=true;
+ $s = preg_replace_callback('|{{ *([a-z]*) *([^}]*)}}([^{]*({{ *else *}}[^{]*)?){{ *end\1 *}}|', array($this, "_replcb"), $s);
+ if ($s==Null) $this->_preg_error();
+ }
+ //({{ *else *}}[^{]*)?
+ krsort($this->nodes);
+
+ return $s;
+ }
+
+ private function var_replace($s) {
+ $m = array();
+ /** regexp:
+ * \$ literal $
+ * (\[)? optional open square bracket
+ * ([a-zA-Z0-9-_]+\.?)+ var name, followed by optional
+ * dot, repeated at least 1 time
+ * (?(1)\]) if there was opened square bracket
+ * (subgrup 1), match close bracket
+ */
+ if (preg_match_all('/\$(\[)?([a-zA-Z0-9-_]+\.?)+(?(1)\])/', $s,$m)) {
+ foreach ($m[0] as $var) {
+ $exp = str_replace(array("[", "]"), array("", ""), $var);
+ $exptks = explode("|", $exp);
+
+ $varn = $exptks[0];
+ unset($exptks[0]);
+ $val = $this->_get_var($varn, true);
+ if ($val != KEY_NOT_EXISTS) {
+ /* run filters */
+ /*
+ * Filter are in form of:
+ * filtername:arg:arg:arg
+ *
+ * "filtername" is function name
+ * "arg"s are optional, var value is appended to the end
+ * if one "arg"==='x' , is replaced with var value
+ *
+ * examples:
+ * $item.body|htmlspecialchars // escape html chars
+ * $item.body|htmlspecialchars|strtoupper // escape html and uppercase result
+ * $item.created|date:%Y %M %j // format date (created is a timestamp)
+ * $item.body|str_replace:cat:dog // replace all "cat" with "dog"
+ * $item.body|str_replace:cat:dog:x:1 // replace one "cat" with "dog"
+ */
+ foreach ($exptks as $filterstr) {
+ $filter = explode(":", $filterstr);
+ $filtername = $filter[0];
+ unset($filter[0]);
+ $valkey = array_search("x", $filter);
+ if ($valkey === false) {
+ $filter[] = $val;
+ } else {
+ $filter[$valkey] = $val;
+ }
+ if (function_exists($filtername)) {
+ $val = call_user_func_array($filtername, $filter);
+ }
+ }
+ $s = str_replace($var, $val, $s);
+ }
+ }
+ }
+
+ return $s;
+ }
+
+ private function replace($s, $r) {
+ $this->replace_macros($s, $r);
+ }
+
+ // TemplateEngine interface
+
+ public function replace_macros($s, $r) {
+ $this->r = $r;
+
+ $s = $this->_build_nodes($s);
+
+ $s = preg_replace_callback('/\|\|([0-9]+)\|\|/', array($this, "_replcb_node"), $s);
+ if ($s == Null)
+ $this->_preg_error();
+
+ // remove comments block
+ $s = preg_replace('/{#[^#]*#}/', "" , $s);
+
+ //$t2 = dba_timer();
+
+ // replace strings recursively (limit to 10 loops)
+ $os = "";
+ $count=0;
+ while (($os !== $s) && $count<10) {
+ $os=$s;
+ $count++;
+ $s = $this->var_replace($s);
+ }
+
+ return $s;
+ }
+
+ public function get_markup_template($file, $root='') {
+ $template_file = theme_include($file, $root);
+ if ($template_file) {
+ $content = file_get_contents($template_file);
+ }
+
+ return $content;
+ }
+}
+
+
+function template_escape($s) {
+ return str_replace(array('$','{{'),array('!_Doll^Ars1Az_!','!_DoubLe^BraceS4Rw_!'),$s);
+}
+
+function template_unescape($s) {
+ return str_replace(array('!_Doll^Ars1Az_!','!_DoubLe^BraceS4Rw_!'),array('$','{{'),$s);
+}
diff --git a/Zotlabs/Render/SmartyInterface.php b/Zotlabs/Render/SmartyInterface.php
new file mode 100755
index 000000000..0e3a47c2f
--- /dev/null
+++ b/Zotlabs/Render/SmartyInterface.php
@@ -0,0 +1,48 @@
+<?php /** @file */
+
+namespace Zotlabs\Render;
+
+require_once('library/Smarty/libs/Smarty.class.php');
+
+class SmartyInterface extends \Smarty {
+
+ public $filename;
+
+ function __construct() {
+ parent::__construct();
+
+ $theme = Theme::current();
+ $thname = $theme[0];
+
+ // setTemplateDir can be set to an array, which Smarty will parse in order.
+ // The order is thus very important here
+
+ $template_dirs = array('theme' => "view/theme/$thname/tpl/");
+ if( x(\App::$theme_info,"extends") )
+ $template_dirs = $template_dirs + array('extends' => "view/theme/" . \App::$theme_info["extends"] . "/tpl/");
+ $template_dirs = $template_dirs + array('base' => 'view/tpl/');
+ $this->setTemplateDir($template_dirs);
+
+ $basecompiledir = \App::$config['system']['smarty3_folder'];
+
+ $this->setCompileDir($basecompiledir.'/compiled/');
+ $this->setConfigDir($basecompiledir.'/config/');
+ $this->setCacheDir($basecompiledir.'/cache/');
+
+ $this->left_delimiter = \App::get_template_ldelim('smarty3');
+ $this->right_delimiter = \App::get_template_rdelim('smarty3');
+
+ // Don't report errors so verbosely
+ $this->error_reporting = E_ALL & (~E_NOTICE);
+ }
+
+ function parsed($template = '') {
+ if($template) {
+ return $this->fetch('string:' . $template);
+ }
+ return $this->fetch('file:' . $this->filename);
+ }
+}
+
+
+
diff --git a/Zotlabs/Render/SmartyTemplate.php b/Zotlabs/Render/SmartyTemplate.php
new file mode 100755
index 000000000..532d6e42f
--- /dev/null
+++ b/Zotlabs/Render/SmartyTemplate.php
@@ -0,0 +1,75 @@
+<?php /** @file */
+
+namespace Zotlabs\Render;
+
+class SmartyTemplate implements TemplateEngine {
+
+ static $name ="smarty3";
+
+ public function __construct(){
+
+ // Cannot use get_config() here because it is called during installation when there is no DB.
+ // FIXME: this may leak private information such as system pathnames.
+
+ $basecompiledir = ((array_key_exists('smarty3_folder',\App::$config['system']))
+ ? \App::$config['system']['smarty3_folder'] : '');
+ if (!$basecompiledir) $basecompiledir = str_replace('Zotlabs','',dirname(__dir__)) . "/" . TEMPLATE_BUILD_PATH;
+ if (!is_dir($basecompiledir)) {
+ echo "<b>ERROR:</b> folder <tt>$basecompiledir</tt> does not exist."; killme();
+ }
+ if(!is_writable($basecompiledir)){
+ echo "<b>ERROR:</b> folder <tt>$basecompiledir</tt> must be writable by webserver."; killme();
+ }
+ \App::$config['system']['smarty3_folder'] = $basecompiledir;
+ }
+
+ // TemplateEngine interface
+
+ public function replace_macros($s, $r) {
+ $template = '';
+ if(gettype($s) === 'string') {
+ $template = $s;
+ $s = new SmartyInterface();
+ }
+ foreach($r as $key=>$value) {
+ if($key[0] === '$') {
+ $key = substr($key, 1);
+ }
+ $s->assign($key, $value);
+ }
+ return $s->parsed($template);
+ }
+
+ public function get_markup_template($file, $root=''){
+ $template_file = theme_include($file, $root);
+ if($template_file) {
+ $template = new SmartyInterface();
+ $template->filename = $template_file;
+
+ return $template;
+ }
+ return "";
+ }
+
+ public function get_intltext_template($file, $root='') {
+
+ $lang = \App::$language;
+
+ if(file_exists("view/$lang/$file"))
+ $template_file = "view/$lang/$file";
+ elseif(file_exists("view/en/$file"))
+ $template_file = "view/en/$file";
+ else
+ $template_file = theme_include($file,$root);
+ if($template_file) {
+ $template = new SmartyInterface();
+ $template->filename = $template_file;
+
+ return $template;
+ }
+ return "";
+ }
+
+
+
+}
diff --git a/Zotlabs/Render/TemplateEngine.php b/Zotlabs/Render/TemplateEngine.php
new file mode 100755
index 000000000..600ff913e
--- /dev/null
+++ b/Zotlabs/Render/TemplateEngine.php
@@ -0,0 +1,12 @@
+<?php
+
+namespace Zotlabs\Render;
+
+/**
+ * @brief Interface for template engines.
+ */
+
+interface TemplateEngine {
+ public function replace_macros($s, $v);
+ public function get_markup_template($file, $root='');
+}
diff --git a/Zotlabs/Render/Theme.php b/Zotlabs/Render/Theme.php
new file mode 100644
index 000000000..a8b86f371
--- /dev/null
+++ b/Zotlabs/Render/Theme.php
@@ -0,0 +1,131 @@
+<?php
+
+namespace Zotlabs\Render;
+
+
+class Theme {
+
+ static $system_theme = null;
+ static $system_mobile_theme = null;
+
+ static $session_theme = null;
+ static $session_mobile_theme = null;
+
+ static $base_themes = array('redbasic');
+
+ static public function current(){
+
+ self::$system_theme = ((isset(\App::$config['system']['theme']))
+ ? \App::$config['system']['theme'] : '');
+ self::$session_theme = ((isset($_SESSION) && x($_SESSION,'theme'))
+ ? $_SESSION['theme'] : self::$system_theme);
+ self::$system_mobile_theme = ((isset(\App::$config['system']['mobile_theme']))
+ ? \App::$config['system']['mobile_theme'] : '');
+ self::$session_mobile_theme = ((isset($_SESSION) && x($_SESSION,'mobile_theme'))
+ ? $_SESSION['mobile_theme'] : self::$system_mobile_theme);
+
+ $page_theme = null;
+
+ // Find the theme that belongs to the channel whose stuff we are looking at
+
+ if(\App::$profile_uid) {
+ $r = q("select channel_theme from channel where channel_id = %d limit 1",
+ intval(\App::$profile_uid)
+ );
+ if($r) {
+ $page_theme = $r[0]['channel_theme'];
+ }
+ }
+
+ // Themes from Comanche layouts over-ride the channel theme
+
+ if(array_key_exists('theme', \App::$layout) && \App::$layout['theme'])
+ $page_theme = \App::$layout['theme'];
+
+ // If the viewer is on a mobile device, ensure that we're using a mobile
+ // theme of some kind or whatever the viewer's preference is for mobile
+ // viewing (if applicable)
+
+ if(\App::$is_mobile || \App::$is_tablet) {
+ if(isset($_SESSION['show_mobile']) && (! $_SESSION['show_mobile'])) {
+ $chosen_theme = self::$session_theme;
+ }
+ else {
+ $chosen_theme = self::$session_mobile_theme;
+
+ if($chosen_theme === '' || $chosen_theme === '---' ) {
+ // user has selected to have the mobile theme be the same as the normal one
+ $chosen_theme = self::$session_theme;
+ }
+ }
+ }
+ else {
+ $chosen_theme = self::$session_theme;
+
+ if($page_theme) {
+ $chosen_theme = $page_theme;
+ }
+ }
+
+ // Allow theme selection of the form 'theme_name:schema_name'
+
+ $themepair = explode(':', $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);
+ }
+
+ foreach(self::$base_themes as $t) {
+ if(file_exists('view/theme/' . $t . '/css/style.css') ||
+ file_exists('view/theme/' . $t . '/php/style.php')) {
+ return(array($t));
+ }
+ }
+
+ // Worst case scenario, the default base theme or themes don't exist; perhaps somebody renamed it/them.
+
+ // Find any theme at all and use it.
+
+ $fallback = array_merge(glob('view/theme/*/css/style.css'),glob('view/theme/*/php/style.php'));
+ if(count($fallback))
+ return(array(str_replace('view/theme/','', substr($fallback[0],0,-14))));
+
+
+ }
+
+
+ /**
+ * @brief Return full URL to theme which is currently in effect.
+ *
+ * Provide a sane default if nothing is chosen or the specified theme does not exist.
+ *
+ * @param bool $installing default false
+ *
+ * @return string
+ */
+
+ function url($installing = false) {
+
+ if($installing)
+ return self::$base_themes[0];
+
+ $theme = self::current();
+
+ $t = $theme[0];
+ $s = ((count($theme) > 1) ? $t[1] : '');
+
+ $opts = '';
+ $opts = ((\App::$profile_uid) ? '?f=&puid=' . \App::$profile_uid : '');
+
+ $schema_str = ((x(\App::$layout,'schema')) ? '&schema=' . App::$layout['schema'] : '');
+ if(($s) && (! $schema_str))
+ $schema_str = '&schema=' . $s;
+ $opts .= $schema_str;
+
+ if(file_exists('view/theme/' . $t . '/php/style.php'))
+ return('view/theme/' . $t . '/php/style.pcss' . $opts);
+
+ return('view/theme/' . $t . '/css/style.css');
+ }
+}
+
diff --git a/Zotlabs/Storage/BasicAuth.php b/Zotlabs/Storage/BasicAuth.php
index da5af7659..121a9c3a1 100644
--- a/Zotlabs/Storage/BasicAuth.php
+++ b/Zotlabs/Storage/BasicAuth.php
@@ -73,10 +73,12 @@ class BasicAuth extends DAV\Auth\Backend\AbstractBasic {
protected $timezone = '';
+ public $module_disabled = false;
+
+
/**
* @brief Validates a username and password.
*
- * Guest access is granted with the password "+++".
*
* @see \Sabre\DAV\Auth\Backend\AbstractBasic::validateUserPass
* @param string $username
@@ -92,7 +94,7 @@ class BasicAuth extends DAV\Auth\Backend\AbstractBasic {
intval($record['account_id']),
intval($record['account_default_channel'])
);
- if ($r) {
+ if($r && $this->check_module_access($r[0]['channel_id'])) {
return $this->setAuthenticated($r[0]);
}
}
@@ -109,13 +111,17 @@ class BasicAuth extends DAV\Auth\Backend\AbstractBasic {
if ((($record['account_flags'] == ACCOUNT_OK) || ($record['account_flags'] == ACCOUNT_UNVERIFIED))
&& (hash('whirlpool', $record['account_salt'] . $password) === $record['account_password'])) {
logger('password verified for ' . $username);
- return $this->setAuthenticated($r[0]);
+ if($this->check_module_access($r[0]['channel_id']))
+ return $this->setAuthenticated($r[0]);
}
}
}
}
- $error = 'password failed for ' . $username;
+ if($this->module_disabled)
+ $error = 'module not enabled for ' . $username;
+ else
+ $error = 'password failed for ' . $username;
logger($error);
log_failed_login($error);
@@ -139,6 +145,17 @@ class BasicAuth extends DAV\Auth\Backend\AbstractBasic {
return true;
}
+ protected function check_module_access($channel_id) {
+ if($channel_id && \App::$module === 'cdav') {
+ $x = get_pconfig($channel_id,'cdav','enabled');
+ if(! $x) {
+ $this->module_disabled = true;
+ return false;
+ }
+ }
+ return true;
+ }
+
/**
* Sets the channel_name from the currently logged-in channel.
*
diff --git a/Zotlabs/Storage/Browser.php b/Zotlabs/Storage/Browser.php
index ca262b739..f875cbf33 100644
--- a/Zotlabs/Storage/Browser.php
+++ b/Zotlabs/Storage/Browser.php
@@ -246,14 +246,17 @@ class Browser extends DAV\Browser\Plugin {
\App::$page['content'] = $html;
load_pdl($a);
- $theme_info_file = "view/theme/" . current_theme() . "/php/theme.php";
+ $current_theme = \Zotlabs\Render\Theme::current();
+
+ $theme_info_file = "view/theme/" . $current_theme[0] . "/php/theme.php";
if (file_exists($theme_info_file)){
require_once($theme_info_file);
- if (function_exists(str_replace('-', '_', current_theme()) . '_init')) {
- $func = str_replace('-', '_', current_theme()) . '_init';
+ if (function_exists(str_replace('-', '_', $current_theme[0]) . '_init')) {
+ $func = str_replace('-', '_', $current_theme[0]) . '_init';
$func($a);
}
}
+ $this->server->httpResponse->setHeader('Content-Security-Policy', "script-src 'self' 'unsafe-inline' 'unsafe-eval'; style-src 'self' 'unsafe-inline'");
construct_page($a);
}
diff --git a/Zotlabs/Storage/Directory.php b/Zotlabs/Storage/Directory.php
index 3c0cff6ef..06ae90a5f 100644
--- a/Zotlabs/Storage/Directory.php
+++ b/Zotlabs/Storage/Directory.php
@@ -194,7 +194,7 @@ class Directory extends DAV\Node implements DAV\ICollection, DAV\IQuota {
* @return null|string ETag
*/
public function createFile($name, $data = null) {
- logger($name, LOGGER_DEBUG);
+ logger('create file in directory ' . $name, LOGGER_DEBUG);
if (! $this->auth->owner_id) {
logger('permission denied ' . $name);
@@ -246,7 +246,7 @@ class Directory extends DAV\Node implements DAV\ICollection, DAV\IQuota {
$deny_gid = $c[0]['channel_deny_gid'];
}
- $r = q("INSERT INTO attach ( aid, uid, hash, creator, filename, folder, os_storage, filetype, filesize, revision, is_photo, data, created, edited, allow_cid, allow_gid, deny_cid, deny_gid )
+ $r = q("INSERT INTO attach ( aid, uid, hash, creator, filename, folder, os_storage, filetype, filesize, revision, is_photo, content, created, edited, allow_cid, allow_gid, deny_cid, deny_gid )
VALUES ( %d, %d, '%s', '%s', '%s', '%s', '%s', '%s', %d, %d, %d, '%s', '%s', '%s', '%s', '%s', '%s', '%s' ) ",
intval($c[0]['channel_account_id']),
intval($c[0]['channel_id']),
@@ -358,7 +358,7 @@ class Directory extends DAV\Node implements DAV\ICollection, DAV\IQuota {
* @return void
*/
public function createDirectory($name) {
- logger($name, LOGGER_DEBUG);
+ logger('create directory ' . $name, LOGGER_DEBUG);
if ((! $this->auth->owner_id) || (! perm_is_allowed($this->auth->owner_id, $this->auth->observer, 'write_storage'))) {
throw new DAV\Exception\Forbidden('Permission denied.');
@@ -372,7 +372,9 @@ class Directory extends DAV\Node implements DAV\ICollection, DAV\IQuota {
$result = attach_mkdir($r[0], $this->auth->observer, array('filename' => $name, 'folder' => $this->folder_hash));
if($result['success']) {
- $sync = attach_export_data($r[0],$ret['data']['hash']);
+ $sync = attach_export_data($r[0],$result['data']['hash']);
+ logger('createDirectory: attach_export_data returns $sync:' . print_r($sync, true), LOGGER_DEBUG);
+
if($sync) {
build_sync_packet($r[0]['channel_id'],array('file' => array($sync)));
}
@@ -563,4 +565,4 @@ class Directory extends DAV\Node implements DAV\ICollection, DAV\IQuota {
$free
);
}
-} \ No newline at end of file
+}
diff --git a/Zotlabs/Storage/File.php b/Zotlabs/Storage/File.php
index d40fee0ea..ecd15cc55 100644
--- a/Zotlabs/Storage/File.php
+++ b/Zotlabs/Storage/File.php
@@ -124,7 +124,7 @@ class File extends DAV\Node implements DAV\IFile {
);
if ($r) {
if (intval($r[0]['os_storage'])) {
- $d = q("select folder, data from attach where hash = '%s' and uid = %d limit 1",
+ $d = q("select folder, content from attach where hash = '%s' and uid = %d limit 1",
dbesc($this->data['hash']),
intval($c[0]['channel_id'])
);
@@ -139,7 +139,7 @@ class File extends DAV\Node implements DAV\IFile {
$direct = $f1[0];
}
}
- $fname = dbunescbin($d[0]['data']);
+ $fname = dbunescbin($d[0]['content']);
if(strpos($fname,'store') === false)
$f = 'store/' . $this->auth->owner_nick . '/' . $fname ;
else
@@ -158,12 +158,12 @@ class File extends DAV\Node implements DAV\IFile {
}
else {
// this shouldn't happen any more
- $r = q("UPDATE attach SET data = '%s' WHERE hash = '%s' AND uid = %d",
+ $r = q("UPDATE attach SET content = '%s' WHERE hash = '%s' AND uid = %d",
dbescbin(stream_get_contents($data)),
dbesc($this->data['hash']),
intval($this->data['uid'])
);
- $r = q("SELECT length(data) AS fsize FROM attach WHERE hash = '%s' AND uid = %d LIMIT 1",
+ $r = q("SELECT length(content) AS fsize FROM attach WHERE hash = '%s' AND uid = %d LIMIT 1",
dbesc($this->data['hash']),
intval($this->data['uid'])
);
@@ -236,7 +236,7 @@ class File extends DAV\Node implements DAV\IFile {
logger('get file ' . basename($this->name), LOGGER_DEBUG);
logger('os_path: ' . $this->os_path, LOGGER_DATA);
- $r = q("SELECT data, flags, os_storage, filename, filetype FROM attach WHERE hash = '%s' AND uid = %d LIMIT 1",
+ $r = q("SELECT content, flags, os_storage, filename, filetype FROM attach WHERE hash = '%s' AND uid = %d LIMIT 1",
dbesc($this->data['hash']),
intval($this->data['uid'])
);
@@ -250,14 +250,14 @@ class File extends DAV\Node implements DAV\IFile {
}
if (intval($r[0]['os_storage'])) {
- $x = dbunescbin($r[0]['data']);
+ $x = dbunescbin($r[0]['content']);
if(strpos($x,'store') === false)
$f = 'store/' . $this->auth->owner_nick . '/' . (($this->os_path) ? $this->os_path . '/' : '') . $x;
else
$f = $x;
return fopen($f, 'rb');
}
- return dbunescbin($r[0]['data']);
+ return dbunescbin($r[0]['content']);
}
}
diff --git a/Zotlabs/Storage/GitRepo.php b/Zotlabs/Storage/GitRepo.php
index 2a24e03c0..306abc0ba 100644
--- a/Zotlabs/Storage/GitRepo.php
+++ b/Zotlabs/Storage/GitRepo.php
@@ -75,6 +75,15 @@ class GitRepo {
}
}
}
+
+ public function initRepo() {
+ if(!$this->path) return false;
+ try {
+ return $this->git->init($this->path);
+ } catch (\PHPGit\Exception\GitException $ex) {
+ return false;
+ }
+ }
public function pull() {
try {
@@ -118,6 +127,15 @@ class GitRepo {
$repo['logs'] = $git->log(array('limit' => 50));
return $repo;
}
+
+ // Commit changes to the repo. Default is to stage all changes and commit everything.
+ public function commit($msg, $options = array()) {
+ try {
+ return $this->git->commit($msg, $options);
+ } catch (\PHPGit\Exception\GitException $ex) {
+ return false;
+ }
+ }
public static function isValidGitRepoURL($url) {
if (validate_url($url) && strrpos(parse_url($url, PHP_URL_PATH), '.')) {
diff --git a/Zotlabs/Web/Router.php b/Zotlabs/Web/Router.php
index e6733ffdb..f9290ac30 100644
--- a/Zotlabs/Web/Router.php
+++ b/Zotlabs/Web/Router.php
@@ -206,13 +206,15 @@ class Router {
* load current theme info
*/
- $theme_info_file = 'view/theme/' . current_theme() . '/php/theme.php';
+ $current_theme = \Zotlabs\Render\Theme::current();
+
+ $theme_info_file = 'view/theme/' . $current_theme[0] . '/php/theme.php';
if (file_exists($theme_info_file)){
require_once($theme_info_file);
}
- if(function_exists(str_replace('-', '_', current_theme()) . '_init')) {
- $func = str_replace('-', '_', current_theme()) . '_init';
+ if(function_exists(str_replace('-', '_', $current_theme[0]) . '_init')) {
+ $func = str_replace('-', '_', $current_theme[0]) . '_init';
$func($a);
}
elseif (x(\App::$theme_info, 'extends') && file_exists('view/theme/' . \App::$theme_info['extends'] . '/php/theme.php')) {
diff --git a/Zotlabs/Web/Session.php b/Zotlabs/Web/Session.php
index e18ad38fb..4f2a3f1f7 100644
--- a/Zotlabs/Web/Session.php
+++ b/Zotlabs/Web/Session.php
@@ -13,10 +13,10 @@ namespace Zotlabs\Web;
class Session {
- private static $handler = null;
- private static $session_started = false;
+ private $handler = null;
+ private $session_started = false;
- function init() {
+ public function init() {
$gc_probability = 50;
@@ -29,7 +29,8 @@ class Session {
*/
$handler = new \Zotlabs\Web\SessionHandler();
- self::$handler = $handler;
+
+ $this->handler = $handler;
$x = session_set_save_handler($handler,false);
if(! $x)
@@ -38,11 +39,17 @@ class Session {
// Force cookies to be secure (https only) if this site is SSL enabled.
// Must be done before session_start().
+
$arr = session_get_cookie_params();
+
+ // Note when setting cookies: set the domain to false which creates a single domain
+ // cookie. If you use a hostname it will create a .domain.com wildcard which will
+ // have some nasty side effects if you have any other subdomains running hubzilla.
+
session_set_cookie_params(
((isset($arr['lifetime'])) ? $arr['lifetime'] : 0),
((isset($arr['path'])) ? $arr['path'] : '/'),
- ((isset($arr['domain'])) ? $arr['domain'] : App::get_hostname()),
+ (($arr['domain']) ? $arr['domain'] : false),
((isset($_SERVER['HTTPS']) && strtolower($_SERVER['HTTPS']) == 'on') ? true : false),
((isset($arr['httponly'])) ? $arr['httponly'] : true)
);
@@ -51,9 +58,9 @@ class Session {
}
- function start() {
+ public function start() {
session_start();
- self::$session_started = true;
+ $this->session_started = true;
}
/**
@@ -62,8 +69,8 @@ class Session {
* @return void
*/
- function nuke() {
- self::new_cookie(0); // 0 means delete on browser exit
+ public function nuke() {
+ $this->new_cookie(0); // 0 means delete on browser exit
if($_SESSION && count($_SESSION)) {
foreach($_SESSION as $k => $v) {
unset($_SESSION[$k]);
@@ -71,48 +78,53 @@ class Session {
}
}
- function new_cookie($xtime) {
+ public function new_cookie($xtime) {
$newxtime = (($xtime> 0) ? (time() + $xtime) : 0);
$old_sid = session_id();
- if(self::$handler && self::$session_started) {
+ $arr = session_get_cookie_params();
+
+ if($this->handler && $this->session_started) {
+
session_regenerate_id(true);
// force SessionHandler record creation with the new session_id
// which occurs as a side effect of read()
- self::$handler->read(session_id());
+ $this->handler->read(session_id());
}
else
logger('no session handler');
if (x($_COOKIE, 'jsdisabled')) {
- setcookie('jsdisabled', $_COOKIE['jsdisabled'], $newxtime);
+ setcookie('jsdisabled', $_COOKIE['jsdisabled'], $newxtime, '/', false,((isset($_SERVER['HTTPS']) && strtolower($_SERVER['HTTPS']) == 'on') ? true : false),((isset($arr['httponly'])) ? $arr['httponly'] : true));
}
- setcookie(session_name(),session_id(),$newxtime);
+ setcookie(session_name(),session_id(),$newxtime, '/', false,((isset($_SERVER['HTTPS']) && strtolower($_SERVER['HTTPS']) == 'on') ? true : false),((isset($arr['httponly'])) ? $arr['httponly'] : true));
$arr = array('expire' => $xtime);
call_hooks('new_cookie', $arr);
}
- function extend_cookie() {
+ public function extend_cookie() {
+
+ $arr = session_get_cookie_params();
// if there's a long-term cookie, extend it
$xtime = (($_SESSION['remember_me']) ? (60 * 60 * 24 * 365) : 0 );
if($xtime)
- setcookie(session_name(),session_id(),(time() + $xtime));
+ setcookie(session_name(),session_id(),(time() + $xtime), '/', false,((isset($_SERVER['HTTPS']) && strtolower($_SERVER['HTTPS']) == 'on') ? true : false),((isset($arr['httponly'])) ? $arr['httponly'] : true));
$arr = array('expire' => $xtime);
call_hooks('extend_cookie', $arr);
}
- function return_check() {
+ public function return_check() {
// check a returning visitor against IP changes.
// If the change results in being blocked from re-entry with the current cookie
@@ -152,7 +164,7 @@ class Session {
// check any difference at all
logger('Session address changed. Paranoid setting in effect, blocking session. '
. $_SESSION['addr'] . ' != ' . $_SERVER['REMOTE_ADDR']);
- self::nuke();
+ $this->nuke();
goaway(z_root());
break;
}
diff --git a/Zotlabs/Web/SessionHandler.php b/Zotlabs/Web/SessionHandler.php
index 6980a6408..6e7333b4b 100644
--- a/Zotlabs/Web/SessionHandler.php
+++ b/Zotlabs/Web/SessionHandler.php
@@ -18,10 +18,10 @@ class SessionHandler implements \SessionHandlerInterface {
function read ($id) {
if($id) {
- $r = q("SELECT `data` FROM `session` WHERE `sid`= '%s'", dbesc($id));
+ $r = q("SELECT `sess_data` FROM `session` WHERE `sid`= '%s'", dbesc($id));
if($r) {
- return $r[0]['data'];
+ return $r[0]['sess_data'];
}
else {
q("INSERT INTO `session` (sid, expire) values ('%s', '%s')",
@@ -59,7 +59,7 @@ class SessionHandler implements \SessionHandlerInterface {
}
q("UPDATE `session`
- SET `data` = '%s', `expire` = '%s' WHERE `sid` = '%s'",
+ SET `sess_data` = '%s', `expire` = '%s' WHERE `sid` = '%s'",
dbesc($data),
dbesc($expire),
dbesc($id)
diff --git a/Zotlabs/Web/WebServer.php b/Zotlabs/Web/WebServer.php
new file mode 100644
index 000000000..88ab4995b
--- /dev/null
+++ b/Zotlabs/Web/WebServer.php
@@ -0,0 +1,130 @@
+<?php /** @file */
+
+namespace Zotlabs\Web;
+
+class WebServer {
+
+ public function run() {
+
+
+ /*
+ * Bootstrap the application, load configuration, load modules, load theme, etc.
+ */
+
+ require_once('boot.php');
+
+ sys_boot();
+
+
+ \App::$language = get_best_language();
+ load_translation_table(\App::$language,\App::$install);
+
+
+ /**
+ *
+ * Important stuff we always need to do.
+ *
+ * The order of these may be important so use caution if you think they're all
+ * intertwingled with no logical order and decide to sort it out. Some of the
+ * dependencies have changed, but at least at one time in the recent past - the
+ * order was critical to everything working properly
+ *
+ */
+
+ if(\App::$session) {
+ \App::$session->start();
+ }
+ else {
+ session_start();
+ register_shutdown_function('session_write_close');
+ }
+
+ /**
+ * Language was set earlier, but we can over-ride it in the session.
+ * We have to do it here because the session was just now opened.
+ */
+
+ if(array_key_exists('system_language',$_POST)) {
+ if(strlen($_POST['system_language']))
+ $_SESSION['language'] = $_POST['system_language'];
+ else
+ unset($_SESSION['language']);
+ }
+ if((x($_SESSION, 'language')) && ($_SESSION['language'] !== $lang)) {
+ \App::$language = $_SESSION['language'];
+ load_translation_table(\App::$language);
+ }
+
+ if((x($_GET,'zid')) && (! \App::$install)) {
+ \App::$query_string = strip_zids(\App::$query_string);
+ if(! local_channel()) {
+ $_SESSION['my_address'] = $_GET['zid'];
+ zid_init($a);
+ }
+ }
+
+ if((x($_SESSION, 'authenticated')) || (x($_POST, 'auth-params')) || (\App::$module === 'login'))
+ require('include/auth.php');
+
+ if(! x($_SESSION, 'sysmsg'))
+ $_SESSION['sysmsg'] = array();
+
+ if(! x($_SESSION, 'sysmsg_info'))
+ $_SESSION['sysmsg_info'] = array();
+
+ /*
+ * check_config() is responsible for running update scripts. These automatically
+ * update the DB schema whenever we push a new one out. It also checks to see if
+ * any plugins have been added or removed and reacts accordingly.
+ */
+
+
+ if(\App::$install) {
+ /* Allow an exception for the view module so that pcss will be interpreted during installation */
+ if(\App::$module != 'view')
+ \App::$module = 'setup';
+ }
+ else
+ check_config($a);
+
+ nav_set_selected('nothing');
+
+ $Router = new Router($a);
+
+ /* initialise content region */
+
+ if(! x(\App::$page, 'content'))
+ \App::$page['content'] = '';
+
+ call_hooks('page_content_top', \App::$page['content']);
+
+
+ $Router->Dispatch($a);
+
+
+ // If you're just visiting, let javascript take you home
+
+ if(x($_SESSION, 'visitor_home')) {
+ $homebase = $_SESSION['visitor_home'];
+ } elseif(local_channel()) {
+ $homebase = z_root() . '/channel/' . \App::$channel['channel_address'];
+ }
+
+ if(isset($homebase)) {
+ \App::$page['content'] .= '<script>var homebase = "' . $homebase . '";</script>';
+ }
+
+ // now that we've been through the module content, see if the page reported
+ // a permission problem and if so, a 403 response would seem to be in order.
+
+ if(stristr(implode("", $_SESSION['sysmsg']), t('Permission denied'))) {
+ header($_SERVER['SERVER_PROTOCOL'] . ' 403 ' . t('Permission denied.'));
+ }
+
+ call_hooks('page_end', \App::$page['content']);
+
+ construct_page($a);
+
+ killme();
+ }
+} \ No newline at end of file
diff --git a/Zotlabs/Zot/Auth.php b/Zotlabs/Zot/Auth.php
index f764172fa..0837be21a 100644
--- a/Zotlabs/Zot/Auth.php
+++ b/Zotlabs/Zot/Auth.php
@@ -80,11 +80,9 @@ class Auth {
if(! $x) {
// finger them if they can't be found.
- $ret = zot_finger($address, null);
- if ($ret['success']) {
- $j = json_decode($ret['body'], true);
- if($j)
- import_xchan($j);
+ $j = Finger::run($address, null);
+ if ($j['success']) {
+ import_xchan($j);
$x = q("select * from hubloc left join xchan on xchan_hash = hubloc_hash
where hubloc_addr = '%s' order by hubloc_id desc",
dbesc($address)
diff --git a/Zotlabs/Zot/Finger.php b/Zotlabs/Zot/Finger.php
new file mode 100644
index 000000000..229fda8bd
--- /dev/null
+++ b/Zotlabs/Zot/Finger.php
@@ -0,0 +1,130 @@
+<?php
+
+namespace Zotlabs\Zot;
+
+
+class Finger {
+
+ static private $token;
+
+ /**
+ * @brief Look up information about channel.
+ *
+ * @param string $webbie
+ * does not have to be host qualified e.g. 'foo' is treated as 'foo\@thishub'
+ * @param array $channel
+ * (optional), if supplied permissions will be enumerated specifically for $channel
+ * @param boolean $autofallback
+ * fallback/failover to http if https connection cannot be established. Default is true.
+ *
+ * @return zotinfo array (with 'success' => true) or array('success' => false);
+ */
+
+ static public function run($webbie, $channel = null, $autofallback = true) {
+
+ $ret = array('success' => false);
+
+ self::$token = random_string();
+
+ if (strpos($webbie,'@') === false) {
+ $address = $webbie;
+ $host = App::get_hostname();
+ } else {
+ $address = substr($webbie,0,strpos($webbie,'@'));
+ $host = substr($webbie,strpos($webbie,'@')+1);
+ }
+
+ $xchan_addr = $address . '@' . $host;
+
+ if ((! $address) || (! $xchan_addr)) {
+ logger('zot_finger: no address :' . $webbie);
+ return $ret;
+ }
+
+ logger('using xchan_addr: ' . $xchan_addr, LOGGER_DATA, LOG_DEBUG);
+
+ // potential issue here; the xchan_addr points to the primary hub.
+ // The webbie we were called with may not, so it might not be found
+ // unless we query for hubloc_addr instead of xchan_addr
+
+ $r = q("select xchan.*, hubloc.* from xchan
+ left join hubloc on xchan_hash = hubloc_hash
+ where xchan_addr = '%s' and hubloc_primary = 1 limit 1",
+ dbesc($xchan_addr)
+ );
+
+ if ($r) {
+ $url = $r[0]['hubloc_url'];
+
+ if ($r[0]['hubloc_network'] && $r[0]['hubloc_network'] !== 'zot') {
+ logger('zot_finger: alternate network: ' . $webbie);
+ logger('url: '.$url.', net: '.var_export($r[0]['hubloc_network'],true), LOGGER_DATA, LOG_DEBUG);
+ return $ret;
+ }
+ }
+ else {
+ $url = 'https://' . $host;
+ }
+
+ $rhs = '/.well-known/zot-info';
+ $https = ((strpos($url,'https://') === 0) ? true : false);
+
+ logger('zot_finger: ' . $address . ' at ' . $url, LOGGER_DEBUG);
+
+ if ($channel) {
+ $postvars = array(
+ 'address' => $address,
+ 'target' => $channel['channel_guid'],
+ 'target_sig' => $channel['channel_guid_sig'],
+ 'key' => $channel['channel_pubkey'],
+ 'token' => self::$token
+ );
+
+ $result = z_post_url($url . $rhs,$postvars);
+
+ if ((! $result['success']) && ($autofallback)) {
+ if ($https) {
+ logger('zot_finger: https failed. falling back to http');
+ $result = z_post_url('http://' . $host . $rhs,$postvars);
+ }
+ }
+ }
+ else {
+ $rhs .= '?f=&address=' . urlencode($address) . '&token=' . self::$token;
+
+ $result = z_fetch_url($url . $rhs);
+ if ((! $result['success']) && ($autofallback)) {
+ if ($https) {
+ logger('zot_finger: https failed. falling back to http');
+ $result = z_fetch_url('http://' . $host . $rhs);
+ }
+ }
+ }
+
+ if(! $result['success']) {
+ logger('zot_finger: no results');
+ return $ret;
+ }
+
+ $x = json_decode($result['body'],true);
+ if($x) {
+ $signed_token = ((is_array($x) && array_key_exists('signed_token',$x)) ? $x['signed_token'] : null);
+ if($signed_token) {
+ $valid = rsa_verify('token.' . self::$token,base64url_decode($signed_token),$x['key']);
+ if(! $valid) {
+ logger('invalid signed token: ' . $url . $rhs, LOGGER_NORMAL, LOG_ERR);
+ return $ret;
+ }
+ }
+ else {
+ logger('No signed token from ' . $url . $rhs, LOGGER_NORMAL, LOG_WARNING);
+ // after 2017-01-01 this will be a hard error unless you over-ride it.
+ if((time() > 1483228800) && (! get_config('system','allow_unsigned_zotfinger')))
+ return $ret;
+ }
+ }
+
+ return $x;
+ }
+
+} \ No newline at end of file
diff --git a/Zotlabs/Zot/Verify.php b/Zotlabs/Zot/Verify.php
index 1192202db..06bd3188c 100644
--- a/Zotlabs/Zot/Verify.php
+++ b/Zotlabs/Zot/Verify.php
@@ -6,7 +6,7 @@ namespace Zotlabs\Zot;
class Verify {
function create($type,$channel_id,$token,$meta) {
- return q("insert into verify ( type, channel, token, meta, created ) values ( '%s', %d, '%s', '%s', '%s' )",
+ return q("insert into verify ( vtype, channel, token, meta, created ) values ( '%s', %d, '%s', '%s', '%s' )",
dbesc($type),
intval($channel_id),
dbesc($token),
@@ -16,7 +16,7 @@ class Verify {
}
function match($type,$channel_id,$token,$meta) {
- $r = q("select id from verify where type = '%s' and channel = %d and token = '%s' and meta = '%s' limit 1",
+ $r = q("select id from verify where vtype = '%s' and channel = %d and token = '%s' and meta = '%s' limit 1",
dbesc($type),
intval($channel_id),
dbesc($token),
@@ -32,7 +32,7 @@ class Verify {
}
function purge($type,$interval) {
- q("delete from verify where type = '%s' and created < %s - INTERVAL %s",
+ q("delete from verify where vtype = '%s' and created < %s - INTERVAL %s",
dbesc($type),
db_utcnow(),
db_quoteinterval($interval)