aboutsummaryrefslogtreecommitdiffstats
path: root/Zotlabs
diff options
context:
space:
mode:
Diffstat (limited to 'Zotlabs')
-rw-r--r--Zotlabs/Daemon/Cron.php10
-rw-r--r--Zotlabs/Daemon/Cron_daily.php1
-rw-r--r--Zotlabs/Daemon/Queue.php2
-rw-r--r--Zotlabs/Lib/Activity.php183
-rw-r--r--Zotlabs/Lib/Apps.php42
-rw-r--r--Zotlabs/Lib/Connect.php6
-rw-r--r--Zotlabs/Lib/Enotify.php8
-rw-r--r--Zotlabs/Lib/Libsync.php5
-rw-r--r--Zotlabs/Lib/Libzot.php7
-rw-r--r--Zotlabs/Lib/NativeWiki.php35
-rw-r--r--Zotlabs/Lib/NativeWikiPage.php29
-rw-r--r--Zotlabs/Lib/Queue.php4
-rw-r--r--Zotlabs/Lib/ThreadItem.php2
-rw-r--r--Zotlabs/Module/Admin.php9
-rw-r--r--Zotlabs/Module/Admin/Accounts.php234
-rw-r--r--Zotlabs/Module/Admin/Channels.php2
-rw-r--r--Zotlabs/Module/Admin/Site.php398
-rw-r--r--Zotlabs/Module/Bookmarks.php6
-rw-r--r--Zotlabs/Module/Cal.php68
-rw-r--r--Zotlabs/Module/Cdav.php45
-rw-r--r--Zotlabs/Module/Channel.php19
-rw-r--r--Zotlabs/Module/Channel_calendar.php2
-rw-r--r--Zotlabs/Module/Cloud.php3
-rw-r--r--Zotlabs/Module/Connect.php58
-rw-r--r--Zotlabs/Module/Directory.php2
-rw-r--r--Zotlabs/Module/Display.php57
-rw-r--r--Zotlabs/Module/Follow.php24
-rw-r--r--Zotlabs/Module/Hq.php34
-rw-r--r--Zotlabs/Module/Invite.php629
-rw-r--r--Zotlabs/Module/Item.php2
-rw-r--r--Zotlabs/Module/Network.php20
-rw-r--r--Zotlabs/Module/New_channel.php76
-rw-r--r--Zotlabs/Module/Oep.php262
-rw-r--r--Zotlabs/Module/Photo.php2
-rw-r--r--Zotlabs/Module/Regate.php447
-rw-r--r--Zotlabs/Module/Register.php606
-rw-r--r--Zotlabs/Module/Search.php4
-rw-r--r--Zotlabs/Module/Settings/Account.php34
-rw-r--r--Zotlabs/Module/Sse.php1
-rw-r--r--Zotlabs/Module/Sse_bs.php37
-rw-r--r--Zotlabs/Module/Suggest.php34
-rw-r--r--Zotlabs/Module/Wiki.php85
-rw-r--r--Zotlabs/Render/Comanche.php7
-rw-r--r--Zotlabs/Render/SmartyTemplate.php16
-rw-r--r--Zotlabs/Storage/BasicAuth.php12
-rw-r--r--Zotlabs/Update/_1244.php15
-rw-r--r--Zotlabs/Update/_1245.php29
-rw-r--r--Zotlabs/Web/HTTPSig.php2
-rw-r--r--Zotlabs/Web/Session.php36
-rw-r--r--Zotlabs/Web/SessionRedis.php123
-rw-r--r--Zotlabs/Widget/Activity_filter.php22
-rw-r--r--Zotlabs/Widget/Cover_photo.php2
-rw-r--r--Zotlabs/Widget/Notifications.php6
-rw-r--r--Zotlabs/Widget/Pinned.php28
54 files changed, 2862 insertions, 970 deletions
diff --git a/Zotlabs/Daemon/Cron.php b/Zotlabs/Daemon/Cron.php
index 4732dfa75..335ff9751 100644
--- a/Zotlabs/Daemon/Cron.php
+++ b/Zotlabs/Daemon/Cron.php
@@ -55,11 +55,13 @@ class Cron {
db_utcnow()
);
+ remove_expired_registrations();
+
$interval = get_config('system', 'delivery_interval', 3);
// expire any expired items
- $r = q("select id,item_wall from item where expires > '2001-01-01 00:00:00' and expires < %s
+ $r = q("select id,item_wall from item where expires > '2001-01-01 00:00:00' and expires < %s
and item_deleted = 0 ",
db_utcnow()
);
@@ -131,7 +133,7 @@ class Cron {
// 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.
+ // 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(),
@@ -192,7 +194,7 @@ class Cron {
// 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 = ''
+ $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')
@@ -238,7 +240,7 @@ class Cron {
set_config('system', 'lastcron', datetime_convert());
- //All done - clear the lockfile
+ //All done - clear the lockfile
@unlink($lockfile);
return;
diff --git a/Zotlabs/Daemon/Cron_daily.php b/Zotlabs/Daemon/Cron_daily.php
index 1983c68e6..bebccca9d 100644
--- a/Zotlabs/Daemon/Cron_daily.php
+++ b/Zotlabs/Daemon/Cron_daily.php
@@ -93,6 +93,7 @@ class Cron_daily {
Master::Summon(array('Cli_suggest'));
remove_obsolete_hublocs();
+ remove_duplicate_singleton_hublocs();
z6_discover();
diff --git a/Zotlabs/Daemon/Queue.php b/Zotlabs/Daemon/Queue.php
index 36bdcfe81..e1f4b73de 100644
--- a/Zotlabs/Daemon/Queue.php
+++ b/Zotlabs/Daemon/Queue.php
@@ -28,7 +28,7 @@ class Queue {
if ($r) {
foreach ($r as $rr) {
$h = parse_url($rr['outq_posturl']);
- $desturl = $h['scheme'] . '://' . $h['host'] . (($h['port']) ? ':' . $h['port'] : '');
+ $desturl = $h['scheme'] . '://' . $h['host'] . (isset($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')
diff --git a/Zotlabs/Lib/Activity.php b/Zotlabs/Lib/Activity.php
index 24fe5e5c0..6e8344def 100644
--- a/Zotlabs/Lib/Activity.php
+++ b/Zotlabs/Lib/Activity.php
@@ -104,7 +104,10 @@ class Activity {
if ($x['success']) {
$m = parse_url($url);
if ($m) {
- $site_url = unparse_url(['scheme' => $m['scheme'], 'host' => $m['host'], 'port' => $m['port'] ]);
+ $y = [ 'scheme' => $m['scheme'], 'host' => $m['host'] ];
+ if (array_key_exists('port', $m))
+ $y['port'] = $m['port'];
+ $site_url = unparse_url($y);
q("UPDATE site SET site_update = '%s', site_dead = 0 WHERE site_url = '%s' AND site_update < %s - INTERVAL %s",
dbesc(datetime_convert()),
dbesc($site_url),
@@ -129,8 +132,8 @@ class Activity {
}
static function fetch_profile($x) {
- $r = q("select * from xchan where xchan_url like '%s' limit 1",
- dbesc($x['id'] . '/%')
+ $r = q("select * from xchan where xchan_url = '%s' limit 1",
+ dbesc($x['id'])
);
if (!$r) {
$r = q("select * from xchan where xchan_hash = '%s' limit 1",
@@ -572,7 +575,7 @@ class Activity {
$ret = [];
- if ($item['tag'] && is_array($item['tag'])) {
+ if (array_key_exists('tag', $item) && is_array($item['tag'])) {
$ptr = $item['tag'];
if (!array_key_exists(0, $ptr)) {
$ptr = [$ptr];
@@ -581,23 +584,25 @@ class Activity {
if (!array_key_exists('type', $t))
$t['type'] = 'Hashtag';
- switch ($t['type']) {
- case 'Hashtag':
- $ret[] = ['ttype' => TERM_HASHTAG, 'url' => $t['href'], 'term' => escape_tags((substr($t['name'], 0, 1) === '#') ? substr($t['name'], 1) : $t['name'])];
- break;
+ if (array_key_exists('href', $t) && array_key_exists('name', $t)) {
+ switch ($t['type']) {
+ case 'Hashtag':
+ $ret[] = ['ttype' => TERM_HASHTAG, 'url' => $t['href'], 'term' => escape_tags((substr($t['name'], 0, 1) === '#') ? substr($t['name'], 1) : $t['name'])];
+ break;
- case 'Mention':
- $mention_type = substr($t['name'], 0, 1);
- if ($mention_type === '!') {
- $ret[] = ['ttype' => TERM_FORUM, 'url' => $t['href'], 'term' => escape_tags(substr($t['name'], 1))];
- }
- else {
- $ret[] = ['ttype' => TERM_MENTION, 'url' => $t['href'], 'term' => escape_tags((substr($t['name'], 0, 1) === '@') ? substr($t['name'], 1) : $t['name'])];
- }
- break;
+ case 'Mention':
+ $mention_type = substr($t['name'], 0, 1);
+ if ($mention_type === '!') {
+ $ret[] = ['ttype' => TERM_FORUM, 'url' => $t['href'], 'term' => escape_tags(substr($t['name'], 1))];
+ }
+ else {
+ $ret[] = ['ttype' => TERM_MENTION, 'url' => $t['href'], 'term' => escape_tags((substr($t['name'], 0, 1) === '@') ? substr($t['name'], 1) : $t['name'])];
+ }
+ break;
- default:
- break;
+ default:
+ break;
+ }
}
}
}
@@ -609,7 +614,7 @@ class Activity {
$ret = [];
- if ($item['term']) {
+ if (array_key_exists('term', $item) && is_array($item['term'])) {
foreach ($item['term'] as $t) {
switch ($t['ttype']) {
case TERM_HASHTAG:
@@ -640,7 +645,7 @@ class Activity {
$ret = [];
- if ($item['attach']) {
+ if (array_key_exists('attach', $item)) {
$atts = ((is_array($item['attach'])) ? $item['attach'] : json_decode($item['attach'], true));
if ($atts) {
foreach ($atts as $att) {
@@ -653,7 +658,7 @@ class Activity {
}
}
}
- if ($item['iconfig']) {
+ if (array_key_exists('iconfig', $item) && is_array($item['iconfig'])) {
foreach ($item['iconfig'] as $att) {
if ($att['sharing']) {
$value = ((is_string($att['v']) && preg_match('|^a:[0-9]+:{.*}$|s', $att['v'])) ? unserialize($att['v']) : $att['v']);
@@ -697,16 +702,16 @@ class Activity {
$ret = [];
- if ($item['attachment']) {
+ if (array_key_exists('attachment', $item) && is_array($item['attachment'])) {
foreach ($item['attachment'] as $att) {
$entry = [];
- if ($att['href'])
+ if (array_key_exists('href', $att))
$entry['href'] = $att['href'];
- elseif ($att['url'])
+ elseif (array_key_exists('url', $att))
$entry['href'] = $att['url'];
- if ($att['mediaType'])
+ if (array_key_exists('mediaType', $att))
$entry['type'] = $att['mediaType'];
- elseif ($att['type'] === 'Image')
+ elseif (array_key_exists('type', $att) && $att['type'] === 'Image')
$entry['type'] = 'image/jpeg';
if ($entry)
$ret[] = $entry;
@@ -978,19 +983,17 @@ class Activity {
// Returns an array of URLS for any mention tags found in the item array $i.
static function map_mentions($i) {
- if (!$i['term']) {
- return [];
- }
-
$list = [];
- foreach ($i['term'] as $t) {
- if (!$t['url']) {
- continue;
- }
- if ($t['ttype'] == TERM_MENTION) {
- $url = self::lookup_term_url($t['url']);
- $list[] = (($url) ? $url : $t['url']);
+ if (array_key_exists('term', $i) && is_array($i['term'])) {
+ foreach ($i['term'] as $t) {
+ if (!$t['url']) {
+ continue;
+ }
+ if ($t['ttype'] == TERM_MENTION) {
+ $url = self::lookup_term_url($t['url']);
+ $list[] = (($url) ? $url : $t['url']);
+ }
}
}
@@ -1091,18 +1094,7 @@ class Activity {
'height' => 300,
'width' => 300,
];
- $ret['url'] = [
- [
- 'type' => 'Link',
- 'mediaType' => 'text/html',
- 'href' => $p['xchan_url']
- ],
- [
- 'type' => 'Link',
- 'mediaType' => 'text/x-zot+json',
- 'href' => $p['xchan_url']
- ]
- ];
+ $ret['url'] = $p['xchan_url'];
$ret['publicKey'] = [
'id' => $p['xchan_url'],
@@ -1331,12 +1323,12 @@ class Activity {
*
*/
- $person_obj = $act->actor;
-
- if ($act->type === 'Follow') {
+ if (in_array($act->type, [ 'Follow', 'Invite', 'Join'])) {
$their_follow_id = $act->id;
}
+ $person_obj = (($act->type == 'Invite') ? $act->obj : $act->actor);
+
if (is_array($person_obj)) {
// store their xchan and hubloc
@@ -1354,9 +1346,8 @@ class Activity {
}
}
- $x = PermissionRoles::role_perms('social');
- $p = Permissions::FilledPerms($x['perms_connect']);
- $their_perms = Permissions::serialise($p);
+ $x = \Zotlabs\Access\PermissionRoles::role_perms('social');
+ $their_perms = \Zotlabs\Access\Permissions::FilledPerms($x['perms_connect']);
if ($contact && $contact['abook_id']) {
@@ -1365,18 +1356,18 @@ class Activity {
switch ($act->type) {
case 'Follow':
+ case 'Invite':
+ case 'Join':
// A second Follow request, but we haven't approved the first one
-
if ($contact['abook_pending']) {
return;
}
// We've already approved them or followed them first
// Send an Accept back to them
-
set_abconfig($channel['channel_id'], $person_obj['id'], 'pubcrawl', 'their_follow_id', $their_follow_id);
- Master::Summon(['Notifier', 'permissions_accept', $contact['abook_id']]);
+ Master::Summon(['Notifier', 'permission_accept', $contact['abook_id']]);
return;
case 'Accept':
@@ -1430,8 +1421,8 @@ class Activity {
}
$ret = $r[0];
- $p = Permissions::connect_perms($channel['channel_id']);
- $my_perms = Permissions::serialise($p['perms']);
+ $p = \Zotlabs\Access\Permissions::connect_perms($channel['channel_id']);
+ $my_perms = $p['perms'];
$automatic = $p['automatic'];
$closeness = get_pconfig($channel['channel_id'], 'system', 'new_abook_closeness', 80);
@@ -1451,12 +1442,13 @@ class Activity {
]
);
- if ($my_perms)
- set_abconfig($channel['channel_id'], $ret['xchan_hash'], 'system', 'my_perms', $my_perms);
-
- if ($their_perms)
- set_abconfig($channel['channel_id'], $ret['xchan_hash'], 'system', 'their_perms', $their_perms);
+ if($my_perms)
+ foreach($my_perms as $k => $v)
+ set_abconfig($channel['channel_id'],$ret['xchan_hash'],'my_perms',$k,$v);
+ if($their_perms)
+ foreach($their_perms as $k => $v)
+ set_abconfig($channel['channel_id'],$ret['xchan_hash'],'their_perms',$k,$v);
if ($r) {
logger("New ActivityPub follower for {$channel['channel_name']}");
@@ -1477,9 +1469,9 @@ class Activity {
if ($my_perms && $automatic) {
// send an Accept for this Follow activity
- Master::Summon(['Notifier', 'permissions_accept', $new_connection[0]['abook_id']]);
+ Master::Summon(['Notifier', 'permission_accept', $new_connection[0]['abook_id']]);
// Send back a Follow notification to them
- Master::Summon(['Notifier', 'permissions_create', $new_connection[0]['abook_id']]);
+ Master::Summon(['Notifier', 'permission_create', $new_connection[0]['abook_id']]);
}
$clone = [];
@@ -1604,13 +1596,13 @@ class Activity {
if ($inbox) {
$collections['inbox'] = $inbox;
- if ($person_obj['outbox'])
+ if (array_key_exists('outbox', $person_obj))
$collections['outbox'] = $person_obj['outbox'];
- if ($person_obj['followers'])
+ if (array_key_exists('followers', $person_obj))
$collections['followers'] = $person_obj['followers'];
- if ($person_obj['following'])
+ if (array_key_exists('following', $person_obj))
$collections['following'] = $person_obj['following'];
- if ($person_obj['endpoints'] && $person_obj['endpoints']['sharedInbox'])
+ if (array_key_exists('endpoints', $person_obj) && array_key_exists('sharedInbox', $person_obj['endpoints']))
$collections['sharedInbox'] = $person_obj['endpoints']['sharedInbox'];
}
@@ -2123,22 +2115,22 @@ class Activity {
$s['uuid'] = $act->obj['diaspora:guid'];
$s['parent_mid'] = $act->parent_id;
- if ($act->data['published']) {
+ if (array_key_exists('published', $act->data)) {
$s['created'] = datetime_convert('UTC', 'UTC', $act->data['published']);
}
- elseif ($act->obj['published']) {
+ elseif (array_key_exists('published', $act->obj)) {
$s['created'] = datetime_convert('UTC', 'UTC', $act->obj['published']);
}
- if ($act->data['updated']) {
+ if (array_key_exists('updated', $act->data)) {
$s['edited'] = datetime_convert('UTC', 'UTC', $act->data['updated']);
}
- elseif ($act->obj['updated']) {
+ elseif (array_key_exists('updated', $act->obj)) {
$s['edited'] = datetime_convert('UTC', 'UTC', $act->obj['updated']);
}
- if ($act->data['expires']) {
+ if (array_key_exists('expires', $act->data)) {
$s['expires'] = datetime_convert('UTC', 'UTC', $act->data['expires']);
}
- elseif ($act->obj['expires']) {
+ elseif (array_key_exists('expires', $act->obj)) {
$s['expires'] = datetime_convert('UTC', 'UTC', $act->obj['expires']);
}
@@ -2198,10 +2190,10 @@ class Activity {
}
}
- if (!$s['created'])
+ if (! array_key_exists('created', $s))
$s['created'] = datetime_convert();
- if (!$s['edited'])
+ if (! array_key_exists('edited', $s))
$s['edited'] = $s['created'];
$s['title'] = (($response_activity) ? EMPTY_STR : self::bb_content($content, 'name'));
@@ -2315,7 +2307,7 @@ class Activity {
}
}
- if ($act->obj['closed']) {
+ if (array_key_exists('closed', $act->obj)) {
$s['comments_closed'] = datetime_convert('UTC', 'UTC', $act->obj['closed']);
}
@@ -2731,7 +2723,7 @@ class Activity {
}
}
- if ($act->obj['conversation']) {
+ if (array_key_exists('conversation', $act->obj)) {
set_iconfig($item, 'ostatus', 'conversation', $act->obj['conversation'], 1);
}
@@ -3384,22 +3376,25 @@ class Activity {
require_once('include/event.php');
$ret = false;
- if (is_array($content[$field])) {
- foreach ($content[$field] as $k => $v) {
- $ret .= html2bbcode($v);
- // save this for auto-translate or dynamic filtering
- // $ret .= '[language=' . $k . ']' . html2bbcode($v) . '[/language]';
- }
- }
- else {
- if ($field === 'bbcode' && array_key_exists('bbcode', $content)) {
- $ret = $content[$field];
+ if (array_key_exists($field, $content)) {
+ if (is_array($content[$field])) {
+ foreach ($content[$field] as $k => $v) {
+ $ret .= html2bbcode($v);
+ // save this for auto-translate or dynamic filtering
+ // $ret .= '[language=' . $k . ']' . html2bbcode($v) . '[/language]';
+ }
}
else {
- $ret = html2bbcode($content[$field]);
+ if ($field === 'bbcode' && array_key_exists('bbcode', $content)) {
+ $ret = $content[$field];
+ }
+ else {
+ $ret = html2bbcode($content[$field]);
+ }
}
}
- if ($field === 'content' && $content['event'] && (!strpos($ret, '[event'))) {
+
+ if ($field === 'content' && array_key_exists('event', $content) && (!strpos($ret, '[event'))) {
$ret .= format_event_bbcode($content['event']);
}
diff --git a/Zotlabs/Lib/Apps.php b/Zotlabs/Lib/Apps.php
index d77a3fda2..5ef4ecc8d 100644
--- a/Zotlabs/Lib/Apps.php
+++ b/Zotlabs/Lib/Apps.php
@@ -551,7 +551,7 @@ class Apps {
'$app' => $papp,
'$icon' => $icon,
'$hosturl' => $hosturl,
- '$purchase' => (($papp['page'] && (! $installed)) ? t('Purchase') : ''),
+ '$purchase' => ((isset($papp['page']) && (! $installed)) ? t('Purchase') : ''),
'$installed' => $installed,
'$action_label' => (($hosturl && in_array($mode, ['view','install'])) ? $install_action : ''),
'$edit' => ((local_channel() && $installed && $mode == 'edit') ? t('Edit') : ''),
@@ -559,8 +559,8 @@ class Apps {
'$undelete' => ((local_channel() && $mode == 'edit') ? t('Undelete') : ''),
'$settings_url' => ((local_channel() && $installed && $mode == 'list') ? $papp['settings_url'] : ''),
'$deleted' => $papp['deleted'],
- '$feature' => (($papp['embed'] || $mode == 'edit') ? false : true),
- '$pin' => (($papp['embed'] || $mode == 'edit') ? false : true),
+ '$feature' => ((isset($papp['embed']) || $mode == 'edit') ? false : true),
+ '$pin' => ((isset($papp['embed']) || $mode == 'edit') ? false : true),
'$featured' => ((strpos($papp['categories'], 'nav_featured_app') === false) ? false : true),
'$pinned' => ((strpos($papp['categories'], 'nav_pinned_app') === false) ? false : true),
'$navapps' => (($mode == 'nav') ? true : false),
@@ -1276,58 +1276,58 @@ class Apps {
$ret['type'] = 'personal';
- if($app['app_id'])
+ if(!empty($app['app_id']))
$ret['guid'] = $app['app_id'];
- if($app['app_sig'])
+ if(!empty($app['app_sig']))
$ret['sig'] = $app['app_sig'];
- if($app['app_author'])
+ if(!empty($app['app_author']))
$ret['author'] = $app['app_author'];
- if($app['app_name'])
+ if(!empty($app['app_name']))
$ret['name'] = $app['app_name'];
- if($app['app_desc'])
+ if(!empty($app['app_desc']))
$ret['desc'] = $app['app_desc'];
- if($app['app_url'])
+ if(!empty($app['app_url']))
$ret['url'] = $app['app_url'];
- if($app['app_photo'])
+ if(!empty($app['app_photo']))
$ret['photo'] = $app['app_photo'];
- if($app['app_icon'])
+ if(!empty($app['app_icon']))
$ret['icon'] = $app['app_icon'];
- if($app['app_version'])
+ if(!empty($app['app_version']))
$ret['version'] = $app['app_version'];
- if($app['app_addr'])
+ if(!empty($app['app_addr']))
$ret['addr'] = $app['app_addr'];
- if($app['app_price'])
+ if(!empty($app['app_price']))
$ret['price'] = $app['app_price'];
- if($app['app_page'])
+ if(!empty($app['app_page']))
$ret['page'] = $app['app_page'];
- if($app['app_requires'])
+ if(!empty($app['app_requires']))
$ret['requires'] = $app['app_requires'];
- if($app['app_system'])
+ if(!empty($app['app_system']))
$ret['system'] = $app['app_system'];
- if($app['app_options'])
+ if(!empty($app['app_options']))
$ret['options'] = $app['app_options'];
- if($app['app_plugin'])
+ if(!empty($app['app_plugin']))
$ret['plugin'] = trim($app['app_plugin']);
- if($app['app_deleted'])
+ if(!empty($app['app_deleted']))
$ret['deleted'] = $app['app_deleted'];
- if($app['term']) {
+ if(!empty($app['term']) && is_array($app['term'])) {
$s = '';
foreach($app['term'] as $t) {
if($s)
diff --git a/Zotlabs/Lib/Connect.php b/Zotlabs/Lib/Connect.php
index 481b02ce2..21bec171b 100644
--- a/Zotlabs/Lib/Connect.php
+++ b/Zotlabs/Lib/Connect.php
@@ -207,13 +207,13 @@ class Connect {
}
$my_perms = $p['perms'];
-
+
$profile_assign = get_pconfig($uid,'system','profile_assign','');
// See if we are already connected by virtue of having an abook record
- $r = q("select abook_id, abook_xchan, abook_pending, abook_instance from abook
+ $r = q("select abook_id, abook_xchan, abook_pending, abook_instance from abook
where abook_xchan = '%s' and abook_channel = %d limit 1",
dbesc($xchan_hash),
intval($uid)
@@ -282,7 +282,7 @@ class Connect {
// fetch the entire record
- $r = q("select abook.*, xchan.* from abook left join xchan on abook_xchan = xchan_hash
+ $r = q("select abook.*, xchan.* from abook left join xchan on abook_xchan = xchan_hash
where abook_xchan = '%s' and abook_channel = %d limit 1",
dbesc($xchan_hash),
intval($uid)
diff --git a/Zotlabs/Lib/Enotify.php b/Zotlabs/Lib/Enotify.php
index d2a0f0abc..7e33f09b8 100644
--- a/Zotlabs/Lib/Enotify.php
+++ b/Zotlabs/Lib/Enotify.php
@@ -978,12 +978,12 @@ class Enotify {
$x = [
'notify_link' => z_root() . '/admin/accounts',
- 'name' => $rr['account_email'],
- //'addr' => $rr['account_email'],
+ 'name' => $rr['reg_did2'],
+ //'addr' => '',
'photo' => z_root() . '/' . get_default_profile_photo(48),
- 'when' => datetime_convert('UTC', date_default_timezone_get(),$rr['account_created']),
+ 'when' => datetime_convert('UTC', date_default_timezone_get(),$rr['reg_created']),
'hclass' => ('notify-unseen'),
- 'message' => t('requires approval')
+ 'message' => t('status verified')
];
return $x;
diff --git a/Zotlabs/Lib/Libsync.php b/Zotlabs/Lib/Libsync.php
index e16b68cf8..5455aa2ea 100644
--- a/Zotlabs/Lib/Libsync.php
+++ b/Zotlabs/Lib/Libsync.php
@@ -716,6 +716,9 @@ class Libsync {
dbesc($sender['hash'])
);
+ if(!$xisting)
+ $xisting = [];
+
// See if a primary is specified
$has_primary = false;
@@ -781,7 +784,7 @@ class Libsync {
$t = datetime_convert('UTC', 'UTC', 'now - 15 minutes');
if (array_key_exists('site', $arr) && $location['url'] == $arr['site']['url']) {
- q("update hubloc set hubloc_connected = '%s', hubloc_updated = '%s' where hubloc_id = %d and hubloc_connected < '%s'",
+ q("update hubloc set hubloc_connected = '%s', hubloc_updated = '%s' where hubloc_id = %d and hubloc_updated < '%s'",
dbesc(datetime_convert()),
dbesc(datetime_convert()),
intval($r[0]['hubloc_id']),
diff --git a/Zotlabs/Lib/Libzot.php b/Zotlabs/Lib/Libzot.php
index 6aa49c5a7..a19c8e544 100644
--- a/Zotlabs/Lib/Libzot.php
+++ b/Zotlabs/Lib/Libzot.php
@@ -299,7 +299,6 @@ class Libzot {
}
$record = Zotfinger::exec($url, $channel);
-
// Check the HTTP signature
$hsig = $record['signature'];
@@ -2665,9 +2664,9 @@ class Libzot {
// we may only end up with one; which results in posts with no author name or photo and are a bit
// of a hassle to repair. If either or both are missing, do a full discovery probe.
- if (!array_key_exists('id', $x)) {
- return import_author_activitypub($x);
- }
+ //if (!array_key_exists('id', $x)) {
+ //return import_author_activitypub($x);
+ //}
$hash = self::make_xchan_hash($x['id'], $x['key']);
diff --git a/Zotlabs/Lib/NativeWiki.php b/Zotlabs/Lib/NativeWiki.php
index c3032d02c..9e6a3ac85 100644
--- a/Zotlabs/Lib/NativeWiki.php
+++ b/Zotlabs/Lib/NativeWiki.php
@@ -101,6 +101,7 @@ class NativeWiki {
}
}
+
public static function update_wiki($channel_id, $observer_hash, $arr, $acl) {
$w = self::get_wiki($channel_id, $observer_hash, $arr['resource_id']);
@@ -156,8 +157,8 @@ class NativeWiki {
}
}
- public static function sync_a_wiki_item($uid,$id,$resource_id) {
+ public static function sync_a_wiki_item($uid,$id,$resource_id) {
$r = q("SELECT * from item WHERE uid = %d AND ( id = %d OR ( resource_type = '%s' and resource_id = '%s' )) ",
intval($uid),
@@ -165,8 +166,8 @@ class NativeWiki {
dbesc(NWIKI_ITEM_RESOURCE_TYPE),
dbesc($resource_id)
);
-
if($r) {
+
$q = q("select * from item where resource_type = 'nwikipage' and resource_id = '%s'",
dbesc($r[0]['resource_id'])
);
@@ -185,20 +186,27 @@ class NativeWiki {
}
}
+
public static function delete_wiki($channel_id,$observer_hash,$resource_id) {
$w = self::get_wiki($channel_id,$observer_hash,$resource_id);
- $item = $w['wiki'];
- if(! $item) {
- return array('item' => null, 'success' => false);
- }
- else {
- $drop = drop_item($item['id'], false, DROPITEM_NORMAL);
+ if(! $w['wiki']) {
+ return [ 'success' => false ];
}
+ else {
+
+ $r = q("SELECT id FROM item WHERE uid = %s AND resource_id = '%s'",
+ intval($channel_id),
+ dbesc($resource_id)
+ );
+
+ $ids = array_column($r, 'id');
+ drop_items($ids, true, DROPITEM_PHASE1);
- info( t('Wiki files deleted successfully'));
+ info(t('Wiki files deleted successfully'));
- return array('item' => $item, 'item_id' => $item['id'], 'success' => (($drop === 1) ? true : false));
+ return [ 'success' => true ];
+ }
}
@@ -207,13 +215,13 @@ class NativeWiki {
$sql_extra = item_permissions_sql($channel_id,$observer_hash);
$item = q("SELECT * FROM item WHERE uid = %d AND resource_type = '%s' AND resource_id = '%s' AND item_deleted = 0
- $sql_extra limit 1",
+ $sql_extra ORDER BY id LIMIT 1",
intval($channel_id),
dbesc(NWIKI_ITEM_RESOURCE_TYPE),
dbesc($resource_id)
);
if(! $item) {
- return array('wiki' => null);
+ return [ 'wiki' => null ];
}
else {
@@ -259,6 +267,7 @@ class NativeWiki {
public static function get_permissions($resource_id, $owner_id, $observer_hash) {
+
// TODO: For now, only the owner can edit
$sql_extra = item_permissions_sql($owner_id, $observer_hash);
@@ -283,6 +292,7 @@ class NativeWiki {
}
}
+
public static function name_encode ($string) {
$string = html_entity_decode($string);
@@ -298,6 +308,7 @@ class NativeWiki {
return $ret;
}
+
public static function name_decode ($string) {
$encoding = mb_internal_encoding();
diff --git a/Zotlabs/Lib/NativeWikiPage.php b/Zotlabs/Lib/NativeWikiPage.php
index 71f193b70..3c61ea800 100644
--- a/Zotlabs/Lib/NativeWikiPage.php
+++ b/Zotlabs/Lib/NativeWikiPage.php
@@ -109,6 +109,7 @@ class NativeWikiPage {
return [ 'success' => false, 'message' => t('Wiki page create failed.') ];
}
+
static public function rename_page($arr) {
$pageUrlName = ((array_key_exists('pageUrlName',$arr)) ? $arr['pageUrlName'] : '');
@@ -167,7 +168,9 @@ class NativeWikiPage {
}
+
static public function get_page_content($arr) {
+
$pageUrlName = ((array_key_exists('pageUrlName',$arr)) ? $arr['pageUrlName'] : '');
$resource_id = ((array_key_exists('resource_id',$arr)) ? $arr['resource_id'] : '');
$observer_hash = ((array_key_exists('observer_hash',$arr)) ? $arr['observer_hash'] : '');
@@ -198,7 +201,9 @@ class NativeWikiPage {
}
+
static public function page_history($arr) {
+
$pageUrlName = ((array_key_exists('pageUrlName',$arr)) ? $arr['pageUrlName'] : '');
$resource_id = ((array_key_exists('resource_id',$arr)) ? $arr['resource_id'] : '');
$observer_hash = ((array_key_exists('observer_hash',$arr)) ? $arr['observer_hash'] : '');
@@ -290,6 +295,7 @@ class NativeWikiPage {
return null;
}
+
static public function load_page_history($arr) {
$pageUrlName = ((array_key_exists('pageUrlName',$arr)) ? $arr['pageUrlName'] : '');
@@ -338,6 +344,7 @@ class NativeWikiPage {
return null;
}
+
static public function save_page($arr) {
$pageUrlName = ((array_key_exists('pageUrlName',$arr)) ? $arr['pageUrlName'] : '');
$content = ((array_key_exists('content',$arr)) ? $arr['content'] : '');
@@ -389,14 +396,15 @@ class NativeWikiPage {
return array('message' => t('Page update failed.'), 'success' => false);
}
+
static public function delete_page($arr) {
- $pageUrlName = ((array_key_exists('pageUrlName',$arr)) ? $arr['pageUrlName'] : '');
- $resource_id = ((array_key_exists('resource_id',$arr)) ? $arr['resource_id'] : '');
- $observer_hash = ((array_key_exists('observer_hash',$arr)) ? $arr['observer_hash'] : '');
- $channel_id = ((array_key_exists('channel_id',$arr)) ? $arr['channel_id'] : 0);
- $w = Zlib\NativeWiki::get_wiki($channel_id, $observer_hash, $resource_id);
+ $pageUrlName = (array_key_exists('pageUrlName',$arr) ? $arr['pageUrlName'] : '');
+ $resource_id = (array_key_exists('resource_id',$arr) ? $arr['resource_id'] : '');
+ $observer_hash = (array_key_exists('observer_hash',$arr) ? $arr['observer_hash'] : '');
+ $channel_id = (array_key_exists('channel_id',$arr) ? $arr['channel_id'] : 0);
+ $w = Zlib\NativeWiki::get_wiki($channel_id, $observer_hash, $resource_id);
if(! $w['wiki']) {
return [ 'success' => false, 'message' => t('Error reading wiki') ];
}
@@ -416,14 +424,16 @@ class NativeWikiPage {
}
if($ids) {
- drop_items($ids);
+ drop_items($ids, true, DROPITEM_PHASE1);
return [ 'success' => true ];
}
return [ 'success' => false, 'message' => t('Nothing deleted') ];
}
+
static public function revert_page($arr) {
+
$pageUrlName = ((array_key_exists('pageUrlName',$arr)) ? $arr['pageUrlName'] : '');
$resource_id = ((array_key_exists('resource_id',$arr)) ? $arr['resource_id'] : '');
$commitHash = ((array_key_exists('commitHash',$arr)) ? $arr['commitHash'] : null);
@@ -454,7 +464,9 @@ class NativeWikiPage {
}
}
+
static public function compare_page($arr) {
+
$pageUrlName = ((array_key_exists('pageUrlName',$arr)) ? $arr['pageUrlName'] : '');
$resource_id = ((array_key_exists('resource_id',$arr)) ? $arr['resource_id'] : '');
$currentCommit = ((array_key_exists('currentCommit',$arr)) ? $arr['currentCommit'] : (-1));
@@ -490,6 +502,7 @@ class NativeWikiPage {
}
+
static public function commit($arr) {
$commit_msg = ((array_key_exists('commit_msg', $arr)) ? $arr['commit_msg'] : t('Page updated'));
@@ -570,7 +583,6 @@ class NativeWikiPage {
}
-
/**
* Replace the instances of the string [toc] with a list element that will be populated by
* a table of contents by the JavaScript library
@@ -586,6 +598,7 @@ class NativeWikiPage {
return $s;
}
+
/**
* Converts a select set of bbcode tags. Much of the code is copied from include/bbcode.php
* @param string $s
@@ -625,7 +638,9 @@ class NativeWikiPage {
return $s;
}
+
static public function get_file_ext($arr) {
+
if($arr['mimetype'] === 'text/bbcode')
return '.bb';
elseif($arr['mimetype'] === 'text/markdown')
diff --git a/Zotlabs/Lib/Queue.php b/Zotlabs/Lib/Queue.php
index 779719d8b..373a7d304 100644
--- a/Zotlabs/Lib/Queue.php
+++ b/Zotlabs/Lib/Queue.php
@@ -116,7 +116,7 @@ class Queue {
dbesc(($arr['driver']) ? $arr['driver'] : 'zot6'),
dbesc($arr['posturl']),
intval(1),
- intval(($arr['priority']) ? $arr['priority'] : 0),
+ intval(isset($arr['priority']) ? $arr['priority'] : 0),
dbesc(datetime_convert()),
dbesc(datetime_convert()),
dbesc(datetime_convert()),
@@ -134,7 +134,7 @@ class Queue {
$base = null;
$h = parse_url($outq['outq_posturl']);
if($h !== false)
- $base = $h['scheme'] . '://' . $h['host'] . (($h['port']) ? ':' . $h['port'] : '');
+ $base = $h['scheme'] . '://' . $h['host'] . (isset($h['port']) ? ':' . $h['port'] : '');
if(($base) && ($base !== z_root()) && ($immediate)) {
$y = q("select site_update, site_dead from site where site_url = '%s' ",
diff --git a/Zotlabs/Lib/ThreadItem.php b/Zotlabs/Lib/ThreadItem.php
index 2fb07c1cb..c0d5c001b 100644
--- a/Zotlabs/Lib/ThreadItem.php
+++ b/Zotlabs/Lib/ThreadItem.php
@@ -43,7 +43,7 @@ class ThreadItem {
$observer = \App::get_observer();
// Prepare the children
- if($data['children']) {
+ if(isset($data['children'])) {
foreach($data['children'] as $item) {
/*
diff --git a/Zotlabs/Module/Admin.php b/Zotlabs/Module/Admin.php
index 88b84b9d2..44c10b339 100644
--- a/Zotlabs/Module/Admin.php
+++ b/Zotlabs/Module/Admin.php
@@ -101,11 +101,14 @@ class Admin extends \Zotlabs\Web\Controller {
// pending registrations
- $pdg = q("SELECT account.*, register.hash from account left join register on account_id = register.uid where (account_flags & %d ) > 0 ",
- intval(ACCOUNT_PENDING)
+ // $pdg = q("SELECT account.*, register.reg_hash from account left join register on account_id = register.reg_uid // where (account_flags & %d ) > 0 ",
+ // intval(ACCOUNT_PENDING)
+ // );
+ $pdg = q("SELECT COUNT(*) AS pdg FROM register WHERE reg_vital = 1 AND reg_expires > '%s' ",
+ dbesc(date('Y-m-d H:i:s'))
);
- $pending = (($pdg) ? count($pdg) : 0);
+ $pending = ($pdg ? $pdg[0]['pdg'] : 0);
// available channels, primary and clones
$channels = array();
diff --git a/Zotlabs/Module/Admin/Accounts.php b/Zotlabs/Module/Admin/Accounts.php
index 0c7e089be..1c1911b3a 100644
--- a/Zotlabs/Module/Admin/Accounts.php
+++ b/Zotlabs/Module/Admin/Accounts.php
@@ -5,7 +5,7 @@ namespace Zotlabs\Module\Admin;
class Accounts {
-
+
/**
* @brief Handle POST actions on accounts admin page.
*
@@ -15,14 +15,105 @@ class Accounts {
*
*/
+ const MYP = 'ZAR'; // ZAR2x
+ const VERSION = '2.0.0';
+
function post() {
$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/accounts', 'admin_accounts');
-
+
+ $isajax = is_ajax();
+ $rc = 0;
+
+ If (!is_site_admin()) {
+ if ($isajax) {
+ killme();
+ exit;
+ }
+ goaway(z_root() . '/');
+ }
+
+ if ($isajax) {
+ //$debug = print_r($_SESSION[self::MYP],true);
+ $zarop = (x($_POST['zardo']) && preg_match('/^[ad]{1,1}$/', $_POST['zardo']) )
+ ? $_POST['zardo'] : '';
+ // zarat arrives with leading underscore _n
+ $zarat = (x($_POST['zarat']) && preg_match('/^_{1,1}[0-9]{1,6}$/', $_POST['zarat']) )
+ ? substr($_POST['zarat'],1) : '';
+ $zarse = (x($_POST['zarse']) && preg_match('/^[0-9a-f]{8,8}$/', $_POST['zarse']) )
+ ? hex2bin($_POST['zarse']) : '';
+
+ if ($zarop && $zarat >= 0 && $zarse && $zarse == $_SESSION[self::MYP]['h'][$zarat]) {
+
+ //
+ if ($zarop == 'd') {
+ $rd = q("UPDATE register SET reg_vital = 0 WHERE reg_id = %d AND SUBSTR(reg_hash,1,4) = '%s' ",
+ intval($_SESSION[self::MYP]['i'][$zarat]),
+ dbesc($_SESSION[self::MYP]['h'][$zarat])
+ );
+ $rc = '×';
+ }
+ elseif ($zarop == 'a') {
+ // approval, REGISTER_DENIED by user 0x0040, REGISTER_AGREED by user 0x0020 @Regate
+ $rd = q("UPDATE register SET reg_flags = (reg_flags & ~ 16), "
+ . " reg_vital = (CASE (reg_flags & ~ 48) WHEN 0 THEN 0 ELSE 1 END) "
+ . " WHERE reg_vital = 1 AND reg_id = %d AND SUBSTR(reg_hash,1,4) = '%s' ",
+ intval($_SESSION[self::MYP]['i'][$zarat]),
+ dbesc($_SESSION[self::MYP]['h'][$zarat])
+ );
+ $rc = 0;
+ $rs = q("SELECT * from register WHERE reg_id = %d ",
+ intval($_SESSION[self::MYP]['i'][$zarat])
+ );
+ if ($rs && ($rs[0]['reg_flags'] & ~ 48) == 0) {
+ // create account
+ $rc = 'ok'.$rs[0]['reg_id'];
+ $ac = create_account_from_register($rs[0]);
+ if ( $ac['success'] ) {
+ $rc .= '✔';
+
+ $auto_create = get_config('system','auto_channel_create',1);
+
+ if($auto_create) {
+ $reonar = json_decode($rs[0]['reg_stuff'], true);
+ // prepare channel creation
+ if($reonar['chan.name'])
+ set_aconfig($ac['account']['account_id'], 'register', 'channel_name', $reonar['chan.name']);
+
+ if($reonar['chan.did1'])
+ set_aconfig($ac['account']['account_id'], 'register', 'channel_address', $reonar['chan.did1']);
+
+ $permissions_role = get_config('system','default_permissions_role');
+ if($permissions_role)
+ set_aconfig($ac['account']['account_id'], 'register', 'permissions_role', $permissions_role);
+
+ // create channel
+ $new_channel = auto_channel_create($ac['account']['account_id']);
+
+ if($new_channel['success']) {
+ $rc .= ' c,ok' . $new_channel['channel']['channel_id'] . '✔';
+ }
+ else {
+ $rc .= ' c ×';
+ }
+ }
+
+
+ }
+ } else {
+ $rc='oh ×';
+ }
+ }
+ echo json_encode(array('re' => $zarop, 'at' => '_' . $zarat, 'rc' => $rc));
+ }
+ killme();
+ exit;
+ }
+
// change to switch structure?
// account block/unblock button was submitted
if (x($_POST, 'page_accounts_block')) {
@@ -55,7 +146,7 @@ class Accounts {
account_deny($hash);
}
}
-
+
goaway(z_root() . '/admin/accounts' );
}
@@ -75,19 +166,21 @@ class Accounts {
$account = q("SELECT * FROM account WHERE account_id = %d",
intval($uid)
);
-
+
if (! $account) {
notice( t('Account not found') . EOL);
goaway(z_root() . '/admin/accounts' );
}
-
+
check_form_security_token_redirectOnErr('/admin/accounts', 'admin_accounts', 't');
-
+
+ $debug = '';
+
switch (argv(2)){
case 'delete':
// delete user
account_remove($uid,true,false);
-
+
notice( sprintf(t("Account '%s' deleted"), $account[0]['account_email']) . EOL);
break;
case 'block':
@@ -95,7 +188,7 @@ class Accounts {
intval(ACCOUNT_BLOCKED),
intval($uid)
);
-
+
notice( sprintf( t("Account '%s' blocked") , $account[0]['account_email']) . EOL);
break;
case 'unblock':
@@ -103,27 +196,74 @@ class Accounts {
intval(ACCOUNT_BLOCKED),
intval($uid)
);
-
+
notice( sprintf( t("Account '%s' unblocked"), $account[0]['account_email']) . EOL);
break;
}
-
+
goaway(z_root() . '/admin/accounts' );
}
-
- /* get pending */
- $pending = q("SELECT account.*, register.hash from account left join register on account_id = register.uid where (account_flags & %d )>0 ",
- intval(ACCOUNT_PENDING)
- );
-
+
+ $tao = 'tao.zar.zarax = ' . "'" . '<img src="' . z_root() . '/images/zapax16.gif">' . "';\n";
+
+
+ // by default we will only return verified results. if reg_all is set we will return everything''
+ $get_all = isset($_REQUEST['get_all']);
+ $pending = get_pending_accounts($get_all);
+
+ unset($_SESSION[self::MYP]);
+
+ if ($pending) {
+ // collect and group all ip
+ $atips = dbq("SELECT reg_atip AS atip, COUNT(reg_atip) AS atips FROM register
+ WHERE reg_vital = 1 GROUP BY reg_atip"
+ );
+
+ (($atips) ? $atipn = array_column($atips, 'atips', 'atip') : $atipn = ['' => 0]);
+
+ $tao .= 'tao.zar.zarar = {';
+ foreach ($pending as $n => $v) {
+
+ $stuff = json_decode($v['reg_stuff'], true);
+
+ if(isset($stuff['msg'])) {
+ $pending[$n]['msg'] = $stuff['msg'];
+ }
+
+ if (array_key_exists($v['reg_atip'], $atipn)) {
+ $pending[$n]['reg_atip'] = $v['reg_atip'];
+ $pending[$n]['reg_atip_n'] = $atipn[$v['reg_atip']];
+ }
+
+ $pending[$n]['status'] = '';
+ if($pending[$n]['reg_flags'] & ACCOUNT_UNVERIFIED > 0)
+ $pending[$n]['status'] = [t('Unverified'), 'bg-warning'];
+
+ if($pending[$n]['status'] && $pending[$n]['reg_expires'] < datetime_convert())
+ $pending[$n]['status'] = [t('Expired'), 'bg-danger text-white'];
+
+ // timezone adjust date_time for display
+ $pending[$n]['reg_created'] = datetime_convert('UTC', date_default_timezone_get(), $pending[$n]['reg_created']);
+ $pending[$n]['reg_startup'] = datetime_convert('UTC', date_default_timezone_get(), $pending[$n]['reg_startup']);
+ $pending[$n]['reg_expires'] = datetime_convert('UTC', date_default_timezone_get(), $pending[$n]['reg_expires']);
+
+ // better secure
+ $tao .= $n . ": '" . substr(bin2hex($v['reg_hash']),0,8) . "',";
+ $_SESSION[self::MYP]['h'][] = substr($v['reg_hash'],0,4);
+ $_SESSION[self::MYP]['i'][] = $v['reg_id'];
+ }
+ $tao = rtrim($tao,',') . '};' . "\n";
+ }
+ // <- hilmar]
+
/* get accounts */
-
+
$total = q("SELECT count(*) as total FROM account");
if (count($total)) {
\App::set_pager_total($total[0]['total']);
\App::set_pager_itemspage(100);
}
-
+
$serviceclass = (($_REQUEST['class']) ? " and account_service_class = '" . dbesc($_REQUEST['class']) . "' " : '');
$key = (($_REQUEST['key']) ? dbesc($_REQUEST['key']) : 'account_id');
@@ -134,8 +274,8 @@ class Accounts {
$base = z_root() . '/admin/accounts?f=';
$odir = (($dir === 'asc') ? '0' : '1');
- $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
+ $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 and account_flags != %d order by $key $dir limit %d offset %d ",
intval(ACCOUNT_BLOCKED),
db_concat('ch.channel_address', ' '),
@@ -143,15 +283,15 @@ class Accounts {
intval(\App::$pager['itemspage']),
intval(\App::$pager['start'])
);
-
+
// function _setup_users($e){
// $accounts = Array(
- // t('Normal Account'),
+ // t('Normal Account'),
// t('Soapbox Account'),
// t('Community/Celebrity Account'),
// t('Automatic Friend Account')
// );
-
+
// $e['page_flags'] = $accounts[$e['page-flags']];
// $e['register_date'] = relative_date($e['register_date']);
// $e['login_date'] = relative_date($e['login_date']);
@@ -159,49 +299,57 @@ class Accounts {
// return $e;
// }
// $users = array_map("_setup_users", $users);
-
+
$t = get_markup_template('admin_accounts.tpl');
$o = replace_macros($t, array(
// strings //
+ '$debug' => $debug,
'$title' => t('Administration'),
'$page' => t('Accounts'),
'$submit' => t('Submit'),
- '$select_all' => t('select all'),
- '$h_pending' => t('Registrations waiting for confirm'),
- '$th_pending' => array( t('Request date'), t('Email') ),
- '$no_pending' => t('No registrations.'),
+ '$get_all' => (($get_all) ? t('Show verified registrations') : t('Show all registrations')),
+ '$get_all_link' => (($get_all) ? z_root() .'/admin/accounts' : z_root() .'/admin/accounts?get_all'),
+ '$sel_tall' => t('Select toggle'),
+ '$sel_deny' => t('Deny selected'),
+ '$sel_aprv' => t('Approve selected'),
+ '$h_pending' => (($get_all) ? t('All registrations') : t('Verified registrations waiting for approval')),
+ '$th_pending' => array(t('Request date'), 'dId2', t('Email'), 'IP', t('Requests')),
+ '$no_pending' => (($get_all) ? t('No registrations available') : t('No verified registrations available')),
'$approve' => t('Approve'),
'$deny' => t('Deny'),
'$delete' => t('Delete'),
'$block' => t('Block'),
'$unblock' => t('Unblock'),
+ '$verified' => t('Verified'),
+ '$not_verified' => t('Not yet verified'),
'$odir' => $odir,
'$base' => $base,
'$h_users' => t('Accounts'),
- '$th_users' => array(
+ '$th_users' => array(
[ t('ID'), 'account_id' ],
[ t('Email'), 'account_email' ],
- [ t('All Channels'), 'channels' ],
+ [ 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?'),
-
+ [ t('Service class'), 'account_service_class'] ),
+
+ '$confirm_delete_multi' => p2j(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' => p2j(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_accounts"),
-
+
// values //
- '$baseurl' => z_root(),
-
- '$pending' => $pending,
- '$users' => $users,
+ '$baseurl' => z_root(),
+ '$tao' => $tao,
+ '$pending' => $pending,
+ '$users' => $users,
+ '$msg' => t('Message')
));
$o .= paginate($a);
-
+
return $o;
}
-
}
+
diff --git a/Zotlabs/Module/Admin/Channels.php b/Zotlabs/Module/Admin/Channels.php
index e0f26112d..09769a166 100644
--- a/Zotlabs/Module/Admin/Channels.php
+++ b/Zotlabs/Module/Admin/Channels.php
@@ -173,4 +173,4 @@ class Channels {
return $o;
}
-} \ No newline at end of file
+}
diff --git a/Zotlabs/Module/Admin/Site.php b/Zotlabs/Module/Admin/Site.php
index 011bf3ce4..3b2632411 100644
--- a/Zotlabs/Module/Admin/Site.php
+++ b/Zotlabs/Module/Admin/Site.php
@@ -5,14 +5,25 @@ namespace Zotlabs\Module\Admin;
class Site {
+
/**
* @brief POST handler for Admin Site Page.
*
*/
function post(){
+ // [hilmar->
+ $this->isajax = is_ajax();
+ $this->eol = $this->isajax ? "\n" : EOL;
+ // ]
if (!x($_POST, 'page_site')) {
- return;
+ // [
+ if (!$this->isajax)
+ // ]
+ return;
}
+ // [
+ $this->msgbg = '';
+ // <-hilmar]
check_form_security_token_redirectOnErr('/admin/site', 'admin_site');
@@ -24,14 +35,17 @@ class Site {
$siteinfo = ((x($_POST,'siteinfo')) ? trim($_POST['siteinfo']) : '');
$language = ((x($_POST,'language')) ? notags(trim($_POST['language'])) : '');
$theme = ((x($_POST,'theme')) ? notags(trim($_POST['theme'])) : '');
-// $theme_mobile = ((x($_POST,'theme_mobile')) ? notags(trim($_POST['theme_mobile'])) : '');
-// $site_channel = ((x($_POST,'site_channel')) ? notags(trim($_POST['site_channel'])) : '');
+ // $theme_mobile = ((x($_POST,'theme_mobile')) ? notags(trim($_POST['theme_mobile'])) : '');
+ // $site_channel = ((x($_POST,'site_channel')) ? notags(trim($_POST['site_channel'])) : '');
$maximagesize = ((x($_POST,'maximagesize')) ? intval(trim($_POST['maximagesize'])) : 0);
$register_policy = ((x($_POST,'register_policy')) ? intval(trim($_POST['register_policy'])) : 0);
+ $register_wo_email = ((x($_POST,'register_wo_email')) ? intval(trim($_POST['register_wo_email'])) : 0);
$minimum_age = ((x($_POST,'minimum_age')) ? intval(trim($_POST['minimum_age'])) : 13);
$access_policy = ((x($_POST,'access_policy')) ? intval(trim($_POST['access_policy'])) : 0);
- $invite_only = ((x($_POST,'invite_only')) ? True : False);
+ $reg_autochannel = ((x($_POST,'auto_channel_create')) ? True : False);
+ $invitation_only = ((x($_POST,'invitation_only')) ? True : False);
+ $invitation_also = ((x($_POST,'invitation_also')) ? True : False);
$abandon_days = ((x($_POST,'abandon_days')) ? intval(trim($_POST['abandon_days'])) : 0);
$register_text = ((x($_POST,'register_text')) ? notags(trim($_POST['register_text'])) : '');
@@ -75,6 +89,16 @@ class Site {
$maxloadavg = ((x($_POST,'maxloadavg')) ? intval(trim($_POST['maxloadavg'])) : 50);
$feed_contacts = ((x($_POST,'feed_contacts')) ? intval($_POST['feed_contacts']) : 0);
$verify_email = ((x($_POST,'verify_email')) ? 1 : 0);
+ $register_perday = ((x($_POST,'register_perday')) ? intval(trim($_POST['register_perday'])) : 50);
+ $register_sameip = ((x($_POST,'register_sameip')) ? intval(trim($_POST['register_sameip'])) : 3);
+
+ $regdelayn = ((x($_POST,'zardelayn')) ? intval(trim($_POST['zardelayn'])) : 0);
+ $regdelayu = ((x($_POST,'zardelay')) ? notags(trim($_POST['zardelay'])) : '');
+ $reg_delay = (preg_match('/^[a-z]{1,1}$/', $regdelayu) ? $regdelayn . $regdelayu : '');
+ $regexpiren = ((x($_POST,'zarexpiren')) ? intval(trim($_POST['zarexpiren'])) : 0);
+ $regexpireu = ((x($_POST,'zarexpire')) ? notags(trim($_POST['zarexpire'])) : '');
+ $reg_expire = (preg_match('/^[a-z]{1,1}$/', $regexpireu) ? $regexpiren . $regexpireu : '');
+
$imagick_path = ((x($_POST,'imagick_path')) ? trim($_POST['imagick_path']) : '');
$force_queue = ((intval($_POST['force_queue']) > 0) ? intval($_POST['force_queue']) : 3000);
$pub_incl = escape_tags(trim($_POST['pub_incl']));
@@ -82,6 +106,35 @@ class Site {
$permissions_role = escape_tags(trim($_POST['permissions_role']));
+ // [hilmar->
+ $this->register_duty = ((x($_POST,'register_duty')) ? notags(trim($_POST['register_duty'])) : '');
+ if (! preg_match('/^[0-9 .,:\-]{0,191}$/', $this->register_duty)) {
+ $this->msgbg .= 'ZAR0131E,' . t('Invalid input') . $this->eol;
+ $this->error++;
+ } else {
+
+ $this->duty();
+
+ if ($this->isajax) {
+ echo json_encode(array('msgbg' => $this->msgbg, 'me' => 'zar'));
+ // that mission is complete
+ killme();
+ exit;
+
+ } else {
+
+ //logger( print_r( $this->msgbg, true) );
+ //logger( print_r( $this->joo, true) );
+ if ($this->error === 0) {
+ set_config('system', 'register_duty', $this->register_duty);
+ set_config('system', 'register_duty_jso', $this->joo);
+ } else {
+ notice('ZAR0130E,'.t('Errors') . ': ' . $this->error) . EOL . $this->msgfg;
+ }
+ }
+ }
+ // <-hilmar]
+
set_config('system', 'feed_contacts', $feed_contacts);
set_config('system', 'delivery_interval', $delivery_interval);
set_config('system', 'delivery_batch_count', $delivery_batch_count);
@@ -96,6 +149,10 @@ class Site {
set_config('system', 'login_on_homepage', $login_on_homepage);
set_config('system', 'enable_context_help', $enable_context_help);
set_config('system', 'verify_email', $verify_email);
+ set_config('system', 'max_daily_registrations', $register_perday);
+ set_config('system', 'register_sameip', $register_sameip);
+ set_config('system', 'register_delay', $reg_delay);
+ set_config('system', 'register_expire', $reg_expire);
set_config('system', 'default_expire_days', $default_expire_days);
set_config('system', 'active_expire_days', $active_expire_days);
set_config('system', 'reply_address', $reply_address);
@@ -126,17 +183,20 @@ class Site {
set_config('system','siteinfo',$siteinfo);
set_config('system', 'language', $language);
set_config('system', 'theme', $theme);
-// if ( $theme_mobile === '---' ) {
-// del_config('system', 'mobile_theme');
-// } else {
-// set_config('system', 'mobile_theme', $theme_mobile);
-// }
- // set_config('system','site_channel', $site_channel);
+ // if ( $theme_mobile === '---' ) {
+ // del_config('system', 'mobile_theme');
+ // } else {
+ // set_config('system', 'mobile_theme', $theme_mobile);
+ // }
+ // set_config('system','site_channel', $site_channel);
set_config('system','maximagesize', $maximagesize);
set_config('system','register_policy', $register_policy);
+ set_config('system','register_wo_email', $register_wo_email);
set_config('system','minimum_age', $minimum_age);
- set_config('system','invitation_only', $invite_only);
+ set_config('system','auto_channel_create', $reg_autochannel);
+ set_config('system', 'invitation_only', $invitation_only);
+ set_config('system', 'invitation_also', $invitation_also);
set_config('system','access_policy', $access_policy);
set_config('system','account_abandon_days', $abandon_days);
set_config('system','register_text', $register_text);
@@ -260,6 +320,8 @@ class Site {
REGISTER_APPROVE => t("Yes - with approval"),
REGISTER_OPEN => t("Yes")
);
+ $this->register_duty = get_config('system', 'register_duty', '-:-');
+ $register_perday = get_config('system','max_daily_registrations', 50);
/* Acess policy */
$access_choices = Array(
@@ -286,9 +348,66 @@ class Site {
$homelogin = get_config('system','login_on_homepage');
$enable_context_help = get_config('system','enable_context_help');
+ // for reuse reg_delay and reg_expire
+ $reg_rabots = array(
+ 'i' => t('Minute(s)'),
+ 'h' => t('Hour(s)') ,
+ 'd' => t('Day(s)') ,
+ 'w' => t('Week(s)') ,
+ 'm' => t('Month(s)') ,
+ 'y' => t('Year(s)')
+ );
+ $regdelay_n = $regdelay_u = false;
+ $regdelay = get_config('system','register_delay');
+ if ($regdelay)
+ list($regdelay_n, $regdelay_u) = array(substr($regdelay,0,-1),substr($regdelay,-1));
+ $reg_delay = replace_macros(get_markup_template('field_duration.qmc.tpl'),
+ array(
+ 'label' => t('Register verification delay'),
+ 'qmc' => 'zar',
+ 'qmcid' => '',
+ 'help' => t('Time to wait before a registration can be verified'),
+ 'field' => array(
+ 'name' => 'delay',
+ 'title' => t('duration up from now'),
+ 'value' => ($regdelay_n === false ? 0 : $regdelay_n),
+ 'min' => '0',
+ 'max' => '99',
+ 'size' => '2',
+ 'default' => ($regdelay_u === false ? 'i' : $regdelay_u)
+ ),
+ 'rabot' => $reg_rabots
+ )
+ );
+ $regexpire_n = $regexpire_u = false;
+ $regexpire = get_config('system','register_expire');
+ if ($regexpire)
+ list($regexpire_n, $regexpire_u) = array(substr($regexpire,0,-1),substr($regexpire,-1));
+ $reg_expire = replace_macros(get_markup_template('field_duration.qmc.tpl'),
+ array(
+ 'label' => t('Register verification expiration time'),
+ 'qmc' => 'zar',
+ 'qmcid' => '',
+ 'help' => t('Time before an unverified registration will expire'),
+ 'field' => array(
+ 'name' => 'expire',
+ 'title' => t('duration up from now'),
+ 'value' => ($regexpire_n === false ? 3 : $regexpire_n),
+ 'min' => '0',
+ 'max' => '99',
+ 'size' => '2',
+ 'default' => ($regexpire_u === false ? 'd' : $regexpire_u)
+ ),
+ 'rabot' => $reg_rabots
+ )
+ );
+
+ $tao = '';
$t = get_markup_template("admin_site.tpl");
return replace_macros($t, array(
'$title' => t('Administration'),
+ // interfacing js vars
+ '$tao' => $tao,
'$page' => t('Site'),
'$submit' => t('Submit'),
'$registration' => t('Registration'),
@@ -305,21 +424,87 @@ class Site {
'$siteinfo' => array('siteinfo', t('Site Information'), get_config('system','siteinfo'), t("Publicly visible description of this site. Displayed on siteinfo page. BBCode can be used here")),
'$language' => array('language', t("System language"), get_config('system','language'), "", $lang_choices),
'$theme' => array('theme', t("System theme"), get_config('system','theme'), t("Default system theme - may be over-ridden by user profiles - <a href='#' id='cnftheme'>change theme settings</a>"), $theme_choices),
-// '$theme_mobile' => array('theme_mobile', t("Mobile system theme"), get_config('system','mobile_theme'), t("Theme for mobile devices"), $theme_choices_mobile),
-// '$site_channel' => array('site_channel', t("Channel to use for this website's static pages"), get_config('system','site_channel'), t("Site Channel")),
+ // '$theme_mobile' => array('theme_mobile', t("Mobile system theme"), get_config('system','mobile_theme'), t("Theme for mobile devices"), $theme_choices_mobile),
+ // '$site_channel' => array('site_channel', t("Channel to use for this website's static pages"), get_config('system','site_channel'), t("Site Channel")),
'$feed_contacts' => array('feed_contacts', t('Allow Feeds as Connections'),get_config('system','feed_contacts'),t('(Heavy system resource usage)')),
'$maximagesize' => array('maximagesize', t("Maximum image size"), intval(get_config('system','maximagesize')), t("Maximum size in bytes of uploaded images. Default is 0, which means no limits.")),
- '$register_policy' => array('register_policy', t("Does this site allow new member registration?"), get_config('system','register_policy'), "", $register_choices),
- '$invite_only' => array('invite_only', t("Invitation only"), get_config('system','invitation_only'), t("Only allow new member registrations with an invitation code. Above register policy must be set to Yes.")),
'$minimum_age' => array('minimum_age', t("Minimum age"), (x(get_config('system','minimum_age'))?get_config('system','minimum_age'):13), t("Minimum age (in years) for who may register on this site.")),
'$access_policy' => array('access_policy', t("Which best describes the types of account offered by this hub?"), get_config('system','access_policy'), t("This is displayed on the public server site list."), $access_choices),
- '$register_text' => array('register_text', t("Register text"), htmlspecialchars(get_config('system','register_text'), ENT_QUOTES, 'UTF-8'), t("Will be displayed prominently on the registration page.")),
+
+ // Register
+ // [hilmar->
+ '$register_text' => [
+ 'register_text',
+ t("Register text"),
+ htmlspecialchars(get_config('system','register_text'), ENT_QUOTES, 'UTF-8'),
+ t("This text will be displayed prominently at the registration page")
+ ],
+ '$register_policy' => [
+ 'register_policy',
+ t("Does this site allow new member registration?"),
+ get_config('system','register_policy'),
+ "",
+ $register_choices,
+ ],
+ '$register_duty' => [
+ 'register_duty',
+ t('Configure the registration open days/hours'),
+ get_config('system', 'register_duty', '-:-'),
+ t('Empty or \'-:-\' value will keep registration open 24/7 (default)') . EOL .
+ t('Weekdays and hours must be separated by colon \':\', From-To ranges with a dash `-` example: 1:800-1200') . EOL .
+ t('Weekday:Hour pairs must be separated by space \' \' example: 1:900-1700 2:900-1700') . EOL .
+ t('From-To ranges must be separated by comma \',\' example: 1:800-1200,1300-1700 or 1-2,4-5:900-1700') . EOL .
+ t('Advanced examples:') . ' 1-5:0900-1200,1300-1700 6:900-1230 ' . t('or') . ' 1-2,4-5:800-1800<br>' . EOL .
+ '<a id="zar083a" class="btn btn-sm btn-outline-secondary zuia">' . t('Check your configuration') . '</a>'. EOL
+ ],
+ '$register_perday' => [
+ 'register_perday',
+ t('Max account registrations per day'),
+ get_config('system', 'max_daily_registrations', 50),
+ t('Unlimited if zero or no value - default 50')
+ ],
+ '$register_sameip' => [
+ 'register_sameip',
+ t('Max account registrations from same IP'),
+ get_config('system', 'register_sameip', 3),
+ t('Unlimited if zero or no value - default 3')
+ ],
+ '$reg_delay' => $reg_delay,
+ '$reg_expire' => $reg_expire,
+ '$reg_autochannel' => [
+ 'auto_channel_create',
+ t("Auto channel create"),
+ get_config('system','auto_channel_create', 1),
+ t("If disabled the channel will be created in a separate step during the registration process")
+ ],
+ '$invitation_only' => [
+ 'invitation_only',
+ t("Require invite code"),
+ $invitation_only
+ ],
+ '$invitation_also' => [
+ 'invitation_also',
+ t("Allow invite code"),
+ $invitation_also
+ ],
+ '$verify_email' => [
+ 'verify_email',
+ t("Require email address"),
+ get_config('system','verify_email'),
+ t("The provided email address will be verified (recommended)")
+ ],
+ '$abandon_days' => [
+ 'abandon_days',
+ t('Abandon account after x days'),
+ get_config('system','account_abandon_days'),
+ t('Will not waste system resources polling external sites for abandonded accounts. Enter 0 for no time limit.')
+ ],
+ // <-hilmar]
+
'$role' => $role,
'$frontpage' => array('frontpage', t("Site homepage to show visitors (default: login box)"), get_config('system','frontpage'), t("example: 'pubstream' to show public stream, 'page/sys/home' to show a system webpage called 'home' or 'include:home.html' to include a file.")),
'$mirror_frontpage' => array('mirror_frontpage', t("Preserve site homepage URL"), get_config('system','mirror_frontpage'), t('Present the site homepage in a frame at the original location instead of redirecting')),
- '$abandon_days' => array('abandon_days', t('Accounts abandoned after x days'), get_config('system','account_abandon_days'), t('Will not waste system resources polling external sites for abandonded accounts. Enter 0 for no time limit.')),
'$allowed_sites' => array('allowed_sites', t("Allowed friend domains"), get_config('system','allowed_sites'), t("Comma separated list of domains which are allowed to establish friendships with this site. Wildcards are accepted. Empty to allow any domains")),
- '$verify_email' => array('verify_email', t("Verify Email Addresses"), get_config('system','verify_email'), t("Check to verify email addresses used in account registration (recommended).")),
'$force_publish' => array('publish_all', t("Force publish"), get_config('system','publish_all'), t("Check to force all profiles on this site to be listed in the site directory.")),
'$disable_discover_tab' => array('disable_discover_tab', t('Import Public Streams'), $discover_tab, t('Import and allow access to public content pulled from other sites. Warning: this content is unmoderated.')),
'$site_firehose' => array('site_firehose', t('Site only Public Streams'), get_config('system','site_firehose'), t('Allow access to public content originating only from this site if Imported Public Streams are disabled.')),
@@ -350,15 +535,184 @@ class Site {
'$maxloadavg' => array('maxloadavg', t("Maximum Load Average"), ((intval(get_config('system','maxloadavg')) > 0)?get_config('system','maxloadavg'):50), t("Maximum system load before delivery and poll processes are deferred - default 50.")),
'$default_expire_days' => array('default_expire_days', t('Expiration period in days for imported (grid/network) content'), intval(get_config('system','default_expire_days')), t('0 for no expiration of imported content')),
'$active_expire_days' => array('active_expire_days', t('Do not expire any posts which have comments less than this many days ago'), intval(get_config('system','active_expire_days',7)), ''),
-
'$sellpage' => array('site_sellpage', t('Public servers: Optional landing (marketing) webpage for new registrants'), get_config('system','sellpage',''), sprintf( t('Create this page first. Default is %s/register'),z_root())),
'$first_page' => array('first_page', t('Page to display after creating a new channel'), get_config('system','workflow_channel_next','profiles'), t('Default: profiles')),
-
'$location' => array('site_location', t('Optional: site location'), get_config('system','site_location',''), t('Region or country')),
-
-
'$form_security_token' => get_form_security_token("admin_site"),
));
}
+ /**
+ * @brief Admin page site common post submit and ajax interaction
+ * @author hilmar runge
+ * @since 2020-02-04
+ * Configure register office duty weekdays and hours
+ * Syntax: weekdays:hours [weekdays:hours]
+ * [.d[,d-d.]]]:hhmm-hhmm[,hhmm-hhmm...]
+ * ranges are between blanks, days are 1-7, where 1 = Monday
+ * hours are [h]hmm 3-4digit 24 clock values
+ * ie 0900-1200,1300-1800 for hours
+ * ie 1-2,4,5 for weekdays
+ * ie 1-2:900-1800 monday and tuesday open from 9 to 18h
+ *
+ * @var $register_duty is the input field from the admin -> site page
+ * @return the results are in the class vars $error, $msgbg and $jsoo
+ * $jsoo is
+ */
+
+ // 3-4 digit 24h clock regex
+ const regxTime34 = '/^(?:2[0-3]|[01][0-9]|[0-9])[0-5][0-9]$/';
+ var $wdconst = array('','mo','tu','we','th','fr','sa','so');
+
+ // in
+ var $register_duty;
+ // intermediate
+ var $isajax;
+ // return
+ var $jsoo;
+ var $msgbg;
+ var $error = 0;
+ var $msgfg = '';
+
+ private function duty() {
+
+ $aro=array_fill(1, 7, 0);
+
+ if ($this->isajax) {
+ $op = (preg_match('/[a-z]{2,4}/', $_REQUEST['zarop'])) ? $_REQUEST['zarop'] : '';
+ if ($op == 'zar083') {
+ $this->msgbg = 'Testmode:' . $this->eol . $this->msgbg;
+ } else {
+ killme();
+ exit;
+ }
+ }
+
+ $ranges = preg_split('/\s+/', $this->register_duty);
+ $this->msgbg .= '..ranges: ' . print_r(count($ranges),true) . $this->eol;
+
+ foreach ($ranges as $rn => $range) {
+ list($ws,$hs,) = explode(':', $range);
+
+ $ws ? $arw = explode( ',', $ws) : $arw=array();
+ $this->msgbg .= ($rn+1).'.weekday ranges: ' . count($arw) . $this->eol;
+ // $this->msgbg .= print_r($arw,true);
+ $hs ? $arh = explode( ',', $hs) : $arh=array();
+ $this->msgbg .= ($rn+1).'.hour ranges: ' . count($arh) . $this->eol;
+
+ $this->msgbg .= ($rn+1).'.wdays: ' . ( $ws ? print_r($ws,true) : 'none') . ' : '
+ . ' hours: ' . print_r($hs,true) . $this->eol;
+
+ // several hs may belog to one wd
+ // aro[0] is tmp store
+ foreach ($arh as $hs) {
+ list($ho,$hc,) = explode( '-', $hs );
+
+ // no value forces open very early, and be sure having valid hhmm values
+ !$ho ? $ho = "0000" : '';
+ !$hc ? $hc = "0000" : ''; // pseudo
+ if (preg_match(self::regxTime34, $ho)
+ && preg_match(self::regxTime34, $hc)) {
+
+ // fix pseudo, allow no reverse range
+ $hc == "0000" || $ho > $hc ? $hc = "2400" : '';
+
+ $aro[0][$ho] = 0;
+ $aro[0][$hc] = 1;
+
+ $this->msgbg .= ($ho ? ' .open:' . $ho : '') . ($hc ? ' close:' . $hc : '') .$this->eol;
+ } else {
+ $this->msgbg .= ' .' . t('Invalid 24h time value (hhmm/hmm)') . $this->eol;
+ $this->msgfg .= ' .ZAR0132E,' . t('Invalid 24h time value (hhmm/hmm)') . $this->eol;
+ $this->error++;
+ }
+ }
+
+ // the weekday(s) values or ranges
+ foreach ($arw as $ds) {
+ $wd=explode('-', $ds);
+ array_key_exists("1", $wd) && $wd[1]=="" ? $wd[1] = "7" : ''; // a case 3-
+ array_key_exists("1", $wd) && $wd[0]=="" ? $wd[0] = "1" : ''; // a case -3
+ !array_key_exists("1", $wd) ? $wd[1] = $wd[0] : ''; // a case 3
+ if ($wd[0] > $wd[1]) continue; // reverse order will be ignored // a case 5-3
+ if (preg_match('/^[1-7]{1}$/', $wd[0])) {
+ if (preg_match('/^[1-7]{1}$/', $wd[1])) {
+ // $this->msgbg .= print_r($wd,true);
+ for ($i=$wd[0]; $i<=$wd[1]; $i++) {
+ // take the tmp store for the selected day(s)
+ $aro[$i]=$aro[0];
+ }
+ }
+ }
+ }
+ //$this->msgbg .= 'aro0: ' . print_r($aro,true) . $this->eol; // 4devels
+ // clear the tmp store
+ $aro[0]=array();
+ }
+ // discart the tmp store
+ unset($aro[0]);
+ // not configured days close at the beginning 0000h
+ for ($i=1;$i<=7;$i++) { is_array($aro[$i]) ? '' : $aro[$i] = array("0000" => 1); }
+ // $this->msgbg .= 'aro: ' . print_r($aro,true) . $this->eol; // 4devels
+
+ if ($this->isajax) {
+ // tell what we have
+ // $this->msgbg .= 'aro0: ' . print_r($aro,true) . $this->eol; // 4devels
+ $this->msgbg .= 'Duty time table:' . $this->eol;
+ foreach ($aro as $dow => $hrs) {
+ $this->msgbg .= ' ' . $this->wdconst[$dow] . ' ';
+ // $this->msgbg .= '**' . print_r($hrs,true);
+ foreach ($hrs as $h => $o) {
+ $this->msgbg .= ((!$o) ? $h . ':open' : $h . ':close') . ', ';
+ }
+ $this->msgbg = rtrim($this->msgbg, ', ') . $this->eol;
+ }
+
+ $this->msgbg .= 'Generating 6 random times to check duty hours: ' . $this->eol;
+ // we only need some random dates from anyway in past or future
+ // because only the weekday and the clock is to test
+ for ($i=0; $i<6; $i++) {
+ $adow = rand(1, 7); // 1 to 7 (days)
+ $cdow = $this->wdconst[$adow];
+ // below is the essential algo to verify a date (of format Hi) meets an open or closed condition
+ $t = date('Hi', ( rand(time(), 60*60*24+time()) ) );
+ $how='close';
+ foreach ($aro[$adow] as $o => $v) {
+ // $this->msgbg .= 'debug: ' . $o . ' gt ' . $t . ' / ' . $v . $this->eol; // 4devels
+ if ($o > $t) {
+ $how = ($v ? 'open' : 'close');
+ break;
+ }
+ }
+ // now we know
+ $this->msgbg .= ' ' . $cdow . '.' . $t . '=' . $how . ', ';
+ }
+ $this->msgbg = rtrim($this->msgbg, ', ') . $this->eol;
+ }
+
+ /*
+ //$jov1 = array( 'view1' => $aro, 'view2' => '');
+ $jov2=array();
+ foreach ($aro as $d => $ts) {
+ foreach ($ts as $t => $ft) {
+ $jov2['view2'][$ft][] = $d.$t;
+ //$ft=="1" && $t=="0000" ? $jov2['view2']["0"][] = $d."2400" : '';
+ }
+ }
+ $this->msgbg .= print_r($jov2, true) . $this->eol; // 4devels
+ */
+
+ $this->joo = json_encode($aro);
+ // $this->msgbg .= $this->joo . $this->eol; // 4devels
+ // $this->msgbg .= print_r($aro, true) . $this->eol; // 4devels
+ $okko = (json_decode($this->joo, true) ? true : false);
+ if (!$okko) {
+ $this->msgbg .= 'ZAR0139D,json 4 duty KO crash' . $this->eol;
+ $this->msgfg .= 'ZAR0139D,json 4 duty KO crash' . $this->eol;
+ $this->error++;
+ }
+ return ;
+ }
+
+
}
diff --git a/Zotlabs/Module/Bookmarks.php b/Zotlabs/Module/Bookmarks.php
index 4b4929c65..822b18308 100644
--- a/Zotlabs/Module/Bookmarks.php
+++ b/Zotlabs/Module/Bookmarks.php
@@ -16,8 +16,8 @@ class Bookmarks extends \Zotlabs\Web\Controller {
nav_set_selected('Bookmarks');
- $item_id = intval($_REQUEST['item']);
- $burl = trim($_REQUEST['burl']);
+ $item_id = (isset($_REQUEST['item']) ? $_REQUEST['item'] : false);
+ $burl = (isset($_REQUEST['burl']) ? trim($_REQUEST['burl']) : '');
if(! $item_id)
return;
@@ -38,7 +38,7 @@ class Bookmarks extends \Zotlabs\Web\Controller {
$item = $i[0];
- $terms = get_terms_oftype($item['term'],TERM_BOOKMARK);
+ $terms = (x($item, 'term') ? get_terms_oftype($item['term'],TERM_BOOKMARK) : false);
if($terms) {
require_once('include/bookmarks.php');
diff --git a/Zotlabs/Module/Cal.php b/Zotlabs/Module/Cal.php
index 65dba927b..329150424 100644
--- a/Zotlabs/Module/Cal.php
+++ b/Zotlabs/Module/Cal.php
@@ -19,45 +19,45 @@ class Cal extends Controller {
if(observer_prohibited()) {
return;
}
-
+
if(argc() > 1) {
$nick = argv(1);
-
+
profile_load($nick);
-
+
$channelx = channelx_by_nick($nick);
-
+
if(! $channelx) {
notice( t('Channel not found.') . EOL);
return;
}
-
+
App::$data['channel'] = $channelx;
-
+
$observer = App::get_observer();
App::$data['observer'] = $observer;
-
+
head_set_icon(App::$data['channel']['xchan_photo_s']);
-
+
App::$page['htmlhead'] .= "<script> var profile_uid = " . ((App::$data['channel']) ? App::$data['channel']['channel_id'] : 0) . "; </script>" ;
-
+
}
-
+
return;
}
-
-
-
+
+
+
function get() {
-
+
if(observer_prohibited()) {
return;
}
-
+
$channel = App::$data['channel'];
// since we don't currently have an event permission - use the stream permission
-
+
if(! perm_is_allowed($channel['channel_id'], get_observer_hash(), 'view_stream')) {
notice( t('Permissions denied.') . EOL);
return;
@@ -76,10 +76,10 @@ class Cal extends Controller {
if(! perm_is_allowed($channel['channel_id'], get_observer_hash(), 'view_contacts') || App::$profile['hide_friends'])
$sql_extra .= " and etype != 'birthday' ";
-
+
$first_day = feature_enabled($channel['channel_id'], 'cal_first_day');
$first_day = (($first_day) ? $first_day : 0);
-
+
$start = '';
$finish = '';
@@ -87,7 +87,7 @@ class Cal extends Controller {
if (x($_GET,'start')) $start = $_GET['start'];
if (x($_GET,'end')) $finish = $_GET['end'];
}
-
+
$start = datetime_convert('UTC','UTC',$start);
$finish = datetime_convert('UTC','UTC',$finish);
$adjust_start = datetime_convert('UTC', date_default_timezone_get(), $start);
@@ -107,10 +107,10 @@ class Cal extends Controller {
// Noting this for now - it will need to be fixed here and in Friendica.
// Ultimately the finish date shouldn't be involved in the query.
$r = q("SELECT event.*, item.plink, item.item_flags, item.author_xchan, item.owner_xchan, item.id as item_id
- from event left join item on event.event_hash = item.resource_id
- where item.resource_type = 'event' and event.uid = %d and event.uid = item.uid
- AND (( event.adjust = 0 AND ( event.dtend >= '%s' or event.nofinish = 1 ) AND event.dtstart <= '%s' )
- OR ( event.adjust = 1 AND ( event.dtend >= '%s' or event.nofinish = 1 ) AND event.dtstart <= '%s' ))
+ from event left join item on event.event_hash = item.resource_id
+ where item.resource_type = 'event' and event.uid = %d and event.uid = item.uid
+ AND (( event.adjust = 0 AND ( event.dtend >= '%s' or event.nofinish = 1 ) AND event.dtstart <= '%s' )
+ OR ( event.adjust = 1 AND ( event.dtend >= '%s' or event.nofinish = 1 ) AND event.dtstart <= '%s' ))
$sql_extra",
intval($channel['channel_id']),
dbesc($start),
@@ -119,7 +119,7 @@ class Cal extends Controller {
dbesc($adjust_finish)
);
}
-
+
if($r) {
xchan_query($r);
$r = fetch_post_tags($r,true);
@@ -127,20 +127,16 @@ class Cal extends Controller {
}
$events = [];
-
+
if($r) {
foreach($r as $rr) {
- $tz = get_iconfig($rr, 'event', 'timezone');
- if(! $tz)
- $tz = 'UTC';
-
- $start = (($rr['adjust']) ? datetime_convert($tz, date_default_timezone_get(), $rr['dtstart'], 'c') : datetime_convert('UTC', 'UTC', $rr['dtstart'], '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($tz, date_default_timezone_get(), $rr['dtend'], 'c') : datetime_convert('UTC', 'UTC', $rr['dtend'], 'c'));
+ $end = (($rr['adjust']) ? datetime_convert('UTC', date_default_timezone_get(), $rr['dtend'], 'c') : datetime_convert('UTC', 'UTC', $rr['dtend'], 'c'));
}
$html = '';
@@ -149,6 +145,10 @@ class Cal extends Controller {
$html = format_event_html($rr);
}
+ $tz = get_iconfig($rr, 'event', 'timezone');
+ if(! $tz)
+ $tz = 'UTC';
+
$events[] = array(
'calendar_id' => 'channel_calendar',
'rw' => true,
@@ -178,7 +178,7 @@ class Cal extends Controller {
echo json_encode($events);
killme();
}
-
+
if (x($_GET,'id')) {
$o = replace_macros(get_markup_template("cal_event.tpl"), [
'$events' => $events
@@ -210,7 +210,7 @@ class Cal extends Controller {
]);
return $o;
-
+
}
-
+
}
diff --git a/Zotlabs/Module/Cdav.php b/Zotlabs/Module/Cdav.php
index fe697a526..e26cdd072 100644
--- a/Zotlabs/Module/Cdav.php
+++ b/Zotlabs/Module/Cdav.php
@@ -135,7 +135,7 @@ class Cdav extends Controller {
$auth = new \Zotlabs\Storage\BasicAuth();
$auth->setRealm(ucfirst(\Zotlabs\Lib\System::get_platform_name()) . 'CalDAV/CardDAV');
- if (local_channel()) {
+ if(local_channel()) {
logger('loggedin');
@@ -153,9 +153,9 @@ class Cdav extends Controller {
$auth->observer = $channel['channel_hash'];
$principalUri = 'principals/' . $channel['channel_address'];
- if(!cdav_principal($principalUri)) {
+ if(! cdav_principal($principalUri)) {
$this->activate($pdo, $channel);
- if(!cdav_principal($principalUri)) {
+ if(! cdav_principal($principalUri)) {
return;
}
}
@@ -168,21 +168,24 @@ class Cdav extends Controller {
if($httpmethod === 'PUT' || $httpmethod === 'DELETE') {
+ $channel = channelx_by_nick(argv(2));
+ $principalUri = 'principals/' . $channel['channel_address'];
$httpuri = $_SERVER['REQUEST_URI'];
logger("debug: method: " . $httpmethod, LOGGER_DEBUG);
logger("debug: uri: " . $httpuri, LOGGER_DEBUG);
- if(strpos($httpuri, 'cdav/addressbooks')) {
+ if(strpos($httpuri, 'cdav/addressbooks') !== false) {
$sync = 'addressbook';
$cdavtable = 'addressbooks';
}
- elseif(strpos($httpuri, 'cdav/calendars')) {
+ elseif(strpos($httpuri, 'cdav/calendars') !== false) {
$sync = 'calendar';
$cdavtable = 'calendarinstances';
}
- else
+ else {
$sync = false;
+ }
if($sync) {
@@ -191,14 +194,13 @@ class Cdav extends Controller {
logger("debug: body: " . $httpbody, LOGGER_DEBUG);
- if($x = get_cdav_id($principalUri, explode("/", $httpuri)[4], $cdavtable)) {
+ if($x = get_cdav_id($principalUri, argv(3), $cdavtable)) {
$cdavdata = $this->get_cdav_data($x['id'], $cdavtable);
-
$etag = (isset($_SERVER['HTTP_IF_MATCH']) ? $_SERVER['HTTP_IF_MATCH'] : false);
// delete
- if($httpmethod === 'DELETE' && $cdavdata['etag'] == $etag)
+ if($httpmethod === 'DELETE' && $cdavdata['etag'] == $etag) {
Libsync::build_sync_packet($channel['channel_id'], [
$sync => [
'action' => 'delete_card',
@@ -206,18 +208,18 @@ class Cdav extends Controller {
'carduri' => $uri
]
]);
+ }
else {
- if($etag) {
+ if($etag && $cdavdata['etag'] !== $etag) {
// update
- if($cdavdata['etag'] !== $etag)
- Libsync::build_sync_packet($channel['channel_id'], [
- $sync => [
- 'action' => 'update_card',
- 'uri' => $cdavdata['uri'],
- 'carduri' => $uri,
- 'card' => $httpbody
- ]
- ]);
+ Libsync::build_sync_packet($channel['channel_id'], [
+ $sync => [
+ 'action' => 'update_card',
+ 'uri' => $cdavdata['uri'],
+ 'carduri' => $uri,
+ 'card' => $httpbody
+ ]
+ ]);
}
else {
// new
@@ -235,7 +237,6 @@ class Cdav extends Controller {
}
}
-
$principalBackend = new \Sabre\DAVACL\PrincipalBackend\PDO($pdo);
$carddavBackend = new \Sabre\CardDAV\Backend\PDO($pdo);
$caldavBackend = new \Sabre\CalDAV\Backend\PDO($pdo);
@@ -268,7 +269,7 @@ class Cdav extends Controller {
// Plugins
$server->addPlugin(new \Sabre\DAV\Auth\Plugin($auth));
- //$server->addPlugin(new \Sabre\DAV\Browser\Plugin());
+ // $server->addPlugin(new \Sabre\DAV\Browser\Plugin());
$server->addPlugin(new \Sabre\DAV\Sync\Plugin());
$server->addPlugin(new \Sabre\DAV\Sharing\Plugin());
$server->addPlugin(new \Sabre\DAVACL\Plugin());
@@ -276,7 +277,7 @@ class Cdav extends Controller {
// CalDAV plugins
$server->addPlugin(new \Sabre\CalDAV\Plugin());
$server->addPlugin(new \Sabre\CalDAV\SharingPlugin());
- //$server->addPlugin(new \Sabre\CalDAV\Schedule\Plugin());
+ // $server->addPlugin(new \Sabre\CalDAV\Schedule\Plugin());
$server->addPlugin(new \Sabre\CalDAV\ICSExportPlugin());
// CardDAV plugins
diff --git a/Zotlabs/Module/Channel.php b/Zotlabs/Module/Channel.php
index 5cf24615d..a7deb4f6b 100644
--- a/Zotlabs/Module/Channel.php
+++ b/Zotlabs/Module/Channel.php
@@ -27,7 +27,7 @@ class Channel extends Controller {
function init() {
- if (in_array(substr($_GET['search'], 0, 1), ['@', '!', '?']) || strpos($_GET['search'], 'https://') === 0)
+ if (array_key_exists('search', $_GET) && (in_array(substr($_GET['search'], 0, 1), ['@', '!', '?']) || strpos($_GET['search'], 'https://') === 0))
goaway(z_root() . '/search?f=&search=' . $_GET['search']);
$which = null;
@@ -155,7 +155,7 @@ class Channel extends Controller {
intval($channel['channel_id'])
);
- opengraph_add_meta($r ? $r[0] : [], $channel);
+ opengraph_add_meta((isset($r) && count($r) ? $r[0] : []), $channel);
}
function get($update = 0, $load = false) {
@@ -168,7 +168,7 @@ class Channel extends Controller {
if (strpos($mid, 'b64.') === 0)
$decoded = @base64url_decode(substr($mid, 4));
- if ($decoded)
+ if (isset($decoded))
$mid = $decoded;
$datequery = ((x($_GET, 'dend') && is_a_date_arg($_GET['dend'])) ? notags($_GET['dend']) : '');
@@ -308,9 +308,9 @@ class Channel extends Controller {
if (($update) && (!$load)) {
if ($mid) {
- $r = q("SELECT parent AS item_id from item where mid like '%s' and uid = %d $item_normal_update
+ $r = q("SELECT parent AS item_id from item where mid = '%s' and uid = %d $item_normal_update
AND item_wall = 1 $simple_update $sql_extra limit 1",
- dbesc($mid . '%'),
+ dbesc($mid),
intval(App::$profile['profile_uid'])
);
}
@@ -328,6 +328,7 @@ class Channel extends Controller {
}
else {
+ $sql_extra2 = '';
if (x($category)) {
$sql_extra2 .= protect_sprintf(term_item_parent_query(App::$profile['profile_uid'], 'item', $category, TERM_CATEGORY));
}
@@ -355,9 +356,9 @@ class Channel extends Controller {
if ($noscript_content || $load) {
if ($mid) {
- $r = q("SELECT parent AS item_id from item where mid like '%s' and uid = %d $item_normal
+ $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 . '%'),
+ dbesc($mid),
intval(App::$profile['profile_uid'])
);
if (!$r) {
@@ -419,7 +420,7 @@ class Channel extends Controller {
if ((!$update) && (!$load)) {
- if ($decoded)
+ if (isset($decoded))
$mid = 'b64.' . base64url_encode($mid);
// This is ugly, but we can't pass the profile_uid through the session to the ajax updater,
@@ -485,7 +486,7 @@ class Channel extends Controller {
$o .= conversation($items, $mode, $update, $page_mode);
- if ($mid && $items[0]['title'])
+ if ($mid && count($items) > 0 && isset($items[0]['title']))
App::$page['title'] = $items[0]['title'] . " - " . App::$page['title'];
}
diff --git a/Zotlabs/Module/Channel_calendar.php b/Zotlabs/Module/Channel_calendar.php
index ac1545644..26c6aaf40 100644
--- a/Zotlabs/Module/Channel_calendar.php
+++ b/Zotlabs/Module/Channel_calendar.php
@@ -116,7 +116,7 @@ class Channel_calendar extends Controller {
if ($results) {
// Set permissions based on tag replacements
- set_linkified_perms($results, $str_contact_allow, $str_group_allow, $uid, false, $private);
+ set_linkified_perms($results, $str_contact_allow, $str_group_allow, $uid, $private);
foreach ($results as $result) {
$success = $result['success'];
diff --git a/Zotlabs/Module/Cloud.php b/Zotlabs/Module/Cloud.php
index 3d1b97980..6ff95b5cf 100644
--- a/Zotlabs/Module/Cloud.php
+++ b/Zotlabs/Module/Cloud.php
@@ -123,7 +123,8 @@ class Cloud extends Controller {
notice( t('Permission denied') . EOL);
}
elseif($err instanceof \Sabre\DAV\Exception\NotImplemented) {
- notice( t('Please refresh page') . EOL);
+ // notice( t('Please refresh page') . EOL);
+ goaway(z_root() . '/' . \App::$query_string);
}
else {
notice( t('Unknown error') . EOL);
diff --git a/Zotlabs/Module/Connect.php b/Zotlabs/Module/Connect.php
index 31da42035..b934cb963 100644
--- a/Zotlabs/Module/Connect.php
+++ b/Zotlabs/Module/Connect.php
@@ -18,11 +18,11 @@ class Connect extends Controller {
App::$error = 404;
return;
}
-
+
$r = q("select * from channel where channel_address = '%s' limit 1",
dbesc($which)
);
-
+
if($r)
App::$data['channel'] = $r[0];
@@ -30,36 +30,36 @@ class Connect extends Controller {
profile_load($which,'');
}
-
+
function post() {
-
+
if(! array_key_exists('channel', App::$data))
return;
$channel_id = App::$data['channel']['channel_id'];
$edit = ((local_channel() && (local_channel() == $channel_id)) ? true : false);
-
+
if($edit) {
$has_premium = ((App::$data['channel']['channel_pageflags'] & PAGE_PREMIUM) ? 1 : 0);
$premium = (($_POST['premium']) ? intval($_POST['premium']) : 0);
$text = escape_tags($_POST['text']);
-
+
if($has_premium != $premium) {
$r = q("update channel set channel_pageflags = ( channel_pageflags %s %d ) where channel_id = %d",
db_getfunc('^'),
intval(PAGE_PREMIUM),
- intval(local_channel())
+ intval(local_channel())
);
-
+
\Zotlabs\Daemon\Master::Summon(array('Notifier','refresh_all',$channel_id));
}
set_pconfig($channel_id,'system','selltext',$text);
// reload the page completely to get fresh data
goaway(z_root() . '/' . App::$query_string);
-
+
}
-
+
$url = '';
$observer = App::get_observer();
if(($observer) && ($_POST['submit'] === t('Continue'))) {
@@ -70,18 +70,18 @@ class Connect extends Controller {
dbesc($observer['xchan_hash'])
);
if($r)
- $url = $r[0]['hubloc_url'] . '/follow?f=&url=' . urlencode(channel_reddress(App::$data['channel']));
+ $url = $r[0]['hubloc_url'] . '/follow?f=&interactive=1&url=' . urlencode(channel_reddress(App::$data['channel']));
}
}
if($url)
goaway($url . '&confirm=1');
else
notice('Unable to connect to your home hub location.');
-
+
}
-
-
-
+
+
+
function get() {
if(! array_key_exists('channel', App::$data))
@@ -90,11 +90,11 @@ class Connect extends Controller {
$channel_id = App::$data['channel']['channel_id'];
$edit = ((local_channel() && (local_channel() == $channel_id)) ? true : false);
-
+
$text = get_pconfig($channel_id,'system','selltext');
-
+
if($edit) {
-
+
$o = replace_macros(get_markup_template('sellpage_edit.tpl'),array(
'$header' => t('Premium Channel Setup'),
'$address' => App::$data['channel']['channel_address'],
@@ -105,36 +105,36 @@ class Connect extends Controller {
'$lbl2' => t('Potential connections will then see the following text before proceeding:'),
'$desc2' => t('By continuing, I certify that I have complied with any instructions provided on this page.'),
'$submit' => t('Submit'),
-
-
+
+
));
return $o;
}
else {
if(! $text)
$text = t('(No specific instructions have been provided by the channel owner.)');
-
+
$submit = replace_macros(get_markup_template('sellpage_submit.tpl'), array(
- '$continue' => t('Continue'),
+ '$continue' => t('Continue'),
'$address' => App::$data['channel']['channel_address']
));
-
+
$o = replace_macros(get_markup_template('sellpage_view.tpl'),array(
'$header' => t('Restricted or Premium Channel'),
'$desc' => t('This channel may require additional steps or acknowledgement of the following conditions prior to connecting:'),
- '$text' => prepare_text($text),
-
+ '$text' => prepare_text($text),
+
'$desc2' => t('By continuing, I certify that I have complied with any instructions provided on this page.'),
'$submit' => $submit,
-
+
));
-
+
$arr = array('channel' => App::$data['channel'],'observer' => App::get_observer(), 'sellpage' => $o, 'submit' => $submit);
call_hooks('connect_premium', $arr);
$o = $arr['sellpage'];
-
+
}
-
+
return $o;
}
}
diff --git a/Zotlabs/Module/Directory.php b/Zotlabs/Module/Directory.php
index 7295f3099..e1555fc2d 100644
--- a/Zotlabs/Module/Directory.php
+++ b/Zotlabs/Module/Directory.php
@@ -245,7 +245,7 @@ class Directory extends Controller {
$profile_link = chanlink_url($rr['url']);
$pdesc = (($rr['description']) ? $rr['description'] . '<br />' : '');
- $connect_link = ((local_channel()) ? z_root() . '/follow?f=&url=' . urlencode($rr['address']) : '');
+ $connect_link = ((local_channel()) ? z_root() . '/follow?f=&interactive=1&url=' . urlencode($rr['address']) : '');
// Checking status is disabled ATM until someone checks the performance impact more carefully
//$online = remote_online_status($rr['address']);
diff --git a/Zotlabs/Module/Display.php b/Zotlabs/Module/Display.php
index 15dfb0dc9..e6caa9906 100644
--- a/Zotlabs/Module/Display.php
+++ b/Zotlabs/Module/Display.php
@@ -97,8 +97,8 @@ class Display extends \Zotlabs\Web\Controller {
if($decoded)
$item_hash = $decoded;
- $r = q("select id, uid, mid, parent, parent_mid, thr_parent, verb, item_type, item_deleted, author_xchan, item_blocked from item where mid like '%s' limit 1",
- dbesc($item_hash . '%')
+ $r = q("select id, uid, mid, parent, parent_mid, thr_parent, verb, item_type, item_deleted, author_xchan, item_blocked from item where mid = '%s' limit 1",
+ dbesc($item_hash)
);
if($r) {
@@ -247,69 +247,62 @@ class Display extends \Zotlabs\Web\Controller {
if($noscript_content || $load) {
- $r = null;
-
require_once('include/channel.php');
$sys = get_sys_channel();
- $sysid = $sys['channel_id'];
+ // in case somebody turned off public access to sys channel content using permissions
+ // make that content unsearchable by ensuring the owner uid can't match
+ $sys_id = perm_is_allowed($sys['channel_id'], $observer_hash, 'view_stream') ? $sys['channel_id'] : 0;
+
+ $r = null;
if(local_channel()) {
- $r = q("SELECT item.id as item_id from item WHERE uid = %d and mid = '%s' $item_normal limit 1",
+ $r = q("SELECT item.id AS item_id FROM item WHERE uid = %d AND mid = '%s' $item_normal LIMIT 1",
intval(local_channel()),
dbesc($target_item['parent_mid'])
);
}
- if($r === null) {
- // in case somebody turned off public access to sys channel content using permissions
- // make that content unsearchable by ensuring the owner uid can't match
-
- if(! perm_is_allowed($sysid,$observer_hash,'view_stream'))
- $sysid = 0;
-
- $r = q("SELECT item.id as item_id from item
+ if(!$r) {
+ $r = q("SELECT item.id AS item_id FROM item
WHERE ((mid = '%s'
- AND (((( item.allow_cid = '' AND item.allow_gid = '' AND item.deny_cid = ''
+ AND (((( item.allow_cid = '' AND item.allow_gid = '' AND item.deny_cid = ''
AND item.deny_gid = '' AND item_private = 0 )
- and uid in ( " . stream_perms_api_uids(($observer_hash) ? (PERMS_NETWORK|PERMS_PUBLIC) : PERMS_PUBLIC) . " ))
+ AND uid IN ( " . stream_perms_api_uids(($observer_hash) ? (PERMS_NETWORK|PERMS_PUBLIC) : PERMS_PUBLIC) . " ))
OR uid = %d ))) OR
(mid = '%s' $sql_extra ))
$item_normal
limit 1",
dbesc($target_item['parent_mid']),
- intval($sysid),
+ intval($sys_id),
dbesc($target_item['parent_mid'])
);
}
}
elseif($update && !$load) {
- $r = null;
-
require_once('include/channel.php');
$sys = get_sys_channel();
- $sysid = $sys['channel_id'];
+ // in case somebody turned off public access to sys channel content using permissions
+ // make that content unsearchable by ensuring the owner uid can't match
+ $sys_id = perm_is_allowed($sys['channel_id'], $observer_hash, 'view_stream') ? $sys['channel_id'] : 0;
+
+ $r = null;
if(local_channel()) {
$r = q("SELECT item.parent AS item_id from item
WHERE uid = %d
- and parent_mid = '%s'
+ AND parent_mid = '%s'
$item_normal_update
$simple_update
- limit 1",
+ LIMIT 1",
intval(local_channel()),
dbesc($target_item['parent_mid'])
);
}
- if($r === null) {
- // in case somebody turned off public access to sys channel content using permissions
- // make that content unsearchable by ensuring the owner_xchan can't match
-
- if(! perm_is_allowed($sysid,$observer_hash,'view_stream'))
- $sysid = 0;
+ if(! $r) {
$r = q("SELECT item.id as item_id from item
WHERE ((parent_mid = '%s'
- AND (((( item.allow_cid = '' AND item.allow_gid = '' AND item.deny_cid = ''
+ AND (((( item.allow_cid = '' AND item.allow_gid = '' AND item.deny_cid = ''
AND item.deny_gid = '' AND item_private = 0 )
and uid in ( " . stream_perms_api_uids(($observer_hash) ? (PERMS_NETWORK|PERMS_PUBLIC) : PERMS_PUBLIC) . " ))
OR uid = %d ))) OR
@@ -317,14 +310,14 @@ class Display extends \Zotlabs\Web\Controller {
$item_normal
limit 1",
dbesc($target_item['parent_mid']),
- intval($sysid),
+ intval($sys_id),
dbesc($target_item['parent_mid'])
);
}
}
else {
- $r = array();
+ $r = [];
}
if($r) {
@@ -332,7 +325,7 @@ class Display extends \Zotlabs\Web\Controller {
if($parents_str) {
$items = q("SELECT item.*, item.id AS item_id
FROM item
- WHERE parent in ( %s ) $item_normal ",
+ WHERE parent in ( %s ) $sql_extra $item_normal ",
dbesc($parents_str)
);
xchan_query($items);
diff --git a/Zotlabs/Module/Follow.php b/Zotlabs/Module/Follow.php
index 11febd8fc..4fe20f56b 100644
--- a/Zotlabs/Module/Follow.php
+++ b/Zotlabs/Module/Follow.php
@@ -14,7 +14,7 @@ use Zotlabs\Daemon\Master;
class Follow extends Controller {
function init() {
-
+
if (ActivityStreams::is_as_request() && argc() == 2) {
$abook_id = intval(argv(1));
@@ -73,11 +73,11 @@ class Follow extends Controller {
$url = notags(trim(punify($_REQUEST['url'])));
$return_url = $_SESSION['return_url'];
$confirm = intval($_REQUEST['confirm']);
- $interactive = (($_REQUEST['interactive']) ? intval($_REQUEST['interactive']) : 1);
+ $interactive = (($_REQUEST['interactive']) ? intval($_REQUEST['interactive']) : 1);
$channel = App::get_channel();
$result = Connect::connect($channel,$url);
-
+
if ($result['success'] == false) {
if ($result['message']) {
notice($result['message']);
@@ -89,9 +89,9 @@ class Follow extends Controller {
json_return_and_die($result);
}
}
-
+
info( t('Connection added.') . EOL);
-
+
$clone = array();
foreach ($result['abook'] as $k => $v) {
if (strpos($k,'abook_') === 0) {
@@ -101,30 +101,30 @@ class Follow extends Controller {
unset($clone['abook_id']);
unset($clone['abook_account']);
unset($clone['abook_channel']);
-
+
$abconfig = load_abconfig($channel['channel_id'],$clone['abook_xchan']);
if ($abconfig) {
$clone['abconfig'] = $abconfig;
}
Libsync::build_sync_packet(0, [ 'abook' => [ $clone ] ], true);
-
+
$can_view_stream = their_perms_contains($channel['channel_id'],$clone['abook_xchan'],'view_stream');
-
+
// If we can view their stream, pull in some posts
-
+
if (($can_view_stream) || ($result['abook']['xchan_network'] === 'rss')) {
Master::Summon([ 'Onepoll', $result['abook']['abook_id'] ]);
}
-
+
if ($interactive) {
goaway(z_root() . '/connedit/' . $result['abook']['abook_id'] . '?follow=1');
}
else {
json_return_and_die([ 'success' => true ]);
}
-
+
}
-
+
function get() {
if (! local_channel()) {
return login();
diff --git a/Zotlabs/Module/Hq.php b/Zotlabs/Module/Hq.php
index 4c2067299..a2c4100ad 100644
--- a/Zotlabs/Module/Hq.php
+++ b/Zotlabs/Module/Hq.php
@@ -41,7 +41,7 @@ class Hq extends \Zotlabs\Web\Controller {
if(argc() > 1 && argv(1) !== 'load') {
$item_hash = argv(1);
}
-
+
if($_REQUEST['mid'])
$item_hash = $_REQUEST['mid'];
@@ -49,9 +49,9 @@ class Hq extends \Zotlabs\Web\Controller {
$item_normal_update = item_normal_update();
if(! $item_hash) {
- $r = q("SELECT mid FROM item
+ $r = q("SELECT mid FROM item
WHERE uid = %d $item_normal
- AND mid = parent_mid
+ AND mid = parent_mid
ORDER BY created DESC LIMIT 1",
intval(local_channel())
);
@@ -71,10 +71,10 @@ class Hq extends \Zotlabs\Web\Controller {
$target_item = null;
- $r = q("select id, uid, mid, parent_mid, thr_parent, verb, item_type, item_deleted, item_blocked from item where mid like '%s' limit 1",
- dbesc($item_hash . '%')
+ $r = q("select id, uid, mid, parent_mid, thr_parent, verb, item_type, item_deleted, item_blocked from item where mid = '%s' limit 1",
+ dbesc($item_hash)
);
-
+
if($r) {
$target_item = $r[0];
}
@@ -83,7 +83,7 @@ class Hq extends \Zotlabs\Web\Controller {
if($target_item['item_blocked'] == ITEM_MODERATED) {
goaway(z_root() . '/moderate/' . $target_item['id']);
}
-
+
$simple_update = '';
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']) . "' ) ";
@@ -94,16 +94,16 @@ class Hq extends \Zotlabs\Web\Controller {
$sys_item = false;
}
-
+
if(! $update) {
$channel = \App::get_channel();
$channel_acl = [
- 'allow_cid' => $channel['channel_allow_cid'],
- 'allow_gid' => $channel['channel_allow_gid'],
- 'deny_cid' => $channel['channel_deny_cid'],
+ 'allow_cid' => $channel['channel_allow_cid'],
+ 'allow_gid' => $channel['channel_allow_gid'],
+ 'deny_cid' => $channel['channel_deny_cid'],
'deny_gid' => $channel['channel_deny_gid']
- ];
+ ];
$x = [
'is_owner' => true,
@@ -143,7 +143,7 @@ class Hq extends \Zotlabs\Web\Controller {
// if the target item is not a post (eg a like) we want to address its thread parent
//$mid = ((($target_item['verb'] == ACTIVITY_LIKE) || ($target_item['verb'] == ACTIVITY_DISLIKE)) ? $target_item['thr_parent'] : $target_item['mid']);
$mid = $target_item['mid'];
- // if we got a decoded hash we must encode it again before handing to javascript
+ // if we got a decoded hash we must encode it again before handing to javascript
if($decoded)
$mid = 'b64.' . base64url_encode($mid);
}
@@ -154,7 +154,7 @@ class Hq extends \Zotlabs\Web\Controller {
$o .= '<div id="live-hq"></div>' . "\r\n";
$o .= "<script> var profile_uid = " . local_channel()
. "; var netargs = '?f='; var profile_page = " . \App::$pager['page'] . ";</script>\r\n";
-
+
\App::$page['htmlhead'] .= replace_macros(get_markup_template("build_query.tpl"),[
'$baseurl' => z_root(),
'$pgtype' => 'hq',
@@ -241,14 +241,14 @@ class Hq extends \Zotlabs\Web\Controller {
else {
$r = [];
}
-
+
if($r) {
- $items = q("SELECT item.*, item.id AS item_id
+ $items = q("SELECT item.*, item.id AS item_id
FROM item
WHERE parent = '%s' $item_normal ",
dbesc($r[0]['item_id'])
);
-
+
xchan_query($items,true,(($sys_item) ? local_channel() : 0));
$items = fetch_post_tags($items,true);
$items = conv_sort($items,'created');
diff --git a/Zotlabs/Module/Invite.php b/Zotlabs/Module/Invite.php
index 6359da54c..34f1858fd 100644
--- a/Zotlabs/Module/Invite.php
+++ b/Zotlabs/Module/Invite.php
@@ -6,7 +6,7 @@ use Zotlabs\Lib\Apps;
use Zotlabs\Web\Controller;
/**
- * module: invite.php
+ * module: invitexv2.php
*
* send email invitations to join social network
*
@@ -15,91 +15,291 @@ use Zotlabs\Web\Controller;
class Invite extends Controller {
+ /**
+ * While coding this, I want to introduce a system of qualified messages and notifications.
+ * Each message consists of a 3 letter prefix, a 4 digit number and a one letter suffix (PREnnnnS).
+ * The spirit about is not from me, but many decades used by IBM inc. in devel with best success.
+ *
+ * The system prefix, used uppercase as system message id, lowercase as css and js prefix (classes, ids etc).
+ * Usually not used as self::MYP, but placed in the code dominant enough for easy to find.
+ *
+ * Concrete here:
+ * The prefix indicates Z for the Zlabs(core), A for Account stuff, I for Invite.
+ * The numbers scope will be 00xx within/for templates, 01xx for get, 02xx for post functions.
+ * Message qualification ends with a uppercase suffix, where
+ * I=Info(only),
+ * W=Warning(more then info and less then error),
+ * E=Error,
+ * F=Fatal(for unexpected errors).
+ * Btw, in case of using fail2ban, a scan of messages going to log is very much more with ease,
+ * esspecially in multi language driven systems where messages vary.
+ *
+ * @author Hilmar Runge
+ * @version 2.0.0
+ * @since 2020-01-20
+ *
+ */
+
+ const MYP = 'ZAI';
+ const VERSION = '2.0.0';
+
function post() {
-
- if(! local_channel()) {
- notice( t('Permission denied.') . EOL);
+
+ // zai02
+
+ if (! local_channel()) {
+ notice( 'ZAI0201E,' .t('Permission denied.') . EOL);
return;
}
- if(! Apps::system_app_installed(local_channel(), 'Invite')) {
+ if (! Apps::system_app_installed(local_channel(), 'Invite')) {
+ notice( 'ZAI0202E,' . t('Invite App') . ' (' . t('Not Installed') . ')' . EOL);
return;
}
-
+
check_form_security_token_redirectOnErr('/', 'send_invite');
-
- $max_invites = intval(get_config('system','max_invites'));
- if(! $max_invites)
- $max_invites = 50;
-
- $current_invites = intval(get_pconfig(local_channel(),'system','sent_invites'));
- if($current_invites > $max_invites) {
- notice( t('Total invitation limit exceeded.') . EOL);
+
+ $ok = $ko = 0;
+ $feedbk = '';
+ $isajax = is_ajax();
+ $eol = $isajax ? "\n" : EOL;
+ $policy = intval(get_config('system','register_policy'));
+ if ($policy == REGISTER_CLOSED) {
+ notice( 'ZAI0212E,' . t('Register is closed') . ')' . EOL);
return;
- };
-
-
- $recips = ((x($_POST,'recipients')) ? explode("\n",$_POST['recipients']) : array());
- $message = ((x($_POST,'message')) ? notags(trim($_POST['message'])) : '');
-
- $total = 0;
-
- if(get_config('system','invitation_only')) {
- $invonly = true;
- $x = get_pconfig(local_channel(),'system','invites_remaining');
- if((! $x) && (! is_site_admin()))
- return;
- }
-
- foreach($recips as $recip) {
-
- $recip = trim($recip);
- if(! $recip)
- continue;
-
- if(! validate_email($recip)) {
- notice( sprintf( t('%s : Not a valid email address.'), $recip) . EOL);
- continue;
+ }
+ if ($policy == REGISTER_OPEN)
+ $flags = 0;
+ elseif ($policy == REGISTER_APPROVE)
+ $flags = ACCOUNT_PENDING;
+ $flags = ($flags | intval(get_config('system','verify_email')));
+
+ // how many max recipients in one mail submit
+ $maxto = get_config('system','invitation_max_recipients', 'na');
+ If (is_site_admin()) {
+ // set, if admin is operator, default to 12
+ if ($maxto === 'na') set_config('system','invitation_max_recipients', 12);
+ }
+ $maxto = ($maxto === 'na') ? 12 : $maxto;
+
+ // language code current for the invitation
+ $lcc = x($_POST['zailcc']) && preg_match('/[a-z\-]{2,5}/', $_POST['zailcc'])
+ ? $_POST['zailcc']
+ : '';
+
+ // expiration duration amount quantity, in case of doubts defaults 2
+ $durn = x($_POST['zaiexpiren']) && preg_match('/[0-9]{1,2}/', $_POST['zaiexpiren'])
+ ? trim(intval($_POST['zaiexpiren']))
+ : '2';
+ !$durn ? $durn = 2 : '';
+
+ // expiration duration unit 1st letter (day, weeks, months, years), defaults days
+ $durq = x($_POST['zaiexpire']) && preg_match('/[ihd]{1,1}/', $_POST['zaiexpire'])
+ ? $_POST['zaiexpire']
+ : 'd';
+
+ $dur = self::calcdue($durn.$durq);
+ $due = t('Note, the invitation code is valid up to') . ' ' . $dur['due'];
+
+ if ($isajax) {
+ $feedbk .= 'ZAI0207I ' . $due . $eol;
+ }
+
+ // take the received email addresses and discart duplicates
+ $recips = array_filter( array_unique( preg_replace('/^\s*$/', '',
+ ((x($_POST,'zaito')) ? explode( "\n",$_POST['zaito']) : array() ) )));
+
+ $havto = count($recips);
+
+ if ( $havto > $maxto) {
+ $feedbk .= 'ZAI0210E ' . sprintf( t('Too many recipients for one invitation (max %d)'), $maxto) . $eol;
+ $ko++;
+
+ } elseif ( $havto == 0 ) {
+ $feedbk .= 'ZAI0211E ' . t('No recipients for this invitation') . $eol;
+ $ko++;
+
+ } else {
+
+ // each email address
+ foreach($recips as $n => $recip) {
+
+ // if empty ignore
+ $recip = $recips[$n] = trim($recip);
+ if(! $recip) continue;
+
+ // see if we have an email address who@domain.tld
+ if (!preg_match('/^.{2,64}\@[a-z0-9.-]{4,32}\.[a-z]{2,12}$/', $recip)) {
+ $feedbk .= 'ZAI0203E ' . ($n+1) . ': ' . sprintf( t('(%s) : Not a valid email address'), $recip) . $eol;
+ $ko++;
+ continue;
+ }
+ if(! validate_email($recip)) {
+ $feedbk .= 'ZAI0204E ' . ($n+1) . ': ' . sprintf( t('(%s) : Not a real email address'), $recip) . $eol;
+ $ko++;
+ continue;
+ }
+
+ // do we accept the email (not black listed)
+ if(! allowed_email($recip)) {
+ $feedbk .= 'ZAI0205E ' . ($n+1) . ': ' . sprintf( t('(%s) : Not allowed email address'), $recip) . $eol;
+ $ko++;
+ continue;
+ }
+
+ // is the email address just in use for account or registered before
+ $r = q("SELECT account_email AS em FROM account WHERE account_email = '%s'"
+ . " UNION "
+ ."SELECT reg_email AS em FROM register WHERE reg_vital = 1 AND reg_email = '%s' LIMIT 1;",
+ dbesc($recip),
+ dbesc($recip)
+ );
+ if($r && $r[0]['em'] == $recip) {
+ $feedbk .= 'ZAI0206E ' . ($n+1) . ': ' . sprintf( t('(%s) : email address already in use'), $recip) . $eol;
+ $ko++;
+ continue;
+ }
+
+ if ($isajax) {
+ // seems we have an email address acceptable
+ $feedbk .= 'ZAI0209I ' . ($n+1) . ': ' . sprintf( t('(%s) : Accepted email address'), $recip) . $eol;
+ }
}
-
- else
- $nmessage = $message;
-
- $account = App::get_account();
-
- $res = z_mail(
- [
+ }
+
+ if ($isajax) {
+ // we are not silent on the ajax road
+ echo json_encode(array('feedbk' => $feedbk, 'due' => $due));
+
+ // that mission is complete
+ killme();
+ exit;
+ }
+
+ // Total ?todo notice( t('Invitation limit exceeded. Please contact your site administrator.') . EOL);
+
+ // any errors up to now in fg?
+
+
+ // down from here, only on the main road (no more ajax)
+
+ // tell if sth is to tell
+ $feedbk ? notice($feedbk) . $eol : '';
+
+ if ($ko > 0) return;
+
+ // the personal mailtext
+ $mailtext = ((x($_POST,'zaitxt')) ? notags(trim($_POST['zaitxt'])) : '');
+
+ // to log in db
+ $reonar = json_decode( ((x($_POST,'zaireon')) ? notags(trim($_POST['zaireon'])) : ''), TRUE, 8) ;
+
+ // me, the invitor
+ $account = App::get_account();
+ $reonar['from'] = $account['account_email'];
+ $reonar['date'] = datetime_convert();
+ $reonar['fromip'] = $_SERVER['REMOTE_ADDR'];
+
+ // who is the invitor on
+ $inby = local_channel();
+
+ $ok = $ko = 0;
+
+ // send the mail(s)
+ foreach($recips as $n => $recip) {
+
+ $reonar['due'] = $due;
+ $reonar['to'] = $recip;
+ $reonar['txtpersonal'] = $mailtext;
+
+ // generate an invide code to store and pm
+ $invite_code = autoname(8) . rand(1000,9999);
+
+ // again the final localized templates $reonar['subject'] $reonar['lang'] $reonar['tpl']
+
+ // save current operators lc and take the desired to mail
+ push_lang($reonar['lang']);
+ // resolve
+ $tx = replace_macros(get_intltext_template('invite.'.$reonar['tpl'].'.tpl'),
+ array(
+ '$projectname' => t('$Projectname'),
+ '$invite_code' => $invite_code,
+ '$invite_where' => z_root() . '/register',
+ '$invite_whereami' => str_replace('@', '@+', $reonar['whereami']),
+ '$invite_whoami' => z_root() . '/channel/' . $reonar['whoami'],
+ '$invite_anywhere' => z_root() . '/pubsites'
+ )
+ );
+ // restore lc to operator
+ pop_lang();
+
+ $reonar['txttemplate'] = $tx;
+
+ // pm
+ $zem = z_mail(
+ [
'toEmail' => $recip,
'fromName' => ' ',
- 'fromEmail' => $account['account_email'],
- 'messageSubject' => t('Please join us on $Projectname'),
- 'textVersion' => $nmessage,
+ 'fromEmail' => $reonar['from'],
+ 'messageSubject' => $reonar['subject'],
+ 'textVersion' => ($mailtext ? $mailtext . "\n\n" : '') . $tx . "\n" . $due,
]
);
-
- if($res) {
- $total ++;
- $current_invites ++;
- set_pconfig(local_channel(),'system','sent_invites',$current_invites);
- if($current_invites > $max_invites) {
- notice( t('Invitation limit exceeded. Please contact your site administrator.') . EOL);
- return;
- }
- }
- else {
- notice( sprintf( t('%s : Message delivery failed.'), $recip) . EOL);
+
+ if(!$zem) {
+
+ $ko++;
+ $msg = 'ZAI0208E,' . sprintf( t('%s : Message delivery failed.'), $recip);
+
+ } else {
+
+ $ok++;
+ $msg = 'ZAI0208I ' . sprintf( t('To %s : Message delivery success.'), $recip);
+
+ // if verify_email is the rule, email becomes a dId2 - NO
+ // $did2 = ($flags & ACCOUNT_UNVERIFIED) == ACCOUNT_UNVERIFIED ? $recip : '';
+
+ // always enforce verify email with invitations, thus email becomes a dId2
+ $did2 = $recip;
+ $flags |= ACCOUNT_UNVERIFIED;
+
+ // defaults vital, reg_pass
+ $r = q("INSERT INTO register ("
+ . "reg_flags,reg_didx,reg_did2,reg_hash,reg_created,reg_startup,reg_expires,reg_email,reg_byc,reg_uid,reg_atip,reg_lang,reg_stuff)"
+ . " VALUES ( %d, 'i', '%s', '%s', '%s', '%s', '%s', '%s', %d, %d, '%s', '%s', '%s') ",
+ intval($flags),
+ dbesc($did2),
+ dbesc($invite_code),
+ dbesc(datetime_convert()),
+ dbesc(datetime_convert()),
+ dbesc($dur['due']),
+ dbesc($recip),
+ intval($inby),
+ intval($account['account_id']),
+ dbesc($reonar['fromip']),
+ dbesc($reonar['lang']),
+ dbesc(json_encode( array('reon' => $reonar) ))
+ );
}
-
+ $msg .= ' (a' . $account['account_id'] . ', c' . $inby . ', from:' . $reonar['from'] . ')';
+ zar_log( $msg);
}
- notice( sprintf( tt("%d message sent.", "%d messages sent.", $total) , $total) . EOL);
+
+ $ok + $ko > 0
+ ? notice( 'ZAI0212I ' . sprintf( t('%1$d mail(s) sent, %2$d mail error(s)'), $ok, $ko) . EOL)
+ : '';
+ //logger( print_r( $reonar, true) );
+
return;
}
-
-
+
+
function get() {
-
+
+ // zai1
+
if(! local_channel()) {
- notice( t('Permission denied.') . EOL);
+ notice( 'ZAI0101E,' . t('Permission denied.') . EOL);
return;
}
@@ -107,68 +307,267 @@ class Invite extends Controller {
//Do not display any associated widgets at this point
App::$pdl = '';
- $o = '<b>' . t('Invite App') . ' (' . t('Not Installed') . '):</b><br>';
- $o .= t('Send email invitations to join this network');
+ $o = 'ZAI0102E,' . t('Invite App') . ' (' . t('Not Installed') . ')' . EOL;
return $o;
}
+ if (! (get_config('system','invitation_also') || get_config('system','invitation_only')) ) {
+ $o = 'ZAI0103E,' . t('Invites not proposed by configuration') . '. ';
+ $o .= t('Contact the site admin');
+ return $o;
+ }
+
+ // invitation_by_user may still not configured, the default 'na' will tell this
+ // if configured, 0 disables invitations by users, other numbers are how many invites a user may propagate
+ $invuser = get_config('system','invitation_by_user', 'na');
+
+ // if the mortal user drives the invitation
+ If (! is_site_admin()) {
+
+ // when not configured, 4 is the default
+ $invuser = ($invuser === 'na') ? 4 : $invuser;
+
+ // a config value 0 disables invitation by users
+ if (!$invuser) {
+ $o = 'ZAI0104E, ' . t('Invites by users not enabled') . '. ';
+ return $o;
+ }
+
+ if ($ihave >= $invuser) {
+ notice( 'ZAI0105W,' . t('You have no more invitations available') . EOL);
+ return '';
+ }
+
+ } else {
+ // general deity admin invite limit infinite (theoretical)
+ if ($invuser === 'na') set_config('system','invitation_by_user', 4);
+ // for display only
+ $invuser = '∞';
+ }
+
+ // xchan record of the page observer
+ // while quoting matters the user, the sending is associated with a channel (of the user)
+ // also the admin may and should decide, which channel will told to the public
+ $ob = App::get_observer();
+ if(! $ob)
+ return 'ZAI0109F,' . t('Not on xchan') . EOL;
+ $whereami = $ob['xchan_addr'];
+ $channel = App::get_channel();
+ $whoami = $channel['channel_address'];
+
+ // to pass also to post()
+ $tao = 'tao.zai.whereami = ' . "'" . $whereami . "';\n"
+ . 'tao.zai.whoami = ' . "'" . $whoami . "';\n";
+
+ // expirations, duration interval
+ $dur = self::calcdue();
+ $tao .= 'tao.zai.expire = { durn: ' . $dur['durn']
+ . ', durq: ' . "'" . $dur['durq'] . "'"
+ . ', due: ' . "'" . $dur['due'] . "' };\n";
+
+ // to easy redisplay the empty form
nav_set_selected('Invite');
-
+
+ // inform about the count of invitations we have at all
+ $r = q("SELECT count(reg_id) as ct FROM register WHERE reg_vital = 1"); // where not admin TODO
+ $wehave = ($r ? $r[0]['ct'] : 0);
+
+ // invites max for all users except admins
+ $invmaxau = intval(get_config('system','invitations_max_users'));
+ if(! $invmaxau) {
+ $invmaxau = 50;
+ if (is_site_admin()) {
+ set_config('system','invitations_max_users',intval($invmaxau));
+ }
+ }
+
+ if ($wehave > $invmaxau) {
+ if (! is_site_admin()) {
+ $feedbk .= 'ZAI0200E,' . t('All users invitation limit exceeded.') . $eol;
+ }
+ }
+
+ // let see how many invites currently used by the user
+ $r = q("SELECT count(reg_id) AS n FROM register WHERE reg_vital = 1 AND reg_byc = %d",
+ intval(local_channel()));
+ $ihave = $r ? $r[0]['n'] : 0;
+
$tpl = get_markup_template('invite.tpl');
- $invonly = false;
-
- if(get_config('system','invitation_only')) {
- $invonly = true;
- $x = get_pconfig(local_channel(),'system','invites_remaining');
- if((! $x) && (! is_site_admin())) {
- notice( t('You have no more invitations available') . EOL);
- return '';
+
+ $inv_rabots = array(
+ 'i' => t('Minute(s)'),
+ 'h' => t('Hour(s)') ,
+ 'd' => t('Day(s)')
+ );
+ $inv_expire = replace_macros(get_markup_template('field_duration.qmc.tpl'),
+ array(
+ 'label' => t('Invitation expires after'),
+ 'qmc' => 'zai',
+ 'qmcid' => 'ZAI0014I',
+ 'field' => array(
+ 'name' => 'expire',
+ 'title' => t('duration up from now'),
+ 'value' => ($invexpire_n ? $invexpire_n : 2),
+ 'min' => '1',
+ 'max' => '99',
+ 'size' => '2',
+ 'default' => ($invexpire_u ? $invexpire_u : 'd')
+ ),
+ 'rabot' => $inv_rabots
+ )
+ );
+
+ // let generate an invite code that here and never will be applied (only to fill displayed template)
+ // real invite codes become generated for each recipient when we store the new invitation(s)
+ // $invite_code = substr(str_shuffle('abcdefghijklmnopqrstuvwxyz'), 0, 8) . rand(1000,9999);
+ // let take one descriptive for template (as said is never used)
+ $invite_code = 'INVITATE2020';
+
+ // what languages we use now
+ $lccmy = ((isset(App::$config['system']['language'])) ? App::$config['system']['language'] : 'en');
+ // and all the localized templates belonging to invite
+ $tpls = glob('view/*/invite.*.tpl');
+
+ $tpla=$tplx=$tplxs=array();
+ foreach ($tpls as $tpli) {
+ list( $nop, $l, $t ) = explode( '/', $tpli);
+ if ( preg_match('/\.subject/', $t) =='1' ) {
+ // indicate a subject tpl exists
+ $t=str_replace(array('invite.', '.subject', '.tpl'), '', $t);
+ $tplxs[$l][$t]=true;
+ continue;
}
+ // collect unique template names cross all languages and
+ // tpla[language][]=template those available in each language
+ $tplx[] = $tpla[$l][] = str_replace( array('invite.', '.tpl'), '', $t);
}
-
- if($invonly && ($x || is_site_admin())) {
- $invite_code = autoname(8) . rand(1000,9999);
- $nmessage = str_replace('$invite_code',$invite_code,$message);
-
- $r = q("INSERT INTO register (hash,created,uid,password,lang) VALUES ('%s', '%s',0,'','') ",
- dbesc($invite_code),
- dbesc(datetime_convert())
+
+ $langs = array_keys($tpla);
+ asort($langs);
+
+ $tplx = array_unique($tplx);
+ asort($tplx);
+
+ // prepare current language and the default standard template (causual) for js
+ // With and in js, I use a var 'tao' as a shortcut for top array object
+ // and also qualify the object with the prefix zai = tao.zai as my var used outsite functions
+ // can be unique within the overall included spaghette whirls
+ // one can say Im too lazy to write prototypes and just I can agree.
+ // tao simply applies the fact of using the same var as object and/or array in ja.
+ $tao.='tao.zai.lccmy = ' . "'" . $lccmy . "';\n" . 'tao.zai.itpl = ' . "'" . 'casual' . "';\n";
+
+ $lcclane=$tx=$tplin='';
+ //$lccsym='<span class="fa zai_fa zai_lccsym"></span>'; // alt 
+ $tplsym='<span class="fa zai_fa"></span>';
+
+ // I will uncomment for js console debug
+ // $tao.='tao.zai.debug = ' . "'" . json_encode($tplxs) . "';\n";
+
+ // running thru the localized templates (subjects and textmsgs) and bring them to tao
+ // lcc LanguageCountryCode,
+ // lcc2 is a 2 character and lcc5 a 5 character LanguageCountryCode
+ foreach($tpla as $l => $tn) {
+
+ // restyle lc to iso getttext format to avoid errors in js, hilite the current
+ $lcc = str_replace('-', '_', $l);
+ $hi = ($l == $lccmy) ? ' zai_hi' : '';
+ $lcc2 = strlen($l) == 2 ? ' zai_lcc2' : '';
+ $lcc5 = strlen($l) == 5 ? ' zai_lcc5' : '';
+ $lccg = ' zai_lccg' . substr( $l, 0, 2 );
+ $lcclane
+ .= '<span class="fa zai_fa zai_lccsym' . $lcc2 . $lcc5 . $lccg . '"></span>'
+ . '<a href="javascript:;" class="zai_lcc' . $lcc2 . $lcc5 . $lccg . $hi . '">' . $lcc . '</a>';
+ // textmsg
+ $tao .= 'tao.zai.t.' . $lcc . ' = {};' . "\n";
+ // subject
+ $tao .= 'tao.zai.s.' . $lcc . ' = {};' . "\n";
+
+ // resolve localized templates and take intented lc for
+ foreach($tn as $t1) {
+
+ // save current lc and take the desired
+ push_lang($l);
+
+ // resolve
+ $tx = replace_macros(get_intltext_template('invite.'.$t1.'.tpl'),
+ array(
+ '$projectname' => t('$Projectname'),
+ '$invite_code' => $invite_code,
+ '$invite_where' => z_root() . '/register',
+ '$invite_whereami' => $whereami,
+ '$invite_whoami' => z_root() . '/channel/' . $whoami,
+ '$invite_anywhere' => z_root() . '/pubsites'
+ )
);
-
- if(! is_site_admin()) {
- $x --;
- if($x >= 0)
- set_pconfig(local_channel(),'system','invites_remaining',$x);
- else
- return;
- }
+
+ // a default subject if no associated exists
+ $ts=t('Invitation');
+ if ( $tplxs[$l][$t1] )
+ $ts = replace_macros(get_intltext_template('invite.'.$t1.'.subject.tpl'),
+ array(
+ '$projectname' => t('$Projectname'),
+ '$invite_loc' => get_config('system','sitename')
+ )
+ );
+
+ // restore lc to current foreground
+ pop_lang();
+
+ // bring to tao as js like it
+ $tao .= 'tao.zai.t.' . $lcc . '.' . $t1 . " = '" . rawurlencode($tx) . "';\n";
+ $tao .= 'tao.zai.s.' . $lcc . '.' . $t1 . " = '" . rawurlencode($ts) . "';\n";
}
-
- $ob = App::get_observer();
- if(! $ob)
- return $o;
-
- $channel = App::get_channel();
-
+ }
+
+ // hilite the current defauls just from the beginning
+ foreach ($tplx as $t1) {
+ $hi = ($t1 == 'casual') ? ' zai_hi' : '';
+ $tplin .= $tplsym.'<a href="javascript:;" id="zai-' . $t1
+ . '" class="invites'.$hi.'">' . $t1 . '</a>';
+ }
+
+ // fill the form for foreground
$o = replace_macros($tpl, array(
'$form_security_token' => get_form_security_token("send_invite"),
+ '$zai' => strtolower(self::MYP),
+ '$tao' => $tao,
'$invite' => t('Send invitations'),
- '$addr_text' => t('Enter email addresses, one per line:'),
- '$msg_text' => t('Your message:'),
- '$default_message' => t('Please join my community on $Projectname.') . "\r\n" . "\r\n"
- . $linktxt
- . (($invonly) ? "\r\n" . "\r\n" . t('You will need to supply this invitation code:') . " " . $invite_code . "\r\n" . "\r\n" : '')
- . t('1. Register at any $Projectname location (they are all inter-connected)')
- . "\r\n" . "\r\n" . z_root() . '/register'
- . "\r\n" . "\r\n" . t('2. Enter my $Projectname network address into the site searchbar.')
- . "\r\n" . "\r\n" . $ob['xchan_addr'] . ' (' . t('or visit') . " " . z_root() . '/channel/' . $channel['channel_address'] . ')'
- . "\r\n" . "\r\n"
- . t('3. Click [Connect]')
- . "\r\n" . "\r\n" ,
+ '$ihave' => 'ZAI0106I, ' . t('Invitations I am using') . ': ' . $ihave . ' / ' . $invuser,
+ '$wehave' => 'ZAI0107I, ' . t('Invitations we are using') . ': ' . $wehave . ' / ' . $invmaxau,
+ '$n10' => 'ZAI0010I', '$m10' => t('§ Note, the email(s) sent will be recorded in the system logs'),
+ '$n11' => 'ZAI0011I', '$m11' => t('Enter email addresses, one per line:'),
+ '$n12' => 'ZAI0012I', '$m12' => t('Your message:'),
+ '$n13' => 'ZAI0013I', '$m13' => t('Invite template'),
+ '$inv_expire' => $inv_expire,
+ '$subject_label' => t('Subject:'),
+ '$subject' => t('Invitation'),
+ '$lcclane' => $lcclane,
+ '$tplin' => $tplin,
+ '$standard_message' => '',
+ '$personal_message' => '',
+ '$personal_pointer' => t('Here you may enter personal notes to the recipient(s)'),
+ '$due' => t('Note, the invitation code is valid up to') . ' ' . $dur['due'],
'$submit' => t('Submit')
));
-
+
return $o;
}
-
+
+ function calcdue($duri=false) {
+ // expirations, duration interval
+ if ($duri===false)
+ $duri = get_config('system','register_expire', '2d');
+ if ( preg_match( '/^[0-9]{1,2}[ihdwmy]{1}$/', $duri ) ) {
+ $durq = substr($duri, -1);
+ $durn = substr($duri, 0, -1);
+ $due = date('Y-m-d H:i:s', strtotime('+' . $durn . ' '
+ . str_replace( array(':i',':h',':d',':w',':m',':y'),
+ array('minutes', 'hours', 'days', 'weeks', 'months', 'years'),
+ (':'.$durq))
+ ));
+ return array( 'durn' => $durn, 'durq' => $durq, 'due' => $due);
+ }
+ return false;
+ }
}
+
diff --git a/Zotlabs/Module/Item.php b/Zotlabs/Module/Item.php
index def3f76dd..ff52babf5 100644
--- a/Zotlabs/Module/Item.php
+++ b/Zotlabs/Module/Item.php
@@ -840,7 +840,7 @@ class Item extends Controller {
if($results) {
// Set permissions based on tag replacements
- set_linkified_perms($results, $str_contact_allow, $str_group_allow, $profile_uid, $parent_item, $private);
+ set_linkified_perms($results, $str_contact_allow, $str_group_allow, $profile_uid, $private, $parent_item);
foreach($results as $result) {
$success = $result['success'];
diff --git a/Zotlabs/Module/Network.php b/Zotlabs/Module/Network.php
index 8a1b51a18..a21095940 100644
--- a/Zotlabs/Module/Network.php
+++ b/Zotlabs/Module/Network.php
@@ -20,8 +20,10 @@ class Network extends \Zotlabs\Web\Controller {
return;
}
- if(in_array(substr($_GET['search'],0,1),[ '@', '!', '?']) || strpos($_GET['search'], 'https://') === 0)
- goaway(z_root() . '/search?f=&search=' . $_GET['search']);
+ $search = $_GET['search'] ?? '';
+
+ if(in_array(substr($search, 0, 1),[ '@', '!', '?']) || strpos($search, 'https://') === 0)
+ goaway(z_root() . '/search?f=&search=' . $search);
if(count($_GET) < 2) {
$network_options = get_pconfig(local_channel(),'system','network_page_default');
@@ -80,7 +82,7 @@ class Network extends \Zotlabs\Web\Controller {
break;
}
- $search = (($_GET['search']) ? $_GET['search'] : '');
+ $search = $_GET['search'] ?? '';
if($search) {
if(strpos($search,'#') === 0) {
$hashtags = substr($search,1);
@@ -128,17 +130,19 @@ class Network extends \Zotlabs\Web\Controller {
$pf = ((x($_GET,'pf')) ? $_GET['pf'] : '');
$unseen = ((x($_GET,'unseen')) ? $_GET['unseen'] : '');
- if (Apps::system_app_installed(local_channel(),'Affinity Tool')) {
+ if (Apps::system_app_installed(local_channel(),'Affinity Tool')) {
$affinity_locked = intval(get_pconfig(local_channel(),'affinity','lock',1));
if ($affinity_locked) {
- set_pconfig(local_channel(),'affinity','cmin',$cmin);
- set_pconfig(local_channel(),'affinity','cmax',$cmax);
+ set_pconfig(local_channel(),'affinity','cmin',$cmin);
+ set_pconfig(local_channel(),'affinity','cmax',$cmax);
}
- }
+ }
if(x($_GET,'search') || $file || (!$pf && $cid) || $hashtags || $verb || $category || $conv || $unseen)
$nouveau = true;
+ $cid_r = [];
+
if($cid) {
$cid_r = q("SELECT abook.abook_xchan, xchan.xchan_addr, xchan.xchan_name, xchan.xchan_url, xchan.xchan_photo_s, xchan.xchan_pubforum from abook left join xchan on abook_xchan = xchan_hash where abook_id = %d and abook_channel = %d and abook_blocked = 0 limit 1",
intval($cid),
@@ -453,6 +457,8 @@ class Network extends \Zotlabs\Web\Controller {
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']) . "' ) ";
+ $items = [];
+
if($nouveau && $load) {
// "New Item View" - show all items unthreaded in reverse created date order
$items = q("SELECT item.*, item.id AS item_id, created FROM item
diff --git a/Zotlabs/Module/New_channel.php b/Zotlabs/Module/New_channel.php
index 98aa480fe..84d492f8f 100644
--- a/Zotlabs/Module/New_channel.php
+++ b/Zotlabs/Module/New_channel.php
@@ -11,7 +11,7 @@ class New_channel extends \Zotlabs\Web\Controller {
function init() {
$cmd = ((argc() > 1) ? argv(1) : '');
-
+
if($cmd === 'autofill.json') {
require_once('library/urlify/URLify.php');
$result = array('error' => false, 'message' => '');
@@ -20,14 +20,14 @@ class New_channel extends \Zotlabs\Web\Controller {
$x = false;
if(get_config('system','unicode_usernames')) {
- $x = punify(mb_strtolower($n));
+ $x = punify(mb_strtolower($n));
}
if((! $x) || strlen($x) > 64)
$x = strtolower(\URLify::transliterate($n));
-
+
$test = array();
-
+
// first name
if(strpos($x,' '))
$test[] = legal_webbie(substr($x,0,strpos($x,' ')));
@@ -44,19 +44,19 @@ class New_channel extends \Zotlabs\Web\Controller {
json_return_and_die(check_webbie($test));
}
-
+
if($cmd === 'checkaddr.json') {
require_once('library/urlify/URLify.php');
$result = array('error' => false, 'message' => '');
$n = trim($_REQUEST['nick']);
if(! $n) {
- $n = trim($_REQUEST['name']);
+ $n = trim($_REQUEST['name']);
}
$x = false;
if(get_config('system','unicode_usernames')) {
- $x = punify(mb_strtolower($n));
+ $x = punify(mb_strtolower($n));
}
if((! $x) || strlen($x) > 64)
@@ -64,7 +64,7 @@ class New_channel extends \Zotlabs\Web\Controller {
$test = array();
-
+
// first name
if(strpos($x,' '))
$test[] = legal_webbie(substr($x,0,strpos($x,' ')));
@@ -80,57 +80,57 @@ class New_channel extends \Zotlabs\Web\Controller {
$test[] = $n;
$test[] = $n . mt_rand(1000,9999);
}
-
+
for($y = 0; $y < 100; $y ++)
$test[] = 'id' . mt_rand(1000,9999);
-
+
json_return_and_die(check_webbie($test));
}
-
-
+
+
}
-
+
function post() {
-
+
$arr = $_POST;
-
+
$acc = \App::get_account();
$arr['account_id'] = get_account_id();
-
- // prevent execution by delegated channels as well as those not logged in.
+
+ // prevent execution by delegated channels as well as those not logged in.
// get_account_id() returns the account_id from the session. But \App::$account
- // may point to the original authenticated account.
-
+ // may point to the original authenticated account.
+
if((! $acc) || ($acc['account_id'] != $arr['account_id'])) {
notice( t('Permission denied.') . EOL );
return;
}
-
+
$result = create_identity($arr);
-
+
if(! $result['success']) {
notice($result['message']);
return;
}
-
+
$newuid = $result['channel']['channel_id'];
-
+
change_channel($result['channel']['channel_id']);
-
- $next_page = get_config('system', 'workflow_channel_next', 'profiles');
+
+ $next_page = get_config('system', 'workflow_channel_next', 'profiles');
goaway(z_root() . '/' . $next_page);
-
+
}
-
+
function get() {
-
+
$acc = \App::get_account();
-
+
if((! $acc) || $acc['account_id'] != get_account_id()) {
notice( t('Permission denied.') . EOL);
return;
}
-
+
$default_role = '';
$aid = get_account_id();
if($aid) {
@@ -140,7 +140,7 @@ class New_channel extends \Zotlabs\Web\Controller {
if($r && (! intval($r[0]['total']))) {
$default_role = get_config('system','default_permissions_role','social');
}
-
+
$limit = account_service_class_fetch(get_account_id(),'total_identities');
$canadd = true;
if($r && ($limit !== false)) {
@@ -155,7 +155,7 @@ class New_channel extends \Zotlabs\Web\Controller {
}
$name_help = '<span id="name_help_loading" style="display:none">' . t('Loading') . '</span><span id="name_help_text">';
- $name_help .= (($default_role)
+ $name_help .= (($default_role)
? t('Your real name is recommended.')
: t('Examples: "Bob Jameson", "Lisa and her Horses", "Soccer", "Aviation Group"')
);
@@ -176,10 +176,10 @@ class New_channel extends \Zotlabs\Web\Controller {
$nickhub = '@' . \App::get_hostname();
$nickname = array('nickname', t('Choose a short nickname'), ((x($_REQUEST,'nickname')) ? $_REQUEST['nickname'] : ''), $nick_help, "*");
$role = array('permissions_role' , t('Channel role and privacy'), ($privacy_role) ? $privacy_role : 'social', t('Select a channel permission role compatible with your usage needs and privacy requirements.') . '<br>' . '<a href="help/member/member_guide#Channel_Permission_Roles" target="_blank">' . t('Read more about channel permission roles') . '</a>',$perm_roles);
-
+
$o = replace_macros(get_markup_template('new_channel.tpl'), array(
'$title' => t('Create a Channel'),
- '$desc' => t('A channel is a unique network identity. It can represent a person (social network profile), a forum (group), a business or celebrity page, a newsfeed, and many other things.') ,
+ '$desc' => t('A channel is a unique network identity. It can represent a person (social network profile), a forum (group), a business or celebrity page, a newsfeed, and many other things.') ,
'$label_import' => t('or <a href="import">import an existing channel</a> from another location.'),
'$name' => $name,
'$role' => $role,
@@ -190,10 +190,10 @@ class New_channel extends \Zotlabs\Web\Controller {
'$channel_usage_message' => $channel_usage_message,
'$canadd' => $canadd
));
-
+
return $o;
-
+
}
-
-
+
+
}
diff --git a/Zotlabs/Module/Oep.php b/Zotlabs/Module/Oep.php
index 75304161b..faad2fc52 100644
--- a/Zotlabs/Module/Oep.php
+++ b/Zotlabs/Module/Oep.php
@@ -11,24 +11,24 @@ require_once('include/security.php');
class Oep extends \Zotlabs\Web\Controller {
function init() {
-
+
logger('oep: ' . print_r($_REQUEST,true), LOGGER_DEBUG, LOG_INFO);
-
+
$html = ((argc() > 1 && argv(1) === 'html') ? true : false);
if($_REQUEST['url']) {
$_REQUEST['url'] = strip_zids($_REQUEST['url']);
$url = $_REQUEST['url'];
}
-
+
if(! $url)
http_status_exit(404, 'Not found');
-
+
$maxwidth = $_REQUEST['maxwidth'];
$maxheight = $_REQUEST['maxheight'];
$format = $_REQUEST['format'];
if($format && $format !== 'json')
http_status_exit(501, 'Not implemented');
-
+
if(fnmatch('*/photos/*/album/*',$url))
$arr = $this->oep_album_reply($_REQUEST);
elseif(fnmatch('*/photos/*/image/*',$url))
@@ -47,7 +47,7 @@ class Oep extends \Zotlabs\Web\Controller {
$arr = $this->oep_cards_reply($_REQUEST);
elseif(fnmatch('*/articles/*',$url))
$arr = $this->oep_articles_reply($_REQUEST);
-
+
if($arr) {
if($html) {
if($arr['type'] === 'rich') {
@@ -61,13 +61,13 @@ class Oep extends \Zotlabs\Web\Controller {
}
killme();
}
-
+
http_status_exit(404,'Not found');
-
+
}
-
+
function oep_display_reply($args) {
-
+
$ret = array();
$url = $args['url'];
$maxwidth = intval($args['maxwidth']);
@@ -83,8 +83,8 @@ class Oep extends \Zotlabs\Web\Controller {
$item_normal = item_normal();
- $p = q("select * from item where mid like '%s' limit 1",
- dbesc($res . '%')
+ $p = q("select * from item where mid = '%s' limit 1",
+ dbesc($res)
);
if(! $p)
@@ -92,7 +92,7 @@ class Oep extends \Zotlabs\Web\Controller {
$c = channelx_by_n($p[0]['uid']);
-
+
if(! ($c && $res))
return;
@@ -100,27 +100,27 @@ class Oep extends \Zotlabs\Web\Controller {
return;
$sql_extra = item_permissions_sql($c['channel_id']);
-
- $p = q("select * from item where mid like '%s' and uid = %d $sql_extra $item_normal limit 1",
- dbesc($res . '%'),
+
+ $p = q("select * from item where mid = '%s' and uid = %d $sql_extra $item_normal limit 1",
+ dbesc($res),
intval($c['channel_id'])
);
if(! $p)
return;
-
+
xchan_query($p,true);
$p = fetch_post_tags($p,true);
// This function can get tripped up if the item is already a reshare
- // (the multiple share declarations do not parse cleanly if nested)
+ // (the multiple share declarations do not parse cleanly if nested)
// So build a template with a known nonsense string as the content, and then
// replace that known string with the actual rendered content, sending
// each content layer through bbcode() separately.
$x = '2eGriplW^*Jmf4';
-
+
$o = "[share author='".urlencode($p[0]['author']['xchan_name']).
"' profile='".$p[0]['author']['xchan_url'] .
"' avatar='".$p[0]['author']['xchan_photo_s'].
@@ -131,29 +131,29 @@ class Oep extends \Zotlabs\Web\Controller {
if($p[0]['title'])
$o .= '[b]'.$p[0]['title'].'[/b]'."\r\n";
- $o .= $x;
+ $o .= $x;
$o .= "[/share]";
$o = bbcode($o);
-
+
$o = str_replace($x,bbcode($p[0]['body']),$o);
-
+
$ret['type'] = 'rich';
-
+
$w = (($maxwidth) ? $maxwidth : 640);
$h = (($maxheight) ? $maxheight : intval($w * 2 / 3));
-
+
$ret['html'] = '<div style="width: ' . $w . '; height: ' . $h . '; font-family: sans-serif,arial,freesans;" >' . $o . '</div>';
-
+
$ret['width'] = $w;
$ret['height'] = $h;
-
+
return $ret;
-
+
}
function oep_cards_reply($args) {
-
+
$ret = [];
$url = $args['url'];
$maxwidth = intval($args['maxwidth']);
@@ -164,7 +164,7 @@ class Oep extends \Zotlabs\Web\Controller {
$res = $matches[3];
}
if(! ($nick && $res))
- return $ret;
+ return $ret;
$channel = channelx_by_nick($nick);
@@ -187,8 +187,8 @@ class Oep extends \Zotlabs\Web\Controller {
return $ret;
}
- $r = q("select * from item
- where item.uid = %d and item_type = %d
+ $r = q("select * from item
+ where item.uid = %d and item_type = %d
$sql_extra order by item.created desc",
intval($channel['channel_id']),
intval(ITEM_TYPE_CARD)
@@ -208,7 +208,7 @@ class Oep extends \Zotlabs\Web\Controller {
$x = '2eGriplW^*Jmf4';
-
+
$o = "[share author='".urlencode($p[0]['author']['xchan_name']).
"' profile='".$p[0]['author']['xchan_url'] .
"' avatar='".$p[0]['author']['xchan_photo_s'].
@@ -219,28 +219,28 @@ class Oep extends \Zotlabs\Web\Controller {
if($p[0]['title'])
$o .= '[b]'.$p[0]['title'].'[/b]'."\r\n";
- $o .= $x;
+ $o .= $x;
$o .= "[/share]";
$o = bbcode($o);
-
+
$o = str_replace($x,bbcode($p[0]['body']),$o);
-
+
$ret['type'] = 'rich';
-
+
$w = (($maxwidth) ? $maxwidth : 640);
$h = (($maxheight) ? $maxheight : intval($w * 2 / 3));
-
+
$ret['html'] = '<div style="width: ' . $w . '; height: ' . $h . '; font-family: sans-serif,arial,freesans;" >' . $o . '</div>';
-
+
$ret['width'] = $w;
$ret['height'] = $h;
-
+
return $ret;
-
+
}
function oep_articles_reply($args) {
-
+
$ret = [];
$url = $args['url'];
$maxwidth = intval($args['maxwidth']);
@@ -251,7 +251,7 @@ class Oep extends \Zotlabs\Web\Controller {
$res = $matches[3];
}
if(! ($nick && $res))
- return $ret;
+ return $ret;
$channel = channelx_by_nick($nick);
@@ -273,8 +273,8 @@ class Oep extends \Zotlabs\Web\Controller {
return $ret;
}
- $r = q("select * from item
- where item.uid = %d and item_type = %d
+ $r = q("select * from item
+ where item.uid = %d and item_type = %d
$sql_extra order by item.created desc",
intval($channel['channel_id']),
intval(ITEM_TYPE_ARTICLE)
@@ -294,7 +294,7 @@ class Oep extends \Zotlabs\Web\Controller {
$x = '2eGriplW^*Jmf4';
-
+
$o = "[share author='".urlencode($p[0]['author']['xchan_name']).
"' profile='".$p[0]['author']['xchan_url'] .
"' avatar='".$p[0]['author']['xchan_photo_s'].
@@ -305,71 +305,71 @@ class Oep extends \Zotlabs\Web\Controller {
if($p[0]['title'])
$o .= '[b]'.$p[0]['title'].'[/b]'."\r\n";
- $o .= $x;
+ $o .= $x;
$o .= "[/share]";
$o = bbcode($o);
-
+
$o = str_replace($x,bbcode($p[0]['body']),$o);
-
+
$ret['type'] = 'rich';
-
+
$w = (($maxwidth) ? $maxwidth : 640);
$h = (($maxheight) ? $maxheight : intval($w * 2 / 3));
-
+
$ret['html'] = '<div style="width: ' . $w . '; height: ' . $h . '; font-family: sans-serif,arial,freesans;" >' . $o . '</div>';
-
+
$ret['width'] = $w;
$ret['height'] = $h;
-
+
return $ret;
-
+
}
-
+
function oep_mid_reply($args) {
-
+
$ret = array();
$url = $args['url'];
$maxwidth = intval($args['maxwidth']);
$maxheight = intval($args['maxheight']);
-
+
if(preg_match('#//(.*?)/(.*?)/(.*?)/(.*?)mid\=(.*?)(&|$)#',$url,$matches)) {
$chn = $matches[3];
$res = $matches[5];
}
-
+
if(! ($chn && $res))
return;
$c = q("select * from channel where channel_address = '%s' limit 1",
dbesc($chn)
);
-
+
if(! $c)
return;
if(! perm_is_allowed($c[0]['channel_id'],get_observer_hash(),'view_stream'))
return;
-
+
$sql_extra = item_permissions_sql($c[0]['channel_id']);
-
+
$p = q("select * from item where mid = '%s' and uid = %d $sql_extra limit 1",
dbesc($res),
intval($c[0]['channel_id'])
);
if(! $p)
return;
-
+
xchan_query($p,true);
$p = fetch_post_tags($p,true);
// This function can get tripped up if the item is already a reshare
- // (the multiple share declarations do not parse cleanly if nested)
+ // (the multiple share declarations do not parse cleanly if nested)
// So build a template with a known nonsense string as the content, and then
// replace that known string with the actual rendered content, sending
// each content layer through bbcode() separately.
$x = '2eGriplW^*Jmf4';
-
+
$o = "[share author='".urlencode($p[0]['author']['xchan_name']).
"' profile='".$p[0]['author']['xchan_url'] .
"' avatar='".$p[0]['author']['xchan_photo_s'].
@@ -379,52 +379,52 @@ class Oep extends \Zotlabs\Web\Controller {
"' message_id='".$p[0]['mid']."']";
if($p[0]['title'])
$o .= '[b]'.$p[0]['title'].'[/b]'."\r\n";
- $o .= $x;
+ $o .= $x;
$o .= "[/share]";
$o = bbcode($o);
-
+
$o = str_replace($x,bbcode($p[0]['body']),$o);
$ret['type'] = 'rich';
-
+
$w = (($maxwidth) ? $maxwidth : 640);
$h = (($maxheight) ? $maxheight : intval($w * 2 / 3));
-
+
$ret['html'] = '<div style="width: ' . $w . '; height: ' . $h . '; font-family: sans-serif,arial,freesans;" >' . $o . '</div>';
-
+
$ret['width'] = $w;
$ret['height'] = $h;
-
+
return $ret;
-
+
}
-
+
function oep_profile_reply($args) {
-
-
+
+
require_once('include/channel.php');
$url = $args['url'];
-
+
if(preg_match('#//(.*?)/(.*?)/(.*?)(/|\?|&|$)#',$url,$matches)) {
$chn = $matches[3];
}
-
+
if(! $chn)
return;
-
+
$c = channelx_by_nick($chn);
-
+
if(! $c)
return;
-
-
+
+
$maxwidth = intval($args['maxwidth']);
$maxheight = intval($args['maxheight']);
-
+
$width = 800;
$height = 375;
-
+
if($maxwidth) {
$width = $maxwidth;
$height = (375 / 800) * $width;
@@ -434,59 +434,59 @@ class Oep extends \Zotlabs\Web\Controller {
$width = (800 / 375) * $maxheight;
$height = $maxheight;
}
- }
+ }
$ret = array();
-
+
$ret['type'] = 'rich';
$ret['width'] = intval($width);
$ret['height'] = intval($height);
-
+
$ret['html'] = get_zcard_embed($c,get_observer_hash(),array('width' => $width, 'height' => $height));
-
+
return $ret;
-
+
}
-
+
function oep_album_reply($args) {
-
+
$ret = array();
$url = $args['url'];
$maxwidth = intval($args['maxwidth']);
$maxheight = intval($args['maxheight']);
-
+
if(preg_match('|//(.*?)/(.*?)/(.*?)/album/|',$url,$matches)) {
$chn = $matches[3];
$res = basename($url);
}
-
+
if(! ($chn && $res))
return;
$c = q("select * from channel where channel_address = '%s' limit 1",
dbesc($chn)
);
-
+
if(! $c)
return;
-
+
if(! perm_is_allowed($c[0]['channel_id'],get_observer_hash(),'view_files'))
return;
$sql_extra = permissions_sql($c[0]['channel_id']);
-
+
$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'])
);
if(! $p)
return;
-
+
$res = $p[0]['resource_id'];
-
+
$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)
);
-
+
if($r) {
foreach($r as $rr) {
$foundres = false;
@@ -494,62 +494,62 @@ class Oep extends \Zotlabs\Web\Controller {
continue;
if($maxwidth && $rr['width'] > $maxwidth)
continue;
- $foundres = true;
+ $foundres = true;
break;
}
-
+
if($foundres) {
$ret['type'] = 'link';
$ret['thumbnail_url'] = z_root() . '/photo/' . '/' . $rr['resource_id'] . '-' . $rr['imgscale'];
$ret['thumbnail_width'] = $rr['width'];
$ret['thumbnail_height'] = $rr['height'];
}
-
-
+
+
}
return $ret;
-
+
}
-
-
+
+
function oep_phototop_reply($args) {
-
+
$ret = array();
$url = $args['url'];
$maxwidth = intval($args['maxwidth']);
$maxheight = intval($args['maxheight']);
-
+
if(preg_match('|//(.*?)/(.*?)/(.*?)$|',$url,$matches)) {
$chn = $matches[3];
}
-
+
if(! $chn)
return;
$c = q("select * from channel where channel_address = '%s' limit 1",
dbesc($chn)
);
-
+
if(! $c)
return;
-
+
if(! perm_is_allowed($c[0]['channel_id'],get_observer_hash(),'view_files'))
return;
$sql_extra = permissions_sql($c[0]['channel_id']);
-
+
$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)
return;
-
+
$res = $p[0]['resource_id'];
-
+
$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)
);
-
+
if($r) {
foreach($r as $rr) {
$foundres = false;
@@ -557,42 +557,42 @@ class Oep extends \Zotlabs\Web\Controller {
continue;
if($maxwidth && $rr['width'] > $maxwidth)
continue;
- $foundres = true;
+ $foundres = true;
break;
}
-
+
if($foundres) {
$ret['type'] = 'link';
$ret['thumbnail_url'] = z_root() . '/photo/' . '/' . $rr['resource_id'] . '-' . $rr['imgscale'];
$ret['thumbnail_width'] = $rr['width'];
$ret['thumbnail_height'] = $rr['height'];
}
-
-
+
+
}
return $ret;
-
+
}
-
-
+
+
function oep_photo_reply($args) {
-
+
$ret = array();
$url = $args['url'];
$maxwidth = intval($args['maxwidth']);
$maxheight = intval($args['maxheight']);
-
+
if(preg_match('|//(.*?)/(.*?)/(.*?)/image/|',$url,$matches)) {
$chn = $matches[3];
$res = basename($url);
}
-
+
if(! ($chn && $res))
return;
$c = q("select * from channel where channel_address = '%s' limit 1",
dbesc($chn)
);
-
+
if(! $c)
return;
@@ -600,13 +600,13 @@ class Oep extends \Zotlabs\Web\Controller {
return;
$sql_extra = permissions_sql($c[0]['channel_id']);
-
-
+
+
$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)
);
-
+
if($r) {
foreach($r as $rr) {
$foundres = false;
@@ -614,20 +614,20 @@ class Oep extends \Zotlabs\Web\Controller {
continue;
if($maxwidth && $rr['width'] > $maxwidth)
continue;
- $foundres = true;
+ $foundres = true;
break;
}
-
+
if($foundres) {
$ret['type'] = 'link';
$ret['thumbnail_url'] = z_root() . '/photo/' . '/' . $rr['resource_id'] . '-' . $rr['imgscale'];
$ret['thumbnail_width'] = $rr['width'];
$ret['thumbnail_height'] = $rr['height'];
}
-
-
+
+
}
return $ret;
-
+
}
}
diff --git a/Zotlabs/Module/Photo.php b/Zotlabs/Module/Photo.php
index ee360dac5..87697f5a7 100644
--- a/Zotlabs/Module/Photo.php
+++ b/Zotlabs/Module/Photo.php
@@ -180,7 +180,7 @@ class Photo extends \Zotlabs\Web\Controller {
$channel = channelx_by_n($r[0]['uid']);
// Now we'll see if we can access the photo
- $e = q("SELECT * FROM photo WHERE resource_id = '%s' AND imgscale = %d $sql_extra LIMIT 1",
+ $e = q("SELECT * FROM photo WHERE resource_id = '%s' AND imgscale = %d LIMIT 1",
dbesc($photo),
intval($resolution)
);
diff --git a/Zotlabs/Module/Regate.php b/Zotlabs/Module/Regate.php
new file mode 100644
index 000000000..379195461
--- /dev/null
+++ b/Zotlabs/Module/Regate.php
@@ -0,0 +1,447 @@
+<?php
+
+namespace Zotlabs\Module;
+
+require_once('include/security.php');
+
+/**
+ *
+ * @version 2.0.0
+ * @author hilmar runge
+ * @since 2020-03-03
+ * Check verification pin
+ * input field email address
+ * input field pin (told during register)
+ * check duty
+ * check startup and expire
+ * compare email address
+ * check pin
+ * limited tries to enter the correct pin/pass 2 handle via f2b
+ * on success create account and update register
+ *
+ */
+
+ define ( 'REGISTER_AGREED', 0x0020 );
+ define ( 'REGISTER_DENIED', 0x0040 );
+
+class Regate extends \Zotlabs\Web\Controller {
+
+ const MYP = 'ZAR'; //ZAR1x
+ const VERSION = '2.0.0';
+
+
+ function post() {
+
+ check_form_security_token_redirectOnErr('/', 'regate');
+
+ if ( argc() > 1 ) {
+ $did2 = hex2bin( substr( argv(1), 0, -1) );
+ $didx = substr( argv(1), -1 );
+ }
+
+ $msg = '';
+ $nextpage = '';
+
+ if ($did2) {
+
+ $nowhhmm = date('Hi');
+ $day = date('N');
+ $now = datetime_convert();
+ $ip = $_SERVER['REMOTE_ADDR'];
+
+ $isduty = zar_register_dutystate();
+
+ if (!$_SESSION['zar']['invite_in_progress'] && ($isduty['isduty'] !== false && $isduty['isduty'] != 1)) {
+ // normally, that should never happen here
+ // log suitable for fail2ban also
+ $logmsg = 'ZAR1230S Unexpected registration verification request for '
+ . get_config('system','sitename') . ' arrived from § ' . $ip . ' §';
+ zar_log($logmsg);
+ goaway(z_root());
+ }
+
+ // do we have a valid dId2 ?
+ if (($didx == 'a' && substr( $did2 , -2) == substr( base_convert( md5( substr( $did2, 1, -2) ),16 ,10), -2)) || ($didx == 'e') || ($didx == 'i')) {
+ // check startup and expiration via [=[register
+ $r = q("SELECT * FROM register WHERE reg_vital = 1 AND reg_did2 = '%s' ORDER BY reg_created DESC ",
+ dbesc($did2)
+ );
+ if ($r && count($r)) {
+ $r = $r[0];
+ // check timeframe
+ if ($r['reg_startup'] <= $now && $r['reg_expires'] >= $now) {
+ if (isset($_POST['resend']) && $didx == 'e') {
+ $re = q("SELECT * FROM register WHERE reg_vital = 1 AND reg_didx = 'e' AND reg_did2 = '%s' ORDER BY reg_created DESC ", dbesc($r['reg_did2']) );
+ if ($re) {
+ $re = $re[0];
+ $reonar = json_decode($re['reg_stuff'], true);
+ if ($reonar) {
+ $reonar['subject'] = 'Re,Fwd,' . $reonar['subject'];
+ $zm = zar_reg_mail($reonar);
+ $msg = (($zm) ? t('Email resent') : t('Email resend failed'));
+ zar_log((($zm) ? 'ZAR1238I' : 'ZAR1238E') . ' ' . $msg . ' ' . $r['reg_did2']);
+ info($msg);
+ return;
+ }
+ }
+ }
+
+ // check hash
+ if ( $didx == 'a' )
+ $acpin = (preg_match('/^[0-9]{6,6}$/', $_POST['acpin']) ? $_POST['acpin'] : false);
+ elseif ( $didx == 'e' )
+ $acpin = (preg_match('/^[0-9a-f]{24,24}$/', $_POST['acpin']) ? $_POST['acpin'] : false);
+ elseif ( $didx == 'i' )
+ $acpin = $r['reg_hash'];
+ else
+ $acpin = false;
+
+ if ( $acpin && ($r['reg_hash'] == $acpin )) {
+
+ $flags = $r['reg_flags'];
+ if (($flags & ACCOUNT_UNVERIFIED) == ACCOUNT_UNVERIFIED) {
+
+ // verification success
+ $msg_code = 'ZAR1237I';
+ $msg = t('Verification successful');
+ $reonar = json_decode( $r['reg_stuff'], true);
+ $reonar['valid'] = $now . ',' . $ip . ' ' . $did2 . ' ' . $msg_code . ' ' . $msg;
+
+ // clear flag
+ $flags &= $flags ^ ACCOUNT_UNVERIFIED;
+
+ // are we invited by the admin?
+ $isa = get_account_by_id($r['reg_uid']);
+ $isa = ($isa && ($isa['account_roles'] && ACCOUNT_ROLE_ADMIN));
+
+ // approve contra invite by admin
+ if ($isa && get_config('system','register_policy') == REGISTER_APPROVE) {
+ $flags &= $flags ^ ACCOUNT_PENDING;
+ }
+
+ // sth todo?
+ $vital = $flags == 0 ? 0 : 1;
+
+ // set flag
+ $flags |= REGISTER_AGREED;
+ zar_log($msg . ' ' . $did2 . ':flags' . $flags . ',rid' . $r['reg_id']);
+
+ q("START TRANSACTION");
+
+ $qu = q("UPDATE register SET reg_stuff = '%s', reg_vital = %d, reg_flags = %d "
+ ." WHERE reg_id = %d ",
+ dbesc(json_encode($reonar)),
+ intval($vital),
+ intval($flags),
+ intval($r['reg_id'])
+ );
+
+ if (($flags & ACCOUNT_PENDING ) == ACCOUNT_PENDING) {
+ $nextpage = 'regate/' . bin2hex($did2) . $didx;
+ q("COMMIT");
+ }
+ elseif (($flags ^ REGISTER_AGREED) == 0) {
+
+ $cra = create_account_from_register([ 'reg_id' => $r['reg_id'] ]);
+
+ if ($cra['success']) {
+
+ q("COMMIT");
+ $msg = t('Account successfull created');
+ // zar_log($msg . ':' . print_r($cra, true));
+ zar_log('ZAR1238I ' . $msg . ' ' . $cra['account']['account_email']
+ . ' ' . $cra['account']['account_language']);
+
+ authenticate_success($cra['account'],null,true,false,true);
+
+ $nextpage = 'new_channel';
+
+ $auto_create = get_config('system', 'auto_channel_create', 1);
+
+ if($auto_create) {
+
+ $new_channel = ['success' => false];
+
+ // We do not reserve a channel_address before the registration is verified
+ // and possibly approved by the admin.
+ // If the provided channel_address has been claimed meanwhile,
+ // we will proceed to /new_channel.
+
+ if(isset($reonar['chan.did1']) && check_webbie([$reonar['chan.did1']])) {
+
+ // prepare channel creation
+ if($reonar['chan.name'])
+ set_aconfig($cra['account']['account_id'], 'register', 'channel_name', $reonar['chan.name']);
+
+ if($reonar['chan.did1'])
+ set_aconfig($cra['account']['account_id'], 'register', 'channel_address', $reonar['chan.did1']);
+
+ $permissions_role = get_config('system','default_permissions_role');
+ if($permissions_role)
+ set_aconfig($cra['account']['account_id'], 'register', 'permissions_role', $permissions_role);
+
+ // create channel
+ $new_channel = auto_channel_create($cra['account']['account_id']);
+
+ if($new_channel['success']) {
+ $channel_id = $new_channel['channel']['channel_id'];
+ change_channel($channel_id);
+ $nextpage = 'profiles/' . $channel_id;
+ $msg_code = 'ZAR1239I';
+ $msg = t('Channel successfull created') . ' ' . $did2;
+ }
+ }
+
+ if(!$new_channel['success']) {
+ $msg_code = 'ZAR1239E';
+ $msg = t('Automatic channel creation failed. Please create a channel.') . ' ' . $did2;
+ $nextpage = 'new_channel?name=' . $reonar['chan.name'];
+ }
+
+ zar_log($msg_code . ' ' . $msg . ' ' . $reonar['chan.did1'] . ' (' . $reonar['chan.name'] . ')');
+
+ }
+ unset($_SESSION['login_return_url']);
+ }
+ else {
+ q("ROLLBACK");
+ $msg_code = 'ZAR1238E';
+ $msg = t('Account creation error');
+ zar_log($msg_code . ' ' . $msg . ': ' . print_r($cra, true));
+ }
+ }
+ else {
+ // new flags implemented and not recognized or sth like
+ zar_log('ZAR1237D unexpected,' . $flags);
+ }
+ }
+ else {
+ // nothing to confirm
+ $msg_code = 'ZAR1236E';
+ $msg = t('Verify failed');
+ }
+ }
+ else {
+ $msg_code = 'ZAR1235E';
+ $msg = t('Token verification failed');
+ }
+ }
+ else {
+ $msg_code = 'ZAR1234W';
+ $msg = t('Request not inside time frame');
+ //info($r[0]['reg_startup'] . EOL . $r[0]['reg_expire'] );
+ }
+ }
+ else {
+ $msg_code = 'ZAR1232E';
+ $msg = t('Identity unknown');
+ zar_log($msg_code . ' ' . $msg . ':' . $did2 . $didx);
+ }
+ }
+ else {
+ $msg_code = 'ZAR1231E';
+ $msg = t('dId2 mistaken');
+ zar_log($msg_code . ' ' . $msg);
+
+ }
+
+ }
+
+ if ($msg > '') info($msg);
+ goaway( z_root() . '/' . $nextpage );
+ }
+
+
+ function get() {
+
+ if (argc() == 1) {
+ if(isset($_GET['reg_id'])) {
+ if ( preg_match('/^.{2,64}\@[a-z0-9.-]{4,32}\.[a-z]{2,12}$/', $_GET['reg_id'] ) ) {
+ // dId2 E email
+ goaway(z_root() . '/regate/' . bin2hex($_GET['reg_id']) . 'e' );
+ }
+ if ( preg_match('/^d{1,1}[0-9]{5,10}$/', $_GET['reg_id'] ) ) {
+ // dId2 A artifical & anonymous
+ goaway(z_root() . '/regate/' . bin2hex($_GET['reg_id']) . 'a' );
+ }
+ notice(t('Identity unknown') . EOL);
+ }
+
+ $o = replace_macros(get_markup_template('plain.tpl'), [
+ '$title' => t('Your Registration ID'),
+ '$now' => '<form action="regate" method="get"><input type="text" name="reg_id" class="form-control form-group"><button class="btn btn-primary float-right">Submit</button></form>'
+ ]);
+
+ return $o;
+ }
+
+ $isduty = zar_register_dutystate();
+ $nowfmt = $isduty['nowfmt'];
+ $atform = $isduty['atform'];
+
+ if ($_SESSION['zar']['delayed']) {
+ $o = replace_macros(get_markup_template('regate_pre.tpl'), [
+ '$title' => t('Registration verification'),
+ '$now' => $nowfmt,
+ '$id' => $_SESSION['zar']['id'],
+ '$pin' => $_SESSION['zar']['pin'],
+ '$regdelay' => $_SESSION['zar']['regdelay'],
+ '$regexpire' => $_SESSION['zar']['regexpire'],
+ '$strings' => [
+ t('Hold on, you can start verification in'),
+ t('Please remember your verification token for ID'),
+ '',
+ t('Token validity')
+ ]
+ ]);
+ unset($_SESSION['zar']['delayed']);
+ return $o;
+ }
+
+ if (argc() < 2)
+ return;
+
+ $did2 = hex2bin( substr( argv(1), 0, -1) );
+ $didx = substr( argv(1), -1 );
+ $deny = argc() > 2 ? argv(2) : '';
+ $deny = preg_match('/^[0-9a-f]{8,8}$/', $deny) ? hex2bin($deny) : false;
+ $now = datetime_convert();
+ $ip = $_SERVER['REMOTE_ADDR'];
+
+ $pin = '';
+
+ if(isset($_SESSION['zar']['pin'])) {
+ $pin = $_SESSION['zar']['pin'];
+ unset($_SESSION['zar']['pin']);
+ }
+
+ // do we have a valid dId2 ?
+ if (($didx == 'a' && substr( $did2 , -2) == substr( base_convert( md5( substr( $did2, 1, -2) ),16 ,10), -2)) || ($didx == 'e') || ($didx == 'i')) {
+
+ $r = q("SELECT * FROM register WHERE reg_vital = 1 AND reg_didx = '%s' AND reg_did2 = '%s' ORDER BY reg_created DESC",
+ dbesc($didx),
+ dbesc($did2)
+ );
+
+ if ($r && count($r) && $r[0]['reg_flags'] &= (ACCOUNT_UNVERIFIED | ACCOUNT_PENDING)) {
+ $r = $r[0];
+
+ // provide a button in case
+ $resend = (($r['reg_didx'] == 'e') ? t('Resend email') : '');
+
+ // is still only instance admins intervention required?
+ if ($r['reg_flags'] == ACCOUNT_PENDING) {
+ $o = replace_macros(get_markup_template('regate_post.tpl'), [
+ '$title' => t('Registration status'),
+ '$id' => $did2,
+ '$strings' => [
+ t('Verification successful!'),
+ t('Your login ID is'),
+ t('After your account has been approved by our administrator you will be able to login with your login ID and your provided password.')
+ ]
+ ]);
+ }
+ else {
+
+ if ($deny) {
+
+ if (substr($r['reg_hash'],0,4) == $deny) {
+ zar_log('ZAR1134S email verfication denied ' . $did2);
+
+ $o = replace_macros(get_markup_template('plain.tpl'), [
+ '$title' => t('Registration request revoked'),
+ '$infos' => t('Sorry for any inconvience. Thank you for your response.')
+ ]);
+
+ $reonar = json_decode( $r['reg_stuff'], true);
+ $reonar['deny'] = $now . ',' . $ip . ' ' . $did2 . ' ' . $msg;
+ $flags = ( $r['reg_flags'] &= ( $r['reg_flags'] ^ ACCOUNT_UNVERIFIED) )
+ | ( $r['reg_flags'] |= REGISTER_DENIED);
+ $rd = q("UPDATE register SET reg_stuff='%s', reg_vital=0, reg_flags=%d WHERE reg_id = %d ",
+ dbesc(json_encode($reonar)),
+ intval($flags),
+ intval($r['reg_id'])
+ );
+ }
+ else {
+ zar_log('ZAR1135E not awaited url parameter received');
+ goaway(z_root);
+ }
+ }
+ else {
+
+ if ( $r['reg_startup'] <= $now && $r['reg_expires'] >= $now) {
+ $o = replace_macros(get_markup_template('regate.tpl'), [
+ '$form_security_token' => get_form_security_token("regate"),
+ '$title' => t('Registration verification'),
+ '$desc' => t('Please enter your verification token for ID'),
+ '$email_extra' => (($didx === 'e') ? t('Please check your email!') : ''),
+ '$id' => $did2,
+ // we might consider to not provide $pin if a registration delay is configured
+ // and the pin turns out to be readable by bots
+ '$pin' => $pin,
+ '$did2' => bin2hex($did2) . $didx,
+ '$now' => $nowfmt,
+ '$atform' => $atform,
+ '$resend' => $resend,
+ '$submit' => t('Submit'),
+ '$acpin' => [ 'acpin', t('Verification token'),'','' ]
+ ]);
+ }
+ else {
+ // expired ?
+ if ( $now > $r['reg_expires'] ) {
+ $rd = q("UPDATE register SET reg_vital = 0 WHERE reg_id = %d ",
+ intval($r['reg_id'])
+ );
+
+ $o = replace_macros(get_markup_template('plain.tpl'), [
+ '$infos' => t('ID expired'),
+ ]);
+
+ return $o;
+ }
+
+ $email_extra = (($didx === 'e') ? t('Please check your email!') : '');
+
+ $o = replace_macros(get_markup_template('regate_pre.tpl'), [
+ '$title' => t('Registration verification'),
+ '$now' => $nowfmt,
+ '$id' => $did2,
+ '$countdown' => datetime_convert('UTC', 'UTC', $r['reg_startup'], 'c'),
+ '$strings' => [
+ t('Hold on, you can start verification in'),
+ t('You will require the verification token for ID'),
+ $email_extra
+ ]
+ ]);
+ }
+ }
+ }
+ }
+ else {
+ $msg = t('Unknown or expired ID');
+ zar_log('ZAR1132E ' . $msg . ':' . $did2 . ',' . $didx);
+ $o = replace_macros(get_markup_template('plain.tpl'), [
+ '$title' => $title,
+ '$now' => $nowfmt,
+ '$infos' => $msg
+ ]);
+ }
+
+ }
+ else {
+ $msg = 'ZAR1131E ' . t('dId2 malformed');
+ // $log = ' from § ' . $ip . ' §' . ' (' . dbesc($did2) . ')';
+ zar_log($msg);
+ $o = replace_macros(get_markup_template('plain.tpl'), [
+ '$title' => $title,
+ '$now' => $nowfmt,
+ '$infos' => $msg
+ ]);
+ }
+
+ return $o;
+ }
+}
+
diff --git a/Zotlabs/Module/Register.php b/Zotlabs/Module/Register.php
index 278cf15ca..683fcdc36 100644
--- a/Zotlabs/Module/Register.php
+++ b/Zotlabs/Module/Register.php
@@ -1,25 +1,34 @@
<?php
+
namespace Zotlabs\Module;
+use App;
use Zotlabs\Web\Controller;
require_once('include/security.php');
+require_once('include/channel.php');
+
class Register extends Controller {
+ const MYP = 'ZAR'; // ZAR0x
+ const VERSION = '2.0.0';
+
function init() {
-
+
+ // ZAR0
+
$result = null;
$cmd = ((argc() > 1) ? argv(1) : '');
-
+
// Provide a stored request for somebody desiring a connection
// when they first need to register someplace. Once they've
- // created a channel, we'll try to revive the connection request
+ // created a channel, we'll try to revive the connection request
// and process it.
-
+
if($_REQUEST['connect'])
$_SESSION['connect'] = $_REQUEST['connect'];
-
+
switch($cmd) {
case 'invite_check.json':
$result = check_account_invite($_REQUEST['invite_code']);
@@ -30,50 +39,161 @@ class Register extends Controller {
case 'password_check.json':
$result = check_account_password($_REQUEST['password1']);
break;
- default:
+ default:
break;
}
if($result) {
json_return_and_die($result);
}
}
-
-
+
function post() {
check_form_security_token_redirectOnErr('/register', 'register');
- $max_dailies = intval(get_config('system','max_daily_registrations'));
- if($max_dailies) {
- $r = q("select count(account_id) as total from account where account_created > %s - INTERVAL %s",
- db_utcnow(), db_quoteinterval('1 day')
+ /**
+ * [hilmar:]
+ * It may happen, the posted form arrives in a strange fashion. With the control of the duty hours
+ * for registration, the input form was disabled at html. While receiving posted data, checks are
+ * required if all is on the right road (most posts are not accepted during off duty).
+ *
+ */
+
+
+ $act = q("SELECT COUNT(*) AS act FROM account")[0]['act'];
+ $is247 = false;
+ $ip = $_SERVER['REMOTE_ADDR'];
+ $sameip = intval(get_config('system','register_sameip', 3));
+ $arr = $_POST;
+ $invite_code = ((x($arr,'invite_code')) ? notags(trim($arr['invite_code'])) : '');
+ $name = '';
+ $nick = '';
+ $email = ((x($arr,'email')) ? notags(punify(trim($arr['email']))) : '');
+ $password = ((x($arr,'password')) ? trim($arr['password']) : '');
+ $password2 = ((x($arr,'password2')) ? trim($arr['password2']) : '');
+ $register_msg = ((x($arr,'register_msg')) ? notags(trim($arr['register_msg'])) : '');
+ $reonar = [];
+ $auto_create = get_config('system','auto_channel_create', 1);
+ $duty = zar_register_dutystate();
+
+ if (!get_config('system', 'register_duty_jso')) {
+ // if not yet configured default to true
+ $duty = array( 'isduty' => true, 'atfrm' => '', 'nowfmt' => '');
+ }
+
+ if($auto_create) {
+ $name = escape_tags(trim($arr['name']));
+
+ $name_error = validate_channelname($name);
+ if($name_error) {
+ notice($name_error . EOL);
+ return $ret;
+ }
+
+ $nick = mb_strtolower(escape_tags(trim($arr['nickname'])));
+ if(!$nick) {
+ notice(t('Nickname is required.'));
+ return;
+ }
+
+ if($nick === 'sys') {
+ notice(t('Reserved nickname. Please choose another.') . EOL);
+ return;
+ }
+
+ if(check_webbie([$nick]) !== $nick) {
+ notice(t('Nickname has unsupported characters or is already being used on this site.') . EOL);
+ return;
+ }
+ }
+
+ $email_verify = get_config('system', 'verify_email');
+ if ($email_verify && !$email) {
+ notice(t('Email address required') . EOL);
+ return;
+ }
+
+ if ($email) {
+ $email_result = check_account_email($email);
+ if ($email_result['error']) {
+ if ($email_result['email_unverified']) {
+ goaway(z_root() . '/regate/' . bin2hex($email) . 'e');
+ }
+ return;
+ }
+
+ }
+
+ // case when an invited prepares the own account by supply own pw, accept tos, prepage channel (if auto)
+ if ($email && $invite_code) {
+ if ( preg_match('/^[a-z0-9]{12,12}$/', $invite_code ) ) {
+ $is247 = true;
+ }
+ }
+
+ if ($act > 0 && !$is247 && !$duty['isduty']) {
+ // normally (except very 1st timr after install), that should never arrive here (ie js hack or sth like)
+ // log suitable for f2b also
+ $logmsg = 'Unexpected registration request off duty';
+ notice($logmsg);
+ zar_log('ZAR0230S ' . $logmsg);
+ return;
+ }
+
+ if ($sameip) {
+ $f = q("SELECT COUNT(reg_atip) AS atip FROM register WHERE reg_vital = 1 AND reg_atip = '%s' ",
+ dbesc($ip)
);
- if($r && $r[0]['total'] >= $max_dailies) {
- notice( t('Maximum daily site registrations exceeded. Please try again tomorrow.') . EOL);
+ if ($f && $f[0]['atip'] >= $sameip) {
+ $logmsg = 'ZAR0239S Exceeding same ip register request of ' . $sameip;
+ notice('Registrations from same IP exceeded.');
+ zar_log($logmsg);
return;
}
}
-
+
+ if (!$password) {
+ notice(t('No password provided') . EOL);
+ return;
+ }
+
+ if ($password !== $password2) {
+ notice(t('Passwords do not match') . EOL);
+ return;
+ }
+
+ $password_result = check_account_password($password);
+ if(!empty($password_result['error'])) {
+ $msg = $password_result['message'];
+ notice($msg);
+ zar_log($msg . ' ' . $did2);
+ return;
+ }
+
+ $salt = random_string(32);
+ $password = $salt . ',' . hash('whirlpool', $salt . $password);
+
+ // accept tos
if(! x($_POST,'tos')) {
- notice( t('Please indicate acceptance of the Terms of Service. Registration failed.') . EOL);
+ // msg!
+ notice(t('Terms of Service not accepted') . EOL);
return;
}
-
- $policy = get_config('system','register_policy');
-
- $email_verify = get_config('system','verify_email');
-
-
+
+ $policy = get_config('system','register_policy');
+ $invonly = get_config('system','invitation_only');
+ $invalso = get_config('system','invitation_also');
+
switch($policy) {
-
+
case REGISTER_OPEN:
$flags = ACCOUNT_OK;
break;
-
+
case REGISTER_APPROVE:
- $flags = ACCOUNT_BLOCKED | ACCOUNT_PENDING;
+ $flags = ACCOUNT_PENDING;
break;
-
+
default:
case REGISTER_CLOSED:
if(! is_site_admin()) {
@@ -83,164 +203,278 @@ class Register extends Controller {
$flags = ACCOUNT_BLOCKED;
break;
}
-
- if($email_verify && $policy == REGISTER_OPEN)
- $flags = $flags | ACCOUNT_UNVERIFIED;
-
-
- if((! $_POST['password']) || ($_POST['password'] !== $_POST['password2'])) {
- notice( t('Passwords do not match.') . EOL);
- return;
- }
-
- $arr = $_POST;
+
+ if($email_verify && ($policy == REGISTER_OPEN || $policy == REGISTER_APPROVE))
+ $flags = ($flags | ACCOUNT_UNVERIFIED);
+
+ // $arr has $_POST;
$arr['account_flags'] = $flags;
-
- $result = create_account($arr);
-
- if(! $result['success']) {
- notice($result['message']);
- return;
- }
- require_once('include/security.php');
-
-
- if($_REQUEST['name'])
- set_aconfig($result['account']['account_id'],'register','channel_name',$_REQUEST['name']);
- if($_REQUEST['nickname'])
- set_aconfig($result['account']['account_id'],'register','channel_address',$_REQUEST['nickname']);
- if($_REQUEST['permissions_role'])
- set_aconfig($result['account']['account_id'],'register','permissions_role',$_REQUEST['permissions_role']);
-
-
- $using_invites = intval(get_config('system','invitation_only'));
- $num_invites = intval(get_config('system','number_invites'));
- $invite_code = ((x($_POST,'invite_code')) ? notags(trim($_POST['invite_code'])) : '');
-
- if($using_invites && $invite_code) {
- q("delete from register where hash = '%s'", dbesc($invite_code));
- // @FIXME - this also needs to be considered when using 'invites_remaining' in mod/invite.php
- set_aconfig($result['account']['account_id'],'system','invites_remaining',$num_invites);
- }
-
- if($policy == REGISTER_OPEN ) {
- if($email_verify) {
- $res = verify_email_address($result);
- }
- else {
- $res = send_register_success_email($result['email'],$result['password']);
- }
- if($res) {
- if($invite_code) {
- info( t('Registration successful. Continue to create your first channel...') . EOL ) ;
- }
- else {
- info( t('Registration successful. Please check your email for validation instructions.') . EOL ) ;
+ $now = datetime_convert();
+ $well = false;
+
+ // s3
+ if ($invite_code) {
+
+ if ($invonly || $invalso) {
+
+ $reg = q("SELECT * from register WHERE reg_vital = 1 AND reg_didx = 'i' AND reg_hash = '%s'",
+ dbesc($invite_code)
+ );
+
+ if ($reg && count($reg) == 1) {
+ $reg = $reg[0];
+ if ($reg['reg_email'] == ($email)) {
+
+ if ($reg['reg_startup'] <= $now && $reg['reg_expires'] >= $now) {
+
+ if ($auto_create) {
+ $reonar['chan.name'] = $name;
+ $reonar['chan.did1'] = $nick;
+ }
+
+ q("UPDATE register set reg_pass = '%s', reg_stuff = '%s' WHERE reg_id = '%s'",
+ dbesc($password),
+ dbesc(json_encode($reonar)),
+ intval($reg['reg_id'])
+ );
+
+ $msg = t('Invitation code succesfully applied');
+ zar_log('ZAR0237I ' . $msg) . ', ' . $email;
+ // msg!
+ info($msg . EOL);
+
+
+ // the invitecode has verified us and we have all the info we need
+ // take the shortcut.
+
+ $_SESSION['zar']['invite_in_progress'] = true;
+
+ $mod = new Regate();
+ $_REQUEST['form_security_token'] = get_form_security_token("regate");
+ App::$argc = 2;
+ App::$argv[0] = 'regate';
+ App::$argv[1] = bin2hex($reg['reg_did2']) . 'i';
+ return $mod->post();
+
+ } else {
+ // msg!
+ notice(t('Invitation not in time or too late') . EOL);
+ return;
+ }
+
+ } else {
+ // no match email adr
+ $msg = t('Invitation email failed');
+ zar_log('ZAR0235S ' . $msg);
+ notice($msg . EOL);
+ return;
+ }
+
+ } else {
+ // no match invitecode
+ $msg = t('Invitation code failed') ;
+ zar_log('ZAR0234S ' . $msg);
+ notice( $msg . EOL);
+ return;
}
+
+ } else {
+ notice(t('Invitations are not available') . EOL);
+ return;
}
+
}
- elseif($policy == REGISTER_APPROVE) {
- $res = send_reg_approval_email($result);
- if($res) {
- info( t('Your registration is pending approval by the site owner.') . EOL ) ;
+ else {
+ if (!$invonly) {
+ $well = true;
}
else {
- notice( t('Your registration can not be processed.') . EOL);
+ $msg = t('Registration on this hub is by invitation only') . EOL;
+ notice($msg);
+ zar_log('ZAR0233E ' . $msg);
+ return;
}
- goaway(z_root());
}
-
- if($email_verify) {
- goaway(z_root() . '/email_validation/' . bin2hex($result['email']));
+
+ // check max daily registrations after we have dealt with the invitecode
+ if (self::check_reg_limits()['is']) {
+ notice('Max registrations per day exceeded.');
+ return;
}
- // fall through and authenticate if no approvals or verifications were required.
-
- authenticate_success($result['account'],null,true,false,true);
-
- $new_channel = false;
- $next_page = 'new_channel';
-
- if(get_config('system','auto_channel_create')) {
- $new_channel = auto_channel_create($result['account']['account_id']);
- if($new_channel['success']) {
- $channel_id = $new_channel['channel']['channel_id'];
- change_channel($channel_id);
- $next_page = '~';
+ if ($well) {
+
+ if($policy == REGISTER_OPEN || $policy == REGISTER_APPROVE ) {
+
+ $cfgdelay = get_config('system', 'register_delay', '0i');
+ $reg_delayed = calculate_adue( $cfgdelay );
+ $regdelay = (($reg_delayed) ? datetime_convert(date_default_timezone_get(), 'UTC', $reg_delayed['due']) : $now);
+
+ $cfgexpire = get_config('system', 'register_expire', '3d');
+ $reg_expires = calculate_adue( $cfgexpire );
+ $regexpire = (($reg_expires) ? datetime_convert(date_default_timezone_get(), 'UTC', $reg_expires['due']) : datetime_convert('UTC', 'UTC', 'now + 99 years'));
+
+ // handle an email request that will be verified or an ivitation associated with an email address
+ if ($email > '' && $email_verify) {
+ // enforce in case of icdone
+ $flags |= ACCOUNT_UNVERIFIED;
+ $empin = $pass2 = random_string(24);
+ $did2 = $email;
+ $didx = 'e';
+
+ push_lang(($reg['lang']) ? $reg['lang'] : App::$language);
+ $reonar['from'] = get_config('system', 'from_email');
+ $reonar['to'] = $email;
+ $reonar['subject'] = sprintf( t('Registration confirmation for %s'), get_config('system','sitename'));
+ $reonar['txttemplate']= replace_macros(get_intltext_template('register_verify_member.tpl'),
+ [
+ '$sitename' => get_config('system','sitename'),
+ '$siteurl' => z_root(),
+ '$email' => $email,
+ '$timeframe' => [$regdelay, $regexpire],
+ '$mail' => bin2hex($email) . 'e',
+ '$ko' => bin2hex(substr($empin,0,4)),
+ '$hash' => $empin
+ ]
+ );
+ pop_lang();
+ zar_reg_mail($reonar);
+
+ } else {
+ // that is an anonymous request without email or with email not to verify
+ $acpin = $pass2 = rand(100000,999999);
+ $did2 = rand(10,99);
+ $didx = 'a';
+ // enforce delayed verify
+ $flags = ($flags | ACCOUNT_UNVERIFIED);
+ if ($email) {
+ $reonar['email.untrust'] = $email;
+ $reonar['email.comment'] = 'received, but no need for';
+ }
+ }
+
+ if ($auto_create) {
+ $reonar['chan.name'] = $name;
+ $reonar['chan.did1'] = $nick;
+ }
+
+ if ($policy == REGISTER_APPROVE) {
+ $reonar['msg'] = $register_msg;
+ }
+
+ $reg = q("INSERT INTO register ("
+ . "reg_flags,reg_didx,reg_did2,reg_hash,reg_created,reg_startup,reg_expires,"
+ . "reg_email,reg_pass,reg_lang,reg_atip,reg_stuff)"
+ . " VALUES (%d, '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s') ",
+ intval($flags),
+ dbesc($didx),
+ dbesc($did2),
+ dbesc($pass2),
+ dbesc($now),
+ dbesc($regdelay),
+ dbesc($regexpire),
+ dbesc($email),
+ dbesc($password),
+ dbesc(App::$language),
+ dbesc($ip),
+ dbesc(json_encode($reonar))
+ );
+
+ if ($didx == 'a') {
+
+ $lid = q("SELECT reg_id FROM register WHERE reg_vital = 1 AND reg_did2 = '%s' AND reg_pass = '%s' ",
+ dbesc($did2),
+ dbesc($password)
+ );
+
+ if ($lid && count($lid) == 1 ) {
+
+ $didnew = ( $lid[0]['reg_id'] . $did2 )
+ . ( substr( base_convert( md5( $lid[0]['reg_id'] . $did2 ), 16, 10 ),-2 ) );
+
+ $reg = q("UPDATE register SET reg_did2 = CONCAT('d','%s') WHERE reg_id = %d ",
+ dbesc($didnew), intval($lid[0]['reg_id'])
+ );
+
+ zar_log( 'ZAR0239A ' . t('New register request') . ' d' . $didnew . ', '
+ . $regdelay . ' - ' . $regexpire);
+
+ if($reg_delayed) {
+ // this could be removed to make registration harder
+ $_SESSION['zar']['id'] = 'd' . $didnew;
+ $_SESSION['zar']['pin'] = $pass2;
+ $_SESSION['zar']['delayed'] = true;
+ $_SESSION['zar']['regdelay'] = datetime_convert('UTC', 'UTC', $regdelay, 'c');
+ $_SESSION['zar']['regexpire'] = datetime_convert('UTC', 'UTC', $regexpire, 'c');
+ }
+ else {
+ $_SESSION['zar']['pin'] = $pass2;
+ }
+
+ goaway(z_root() . '/regate/' . bin2hex('d' . $didnew) . 'a' );
+ }
+ else {
+ $msg = t('Error creating dId A');
+ notice( $msg );
+ zar_log( 'ZAR0239D,' . $msg . ' ' . $did2);
+ }
+ }
+ goaway(z_root() . '/regate/' . bin2hex($email) . $didx );
}
- else
- $new_channel = false;
- }
-
- $x = get_config('system','workflow_register_next');
- if($x) {
- $next_page = $x;
- $_SESSION['workflow'] = true;
}
-
- unset($_SESSION['login_return_url']);
- goaway(z_root() . '/' . $next_page);
-
}
-
-
-
+
+
function get() {
-
+
$registration_is = '';
$other_sites = '';
-
+
if(intval(get_config('system','register_policy')) === REGISTER_CLOSED) {
if(intval(get_config('system','directory_mode')) === DIRECTORY_MODE_STANDALONE) {
- notice( t('Registration on this hub is disabled.') . EOL);
+ notice(t('Registration on this hub is disabled.') . EOL);
return;
}
- $mod = new Pubsites();
+ $mod = new Pubsites();
return $mod->get();
}
-
+
if(intval(get_config('system','register_policy')) == REGISTER_APPROVE) {
$registration_is = t('Registration on this hub is by approval only.');
- $other_sites = t('<a href="pubsites">Register at another affiliated hub.</a>');
+ $other_sites = '<a href="pubsites">' . t('Register at another affiliated hub in case when prefered') . '</a>';
}
+ $duty = zar_register_dutystate();
- $invitations = false;
+ if (!get_config('system', 'register_duty_jso')) {
+ // if not yet configured default to true
+ $duty = array( 'isduty' => true, 'atfrm' => '', 'nowfmt' => '');
+ }
+ $invitations = false;
if(intval(get_config('system','invitation_only'))) {
$invitations = true;
$registration_is = t('Registration on this hub is by invitation only.');
- $other_sites = t('<a href="pubsites">Register at another affiliated hub.</a>');
- }
-
- $max_dailies = intval(get_config('system','max_daily_registrations'));
- if($max_dailies) {
- $r = q("select count(account_id) as total from account where account_created > %s - INTERVAL %s",
- db_utcnow(), db_quoteinterval('1 day')
- );
- if($r && $r[0]['total'] >= $max_dailies) {
- logger('max daily registrations exceeded.');
- notice( t('This site has exceeded the number of allowed daily account registrations. Please try again tomorrow.') . EOL);
- return;
- }
+ $other_sites = '<a href="pubsites">' . t('Register at another affiliated hub') . '</a>';
+ } elseif (intval(get_config('system','invitation_also'))) {
+ $invitations = true;
}
- $privacy_role = ((x($_REQUEST,'permissions_role')) ? $_REQUEST['permissions_role'] : "");
-
- $perm_roles = \Zotlabs\Access\PermissionRoles::roles();
+ $opal = self::check_reg_limits();
+ if ( $opal['is'])
+ $duty['atform'] = 'disabled';
// Configurable terms of service link
-
$tosurl = get_config('system','tos_url');
if(! $tosurl)
$tosurl = z_root() . '/help/TermsOfService';
-
+
$toslink = '<a href="' . $tosurl . '" target="_blank">' . t('Terms of Service') . '</a>';
-
+
// Configurable whether to restrict age or not - default is based on international legal requirements
// This can be relaxed if you are on a restricted server that does not share with public servers
-
+
if(get_config('system','no_age_restriction')) {
$label_tos = sprintf( t('I accept the %s for this website'), $toslink);
}
@@ -253,50 +487,96 @@ class Register extends Controller {
}
$enable_tos = 1 - intval(get_config('system','no_termsofservice'));
-
- $email = array('email', t('Your email address'), ((x($_REQUEST,'email')) ? strip_tags(trim($_REQUEST['email'])) : ""));
- $password = array('password', t('Choose a password'), '');
- $password2 = array('password2', t('Please re-enter your password'), '');
+
+ $auto_create = get_config('system', 'auto_channel_create', 1);
+ $email_verify = get_config('system','verify_email');
+
+ $emailval = ((x($_REQUEST,'email')) ? strip_tags(trim($_REQUEST['email'])) : "");
+ $email = ['email',
+ t('Your email address'),
+ $emailval,
+ (($email_verify) ? t('Required') : t('Optional')),
+ (($email_verify) ? '*' : ''),
+ $duty['atform']
+ ];
+
+ $password = array('password', t('Choose a password'), '', '', '', $duty['atform']);
+ $password2 = array('password2', t('Please re-enter your password'), '', '', '', $duty['atform']);
+
$invite_code = array('invite_code', t('Please enter your invitation code'), ((x($_REQUEST,'invite_code')) ? strip_tags(trim($_REQUEST['invite_code'])) : ""));
- $name = array('name', t('Your Name'), ((x($_REQUEST,'name')) ? $_REQUEST['name'] : ''), t('Real names are preferred.'));
+
+ $name = array('name', t('Your name'), ((x($_REQUEST,'name')) ? $_REQUEST['name'] : ''), t('Real name is preferred'), '', '', $duty['atform']);
$nickhub = '@' . str_replace(array('http://','https://','/'), '', get_config('system','baseurl'));
- $nickname = array('nickname', t('Choose a short nickname'), ((x($_REQUEST,'nickname')) ? $_REQUEST['nickname'] : ''), sprintf( t('Your nickname will be used to create an easy to remember channel address e.g. nickname%s'), $nickhub));
- $role = array('permissions_role' , t('Channel role and privacy'), ($privacy_role) ? $privacy_role : 'social', t('Select a channel permission role for your usage needs and privacy requirements.') . ' <a href="help/member/member_guide#Channel_Permission_Roles" target="_blank">' . t('Read more about channel permission roles') . '</a>',$perm_roles);
- $tos = array('tos', $label_tos, '', '', array(t('no'),t('yes')));
+ $nickname = array('nickname', t('Choose a short nickname'), ((x($_REQUEST,'nickname')) ? $_REQUEST['nickname'] : ''), t('Your nickname will be used to create an easy to remember channel address'), '', '', $duty['atform']);
+ $tos = array('tos', $label_tos, ((x($_REQUEST,'tos')) ? $_REQUEST['tos'] : ''), '', [t('No'),t('Yes')], $duty['atform']);
+
+ $register_msg = ['register_msg', t('Why do you want to join this hub?'), ((x($_REQUEST,'register_msg')) ? $_REQUEST['register_msg'] : ''), t('This will help to review your registration')];
- $auto_create = (get_config('system','auto_channel_create') ? true : false);
- $default_role = get_config('system','default_permissions_role');
- $email_verify = get_config('system','verify_email');
-
require_once('include/bbcode.php');
-
- $o = replace_macros(get_markup_template('register.tpl'), array(
+ $o = replace_macros(get_markup_template('register.tpl'), array(
'$form_security_token' => get_form_security_token("register"),
'$title' => t('Registration'),
'$reg_is' => $registration_is,
+ '$register_msg' => $register_msg,
'$registertext' => bbcode(get_config('system','register_text')),
'$other_sites' => $other_sites,
+ '$msg' => $opal['msg'],
'$invitations' => $invitations,
'$invite_code' => $invite_code,
+ '$haveivc' => t('I have an invite code'),
+ '$now' => $duty['nowfmt'],
+ '$atform' => $duty['atform'],
'$auto_create' => $auto_create,
'$name' => $name,
- '$role' => $role,
- '$default_role' => $default_role,
'$nickname' => $nickname,
'$enable_tos' => $enable_tos,
'$tos' => $tos,
'$email' => $email,
+ '$validate' => $validate,
+ '$validate_link'=> $validate_link,
+ '$validate_here'=> $validate_here,
'$pass1' => $password,
'$pass2' => $password2,
'$submit' => t('Register'),
- '$verify_note' => (($email_verify) ? t('This site requires email verification. After completing this form, please check your email for further instructions.') : ''),
+ '$nickhub' => $nickhub
+
));
-
+
return $o;
-
}
-
-
+
+ function check_reg_limits() {
+ // check against register, account
+ $rear = array( 'is' => false, 'rn' => 0, 'an' => 0, 'msg' => '' );
+
+ $max_dailies = intval(get_config('system', 'max_daily_registrations', 50));
+
+ if ($max_dailies) {
+
+ $r = q("SELECT COUNT(reg_id) AS nr FROM register WHERE reg_vital = 1 AND reg_created > %s - INTERVAL %s",
+ db_utcnow(), db_quoteinterval('1 day')
+ );
+
+ $rear['is'] = ( $r && $r[0]['nr'] >= $max_dailies ) ? true : false;
+ $rear['rn'] = $r[0]['nr'];
+
+ if (!$rear['is']) {
+ $r = q("SELECT COUNT(account_id) AS nr FROM account WHERE account_created > %s - INTERVAL %s",
+ db_utcnow(), db_quoteinterval('1 day')
+ );
+
+ $rear['is'] = ( $r && ($r[0]['nr'] + $rear['rn']) >= $max_dailies ) ? true : false;
+ $rear['ra'] = $r[0]['nr'];
+ }
+
+ if ( $rear['is']) {
+ $rear['msg'] = t('This site has exceeded the number of allowed daily account registrations.');
+ zar_log('ZAR0333W ' . $rear['msg']);
+ $rear['is'] = true;
+ }
+ }
+ return $rear;
+ }
}
diff --git a/Zotlabs/Module/Search.php b/Zotlabs/Module/Search.php
index 8a87d98f7..2ad79e3f6 100644
--- a/Zotlabs/Module/Search.php
+++ b/Zotlabs/Module/Search.php
@@ -58,7 +58,7 @@ class Search extends Controller {
$o .= search($search, 'search-box', '/search', ((local_channel()) ? true : false));
if (local_channel() && strpos($search, 'https://') === 0 && !$update && !$load) {
- $j = Activity::fetch($search, App::get_channel());
+ $j = Activity::fetch(punify($search), App::get_channel());
if ($j) {
$AS = new ActivityStreams($j);
if ($AS->is_valid()) {
@@ -101,7 +101,7 @@ class Search extends Controller {
}
// look for a naked webbie
- if (strpos($search, '@') !== false) {
+ if (strpos($search,'@') !== false && strpos($search,'http') !== 0) {
goaway(z_root() . '/directory' . '?f=1&navsearch=1&search=' . $search);
}
diff --git a/Zotlabs/Module/Settings/Account.php b/Zotlabs/Module/Settings/Account.php
index b40f516ca..97cc9389a 100644
--- a/Zotlabs/Module/Settings/Account.php
+++ b/Zotlabs/Module/Settings/Account.php
@@ -15,20 +15,23 @@ class Account {
$account = \App::get_account();
if($email != $account['account_email']) {
- if(! validate_email($email))
- $errs[] = t('Not valid email.');
- $adm = trim(get_config('system','admin_email'));
- if(($adm) && (strcasecmp($email,$adm) == 0)) {
- $errs[] = t('Protected email address. Cannot change to that email.');
- $email = \App::$account['account_email'];
- }
- if(! $errs) {
- $r = q("update account set account_email = '%s' where account_id = %d",
- dbesc($email),
- intval($account['account_id'])
- );
- if(! $r)
- $errs[] = t('System failure storing new email. Please try again.');
+ // a DId2 not an email addr does not allow to change to email addr
+ if (strpos($email, '@') > 0) {
+ if(! validate_email($email))
+ $errs[] = t('Not valid email.');
+ $adm = trim(get_config('system','admin_email'));
+ if(($adm) && (strcasecmp($email,$adm) == 0)) {
+ $errs[] = t('Protected email address. Cannot change to that email.');
+ $email = \App::$account['account_email'];
+ }
+ if(! $errs) {
+ $r = q("update account set account_email = '%s' where account_id = %d",
+ dbesc($email),
+ intval($account['account_id'])
+ );
+ if(! $r)
+ $errs[] = t('System failure storing new email. Please try again.');
+ }
}
}
@@ -92,6 +95,7 @@ class Account {
call_hooks('account_settings', $account_settings);
$email = \App::$account['account_email'];
+ $attremail = (!strpos($email, '@')) ? 'disabled="disabled"' : '';
$tpl = get_markup_template("settings_account.tpl");
$o .= replace_macros($tpl, array(
@@ -101,7 +105,7 @@ class Account {
'$password1'=> array('npassword', t('Enter New Password'), '', ''),
'$password2'=> array('confirm', t('Confirm New Password'), '', t('Leave password fields blank unless changing')),
'$submit' => t('Submit'),
- '$email' => array('email', t('Email Address:'), $email, ''),
+ '$email' => array('email', t('DId2 or Email Address:'), $email, '', '', $attremail),
'$removeme' => t('Remove Account'),
'$removeaccount' => t('Remove this account including all its channels'),
'$account_settings' => $account_settings
diff --git a/Zotlabs/Module/Sse.php b/Zotlabs/Module/Sse.php
index 46b4a8d87..8bea65207 100644
--- a/Zotlabs/Module/Sse.php
+++ b/Zotlabs/Module/Sse.php
@@ -47,7 +47,6 @@ class Sse extends Controller {
self::$vnotify = get_pconfig(self::$uid, 'system', 'vnotify');
- $sys = get_sys_channel();
$sleep_seconds = 3;
self::$sse_enabled = get_config('system', 'sse_enabled', 0);
diff --git a/Zotlabs/Module/Sse_bs.php b/Zotlabs/Module/Sse_bs.php
index 3b39d5b49..cc67c8eb7 100644
--- a/Zotlabs/Module/Sse_bs.php
+++ b/Zotlabs/Module/Sse_bs.php
@@ -6,6 +6,7 @@ use App;
use Zotlabs\Lib\Apps;
use Zotlabs\Web\Controller;
use Zotlabs\Lib\Enotify;
+use Zotlabs\Lib\XConfig;
class Sse_bs extends Controller {
@@ -101,12 +102,13 @@ class Sse_bs extends Controller {
self::bs_files(),
self::bs_mail(),
self::bs_all_events(),
- self::bs_register()
+ self::bs_register(),
+ self::bs_info_notice()
);
- set_xconfig(self::$ob_hash, 'sse', 'timestamp', datetime_convert());
- set_xconfig(self::$ob_hash, 'sse', 'notifications', []); // reset the cache
- set_xconfig(self::$ob_hash, 'sse', 'language', App::$language);
+ XConfig::Set(self::$ob_hash, 'sse', 'notifications', []);
+ XConfig::Set(self::$ob_hash, 'sse', 'timestamp', datetime_convert());
+ XConfig::Set(self::$ob_hash, 'sse', 'language', App::$language);
json_return_and_die($result);
}
@@ -686,12 +688,15 @@ class Sse_bs extends Controller {
if(! self::$uid && ! is_site_admin())
return $result;
+ $policy = intval(get_config('system','register_policy'));
+ if(($policy & REGISTER_APPROVE) != REGISTER_APPROVE)
+ return $result;
+
if(! (self::$vnotify & VNOTIFY_REGISTER))
return $result;
- $r = q("SELECT account_email, account_created from account where (account_flags & %d) > 0",
- intval(ACCOUNT_PENDING)
- );
+ $r = get_pending_accounts();
+
if($r) {
foreach($r as $rr) {
$result['register']['notifications'][] = Enotify::format_register($rr);
@@ -703,4 +708,22 @@ class Sse_bs extends Controller {
}
+ function bs_info_notice() {
+
+ $result['notice']['notifications'] = [];
+ $result['info']['notifications'] = [];
+
+ $r = XConfig::Get(self::$ob_hash, 'sse', 'notifications', []);
+
+ if(isset($r['notice']))
+ $result['notice']['notifications'] = $r['notice']['notifications'];
+
+ if(isset($r['info']))
+ $result['info']['notifications'] = $r['info']['notifications'];
+
+ return $result;
+
+ }
+
+
}
diff --git a/Zotlabs/Module/Suggest.php b/Zotlabs/Module/Suggest.php
index 18961214e..0ed6ea8d7 100644
--- a/Zotlabs/Module/Suggest.php
+++ b/Zotlabs/Module/Suggest.php
@@ -15,17 +15,17 @@ class Suggest extends \Zotlabs\Web\Controller {
if(! Apps::system_app_installed(local_channel(), 'Suggest Channels'))
return;
-
+
if(x($_GET,'ignore')) {
q("insert into xign ( uid, xchan ) values ( %d, '%s' ) ",
intval(local_channel()),
dbesc($_GET['ignore'])
);
}
-
+
}
-
-
+
+
function get() {
if(! local_channel()) {
@@ -45,22 +45,22 @@ class Suggest extends \Zotlabs\Web\Controller {
$o = '';
nav_set_selected('Suggest Channels');
-
+
$_SESSION['return_url'] = z_root() . '/' . \App::$cmd;
-
+
$r = suggestion_query(local_channel(),get_observer_hash());
-
+
if(! $r) {
info( t('No suggestions available. If this is a new site, please try again in 24 hours.'));
return;
}
-
+
$arr = array();
-
+
foreach($r as $rr) {
-
- $connlnk = z_root() . '/follow/?url=' . $rr['xchan_addr'];
-
+
+ $connlnk = z_root() . '/follow?f=&url=' . $rr['xchan_addr'];
+
$arr[] = array(
'url' => chanlink_url($rr['xchan_url']),
'common' => $rr['total'],
@@ -73,15 +73,15 @@ class Suggest extends \Zotlabs\Web\Controller {
'ignore' => t('Ignore/Hide')
);
}
-
-
+
+
$o = replace_macros(get_markup_template('suggest_page.tpl'),array(
'$title' => t('Channel Suggestions'),
'$entries' => $arr
));
-
+
return $o;
-
+
}
-
+
}
diff --git a/Zotlabs/Module/Wiki.php b/Zotlabs/Module/Wiki.php
index 169dc6de1..04c1dbeaa 100644
--- a/Zotlabs/Module/Wiki.php
+++ b/Zotlabs/Module/Wiki.php
@@ -127,7 +127,6 @@ class Wiki extends Controller {
$resource_id = argv(4);
$w = NativeWiki::get_wiki($owner['channel_id'],$observer_hash,$resource_id);
-
// $w = NativeWiki::get_wiki($owner,$observer_hash,$resource_id);
if(! $w['htmlName']) {
notice(t('Error retrieving wiki') . EOL);
@@ -218,12 +217,12 @@ class Wiki extends Controller {
'$name' => t('Name'),
'$type' => t('Type'),
'$unlocked' => t('Any&nbsp;type'),
- '$lockstate' => $x['lockstate'],
- '$acl' => $x['acl'],
- '$allow_cid' => $x['allow_cid'],
- '$allow_gid' => $x['allow_gid'],
- '$deny_cid' => $x['deny_cid'],
- '$deny_gid' => $x['deny_gid'],
+ '$lockstate' => (x($x,'lockstate') ? $x['lockstate'] : ''),
+ '$acl' => (x($x,'acl') ? $x['acl'] : ''),
+ '$allow_cid' => (x($x,'allow_cid') ? $x['allow_cid'] : ''),
+ '$allow_gid' => (x($x,'allow_gid') ? $x['allow_gid'] : ''),
+ '$deny_cid' => (x($x,'deny_cid') ? $x['deny_cid'] : ''),
+ '$deny_gid' => (x($x,'deny_gid') ? $x['deny_gid'] : ''),
'$typelock' => array('typelock', t('Lock content type'), '', '', array(t('No'), t('Yes'))),
'$notify' => array('postVisible', t('Create a status post for this wiki'), '', '', array(t('No'), t('Yes'))),
'$edit_wiki_name' => t('Edit Wiki Name')
@@ -508,7 +507,7 @@ class Wiki extends Controller {
notice( t('Wiki created, but error creating Home page.'));
goaway(z_root() . '/wiki/' . $nick . '/' . NativeWiki::name_encode($wiki['urlName']));
}
- NativeWiki::sync_a_wiki_item($owner['channel_id'],$homePage['item_id'],$r['item']['resource_id']);
+ NativeWiki::sync_a_wiki_item($owner['channel_id'], $homePage['item_id'], $r['item']['resource_id']);
goaway(z_root() . '/wiki/' . $nick . '/' . NativeWiki::name_encode($wiki['urlName']) . '/' . NativeWiki::name_encode($homePage['page']['urlName']));
}
else {
@@ -542,7 +541,6 @@ class Wiki extends Controller {
}
$wiki = NativeWiki::exists_by_name($owner['channel_id'], $arr['urlName']);
-
if($wiki['resource_id']) {
$arr['resource_id'] = $wiki['resource_id'];
@@ -552,7 +550,7 @@ class Wiki extends Controller {
$r = NativeWiki::update_wiki($owner['channel_id'], $observer_hash, $arr, $acl);
if($r['success']) {
- NativeWiki::sync_a_wiki_item($owner['channel_id'],$r['item_id'],$r['item']['resource_id']);
+ NativeWiki::sync_a_wiki_item($owner['channel_id'], $r['item_id'], $r['item']['resource_id']);
goaway(z_root() . '/wiki/' . $nick);
}
else {
@@ -576,7 +574,7 @@ class Wiki extends Controller {
$resource_id = $_POST['resource_id'];
$deleted = NativeWiki::delete_wiki($owner['channel_id'],$observer_hash,$resource_id);
if ($deleted['success']) {
- NativeWiki::sync_a_wiki_item($owner['channel_id'],$deleted['item_id'],$resource_id);
+ NativeWiki::sync_a_wiki_item($owner['channel_id'], 0, $resource_id);
json_return_and_die(array('message' => '', 'success' => true));
}
else {
@@ -611,18 +609,17 @@ class Wiki extends Controller {
}
$page = NativeWikiPage::create_page($owner['channel_id'],$observer_hash, $name, $resource_id, $mimetype);
-
if($page['item_id']) {
- $commit = NativeWikiPage::commit(array(
+
+ $commit = NativeWikiPage::commit([
'commit_msg' => t('New page created'),
'resource_id' => $resource_id,
'channel_id' => $owner['channel_id'],
'observer_hash' => $observer_hash,
'pageUrlName' => $name
- ));
-
+ ]);
if($commit['success']) {
- NativeWiki::sync_a_wiki_item($owner['channel_id'],$commit['item_id'],$resource_id);
+ NativeWiki::sync_a_wiki_item($owner['channel_id'], $commit['item_id'], $resource_id);
//json_return_and_die(array('url' => '/' . argv(0) . '/' . argv(1) . '/' . urlencode($page['wiki']['urlName']) . '/' . urlencode($page['page']['urlName']), 'success' => true));
json_return_and_die(array('url' => '/' . argv(0) . '/' . argv(1) . '/' . $page['wiki']['urlName'] . '/' . $page['page']['urlName'], 'success' => true));
}
@@ -680,20 +677,25 @@ class Wiki extends Controller {
json_return_and_die(array('success' => false));
}
- $saved = NativeWikiPage::save_page(array('channel_id' => $owner['channel_id'], 'observer_hash' => $observer_hash, 'resource_id' => $resource_id, 'pageUrlName' => $pageUrlName, 'content' => $content));
-
+ $saved = NativeWikiPage::save_page([
+ 'channel_id' => $owner['channel_id'],
+ 'observer_hash' => $observer_hash,
+ 'resource_id' => $resource_id,
+ 'pageUrlName' => $pageUrlName,
+ 'content' => $content
+ ]);
if($saved['success']) {
- $commit = NativeWikiPage::commit(array(
+
+ $commit = NativeWikiPage::commit([
'commit_msg' => $commitMsg,
'pageUrlName' => $pageUrlName,
'resource_id' => $resource_id,
'channel_id' => $owner['channel_id'],
'observer_hash' => $observer_hash,
'revision' => (-1)
- ));
-
+ ]);
if($commit['success']) {
- NativeWiki::sync_a_wiki_item($owner['channel_id'],$commit['item_id'],$resource_id);
+ NativeWiki::sync_a_wiki_item($owner['channel_id'], $commit['item_id'], $resource_id);
json_return_and_die(array('message' => 'Wiki git repo commit made', 'success' => true , 'content' => $content));
}
else {
@@ -738,9 +740,9 @@ class Wiki extends Controller {
if ($pageUrlName === 'Home') {
json_return_and_die(array('message' => t('Cannot delete Home'),'success' => false));
}
+
// Determine if observer has permission to delete pages
// currently just allow page owner
-
if((! local_channel()) || (local_channel() != $owner['channel_id'])) {
logger('Wiki write permission denied. ' . EOL);
json_return_and_die(array('success' => false));
@@ -752,9 +754,14 @@ class Wiki extends Controller {
json_return_and_die(array('success' => false));
}
- $deleted = NativeWikiPage::delete_page(array('channel_id' => $owner['channel_id'], 'observer_hash' => $observer_hash, 'resource_id' => $resource_id, 'pageUrlName' => $pageUrlName));
+ $deleted = NativeWikiPage::delete_page([
+ 'channel_id' => $owner['channel_id'],
+ 'observer_hash' => $observer_hash,
+ 'resource_id' => $resource_id,
+ 'pageUrlName' => $pageUrlName
+ ]);
if($deleted['success']) {
- NativeWiki::sync_a_wiki_item($owner['channel_id'],$commit['item_id'],$resource_id);
+ NativeWiki::sync_a_wiki_item($owner['channel_id'], 0, $resource_id);
json_return_and_die(array('message' => 'Wiki git repo commit made', 'success' => true));
}
else {
@@ -768,18 +775,25 @@ class Wiki extends Controller {
$resource_id = $_POST['resource_id'];
$pageUrlName = $_POST['name'];
$commitHash = $_POST['commitHash'];
- // Determine if observer has permission to revert pages
+ // Determine if observer has permission to revert pages
$perms = NativeWiki::get_permissions($resource_id, intval($owner['channel_id']), $observer_hash);
if(! $perms['write']) {
logger('Wiki write permission denied.' . EOL);
json_return_and_die(array('success' => false));
}
- $reverted = NativeWikiPage::revert_page(array('channel_id' => $owner['channel_id'], 'observer_hash' => $observer_hash, 'commitHash' => $commitHash, 'resource_id' => $resource_id, 'pageUrlName' => $pageUrlName));
+ $reverted = NativeWikiPage::revert_page([
+ 'channel_id' => $owner['channel_id'],
+ 'observer_hash' => $observer_hash,
+ 'commitHash' => $commitHash,
+ 'resource_id' => $resource_id,
+ 'pageUrlName' => $pageUrlName
+ ]);
if($reverted['success']) {
json_return_and_die(array('content' => $reverted['content'], 'message' => '', 'success' => true));
- } else {
+ }
+ else {
json_return_and_die(array('content' => '', 'message' => 'Error reverting page', 'success' => false));
}
}
@@ -826,18 +840,23 @@ class Wiki extends Controller {
json_return_and_die(array('success' => false));
}
- $renamed = NativeWikiPage::rename_page(array('channel_id' => $owner['channel_id'], 'observer_hash' => $observer_hash, 'resource_id' => $resource_id, 'pageUrlName' => $pageUrlName, 'pageNewName' => $pageNewName));
-
+ $renamed = NativeWikiPage::rename_page([
+ 'channel_id' => $owner['channel_id'],
+ 'observer_hash' => $observer_hash,
+ 'resource_id' => $resource_id,
+ 'pageUrlName' => $pageUrlName,
+ 'pageNewName' => $pageNewName
+ ]);
if($renamed['success']) {
- $commit = NativeWikiPage::commit(array(
+ $commit = NativeWikiPage::commit([
'channel_id' => $owner['channel_id'],
'commit_msg' => 'Renamed ' . NativeWiki::name_decode($pageUrlName) . ' to ' . $renamed['page']['htmlName'],
'resource_id' => $resource_id,
'observer_hash' => $observer_hash,
'pageUrlName' => $pageNewName
- ));
+ ]);
if($commit['success']) {
- NativeWiki::sync_a_wiki_item($owner['channel_id'],$commit['item_id'],$resource_id);
+ NativeWiki::sync_a_wiki_item($owner['channel_id'], $commit['item_id'], $resource_id);
json_return_and_die(array('name' => $renamed['page'], 'message' => 'Wiki git repo commit made', 'success' => true));
}
else {
diff --git a/Zotlabs/Render/Comanche.php b/Zotlabs/Render/Comanche.php
index cf87cc7d7..5ce05243b 100644
--- a/Zotlabs/Render/Comanche.php
+++ b/Zotlabs/Render/Comanche.php
@@ -330,6 +330,8 @@ class Comanche {
$name = str_replace($mtch[0], '', $name);
}
}
+ else
+ $var = [];
if($channel_id) {
$m = menu_fetch($name, $channel_id, get_observer_hash());
@@ -408,7 +410,8 @@ class Comanche {
}
//emit the block
- $o .= (($var['wrap'] == 'none') ? '' : '<div class="' . $class . '">');
+ $wrap = (! x($var, 'wrap') || $var['wrap'] == 'none' ? false : true);
+ $o .= ($wrap ? '' : '<div class="' . $class . '">');
if($r[0]['title'] && trim($r[0]['body']) != '$content') {
$o .= '<h3>' . $r[0]['title'] . '</h3>';
@@ -421,7 +424,7 @@ class Comanche {
$o .= prepare_text($r[0]['body'], $r[0]['mimetype']);
}
- $o .= (($var['wrap'] == 'none') ? '' : '</div>');
+ $o .= ($wrap ? '' : '</div>');
}
}
diff --git a/Zotlabs/Render/SmartyTemplate.php b/Zotlabs/Render/SmartyTemplate.php
index 61fb72f8a..2cb96521b 100644
--- a/Zotlabs/Render/SmartyTemplate.php
+++ b/Zotlabs/Render/SmartyTemplate.php
@@ -8,16 +8,16 @@ use App;
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']))
+ $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;
+ $basecompiledir = str_replace('Zotlabs','',dirname(__dir__)) . TEMPLATE_BUILD_PATH;
}
if (! is_dir($basecompiledir)) {
@os_mkdir(TEMPLATE_BUILD_PATH, STORAGE_DEFAULT_PERMISSIONS, true);
@@ -30,7 +30,7 @@ class SmartyTemplate implements TemplateEngine {
}
App::$config['system']['smarty3_folder'] = $basecompiledir;
}
-
+
// TemplateEngine interface
public function replace_macros($s, $r) {
@@ -52,9 +52,9 @@ class SmartyTemplate implements TemplateEngine {
}
$s->assign($key, $value);
}
- return $s->parsed($template);
+ return $s->parsed($template);
}
-
+
public function get_markup_template($file, $root = '') {
$template_file = theme_include($file, $root);
if ($template_file) {
@@ -62,7 +62,7 @@ class SmartyTemplate implements TemplateEngine {
$template->filename = $template_file;
return $template;
- }
+ }
return EMPTY_STR;
}
@@ -84,7 +84,7 @@ class SmartyTemplate implements TemplateEngine {
$template = new SmartyInterface();
$template->filename = $template_file;
return $template;
- }
+ }
return "";
}
diff --git a/Zotlabs/Storage/BasicAuth.php b/Zotlabs/Storage/BasicAuth.php
index 3a48f5004..d23f3d848 100644
--- a/Zotlabs/Storage/BasicAuth.php
+++ b/Zotlabs/Storage/BasicAuth.php
@@ -125,10 +125,10 @@ class BasicAuth extends DAV\Auth\Backend\AbstractBasic {
* Array with the values for the authenticated channel.
* @return bool
*/
- protected function setAuthenticated($r) {
- $this->channel_name = $r['channel_address'];
- $this->channel_id = $r['channel_id'];
- $this->channel_hash = $this->observer = $r['channel_hash'];
+ protected function setAuthenticated($channel) {
+ $this->channel_name = $channel['channel_address'];
+ $this->channel_id = $channel['channel_id'];
+ $this->channel_hash = $this->observer = $channel['channel_hash'];
if ($this->observer) {
$r = q("select * from xchan where xchan_hash = '%s' limit 1",
@@ -139,8 +139,8 @@ class BasicAuth extends DAV\Auth\Backend\AbstractBasic {
}
}
- $_SESSION['uid'] = $r['channel_id'];
- $_SESSION['account_id'] = $r['channel_account_id'];
+ $_SESSION['uid'] = $channel['channel_id'];
+ $_SESSION['account_id'] = $channel['channel_account_id'];
$_SESSION['authenticated'] = true;
return true;
}
diff --git a/Zotlabs/Update/_1244.php b/Zotlabs/Update/_1244.php
new file mode 100644
index 000000000..0aebe4013
--- /dev/null
+++ b/Zotlabs/Update/_1244.php
@@ -0,0 +1,15 @@
+<?php
+
+namespace Zotlabs\Update;
+
+require_once('include/account.php');
+
+class _1244 {
+
+ function run() {
+
+ return verify_register_scheme();
+
+ }
+
+}
diff --git a/Zotlabs/Update/_1245.php b/Zotlabs/Update/_1245.php
new file mode 100644
index 000000000..8212fde08
--- /dev/null
+++ b/Zotlabs/Update/_1245.php
@@ -0,0 +1,29 @@
+<?php
+
+namespace Zotlabs\Update;
+
+class _1245 {
+
+ function run() {
+
+ if(ACTIVE_DBTYPE == DBTYPE_MYSQL) {
+ return UPDATE_SUCCESS;
+ }
+
+ if(ACTIVE_DBTYPE == DBTYPE_POSTGRES) {
+ q("START TRANSACTION");
+
+ $r = dbq("create index hubloc_hash on hubloc (hubloc_hash)");
+
+ if($r) {
+ q("COMMIT");
+ return UPDATE_SUCCESS;
+ }
+
+ q("ROLLBACK");
+ return UPDATE_FAILED;
+ }
+
+ }
+
+}
diff --git a/Zotlabs/Web/HTTPSig.php b/Zotlabs/Web/HTTPSig.php
index 2535c9016..35b18c763 100644
--- a/Zotlabs/Web/HTTPSig.php
+++ b/Zotlabs/Web/HTTPSig.php
@@ -250,7 +250,7 @@ class HTTPSig {
static function convertKey($key) {
if(strstr($key,'RSA ')) {
- return rsatopem($key);
+ return Keyutils::rsaToPem($key);
}
elseif(substr($key,0,5) === 'data:') {
return Keyutils::convertSalmonKey($key);
diff --git a/Zotlabs/Web/Session.php b/Zotlabs/Web/Session.php
index fe0a3fbf9..6f92a0319 100644
--- a/Zotlabs/Web/Session.php
+++ b/Zotlabs/Web/Session.php
@@ -29,34 +29,44 @@ class Session {
/*
* Set our session storage functions.
*/
-
+
if($this->custom_handler) {
/* Custom handler (files, memached, redis..) */
$session_save_handler = strval(get_config('system', 'session_save_handler', Null));
$session_save_path = strval(get_config('system', 'session_save_path', Null));
- $session_gc_probability = intval(get_config('system', 'session_gc_probability', 1));
- $session_gc_divisor = intval(get_config('system', 'session_gc_divisor', 100));
- if(!$session_save_handler || !$session_save_path) {
- logger('Session save handler or path not set.',LOGGER_NORMAL,LOG_ERR);
+
+ if(is_null($session_save_handler) || is_null($session_save_path)) {
+ logger('Session save handler or path not set', LOGGER_NORMAL, LOG_ERR);
}
else {
- ini_set('session.save_handler', $session_save_handler);
- ini_set('session.save_path', $session_save_path);
- ini_set('session.gc_probability', $session_gc_probability);
- ini_set('session.gc_divisor', $session_gc_divisor);
+ // Check if custom sessions backend exists
+ $clsname = '\Zotlabs\Web\Session' . ucfirst(strtolower($session_save_handler));
+ if (class_exists($clsname)) {
+ $handler = new $clsname($session_save_path);
+ }
+ else {
+ ini_set('session.save_handler', $session_save_handler);
+ ini_set('session.save_path', $session_save_path);
+ ini_set('session.gc_probability', intval(get_config('system', 'session_gc_probability', 1)));
+ ini_set('session.gc_divisor', intval(get_config('system', 'session_gc_divisor', 100)));
+ }
}
}
else {
- $handler = new \Zotlabs\Web\SessionHandler();
+ $handler = new SessionHandler();
+ }
+
+ if (isset($handler)) {
$this->handler = $handler;
- $x = session_set_save_handler($handler,false);
- if(! $x)
- logger('Session save handler initialisation failed.',LOGGER_NORMAL,LOG_ERR);
+ $x = session_set_save_handler($handler, false);
+ if(! $x)
+ logger('Session save handler initialisation failed.',LOGGER_NORMAL,LOG_ERR);
}
+
// Force cookies to be secure (https only) if this site is SSL enabled.
// Must be done before session_start().
diff --git a/Zotlabs/Web/SessionRedis.php b/Zotlabs/Web/SessionRedis.php
new file mode 100644
index 000000000..66eb7a02d
--- /dev/null
+++ b/Zotlabs/Web/SessionRedis.php
@@ -0,0 +1,123 @@
+<?php
+
+namespace Zotlabs\Web;
+
+
+class SessionRedis implements \SessionHandlerInterface {
+
+ private $redis = null;
+
+
+ function __construct($connection) {
+
+ $this->redis = new \Redis();
+
+ $credentials = parse_url($connection);
+
+ try {
+ if (isset($credentials['path']))
+ $this->redis->connect($credentials['path']);
+ else {
+
+ if (isset($credentials['query']))
+ parse_str($credentials['query'], $vars);
+ else
+ $vars = [];
+
+ $this->redis->connect(
+ (isset($credentials['scheme']) ? $credentials['scheme'] . '://' : '') . $credentials['host'],
+ (isset($credentials['port']) ? $credentials['port'] : 6379),
+ (isset($vars['timeout']) ? $vars['timeout'] : 1),
+ null,
+ 0,
+ (isset($vars['read_timeout']) ? $vars['read_timeout'] : 0)
+ );
+
+ if (isset($vars['auth']))
+ $this->redis->auth($vars['auth']);
+ }
+ }
+ catch(\RedisException $ex) {
+ logger('Error connecting to Redis: ' . $ex->getMessage());
+ }
+ }
+
+
+ function open($s, $n) {
+
+ return true;
+ }
+
+ // IMPORTANT: if we read the session and it doesn't exist, create an empty record.
+ // We rely on this due to differing PHP implementation of session_regenerate_id()
+ // some which call read explicitly and some that do not. So we call it explicitly
+ // just after sid regeneration to force a record to exist.
+
+ function read($id) {
+
+ if ($id) {
+ $data = $this->redis->get($id);
+
+ if ($data)
+ return $data;
+ else
+ $this->redis->setEx($id, 300, '');
+ }
+
+ return '';
+ }
+
+
+ function write($id, $data) {
+
+ // Pretend everything is hunky-dory, even though it isn't.
+ // There probably isn't anything we can do about it in any event.
+ // See: https://stackoverflow.com/a/43636110
+
+ if(! $id || ! $data)
+ return true;
+
+
+ // Unless we authenticate somehow, only keep a session for 5 minutes
+ // The viewer can extend this by performing any web action using the
+ // original cookie, but this allows us to cleanup the hundreds or
+ // thousands of empty sessions left around from web crawlers which are
+ // assigned cookies on each page that they never use.
+
+ $expire = 300;
+
+ if($_SESSION) {
+ if(array_key_exists('remember_me',$_SESSION) && intval($_SESSION['remember_me']))
+ $expire = 60 * 60 * 24 * 365;
+ elseif(local_channel())
+ $expire = 60 * 60 * 24 * 3;
+ elseif(remote_channel())
+ $expire = 60 * 60 * 24 * 1;
+ }
+
+ $this->redis->setEx($id, $expire, $data);
+
+ return true;
+ }
+
+
+ function close() {
+
+ return true;
+ }
+
+
+ function destroy ($id) {
+
+ $this->redis->del($id);
+
+ return true;
+ }
+
+
+ function gc($expire) {
+
+ return true;
+ }
+
+}
diff --git a/Zotlabs/Widget/Activity_filter.php b/Zotlabs/Widget/Activity_filter.php
index 002a642cb..b7a69752e 100644
--- a/Zotlabs/Widget/Activity_filter.php
+++ b/Zotlabs/Widget/Activity_filter.php
@@ -12,10 +12,14 @@ class Activity_filter {
if(! local_channel())
return '';
- $cmd = \App::$cmd;
- $filter_active = false;
-
- $tabs = [];
+ $filter_active = '';
+ $dm_active = '';
+ $events_active = '';
+ $polls_active = '';
+ $starred_active = '';
+ $conv_active = '';
+ $tabs = [];
+ $cmd = \App::$cmd;
if(x($_GET,'dm')) {
$dm_active = (($_GET['dm'] == 1) ? 'active' : '');
@@ -64,6 +68,8 @@ class Activity_filter {
);
if($groups) {
+ $group_active = '';
+
foreach($groups as $g) {
if(x($_GET,'gid')) {
$group_active = (($_GET['gid'] == $g['id']) ? 'active' : '');
@@ -95,6 +101,8 @@ class Activity_filter {
$channel = App::get_channel();
if($forums) {
+ $forum_active = '';
+
foreach($forums as $f) {
if(x($_GET,'pf') && x($_GET,'cid')) {
$forum_active = ((x($_GET,'pf') && $_GET['cid'] == $f['abook_id']) ? 'active' : '');
@@ -103,10 +111,10 @@ class Activity_filter {
$fsub[] = [
'label' => $f['xchan_name'],
'img' => $f['xchan_photo_s'],
- 'url' => (($f['private_forum']) ? $f['xchan_url'] . '/?f=&zid=' . $channel['xchan_addr'] : z_root() . '/' . $cmd . '/?f=&pf=1&cid=' . $f['abook_id']),
+ 'url' => ((isset($f['private_forum'])) ? $f['xchan_url'] . '/?f=&zid=' . $channel['xchan_addr'] : z_root() . '/' . $cmd . '/?f=&pf=1&cid=' . $f['abook_id']),
'sel' => $forum_active,
'title' => t('Show posts to this forum'),
- 'lock' => (($f['private_forum']) ? 'lock' : '')
+ 'lock' => ((isset($f['private_forum'])) ? 'lock' : '')
];
}
@@ -160,6 +168,8 @@ class Activity_filter {
);
if($terms) {
+ $file_active = '';
+
foreach($terms as $t) {
if(x($_GET,'file')) {
$file_active = (($_GET['file'] == $t['term']) ? 'active' : '');
diff --git a/Zotlabs/Widget/Cover_photo.php b/Zotlabs/Widget/Cover_photo.php
index 955048992..97323ea8c 100644
--- a/Zotlabs/Widget/Cover_photo.php
+++ b/Zotlabs/Widget/Cover_photo.php
@@ -9,7 +9,7 @@ class Cover_photo {
require_once('include/channel.php');
$o = '';
- if(\App::$module == 'channel' && $_REQUEST['mid'])
+ if(\App::$module == 'channel' && isset($_REQUEST['mid']))
return '';
$channel_id = 0;
diff --git a/Zotlabs/Widget/Notifications.php b/Zotlabs/Widget/Notifications.php
index e2a543f80..dd5a6cd46 100644
--- a/Zotlabs/Widget/Notifications.php
+++ b/Zotlabs/Widget/Notifications.php
@@ -175,13 +175,13 @@ class Notifications {
];
}
- $o = replace_macros(get_markup_template('notifications_widget.tpl'), array(
+ $o = replace_macros(get_markup_template('notifications_widget.tpl'), [
'$module' => \App::$module,
'$notifications' => $notifications,
'$no_notifications' => t('Sorry, you have got no notifications at the moment'),
'$loading' => t('Loading'),
- '$startpage' => $channel['channel_startpage']
- ));
+ '$startpage' => ($channel ? $channel['channel_startpage'] : '')
+ ]);
return $o;
diff --git a/Zotlabs/Widget/Pinned.php b/Zotlabs/Widget/Pinned.php
index 0a7806908..cad139a91 100644
--- a/Zotlabs/Widget/Pinned.php
+++ b/Zotlabs/Widget/Pinned.php
@@ -43,7 +43,7 @@ class Pinned {
$midb64 = 'b64.' . base64url_encode($item['mid']);
- if(in_array($observer['xchan_hash'], get_pconfig($item['uid'], 'pinned_hide', $midb64, [])))
+ if(isset($observer['xchan_hash']) && in_array($observer['xchan_hash'], get_pconfig($item['uid'], 'pinned_hide', $midb64, [])))
continue;
$author = channelx_by_hash($item['author_xchan']);
@@ -67,7 +67,7 @@ class Pinned {
$conv_responses['attendno'] = [ 'title' => t('Not attending','title') ];
$conv_responses['attendmaybe'] = [ 'title' => t('Might attend','title') ];
if($commentable && $observer) {
- $attend = array( t('I will attend'), t('I will not attend'), t('I might attend'));
+ $attend = [ t('I will attend'), t('I will not attend'), t('I might attend') ];
$isevent = true;
}
}
@@ -78,7 +78,7 @@ class Pinned {
$conv_responses['disagree'] = [ 'title' => t('Disagree','title') ];
$conv_responses['abstain'] = [ 'title' => t('Abstain','title') ];
if($commentable && $observer) {
- $conlabels = array( t('I agree'), t('I disagree'), t('I abstain'));
+ $conlabels = [ t('I agree'), t('I disagree'), t('I abstain') ];
$canvote = true;
}
}
@@ -93,14 +93,13 @@ class Pinned {
// This actually turns out not to be possible in some protocol stacks without opening up hundreds of new issues.
// Will allow it only for uri resolvable sources.
if(strpos($item['mid'],'http') === 0) {
- $share = []; //Not yet ready for primetime
- //$share = array( t('Repeat This'), t('repeat'));
+ $share = []; // Isn't yet ready for primetime
+ //$share = [ t('Repeat This'), t('repeat') ];
}
- $embed = array( t('Share This'), t('share'));
+ $embed = [ t('Share This'), t('share') ];
}
-
- if(strcmp(datetime_convert('UTC','UTC',$item['created']),datetime_convert('UTC','UTC','now - 12 hours')) > 0)
- $is_new = true;
+
+ $is_new = boolval(strcmp(datetime_convert('UTC','UTC',$item['created']),datetime_convert('UTC','UTC','now - 12 hours')) > 0);
$body = prepare_body($item,true);
@@ -118,7 +117,7 @@ class Pinned {
'isevent' => $isevent,
'attend' => $attend,
'consensus' => $consensus,
- 'conlabels' => $conlabels,
+ 'conlabels' => ($canvote ? $conlabels : []),
'canvote' => $canvote,
'linktitle' => sprintf( t('View %s\'s profile - %s'), $profile_name, ($author['xchan_addr'] ? $author['xchan_addr'] : $author['xchan_url']) ),
'olinktitle' => sprintf( t('View %s\'s profile - %s'), $owner['xchan_name'], ($owner['xchan_addr'] ? $owner['xchan_addr'] : $owner['xchan_url']) ),
@@ -135,7 +134,6 @@ class Pinned {
'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,
'forged' => $forged,
'location' => $location,
@@ -150,12 +148,12 @@ class Pinned {
'event' => $body['event'],
'has_tags' => (($body['tags'] || $body['categories'] || $body['mentions'] || $body['attachments'] || $body['folders']) ? true : false),
// Item toolbar buttons
- 'share' => $share,
- 'embed' => $embed,
+ 'share' => (isset($share) && count($share) ? $share : false),
+ 'embed' => (isset($embed) && count($embed) ? $embed : false),
'plink' => get_plink($item),
'pinned' => t('Pinned post'),
- 'pinme' => (($observer['xchan_hash'] == $owner['xchan_hash']) ? t('Unpin from the top') : ''),
- 'hide' => (! $is_new && $observer && ($observer['xchan_hash'] != $owner['xchan_hash']) ? t("Don't show") : ''),
+ 'pinme' => (isset($observer['xchan_hash']) && $observer['xchan_hash'] == $owner['xchan_hash'] ? t('Unpin from the top') : ''),
+ 'hide' => (! $is_new && isset($observer['xchan_hash']) && $observer['xchan_hash'] != $owner['xchan_hash'] ? t("Don't show") : ''),
// end toolbar buttons
'modal_dismiss' => t('Close'),
'responses' => $conv_responses