diff options
Diffstat (limited to 'include')
-rw-r--r-- | include/Contact.php | 21 | ||||
-rw-r--r-- | include/ItemObject.php | 4 | ||||
-rw-r--r-- | include/RedDAV/RedBrowser.php | 1 | ||||
-rw-r--r-- | include/acl_selectors.php | 3 | ||||
-rw-r--r-- | include/api.php | 17 | ||||
-rw-r--r-- | include/bb2diaspora.php | 28 | ||||
-rw-r--r-- | include/conversation.php | 10 | ||||
-rw-r--r-- | include/datetime.php | 181 | ||||
-rw-r--r-- | include/event.php | 14 | ||||
-rw-r--r-- | include/follow.php | 8 | ||||
-rw-r--r-- | include/html2bbcode.php | 7 | ||||
-rw-r--r-- | include/hubloc.php | 90 | ||||
-rw-r--r-- | include/identity.php | 5 | ||||
-rwxr-xr-x | include/items.php | 21 | ||||
-rw-r--r-- | include/nav.php | 11 | ||||
-rw-r--r-- | include/permissions.php | 51 | ||||
-rw-r--r-- | include/poller.php | 31 | ||||
-rw-r--r-- | include/reddav.php | 4 | ||||
-rw-r--r-- | include/taxonomy.php | 2 | ||||
-rw-r--r-- | include/text.php | 4 | ||||
-rw-r--r-- | include/widgets.php | 13 | ||||
-rw-r--r-- | include/zot.php | 8 |
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("
\n>","",$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 { |