aboutsummaryrefslogtreecommitdiffstats
path: root/include
diff options
context:
space:
mode:
authorhabeascodice <habeascodice@federated.social>2014-10-29 03:39:07 -0700
committerhabeascodice <habeascodice@federated.social>2014-10-29 03:39:07 -0700
commitbc02b933727da7a000d43d2d7d495f066616dc81 (patch)
treee590b70757edb94655872f5b992f143cead61eb3 /include
parentfc12123329133cea39f27615a7c24c57e5b4a35d (diff)
parent7d9f785758ee6e4c19838e532f9930e227e95fc6 (diff)
downloadvolse-hubzilla-bc02b933727da7a000d43d2d7d495f066616dc81.tar.gz
volse-hubzilla-bc02b933727da7a000d43d2d7d495f066616dc81.tar.bz2
volse-hubzilla-bc02b933727da7a000d43d2d7d495f066616dc81.zip
Merge remote branch 'upstream/master'
Diffstat (limited to 'include')
-rw-r--r--include/Contact.php21
-rw-r--r--include/ItemObject.php4
-rw-r--r--include/RedDAV/RedBrowser.php1
-rw-r--r--include/acl_selectors.php3
-rw-r--r--include/api.php17
-rw-r--r--include/bb2diaspora.php28
-rw-r--r--include/conversation.php10
-rw-r--r--include/datetime.php181
-rw-r--r--include/event.php14
-rw-r--r--include/follow.php8
-rw-r--r--include/html2bbcode.php7
-rw-r--r--include/hubloc.php90
-rw-r--r--include/identity.php5
-rwxr-xr-xinclude/items.php21
-rw-r--r--include/nav.php11
-rw-r--r--include/permissions.php51
-rw-r--r--include/poller.php31
-rw-r--r--include/reddav.php4
-rw-r--r--include/taxonomy.php2
-rw-r--r--include/text.php4
-rw-r--r--include/widgets.php13
-rw-r--r--include/zot.php8
22 files changed, 371 insertions, 163 deletions
diff --git a/include/Contact.php b/include/Contact.php
index 4440369dc..20e5e1a1e 100644
--- a/include/Contact.php
+++ b/include/Contact.php
@@ -245,11 +245,13 @@ function channel_remove($channel_id, $local = true, $unset_session=true) {
intval($channel_id)
);
+
$r = q("update hubloc set hubloc_flags = (hubloc_flags | %d) where hubloc_hash = '%s'",
intval(HUBLOC_FLAGS_DELETED),
dbesc($channel['channel_hash'])
);
+
$r = q("update xchan set xchan_flags = (xchan_flags | %d) where xchan_hash = '%s'",
intval(XCHAN_FLAGS_DELETED),
dbesc($channel['channel_hash'])
@@ -257,7 +259,6 @@ function channel_remove($channel_id, $local = true, $unset_session=true) {
proc_run('php','include/notifier.php','purge_all',$channel_id);
-
}
q("DELETE FROM `groups` WHERE `uid` = %d", intval($channel_id));
@@ -291,11 +292,23 @@ function channel_remove($channel_id, $local = true, $unset_session=true) {
dbesc(z_root())
);
- $r = q("update xchan set xchan_flags = (xchan_flags | %d) where xchan_hash = '%s' ",
- intval(XCHAN_FLAGS_DELETED),
- dbesc($channel['channel_hash'])
+ // Do we have any valid hublocs remaining?
+
+ $hublocs = 0;
+
+ $r = q("select hubloc_id from hubloc where hubloc_hash = '%s' and not (hubloc_flags & %d)",
+ dbesc($channel['channel_hash']),
+ intval(HUBLOC_FLAGS_DELETED)
);
+ if($r)
+ $hublocs = count($r);
+ if(! $hublocs) {
+ $r = q("update xchan set xchan_flags = (xchan_flags | %d) where xchan_hash = '%s' ",
+ intval(XCHAN_FLAGS_DELETED),
+ dbesc($channel['channel_hash'])
+ );
+ }
proc_run('php','include/directory.php',$channel_id);
diff --git a/include/ItemObject.php b/include/ItemObject.php
index 7c75e35bd..90c036def 100644
--- a/include/ItemObject.php
+++ b/include/ItemObject.php
@@ -191,7 +191,8 @@ class Item extends BaseObject {
}
- $verified = (($item['item_flags'] & ITEM_VERIFIED) ? t('Message is verified') : '');
+ $verified = (($item['item_flags'] & ITEM_VERIFIED) ? t('Message signature validated') : '');
+ $forged = ((($item['sig']) && (! ($item['item_flags'] & ITEM_VERIFIED))) ? t('Message signature incorrect') : '');
$unverified = '' ; // (($this->is_wall_to_wall() && (! ($item['item_flags'] & ITEM_VERIFIED))) ? t('Message cannot be verified') : '');
@@ -269,6 +270,7 @@ class Item extends BaseObject {
'lock' => $lock,
'verified' => $verified,
'unverified' => $unverified,
+ 'forged' => $forged,
'location' => $location,
'indent' => $indent,
'owner_url' => $this->get_owner_url(),
diff --git a/include/RedDAV/RedBrowser.php b/include/RedDAV/RedBrowser.php
index 6ec5c978d..21ea76aed 100644
--- a/include/RedDAV/RedBrowser.php
+++ b/include/RedDAV/RedBrowser.php
@@ -259,6 +259,7 @@ class RedBrowser extends DAV\Browser\Plugin {
$html .= $output;
get_app()->page['content'] = $html;
+ load_pdl(get_app());
construct_page(get_app());
}
diff --git a/include/acl_selectors.php b/include/acl_selectors.php
index 0b68ba227..5adafff2c 100644
--- a/include/acl_selectors.php
+++ b/include/acl_selectors.php
@@ -248,8 +248,7 @@ function populate_acl($defaults = null,$show_jotnets = true) {
'$aclModalTitle' => t('Permissions'),
'$aclModalDismiss' => t('Close')
));
-
-
+
return $o;
}
diff --git a/include/api.php b/include/api.php
index 2505def4c..9fe2ef47d 100644
--- a/include/api.php
+++ b/include/api.php
@@ -197,7 +197,10 @@ require_once('include/items.php');
case "json":
header ("Content-Type: application/json");
foreach($r as $rr)
- return json_encode($rr);
+ $json = json_encode($rr);
+ if ($_GET['callback'])
+ $json = $_GET['callback']."(".$json.")";
+ return $json;
break;
case "rss":
header ("Content-Type: application/rss+xml");
@@ -618,7 +621,19 @@ require_once('include/items.php');
api_register_func('api/red/group','api_group', true);
+ function api_red_xchan(&$a,$type) {
+ if(api_user() === false)
+ return false;
+ require_once('include/hubloc.php');
+ if($_SERVER['request_method'] === 'POST') {
+ $r = xchan_store($_REQUEST);
+ }
+ $r = xchan_fetch($_REQUEST);
+ json_return_and_die($r);
+ };
+ api_register_func('api/red/xchan','api_red_xchan',true);
+
function api_statuses_mediap(&$a, $type) {
if (api_user() === false) {
diff --git a/include/bb2diaspora.php b/include/bb2diaspora.php
index 76708143b..8a178d1ac 100644
--- a/include/bb2diaspora.php
+++ b/include/bb2diaspora.php
@@ -116,6 +116,8 @@ function diaspora_mention_callback($matches) {
function diaspora2bb($s,$use_zrl = false) {
+ $s = str_replace("&#xD;\n&gt;","",$s);
+
$s = html_entity_decode($s,ENT_COMPAT,'UTF-8');
// Too many new lines. So deactivated the following line
@@ -286,6 +288,23 @@ function bb2diaspora_itemwallwall(&$item) {
. '[url=' . $item['author']['xchan_url'] . ']' . $item['author']['xchan_name'] . '[/url]' . "\n\n"
. $item['body'];
}
+
+ // We have to do something similar for wall-to-wall comments. ITEM_WALL|ITEM_ORIGIN indicates that it was posted on this site.
+ // Regular matrix comments may have one of these bits set, but not both.
+
+ // Update: this is getting triggered way too often and unnecessarily. Commenting out until we find a better solution.
+ // It's not an easy problem. For now we'll live with the mis-attributions, as wall to wall comments are much less frequent
+ // than wall-to-wall posts.
+
+// if(($item['mid'] != $item['parent_mid']) && ($item['author_xchan'] != $item['owner_xchan']) && (($item['item_flags'] & (ITEM_WALL|ITEM_ORIGIN)) == (ITEM_WALL|ITEM_ORIGIN)) && (is_array($item['author'])) && $item['author']['xchan_url'] && $item['author']['xchan_name'] && $item['author']['xchan_photo_m']) {
+// logger('bb2diaspora_itemwallwall: wall to wall comment',LOGGER_DEBUG);
+ // post will come across with the owner's identity. Throw a preamble onto the post to indicate the true author.
+// $item['body'] = "\n\n"
+// . '[img]' . $item['author']['xchan_photo_m'] . '[/img]'
+// . '[url=' . $item['author']['xchan_url'] . ']' . $item['author']['xchan_name'] . '[/url]' . "\n\n"
+// . $item['body'];
+// }
+
// $item['author'] might cause a surprise further down the line if it wasn't expected to be here.
if(! $author_exists)
@@ -321,8 +340,13 @@ function bb2diaspora_itembody($item,$force_update = false) {
if(array_key_exists('item_flags',$item) && ($item['item_flags'] & ITEM_OBSCURED)) {
$key = get_config('system','prvkey');
- $newitem['title'] = (($item['title']) ? crypto_unencapsulate(json_decode($item['title'],true),$key) : '');
- $newitem['body'] = (($item['body']) ? crypto_unencapsulate(json_decode($item['body'],true),$key) : '');
+ $b = json_decode($item['body'],true);
+ // if called from diaspora_process_outbound, this decoding has already been done.
+ // Everything else that calls us will not yet be decoded.
+ if($b && is_array($b) && array_key_exists('iv',$b)) {
+ $newitem['title'] = (($item['title']) ? crypto_unencapsulate(json_decode($item['title'],true),$key) : '');
+ $newitem['body'] = (($item['body']) ? crypto_unencapsulate(json_decode($item['body'],true),$key) : '');
+ }
}
bb2diaspora_itemwallwall($newitem);
diff --git a/include/conversation.php b/include/conversation.php
index 92ba18d13..48fe8af60 100644
--- a/include/conversation.php
+++ b/include/conversation.php
@@ -649,7 +649,10 @@ function conversation(&$a, $items, $mode, $update, $page_mode = 'traditional', $
$likebuttons = false;
$shareable = false;
- $verified = (($item['item_flags'] & ITEM_VERIFIED) ? t('Message is verified') : '');
+ $verified = (($item['item_flags'] & ITEM_VERIFIED) ? t('Message signature validated') : '');
+ $forged = ((($item['sig']) && (! ($item['item_flags'] & ITEM_VERIFIED))) ? t('Message signature incorrect') : '');
+
+
$unverified = '';
@@ -682,6 +685,7 @@ function conversation(&$a, $items, $mode, $update, $page_mode = 'traditional', $
'mentions' => $mentions,
'verified' => $verified,
'unverified' => $unverified,
+ 'forged' => $forged,
'txt_cats' => t('Categories:'),
'txt_folders' => t('Filed under:'),
'has_cats' => ((count($categories)) ? 'true' : ''),
@@ -823,8 +827,8 @@ function conversation(&$a, $items, $mode, $update, $page_mode = 'traditional', $
$threads = null;
}
- if($page_mode === 'preview')
- logger('preview: ' . print_r($threads,true));
+// if($page_mode === 'preview')
+// logger('preview: ' . print_r($threads,true));
// Do not un-comment if smarty3 is in use
// logger('page_template: ' . $page_template);
diff --git a/include/datetime.php b/include/datetime.php
index 84ab1e2fa..fe0f29c7a 100644
--- a/include/datetime.php
+++ b/include/datetime.php
@@ -130,135 +130,98 @@ function datetime_convert($from = 'UTC', $to = 'UTC', $s = 'now', $fmt = "Y-m-d
function dob($dob) {
list($year,$month,$day) = sscanf($dob,'%4d-%2d-%2d');
- $y = datetime_convert('UTC',date_default_timezone_get(),'now','Y');
$f = get_config('system','birthday_input_format');
if(! $f)
$f = 'ymd';
- $o = datesel($f,'',1920,$y,true,$year,$month,$day);
- return $o;
-}
-
-function datesel_format($f) {
-
- $o = '';
+ $o = datesel($f,mktime(0,0,0,0,0,1900),mktime(),mktime(0,0,0,$month,$day,$year),'dob');
- if(strlen($f)) {
- for($x = 0; $x < strlen($f); $x ++) {
- switch($f[$x]) {
- case 'y':
- if(strlen($o))
- $o .= '-';
- $o .= t('year');
- break;
- case 'm':
- if(strlen($o))
- $o .= '-';
- $o .= t('month');
- break;
- case 'd':
- if(strlen($o))
- $o .= '-';
- $o .= t('day');
- break;
- default:
- break;
- }
- }
- }
return $o;
}
-// returns a date selector.
-// $f = format string, e.g. 'ymd' or 'mdy'
-// $pre = prefix (if needed) for HTML name and class fields
-// $ymin = first year shown in selector dropdown
-// $ymax = last year shown in selector dropdown
-// $allow_blank = allow an empty response on any field
-// $y = already selected year
-// $m = already selected month
-// $d = already selected day
-
+/**
+ * returns a date selector
+ * @param $format
+ * format string, e.g. 'ymd' or 'mdy'. Not currently supported
+ * @param $min
+ * unix timestamp of minimum date
+ * @param $max
+ * unix timestap of maximum date
+ * @param $default
+ * unix timestamp of default date
+ * @param $id
+ * id and name of datetimepicker (defaults to "datetimepicker")
+ */
+function datesel($format, $min, $max, $default,$id = 'datepicker') {
+ return datetimesel($format,$min,$max,$default,$id,true,false);
+}
-function datesel($f,$pre,$ymin,$ymax,$allow_blank,$y,$m,$d) {
+/**
+ * returns a date selector
+ * @param $format
+ * format string, e.g. 'ymd' or 'mdy'. Not currently supported
+ * @param $h
+ * already selected hour
+ * @param $m
+ * already selected minute
+ * @param $id
+ * id and name of datetimepicker (defaults to "timepicker")
+ */
+function timesel($format,$h,$m,$id='timepicker') {
+ return datetimesel($format,mktime(),mktime(),mktime($h,$m),$id,false,true);
+}
+/**
+ * returns a datetime selector
+ * @param $format
+ * format string, e.g. 'ymd' or 'mdy'. Not currently supported
+ * @param $min
+ * unix timestamp of minimum date
+ * @param $max
+ * unix timestap of maximum date
+ * @param $default
+ * unix timestamp of default date
+ * @param $id
+ * id and name of datetimepicker (defaults to "datetimepicker")
+ * @param $pickdate
+ * true to show date picker (default)
+ * @param $picktime
+ * true to show time picker (default)
+ * @param $minfrom
+ * set minimum date from picker with id $minfrom (none by default)
+ * @param $maxfrom
+ * set maximum date from picker with id $maxfrom (none by default)
+ */
+function datetimesel($format, $min, $max, $default, $id = 'datetimepicker', $pickdate = true, $picktime = true, $minfrom = '', $maxfrom = '') {
$o = '';
- if(strlen($f)) {
- for($z = 0; $z < strlen($f); $z ++) {
- if($f[$z] === 'y') {
-
- $o .= "<select name=\"{$pre}year\" class=\"{$pre}year\" size=\"1\">";
- if($allow_blank) {
- $sel = (($y == '0000') ? " selected=\"selected\" " : "");
- $o .= "<option value=\"0000\" $sel ></option>";
- }
-
- if($ymax > $ymin) {
- for($x = $ymax; $x >= $ymin; $x --) {
- $sel = (($x == $y) ? " selected=\"selected\" " : "");
- $o .= "<option value=\"$x\" $sel>$x</option>";
- }
- }
- else {
- for($x = $ymax; $x <= $ymin; $x ++) {
- $sel = (($x == $y) ? " selected=\"selected\" " : "");
- $o .= "<option value=\"$x\" $sel>$x</option>";
- }
- }
- }
- elseif($f[$z] == 'm') {
-
- $o .= "</select> <select name=\"{$pre}month\" class=\"{$pre}month\" size=\"1\">";
- for($x = (($allow_blank) ? 0 : 1); $x <= 12; $x ++) {
- $sel = (($x == $m) ? " selected=\"selected\" " : "");
- $y = (($x) ? $x : '');
- $o .= "<option value=\"$x\" $sel>$y</option>";
- }
- }
- elseif($f[$z] == 'd') {
-
- $o .= "</select> <select name=\"{$pre}day\" class=\"{$pre}day\" size=\"1\">";
- for($x = (($allow_blank) ? 0 : 1); $x <= 31; $x ++) {
- $sel = (($x == $d) ? " selected=\"selected\" " : "");
- $y = (($x) ? $x : '');
- $o .= "<option value=\"$x\" $sel>$y</option>";
- }
- }
- }
- }
+ $dateformat = '';
+ if($pickdate) $dateformat .= 'YYYY-MM-DD';
+ if($pickdate && $picktime) $dateformat .= ' ';
+ if($picktime) $dateformat .= 'HH:mm';
- $o .= "</select>";
- return $o;
-}
+ $mindate = $min ? "new Date($min*1000)" : '';
+ $maxdate = $max ? "new Date($max*1000)" : '';
+
+ $defaultDate = $default ? ", defaultDate: new Date($default*1000)" : '';
+ $pickers = '';
+ if(!$pickdate) $pickers .= 'pickDate: false,';
+ if(!$picktime) $pickers .= 'pickTime: false,';
-function timesel($pre,$h,$m) {
+ $extra_js = '';
+ if($minfrom != '')
+ $extra_js .= "\$('#$minfrom').on('dp.change',function (e) { \$('#$id').data('DateTimePicker').setMinDate(e.date); });";
- $o = '';
- $o .= "<select name=\"{$pre}hour\" class=\"{$pre}hour\" size=\"1\">";
- for($x = 0; $x < 24; $x ++) {
- $sel = (($x == $h) ? " selected=\"selected\" " : "");
- $o .= "<option value=\"$x\" $sel>$x</option>";
- }
- $o .= "</select> : <select name=\"{$pre}minute\" class=\"{$pre}minute\" size=\"1\">";
- for($x = 0; $x < 60; $x ++) {
- $sel = (($x == $m) ? " selected=\"selected\" " : "");
- $o .= "<option value=\"$x\" $sel>$x</option>";
- }
+ if($maxfrom != '')
+ $extra_js .= "\$('#$maxfrom').on('dp.change',function (e) { \$('#$id').data('DateTimePicker').setMaxDate(e.date); });";
- $o .= "</select>";
+ $o .= "<div class='date' id='$id'><input type='text' placeholder='$dateformat' name='$id'/></div>";
+ $o .= "<script type='text/javascript'>\$(function () {\$('#$id').datetimepicker({sideBySide: true, $pickers minDate: $mindate, maxDate: $maxdate, format: '$dateformat', useCurrent: false $defaultDate}); $extra_js});</script>";
return $o;
}
-
-
-
-
-
-
-
// implements "3 seconds ago" etc.
// based on $posted_date, (UTC).
// Results relative to current timezone
@@ -516,4 +479,4 @@ function update_birthdays() {
}
}
}
-} \ No newline at end of file
+}
diff --git a/include/event.php b/include/event.php
index 1fe6e6f7f..03ecaa0a7 100644
--- a/include/event.php
+++ b/include/event.php
@@ -400,8 +400,7 @@ function event_store_item($arr,$event) {
}
else {
- $z = q("select * from channel where channel_hash = '%s' and channel_id = %d limit 1",
- dbesc($event['event_xchan']),
+ $z = q("select * from channel where channel_id = %d limit 1",
intval($arr['uid'])
);
@@ -413,7 +412,7 @@ function event_store_item($arr,$event) {
$item_arr['id'] = $item['id'];
}
else {
- $wall = (($z) ? true : false);
+ $wall = (($z[0]['channel_hash'] == $event['event_xchan']) ? true : false);
$item_flags = ITEM_THREAD_TOP;
if($wall) {
@@ -455,7 +454,14 @@ function event_store_item($arr,$event) {
$item_arr['body'] = $prefix . format_event_bbcode($arr);
- $item_arr['plink'] = z_root() . '/channel/' . $z[0]['channel_address'] . '/?f=&mid=' . $item_arr['mid'];
+ // if it's local send the permalink to the channel page.
+ // otherwise we'll fallback to /display/$message_id
+
+ if($wall)
+ $item_arr['plink'] = z_root() . '/channel/' . $z[0]['channel_address'] . '/?f=&mid=' . $item_arr['mid'];
+ else
+ $item_arr['plink'] = z_root() . '/display/' . $item_arr['mid'];
+
$x = q("select * from xchan where xchan_hash = '%s' limit 1",
dbesc($arr['event_xchan'])
diff --git a/include/follow.php b/include/follow.php
index c8bd3c500..20fd7f5fc 100644
--- a/include/follow.php
+++ b/include/follow.php
@@ -13,6 +13,8 @@ require_once('include/zot.php');
function new_contact($uid,$url,$channel,$interactive = false, $confirm = false) {
+
+
$result = array('success' => false,'message' => '');
$a = get_app();
@@ -64,7 +66,11 @@ function new_contact($uid,$url,$channel,$interactive = false, $confirm = false)
if($is_red && $j) {
- $my_perms = PERMS_W_STREAM|PERMS_W_MAIL;
+
+ // fixme - we need to be able to define these somewhere for the custom role
+ $my_perms = PERMS_R_STREAM|PERMS_R_PROFILE|PERMS_R_PHOTOS|PERMS_R_ABOOK
+ |PERMS_W_STREAM|PERMS_W_WALL|PERMS_W_COMMENT|PERMS_W_MAIL|PERMS_W_CHAT
+ |PERMS_R_STORAGE|PERMS_R_PAGES|PERMS_W_LIKE;
$role = get_pconfig($uid,'system','permissions_role');
if($role) {
diff --git a/include/html2bbcode.php b/include/html2bbcode.php
index df430e6c7..9ffc85a82 100644
--- a/include/html2bbcode.php
+++ b/include/html2bbcode.php
@@ -16,7 +16,7 @@ function node2bbcode(&$doc, $oldnode, $attributes, $startbb, $endbb)
function node2bbcodesub(&$doc, $oldnode, $attributes, $startbb, $endbb)
{
- $savestart = str_replace('$', '%', $startbb);
+ $savestart = str_replace('$', '\x01', $startbb);
$replace = false;
$xpath = new DomXPath($doc);
@@ -37,7 +37,7 @@ function node2bbcodesub(&$doc, $oldnode, $attributes, $startbb, $endbb)
foreach ($attributes as $attribute => $value) {
- $startbb = str_replace('%'.++$i, '$1', $startbb);
+ $startbb = str_replace('\x01'.++$i, '$1', $startbb);
if (strpos('*'.$startbb, '$1') > 0) {
@@ -283,8 +283,9 @@ function html2bbcode($message)
array('[b]', '[/b]', '[i]', '[/i]'), $message);
// Handling Yahoo style of mails
- $message = str_replace('[hr][b]From:[/b]', '[quote][b]From:[/b]', $message);
+ // $message = str_replace('[hr][b]From:[/b]', '[quote][b]From:[/b]', $message);
+ $message = htmlspecialchars($message,ENT_COMPAT,'UTF-8',false);
return(trim($message));
}
diff --git a/include/hubloc.php b/include/hubloc.php
index 04c29315a..0a1b51331 100644
--- a/include/hubloc.php
+++ b/include/hubloc.php
@@ -170,4 +170,92 @@ function hubloc_change_primary($hubloc) {
return true;
}
- \ No newline at end of file
+
+
+function xchan_store($arr) {
+
+ if(! $arr['hash'])
+ $arr['hash'] = $arr['guid'];
+ if(! $arr['hash'])
+ return false;
+
+ $r = q("select * from xchan where xchan_hash = '%s' limit 1",
+ dbesc($arr['hash'])
+ );
+ if($r)
+ return true;
+
+ if(! $arr['network'])
+ $arr['network'] = 'unknown';
+ if(! $arr['name'])
+ $arr['name'] = 'unknown';
+ if(! $arr['url'])
+ $arr['url'] = z_root();
+ if(! $arr['photo'])
+ $arr['photo'] = get_default_profile_photo();
+
+ $r = q("insert into xchan ( xchan_hash, xchan_guid, xchan_guid_sig, xchan_pubkey, xchan_addr, xchan_url, xchan_connurl, xchan_follow, xchan_connpage, xchan_name, xchan_network, xchan_instance_url, xchan_flags, xchan_name_date ) values ('%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s','%s','%s','%s',%d,'%s') ",
+ dbesc($arr['hash']),
+ dbesc($arr['guid']),
+ dbesc($arr['guid_sig']),
+ dbesc($arr['pubkey']),
+ dbesc($arr['address']),
+ dbesc($arr['url']),
+ dbesc($arr['connurl']),
+ dbesc($arr['follow']),
+ dbesc($arr['connpage']),
+ dbesc($arr['name']),
+ dbesc($arr['network']),
+ dbesc($arr['instance_url']),
+ intval($arr['flags']),
+ dbesc(datetime_convert())
+ );
+ if(! $r)
+ return $r;
+
+ $photos = import_profile_photo($arr['photo'],$arr['hash']);
+ $r = q("update xchan set xchan_photo_date = '%s', xchan_photo_l = '%s', xchan_photo_m = '%s', xchan_photo_s = '%s', xchan_photo_mimetype = '%s' where xchan_hash = '%s' limit 1",
+ dbesc(datetime_convert()),
+ dbesc($photos[0]),
+ dbesc($photos[1]),
+ dbesc($photos[2]),
+ dbesc($photos[3]),
+ dbesc($arr['hash'])
+ );
+ return $r;
+
+}
+
+
+function xchan_fetch($arr) {
+
+ $key = '';
+ if($arr['hash']) {
+ $key = 'xchan_hash';
+ $v = $arr['hash'];
+ }
+ elseif($arr['guid']) {
+ $key = 'xchan_guid';
+ $v = $arr['guid'];
+ }
+ elseif($arr['address']) {
+ $key = 'xchan_addr';
+ $v = $arr['address'];
+ }
+
+ if(! $key)
+ return false;
+
+ $r = q("select * from xchan where $key = '$v'");
+ if(! $r)
+ return false;
+
+ $ret = array();
+ foreach($r as $k => $v) {
+ if($k === 'xchan_addr')
+ $ret['address'] = $v;
+ else
+ $ret[str_replace('xchan_','',$k)] = $v;
+ }
+ return $ret;
+} \ No newline at end of file
diff --git a/include/identity.php b/include/identity.php
index 07bfaebbd..9a574ea65 100644
--- a/include/identity.php
+++ b/include/identity.php
@@ -176,6 +176,7 @@ function create_identity($arr) {
// save this for auto_friending
$total_identities = $ret['total_identities'];
+
$nick = mb_strtolower(trim($arr['nickname']));
if(! $nick) {
$ret['message'] = t('Nickname is required.');
@@ -389,7 +390,8 @@ function create_identity($arr) {
dbesc( t('Friends') )
);
if($r) {
- q("update channel set channel_allow_gid = '%s' where channel_id = %d limit 1",
+ q("update channel set channel_default_group = '%s', channel_allow_gid = '%s' where channel_id = %d limit 1",
+ dbesc($r[0]['hash']),
dbesc('<' . $r[0]['hash'] . '>'),
intval($newuid)
);
@@ -403,6 +405,7 @@ function create_identity($arr) {
$accts = get_config('system','auto_follow');
if(($accts) && (! $total_identities)) {
+ require_once('include/follow.php');
if(! is_array($accts))
$accts = array($accts);
foreach($accts as $acct) {
diff --git a/include/items.php b/include/items.php
index 40343d505..41c211953 100755
--- a/include/items.php
+++ b/include/items.php
@@ -98,6 +98,7 @@ function collect_recipients($item,&$private_envelope) {
}
}
+
// This is a somewhat expensive operation but important.
// Don't send this item to anybody who isn't allowed to see it
@@ -213,6 +214,7 @@ function can_comment_on_post($observer_xchan,$item) {
break;
case 'any connections':
case 'contacts':
+ case 'authenticated':
case '':
if(array_key_exists('owner',$item)) {
if(($item['owner']['abook_xchan']) && ($item['owner']['abook_their_perms'] & PERMS_W_COMMENT))
@@ -2516,7 +2518,7 @@ function item_store_update($arr,$allow_exec = false) {
return $ret;
}
-function store_diaspora_comment_sig($datarray, $channel, $parent_item, $post_id) {
+function store_diaspora_comment_sig($datarray, $channel, $parent_item, $post_id, $walltowall = false) {
// We won't be able to sign Diaspora comments for authenticated visitors
// - we don't have their private key
@@ -2524,9 +2526,18 @@ function store_diaspora_comment_sig($datarray, $channel, $parent_item, $post_id)
// since Diaspora doesn't handle edits we can only do this for the original text and not update it.
require_once('include/bb2diaspora.php');
- $signed_body = bb2diaspora_itembody($datarray);
+ $signed_body = bb2diaspora_itembody($datarray,$walltowall);
+
+ if($walltowall) {
+ logger('wall to wall comment',LOGGER_DEBUG);
+ // post will come across with the owner's identity. Throw a preamble onto the post to indicate the true author.
+ $signed_body = "\n\n"
+ . '![' . $datarray['author']['xchan_name'] . '](' . $datarray['author']['xchan_photo_m'] . ')'
+ . '[' . $datarray['author']['xchan_name'] . '](' . $datarray['author']['xchan_url'] . ')' . "\n\n"
+ . $signed_body;
+ }
- logger('mod_item: storing diaspora comment signature',LOGGER_DEBUG);
+ logger('storing diaspora comment signature',LOGGER_DEBUG);
$diaspora_handle = $channel['channel_address'] . '@' . get_app()->get_hostname();
@@ -4130,7 +4141,7 @@ function list_post_dates($uid,$wall) {
if(intval(substr($dnow,8)) > 28)
$dnow = substr($dnow,0,8) . '28';
if(intval(substr($dthen,8)) > 28)
- $dnow = substr($dthen,0,8) . '28';
+ $dthen = substr($dthen,0,8) . '28';
$ret = array();
// Starting with the current month, get the first and last days of every
@@ -4164,7 +4175,7 @@ function posted_dates($uid,$wall) {
if(intval(substr($dnow,8)) > 28)
$dnow = substr($dnow,0,8) . '28';
if(intval(substr($dthen,8)) > 28)
- $dnow = substr($dthen,0,8) . '28';
+ $dthen = substr($dthen,0,8) . '28';
$ret = array();
// Starting with the current month, get the first and last days of every
diff --git a/include/nav.php b/include/nav.php
index 4f7d609aa..f1f89db20 100644
--- a/include/nav.php
+++ b/include/nav.php
@@ -84,6 +84,7 @@ EOT;
$nav['usermenu']=array();
$userinfo = null;
+ $nav['loginmenu']=array();
if(local_user()) {
@@ -120,8 +121,9 @@ EOT;
$nav['usermenu'][] = Array('webpages/' . $channel['channel_address'],t('Webpages'),"",t('Your webpages'));
}
else {
- if(! get_account_id())
- $nav['login'] = Array('login',t('Login'), ($a->module == 'login'?'selected':''), t('Sign in'));
+ if(! get_account_id()) {
+ $nav['loginmenu'][] = Array('login',t('Login'),'',t('Sign in'));
+ }
else
$nav['alogout'] = Array('logout',t('Logout'), "", t('End this session'));
@@ -136,14 +138,11 @@ EOT;
}
if($observer) {
- $nav['locked'] = true;
$nav['lock'] = array('logout','','lock',
sprintf( t('%s - click to logout'), $observer['xchan_addr']));
}
else {
- $nav['locked'] = false;
- $nav['lock'] = array('rmagic','','unlock',
- t('Click to authenticate to your home hub'));
+ $nav['loginmenu'][] = Array('rmagic',t('Remote authentication'),'',t('Click to authenticate to your home hub'));
}
/**
diff --git a/include/permissions.php b/include/permissions.php
index 61ac8aea3..186ba32d8 100644
--- a/include/permissions.php
+++ b/include/permissions.php
@@ -460,6 +460,7 @@ function get_role_perms($role) {
$ret['channel_w_chat'] = PERMS_CONTACTS;
$ret['channel_a_delegate'] = 0;
$ret['channel_r_storage'] = PERMS_PUBLIC;
+ $ret['channel_w_storage'] = 0;
$ret['channel_r_pages'] = PERMS_PUBLIC;
$ret['channel_w_pages'] = 0;
$ret['channel_a_republish'] = PERMS_SPECIFIC;
@@ -492,6 +493,7 @@ function get_role_perms($role) {
$ret['channel_w_chat'] = PERMS_CONTACTS;
$ret['channel_a_delegate'] = 0;
$ret['channel_r_storage'] = PERMS_PUBLIC;
+ $ret['channel_w_storage'] = 0;
$ret['channel_r_pages'] = PERMS_PUBLIC;
$ret['channel_w_pages'] = 0;
$ret['channel_a_republish'] = PERMS_SPECIFIC;
@@ -524,6 +526,7 @@ function get_role_perms($role) {
$ret['channel_w_chat'] = PERMS_SPECIFIC;
$ret['channel_a_delegate'] = 0;
$ret['channel_r_storage'] = PERMS_PUBLIC;
+ $ret['channel_w_storage'] = 0;
$ret['channel_r_pages'] = PERMS_PUBLIC;
$ret['channel_w_pages'] = 0;
$ret['channel_a_republish'] = PERMS_SPECIFIC;
@@ -555,6 +558,7 @@ function get_role_perms($role) {
$ret['channel_w_chat'] = PERMS_CONTACTS;
$ret['channel_a_delegate'] = 0;
$ret['channel_r_storage'] = PERMS_PUBLIC;
+ $ret['channel_w_storage'] = 0;
$ret['channel_r_pages'] = PERMS_PUBLIC;
$ret['channel_w_pages'] = 0;
$ret['channel_a_republish'] = PERMS_SPECIFIC;
@@ -586,6 +590,7 @@ function get_role_perms($role) {
$ret['channel_w_chat'] = PERMS_CONTACTS;
$ret['channel_a_delegate'] = 0;
$ret['channel_r_storage'] = PERMS_PUBLIC;
+ $ret['channel_w_storage'] = 0;
$ret['channel_r_pages'] = PERMS_PUBLIC;
$ret['channel_w_pages'] = 0;
$ret['channel_a_republish'] = PERMS_SPECIFIC;
@@ -618,6 +623,7 @@ function get_role_perms($role) {
$ret['channel_w_chat'] = PERMS_SPECIFIC;
$ret['channel_a_delegate'] = 0;
$ret['channel_r_storage'] = PERMS_CONTACTS;
+ $ret['channel_w_storage'] = 0;
$ret['channel_r_pages'] = PERMS_CONTACTS;
$ret['channel_w_pages'] = 0;
$ret['channel_a_republish'] = PERMS_SPECIFIC;
@@ -649,6 +655,7 @@ function get_role_perms($role) {
$ret['channel_w_chat'] = PERMS_CONTACTS;
$ret['channel_a_delegate'] = 0;
$ret['channel_r_storage'] = PERMS_PUBLIC;
+ $ret['channel_w_storage'] = 0;
$ret['channel_r_pages'] = PERMS_PUBLIC;
$ret['channel_w_pages'] = 0;
$ret['channel_a_republish'] = PERMS_NETWORK;
@@ -681,6 +688,7 @@ function get_role_perms($role) {
$ret['channel_w_chat'] = PERMS_CONTACTS;
$ret['channel_a_delegate'] = 0;
$ret['channel_r_storage'] = PERMS_PUBLIC;
+ $ret['channel_w_storage'] = 0;
$ret['channel_r_pages'] = PERMS_PUBLIC;
$ret['channel_w_pages'] = 0;
$ret['channel_a_republish'] = PERMS_SPECIFIC;
@@ -710,6 +718,7 @@ function get_role_perms($role) {
$ret['channel_w_chat'] = 0;
$ret['channel_a_delegate'] = 0;
$ret['channel_r_storage'] = PERMS_PUBLIC;
+ $ret['channel_w_storage'] = 0;
$ret['channel_r_pages'] = PERMS_PUBLIC;
$ret['channel_w_pages'] = 0;
$ret['channel_a_republish'] = PERMS_SPECIFIC;
@@ -717,6 +726,40 @@ function get_role_perms($role) {
break;
+ case 'repository':
+ $ret['perms_auto'] = true;
+ $ret['default_collection'] = false;
+ $ret['directory_publish'] = true;
+ $ret['online'] = false;
+ $ret['perms_follow'] = PERMS_R_STREAM|PERMS_R_PROFILE|PERMS_R_PHOTOS|PERMS_R_ABOOK
+ |PERMS_W_STREAM|PERMS_W_WALL|PERMS_W_COMMENT|PERMS_W_MAIL|PERMS_W_CHAT
+ |PERMS_R_STORAGE|PERMS_W_STORAGE|PERMS_R_PAGES|PERMS_A_REPUBLISH|PERMS_W_LIKE|PERMS_W_TAGWALL;
+ $ret['perms_accept'] = PERMS_R_STREAM|PERMS_R_PROFILE|PERMS_R_PHOTOS|PERMS_R_ABOOK
+ |PERMS_W_STREAM|PERMS_W_WALL|PERMS_W_COMMENT|PERMS_W_MAIL|PERMS_W_CHAT
+ |PERMS_R_STORAGE|PERMS_W_STORAGE|PERMS_R_PAGES|PERMS_A_REPUBLISH|PERMS_W_LIKE|PERMS_W_TAGWALL;
+ $ret['channel_r_stream'] = PERMS_PUBLIC;
+ $ret['channel_r_profile'] = PERMS_PUBLIC;
+ $ret['channel_r_photos'] = PERMS_PUBLIC;
+ $ret['channel_r_abook'] = PERMS_PUBLIC;
+ $ret['channel_w_stream'] = PERMS_CONTACTS;
+ $ret['channel_w_wall'] = PERMS_CONTACTS;
+ $ret['channel_w_tagwall'] = PERMS_CONTACTS;
+ $ret['channel_w_comment'] = PERMS_CONTACTS;
+ $ret['channel_w_mail'] = PERMS_CONTACTS;
+ $ret['channel_w_photos'] = PERMS_CONTACTS;
+ $ret['channel_w_chat'] = PERMS_CONTACTS;
+ $ret['channel_a_delegate'] = 0;
+ $ret['channel_r_storage'] = PERMS_PUBLIC;
+ $ret['channel_w_storage'] = PERMS_CONTACTS;
+ $ret['channel_r_pages'] = PERMS_PUBLIC;
+ $ret['channel_w_pages'] = PERMS_CONTACTS;
+ $ret['channel_a_republish'] = PERMS_SPECIFIC;
+ $ret['channel_w_like'] = PERMS_NETWORK;
+
+ break;
+
+
+
default:
break;
@@ -734,6 +777,10 @@ function get_role_perms($role) {
function role_selector($current) {
+
+ if(! $current)
+ $current = 'custom';
+
$roles = array(
'social' => array( t('Social Networking'),
array('social' => t('Mostly Public'), 'social_restricted' => t('Restricted'), 'social_private' => t('Private'))),
@@ -741,8 +788,8 @@ function role_selector($current) {
array('forum' => t('Mostly Public'), 'forum_restricted' => t('Restricted'), 'forum_private' => t('Private'))),
'feed' => array( t('Feed Republish'),
array('feed' => t('Mostly Public'), 'feed_restricted' => t('Restricted'))),
- 'soapbox' => array( t('Celebrity/Soapbox'),
- array('soapbox' => t('Mostly Public'))),
+ 'special' => array( t('Special Purpose'),
+ array('soapbox' => t('Celebrity/Soapbox'), 'repository' => t('Group Repository'))),
'other' => array( t('Other'),
array('custom' => t('Custom/Expert Mode'))));
$o = '<select name="permissions_role" id="privacy-role-select">';
diff --git a/include/poller.php b/include/poller.php
index 2febaeb32..f11618d37 100644
--- a/include/poller.php
+++ b/include/poller.php
@@ -25,6 +25,15 @@ function poller_run($argv, $argc){
if(! $interval)
$interval = ((get_config('system','delivery_interval') === false) ? 3 : intval(get_config('system','delivery_interval')));
+ // Check for a lockfile. If it exists, but is over an hour old, it's stale. Ignore it.
+ $lockfile = 'store/[data]/poller';
+ if ((file_exists($lockfile)) && (filemtime($lockfile) > (time() - 3600))) {
+ logger("poller: Already running");
+ return;
+ }
+
+ // Create a lockfile. Needs two vars, but $x doesn't need to contain anything.
+ file_put_contents($lockfile, $x);
logger('poller: start');
@@ -254,7 +263,7 @@ function poller_run($argv, $argc){
);
- $contacts = q("SELECT abook_id, abook_flags, abook_updated, abook_connected, abook_closeness, abook_channel
+ $contacts = q("SELECT abook_id, abook_flags, abook_updated, abook_connected, abook_closeness, abook_xchan, abook_channel
FROM abook LEFT JOIN account on abook_account = account_id where 1
$sql_extra
AND (( abook_flags & %d ) OR ( abook_flags = %d ))
@@ -310,12 +319,17 @@ function poller_run($argv, $argc){
// He's dead, Jim
if(strcmp(datetime_convert('UTC','UTC', 'now'),datetime_convert('UTC','UTC', $c . " + 30 day")) > 0) {
- $r = q("update abook set abook_flags = (abook_flags | %d) where abook_id = %d limit 1",
- intval(ABOOK_FLAG_ARCHIVED),
- intval($contact['abook_id'])
+ $n = q("select xchan_network from xchan where xchan_hash = '%s' limit 1",
+ dbesc($contact['abook_xchan'])
);
- $update = false;
- continue;
+ if($n && $n[0]['xchan_network'] == 'zot') {
+ $r = q("update abook set abook_flags = (abook_flags | %d) where abook_id = %d limit 1",
+ intval(ABOOK_FLAG_ARCHIVED),
+ intval($contact['abook_id'])
+ );
+ $update = false;
+ continue;
+ }
}
if($contact['abook_flags'] & ABOOK_FLAG_ARCHIVED) {
@@ -370,7 +384,10 @@ function poller_run($argv, $argc){
}
}
}
-
+
+ //All done - clear the lockfile
+ @unlink($lockfile);
+
return;
}
diff --git a/include/reddav.php b/include/reddav.php
index 86b3a00e4..c16e08e27 100644
--- a/include/reddav.php
+++ b/include/reddav.php
@@ -50,7 +50,7 @@ function RedChannelList(&$auth) {
if ($r) {
foreach ($r as $rr) {
if (perm_is_allowed($rr['channel_id'], $auth->observer, 'view_storage')) {
- logger('found channel: /cloud/' . $rr['channel_address'], LOGGER_DEBUG);
+ logger('found channel: /cloud/' . $rr['channel_address'], LOGGER_DATA);
// @todo can't we drop '/cloud'? It gets stripped off anyway in RedDirectory
$ret[] = new RedDAV\RedDirectory('/cloud/' . $rr['channel_address'], $auth);
}
@@ -188,7 +188,7 @@ function RedCollectionData($file, &$auth) {
* @throw \Sabre\DAV\Exception\Forbidden
*/
function RedFileData($file, &$auth, $test = false) {
- logger($file . (($test) ? ' (test mode) ' : ''), LOGGER_DEBUG);
+ logger($file . (($test) ? ' (test mode) ' : ''), LOGGER_DATA);
$x = strpos($file, '/cloud');
if ($x === 0) {
diff --git a/include/taxonomy.php b/include/taxonomy.php
index 92003328f..35605da22 100644
--- a/include/taxonomy.php
+++ b/include/taxonomy.php
@@ -154,7 +154,7 @@ function tagadelic($uid, $count = 0, $authors = '', $flags = 0, $restrict = 0, $
}
function tags_sort($a,$b) {
- if($a[0] == $b[0])
+ if(strtolower($a[0]) == strtolower($b[0]))
return 0;
return((strtolower($a[0]) < strtolower($b[0])) ? -1 : 1);
}
diff --git a/include/text.php b/include/text.php
index 0e38de2d2..fca23ca22 100644
--- a/include/text.php
+++ b/include/text.php
@@ -619,8 +619,8 @@ function get_tags($s) {
}
if(substr($mtch,-1,1) === '.')
$mtch = substr($mtch,0,-1);
- // ignore strictly numeric tags like #1
- if((strpos($mtch,'#') === 0) && ( ctype_digit(substr($mtch,1)) || substr($mtch,1,1) === '^'))
+ // ignore strictly numeric tags like #1 or #^ bookmarks or ## double hash
+ if((strpos($mtch,'#') === 0) && ( ctype_digit(substr($mtch,1)) || substr($mtch,1,1) === '^') || substr($mtch,1,1) === '#')
continue;
// try not to catch url fragments
if(strpos($s,$mtch) && preg_match('/[a-zA-z0-9\/]/',substr($s,strpos($s,$mtch)-1,1)))
diff --git a/include/widgets.php b/include/widgets.php
index 8905df59a..2e406aa77 100644
--- a/include/widgets.php
+++ b/include/widgets.php
@@ -430,6 +430,8 @@ function widget_settings_menu($arr) {
// Retrieve the 'self' address book entry for use in the auto-permissions link
+ $role = get_pconfig(local_user(),'system','permissions_role');
+
$abk = q("select abook_id from abook where abook_channel = %d and ( abook_flags & %d ) limit 1",
intval(local_user()),
intval(ABOOK_FLAG_SELF)
@@ -487,14 +489,15 @@ function widget_settings_menu($arr) {
'selected' => ''
),
- array(
+ );
+
+ if($role === false || $role === 'custom') {
+ $tabs[] = array(
'label' => t('Automatic Permissions (Advanced)'),
'url' => $a->get_baseurl(true) . '/connedit/' . $abook_self_id,
'selected' => ''
- ),
-
-
- );
+ );
+ }
if(feature_enabled(local_user(),'premium_channel')) {
$tabs[] = array(
diff --git a/include/zot.php b/include/zot.php
index 869bca668..e96eae10d 100644
--- a/include/zot.php
+++ b/include/zot.php
@@ -1476,11 +1476,13 @@ function process_delivery($sender,$arr,$deliveries,$relay,$public = false) {
continue;
}
- $r = q("select id, edited from item where mid = '%s' and uid = %d limit 1",
+ $r = q("select id, edited, item_flags, mid, parent_mid from item where mid = '%s' and uid = %d limit 1",
dbesc($arr['mid']),
intval($channel['channel_id'])
);
if($r) {
+ // We already have this post.
+ // Maybe it has been edited?
$item_id = $r[0]['id'];
if($arr['edited'] > $r[0]['edited']) {
$arr['id'] = $r[0]['id'];
@@ -1492,6 +1494,10 @@ function process_delivery($sender,$arr,$deliveries,$relay,$public = false) {
}
else {
$result[] = array($d['hash'],'update ignored',$channel['channel_name'] . ' <' . $channel['channel_address'] . '@' . get_app()->get_hostname() . '>',$arr['mid']);
+ // We need this line to ensure wall-to-wall comments are relayed (by falling through to the relay bit),
+ // and at the same time not relay any other relayable posts more than once, because to do so is very wasteful.
+ if(! ($r[0]['item_flags'] & ITEM_ORIGIN))
+ continue;
}
}
else {