diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 000000000..4be1c9185 --- /dev/null +++ b/.gitattributes @@ -0,0 +1,2 @@ +# Disable LF normalization for all files +* -text \ No newline at end of file diff --git a/boot.php b/boot.php index ada1ac525..be47184aa 100644 --- a/boot.php +++ b/boot.php @@ -4,12 +4,13 @@ require_once('include/config.php'); require_once('include/network.php'); require_once('include/plugin.php'); require_once('include/text.php'); +require_once('include/datetime.php'); require_once('include/pgettext.php'); require_once('include/nav.php'); require_once('include/cache.php'); define ( 'FRIENDICA_PLATFORM', 'Friendica'); -define ( 'FRIENDICA_VERSION', '3.0.1370' ); +define ( 'FRIENDICA_VERSION', '3.0.1382' ); define ( 'DFRN_PROTOCOL_VERSION', '2.23' ); define ( 'DB_UPDATE_VERSION', 1149 ); @@ -76,14 +77,6 @@ define ( 'CONTACT_IS_SHARING', 2); define ( 'CONTACT_IS_FRIEND', 3); -/** - * Hook array order - */ - -define ( 'HOOK_HOOK', 0); -define ( 'HOOK_FILE', 1); -define ( 'HOOK_FUNCTION', 2); - /** * DB update return values */ @@ -331,8 +324,17 @@ if(! class_exists('App')) { private $curl_code; private $curl_headers; + private $cached_profile_image; + private $cached_profile_picdate; + function __construct() { + global $default_timezone; + + $this->timezone = ((x($default_timezone)) ? $default_timezone : 'UTC'); + + date_default_timezone_set($this->timezone); + $this->config = array(); $this->page = array(); $this->pager= array(); @@ -407,9 +409,6 @@ if(! class_exists('App')) { $this->argc = count($this->argv); if((array_key_exists('0',$this->argv)) && strlen($this->argv[0])) { $this->module = str_replace(".", "_", $this->argv[0]); - if(array_key_exists('2',$this->argv)) { - $this->category = $this->argv[2]; - } } else { $this->argc = 1; @@ -432,7 +431,7 @@ if(! class_exists('App')) { * pagination */ - $this->pager['page'] = ((x($_GET,'page')) ? $_GET['page'] : 1); + $this->pager['page'] = ((x($_GET,'page') && intval($_GET['page']) > 0) ? intval($_GET['page']) : 1); $this->pager['itemspage'] = 50; $this->pager['start'] = ($this->pager['page'] * $this->pager['itemspage']) - $this->pager['itemspage']; $this->pager['total'] = 0; @@ -499,7 +498,7 @@ if(! class_exists('App')) { } function set_pager_itemspage($n) { - $this->pager['itemspage'] = intval($n); + $this->pager['itemspage'] = ((intval($n) > 0) ? intval($n) : 0); $this->pager['start'] = ($this->pager['page'] * $this->pager['itemspage']) - $this->pager['itemspage']; } @@ -539,6 +538,28 @@ if(! class_exists('App')) { return $this->curl_headers; } + function get_cached_avatar_image($avatar_image){ + if($this->cached_profile_image[$avatar_image]) + return $this->cached_profile_image[$avatar_image]; + + $path_parts = explode("/",$avatar_image); + $common_filename = $path_parts[count($path_parts)-1]; + + if($this->cached_profile_picdate[$common_filename]){ + $this->cached_profile_image[$avatar_image] = $avatar_image . $this->cached_profile_picdate[$common_filename]; + } else { + $r = q("SELECT `contact`.`avatar-date` AS picdate FROM `contact` WHERE `contact`.`thumb` like \"%%/%s\"", + $common_filename); + if(! count($r)){ + $this->cached_profile_image[$avatar_image] = $avatar_image; + } else { + $this->cached_profile_picdate[$common_filename] = "?rev=" . urlencode($r[0]['picdate']); + $this->cached_profile_image[$avatar_image] = $avatar_image . $this->cached_profile_picdate[$common_filename]; + } + } + return $this->cached_profile_image[$avatar_image]; + } + } } @@ -1126,9 +1147,9 @@ if(! function_exists('profile_sidebar')) { 'fullname' => $profile['name'], 'firstname' => $firstname, 'lastname' => $lastname, - 'photo300' => $a->get_baseurl() . '/photo/custom/300/' . $profile['uid'] . '.jpg', - 'photo100' => $a->get_baseurl() . '/photo/custom/100/' . $profile['uid'] . '.jpg', - 'photo50' => $a->get_baseurl() . '/photo/custom/50/' . $profile['uid'] . '.jpg', + 'photo300' => $a->get_cached_avatar_image($a->get_baseurl() . '/photo/custom/300/' . $profile['uid'] . '.jpg'), + 'photo100' => $a->get_cached_avatar_image($a->get_baseurl() . '/photo/custom/100/' . $profile['uid'] . '.jpg'), + 'photo50' => $a->get_cached_avatar_image($a->get_baseurl() . '/photo/custom/50/' . $profile['uid'] . '.jpg'), ); if (!$block){ @@ -1363,7 +1384,7 @@ if(! function_exists('proc_run')) { if(! function_exists('current_theme')) { function current_theme(){ - $app_base_themes = array('duepuntozero', 'loozah'); + $app_base_themes = array('duepuntozero', 'dispy', 'quattro'); $a = get_app(); @@ -1381,7 +1402,7 @@ if(! function_exists('current_theme')) { return($t); } - $fallback = glob('view/theme/*/style.[css|php]'); + $fallback = array_merge(glob('view/theme/*/style.css'),glob('view/theme/*/style.php')); if(count($fallback)) return (str_replace('view/theme/','', substr($fallback[0],0,-10))); @@ -1573,3 +1594,30 @@ function zrl($s,$force = false) { return $s . $achar . 'zrl=' . urlencode($mine); return $s; } + +/** +* returns querystring as string from a mapped array +* +* @param params Array +* @return string +*/ +function build_querystring($params, $name=null) { + $ret = ""; + foreach($params as $key=>$val) { + if(is_array($val)) { + if($name==null) { + $ret .= build_querystring($val, $key); + } else { + $ret .= build_querystring($val, $name."[$key]"); + } + } else { + $val = urlencode($val); + if($name!=null) { + $ret.=$name."[$key]"."=$val&"; + } else { + $ret.= "$key=$val&"; + } + } + } + return $ret; +} diff --git a/include/Contact.php b/include/Contact.php index 675d1c81e..14e1a52cd 100644 --- a/include/Contact.php +++ b/include/Contact.php @@ -139,6 +139,10 @@ function terminate_friendship($user,$self,$contact) { if(! function_exists('mark_for_death')) { function mark_for_death($contact) { + + if($contact['archive']) + return; + if($contact['term-date'] == '0000-00-00 00:00:00') { q("UPDATE `contact` SET `term-date` = '%s' WHERE `id` = %d LIMIT 1", dbesc(datetime_convert()), @@ -146,12 +150,23 @@ function mark_for_death($contact) { ); } else { + + // TODO: We really should send a notification to the owner after 2-3 weeks + // so they won't be surprised when the contact vanishes and can take + // remedial action if this was a serious mistake or glitch + $expiry = $contact['term-date'] . ' + 32 days '; if(datetime_convert() > datetime_convert('UTC','UTC',$expiry)) { // relationship is really truly dead. + // archive them rather than delete + // though if the owner tries to unarchive them we'll start the whole process over again - contact_remove($contact['id']); + q("update contact set `archive` = 1 where id = %d limit 1", + intval($contact['id']) + ); + + //contact_remove($contact['id']); } } diff --git a/include/Photo.php b/include/Photo.php index f769a70a6..3af1691ee 100644 --- a/include/Photo.php +++ b/include/Photo.php @@ -121,7 +121,70 @@ class Photo { $this->image = imagerotate($this->image,$degrees,0); $this->width = imagesx($this->image); $this->height = imagesy($this->image); - } + } + + public function flip($horiz = true, $vert = false) { + $w = imagesx($this->image); + $h = imagesy($this->image); + $flipped = imagecreate($w, $h); + if($horiz) { + for ($x = 0; $x < $w; $x++) { + imagecopy($flipped, $this->image, $x, 0, $w - $x - 1, 0, 1, $h); + } + } + if($vert) { + for ($y = 0; $y < $h; $y++) { + imagecopy($flipped, $this->image, 0, $y, 0, $h - $y - 1, $w, 1); + } + } + $this->image = $flipped; + } + + public function orient($filename) { + // based off comment on http://php.net/manual/en/function.imagerotate.php + + if(! function_exists('exif_read_data')) + return; + + $exif = exif_read_data($filename); + $ort = $exif['Orientation']; + + switch($ort) + { + case 1: // nothing + break; + + case 2: // horizontal flip + $this->flip(); + break; + + case 3: // 180 rotate left + $this->rotate(180); + break; + + case 4: // vertical flip + $this->flip(false, true); + break; + + case 5: // vertical flip + 90 rotate right + $this->flip(false, true); + $this->rotate(-90); + break; + + case 6: // 90 rotate right + $this->rotate(-90); + break; + + case 7: // horizontal flip + 90 rotate right + $this->flip(); + $this->rotate(-90); + break; + + case 8: // 90 rotate left + $this->rotate(90); + break; + } + } @@ -256,35 +319,81 @@ class Photo { else $guid = get_guid(); - $r = q("INSERT INTO `photo` - ( `uid`, `contact-id`, `guid`, `resource-id`, `created`, `edited`, `filename`, type, `album`, `height`, `width`, `data`, `scale`, `profile`, `allow_cid`, `allow_gid`, `deny_cid`, `deny_gid` ) - VALUES ( %d, %d, '%s', '%s', '%s', '%s', '%s', '%s', '%s', %d, %d, '%s', %d, %d, '%s', '%s', '%s', '%s' )", - intval($uid), - intval($cid), - dbesc($guid), - dbesc($rid), - dbesc(datetime_convert()), - dbesc(datetime_convert()), - dbesc(basename($filename)), - dbesc($this->type), - dbesc($album), - intval($this->height), - intval($this->width), - dbesc($this->imageString()), - intval($scale), - intval($profile), - dbesc($allow_cid), - dbesc($allow_gid), - dbesc($deny_cid), - dbesc($deny_gid) + $x = q("select id from photo where `resource-id` = '%s' and uid = %d and `contact-id` = %d and `scale` = %d limit 1", + dbesc($rid), + intval($uid), + intval($cid), + intval($scale) ); + if(count($x)) { + $r = q("UPDATE `photo` + set `uid` = %d, + `contact-id` = %d, + `guid` = '%s', + `resource-id` = '%s', + `created` = '%s', + `edited` = '%s', + `filename` = '%s', + `type` = '%s', + `album` = '%s', + `height` = %d, + `width` = %d, + `data` = '%s', + `scale` = %d, + `profile` = %d, + `allow_cid` = '%s', + `allow_gid` = '%s', + `deny_cid` = '%s', + `deny_gid` = '%s' + where id = %d limit 1", + + intval($uid), + intval($cid), + dbesc($guid), + dbesc($rid), + dbesc(datetime_convert()), + dbesc(datetime_convert()), + dbesc(basename($filename)), + dbesc($this->type), + dbesc($album), + intval($this->height), + intval($this->width), + dbesc($this->imageString()), + intval($scale), + intval($profile), + dbesc($allow_cid), + dbesc($allow_gid), + dbesc($deny_cid), + dbesc($deny_gid), + intval($x[0]['id']) + ); + } + else { + $r = q("INSERT INTO `photo` + ( `uid`, `contact-id`, `guid`, `resource-id`, `created`, `edited`, `filename`, type, `album`, `height`, `width`, `data`, `scale`, `profile`, `allow_cid`, `allow_gid`, `deny_cid`, `deny_gid` ) + VALUES ( %d, %d, '%s', '%s', '%s', '%s', '%s', '%s', '%s', %d, %d, '%s', %d, %d, '%s', '%s', '%s', '%s' )", + intval($uid), + intval($cid), + dbesc($guid), + dbesc($rid), + dbesc(datetime_convert()), + dbesc(datetime_convert()), + dbesc(basename($filename)), + dbesc($this->type), + dbesc($album), + intval($this->height), + intval($this->width), + dbesc($this->imageString()), + intval($scale), + intval($profile), + dbesc($allow_cid), + dbesc($allow_gid), + dbesc($deny_cid), + dbesc($deny_gid) + ); + } return $r; } - - - - - }} @@ -326,6 +435,17 @@ function import_profile_photo($photo,$uid,$cid) { $a = get_app(); + $r = q("select `resource-id` from photo where `uid` = %d and `contact-id` = %d and `scale` = 4 and `album` = 'Contact Photos' limit 1", + intval($uid), + intval($cid) + ); + if(count($r)) { + $hash = $r[0]['resource-id']; + } + else { + $hash = photo_new_resource(); + } + $photo_failure = false; $filename = basename($photo); @@ -340,8 +460,6 @@ function import_profile_photo($photo,$uid,$cid) { $img->scaleImageSquare(175); - $hash = photo_new_resource(); - $r = $img->store($uid, $cid, $hash, $filename, 'Contact Photos', 4 ); if($r === false) @@ -361,8 +479,6 @@ function import_profile_photo($photo,$uid,$cid) { if($r === false) $photo_failure = true; - - $photo = $a->get_baseurl() . '/photo/' . $hash . '-4.' . $img->getExt(); $thumb = $a->get_baseurl() . '/photo/' . $hash . '-5.' . $img->getExt(); $micro = $a->get_baseurl() . '/photo/' . $hash . '-6.' . $img->getExt(); diff --git a/include/Scrape.php b/include/Scrape.php index ca8f6e83a..4f53effe9 100644 --- a/include/Scrape.php +++ b/include/Scrape.php @@ -352,10 +352,11 @@ function probe_url($url, $mode = PROBE_NORMAL) { $email_conversant = false; $twitter = ((strpos($url,'twitter.com') !== false) ? true : false); + $lastfm = ((strpos($url,'last.fm/user') !== false) ? true : false); $at_addr = ((strpos($url,'@') !== false) ? true : false); - if(! $twitter) { + if((! $twitter) && (! $lastfm)) { if(strpos($url,'mailto:') !== false && $at_addr) { $url = str_replace('mailto:','',$url); @@ -564,6 +565,14 @@ function probe_url($url, $mode = PROBE_NORMAL) { $vcard['fn'] = $tid . '@twitter'; } + if($lastfm) { + $profile = $url; + $poll = str_replace(array('www.','last.fm/'),array('','ws.audioscrobbler.com/1.0/'),$url) . '/recenttracks.rss'; + $vcard['nick'] = basename($url); + $vcard['fn'] = $vcard['nick'] . t(' on Last.fm'); + $network = NETWORK_FEED; + } + if(! x($vcard,'fn')) if(x($vcard,'nick')) $vcard['fn'] = $vcard['nick']; diff --git a/include/api.php b/include/api.php index 9925b5766..b77156dfa 100644 --- a/include/api.php +++ b/include/api.php @@ -245,7 +245,7 @@ } - logger('api_user: ' . $extra_query . ' ' , $user); + logger('api_user: ' . $extra_query . ', user: ' . $user); // user info $uinfo = q("SELECT *, `contact`.`id` as `cid` FROM `contact` WHERE 1 @@ -719,14 +719,18 @@ if ($page<0) $page=0; $since_id = (x($_REQUEST,'since_id')?$_REQUEST['since_id']:0); $max_id = (x($_REQUEST,'max_id')?$_REQUEST['max_id']:0); + $exclude_replies = (x($_REQUEST,'exclude_replies')?1:0); //$since_id = 0;//$since_id = (x($_REQUEST,'since_id')?$_REQUEST['since_id']:0); $start = $page*$count; //$include_entities = (x($_REQUEST,'include_entities')?$_REQUEST['include_entities']:false); + $sql_extra = ''; if ($max_id > 0) - $sql_extra = 'AND `item`.`id` <= '.intval($max_id); + $sql_extra .= ' AND `item`.`id` <= '.intval($max_id); + if ($exclude_replies > 0) + $sql_extra .= ' AND `item`.`parent` = `item`.`id`'; $r = q("SELECT `item`.*, `item`.`id` AS `item_id`, `contact`.`name`, `contact`.`photo`, `contact`.`url`, `contact`.`rel`, @@ -860,6 +864,8 @@ logger('API: api_statuses_show: '.$id); //$include_entities = (x($_REQUEST,'include_entities')?$_REQUEST['include_entities']:false); + //$sql_extra = ""; + if ($_GET["conversation"] == "true") $sql_extra .= " AND `item`.`parent` = %d ORDER BY `received` ASC "; else $sql_extra .= " AND `item`.`id` = %d"; $r = q("SELECT `item`.*, `item`.`id` AS `item_id`, `contact`.`name`, `contact`.`photo`, `contact`.`url`, `contact`.`rel`, @@ -870,19 +876,24 @@ AND `contact`.`id` = `item`.`contact-id` AND `contact`.`blocked` = 0 AND `contact`.`pending` = 0 $sql_extra - AND `item`.`id`=%d", + ", intval($id) ); - +//var_dump($r); $ret = api_format_items($r,$user_info); - - $data = array('$status' => $ret[0]); - /*switch($type){ - case "atom": - case "rss": - $data = api_rss_extra($a, $data, $user_info); - }*/ - return api_apply_template("status", $type, $data); +//var_dump($ret); + if ($_GET["conversation"] == "true") { + $data = array('$statuses' => $ret); + return api_apply_template("timeline", $type, $data); + } else { + $data = array('$status' => $ret[0]); + /*switch($type){ + case "atom": + case "rss": + $data = api_rss_extra($a, $data, $user_info); + }*/ + return api_apply_template("status", $type, $data); + } } api_register_func('api/statuses/show','api_statuses_show', true); @@ -1061,11 +1072,14 @@ $page = (x($_REQUEST,'page')?$_REQUEST['page']-1:0); if ($page<0) $page=0; $since_id = (x($_REQUEST,'since_id')?$_REQUEST['since_id']:0); + $exclude_replies = (x($_REQUEST,'exclude_replies')?1:0); //$since_id = 0;//$since_id = (x($_REQUEST,'since_id')?$_REQUEST['since_id']:0); $start = $page*$count; - if ($user_info['self']==1) $sql_extra = "AND `item`.`wall` = 1 "; + $sql_extra = ''; + if ($user_info['self']==1) $sql_extra .= " AND `item`.`wall` = 1 "; + if ($exclude_replies > 0) $sql_extra .= ' AND `item`.`parent` = `item`.`id`'; $r = q("SELECT `item`.*, `item`.`id` AS `item_id`, `contact`.`name`, `contact`.`photo`, `contact`.`url`, `contact`.`rel`, @@ -1654,7 +1668,6 @@ account/update_profile_background_image account/update_profile_image blocks/create blocks/destroy -oauth/authorize Not implemented in status.net: statuses/retweeted_to_me diff --git a/include/config.php b/include/config.php index df1070c13..1f2a70e5a 100644 --- a/include/config.php +++ b/include/config.php @@ -18,19 +18,17 @@ if(! function_exists('load_config')) { function load_config($family) { global $a; - $r = q("SELECT * FROM `config` WHERE `cat` = '%s'", - dbesc($family) - ); + $r = q("SELECT * FROM `config` WHERE `cat` = '%s'", dbesc($family)); if(count($r)) { foreach($r as $rr) { $k = $rr['k']; - if ($rr['cat'] === 'config') { + if ($family === 'config') { $a->config[$k] = $rr['v']; } else { $a->config[$family][$k] = $rr['v']; } } - } else if ($rr['cat'] != 'config') { + } else if ($family != 'config') { // Negative caching $a->config[$family] = "!!"; } @@ -128,7 +126,7 @@ function load_pconfig($uid,$family) { $k = $rr['k']; $a->config[$uid][$family][$k] = $rr['v']; } - } else if ($rr['cat'] != 'config') { + } else if ($family != 'config') { // Negative caching $a->config[$uid][$family] = "!!"; } diff --git a/include/conversation.php b/include/conversation.php index a9c6287a9..2244e8df7 100644 --- a/include/conversation.php +++ b/include/conversation.php @@ -173,8 +173,8 @@ function localize_item(&$item){ $item['body'] = str_replace($mtch[0],'@[url=' . zrl($mtch[1]). ']',$item['body']); } } + // add zrl's to public images if(preg_match_all('/\[url=(.*?)\/photos\/(.*?)\/image\/(.*?)\]\[img(.*?)\]h(.*?)\[\/img\]\[\/url\]/is',$item['body'],$matches,PREG_SET_ORDER)) { -logger('matched'); foreach($matches as $mtch) { $item['body'] = str_replace($mtch[0],'[url=' . zrl($mtch[1] . '/photos/' . $mtch[2] . '/image/' . $mtch[3] ,true) . '][img' . $mtch[4] . ']h' . $mtch[5] . '[/img][/url]',$item['body']); } @@ -308,7 +308,7 @@ function conversation(&$a, $items, $mode, $update, $preview = false) { if(($normalised != 'mailbox') && (x($a->contacts[$normalised]))) $profile_avatar = $a->contacts[$normalised]['thumb']; else - $profile_avatar = ((strlen($item['author-avatar'])) ? $item['author-avatar'] : $item['thumb']); + $profile_avatar = ((strlen($item['author-avatar'])) ? $a->get_cached_avatar_image($item['author-avatar']) : $item['thumb']); $locate = array('location' => $item['location'], 'coord' => $item['coord'], 'html' => ''); call_hooks('render_location',$locate); @@ -546,7 +546,7 @@ function conversation(&$a, $items, $mode, $update, $preview = false) { } $likebuttons = ''; - $shareable = ((($profile_owner == local_user()) && (! $item['private'])) ? true : false); //($mode != 'display') && + $shareable = ((($profile_owner == local_user()) && ((! $item['private']) || $item['network'] === NETWORK_FEED)) ? true : false); if($page_writeable) { if($toplevelpost) { @@ -657,7 +657,7 @@ function conversation(&$a, $items, $mode, $update, $preview = false) { if(($normalised != 'mailbox') && (x($a->contacts,$normalised))) $profile_avatar = $a->contacts[$normalised]['thumb']; else - $profile_avatar = (((strlen($item['author-avatar'])) && $diff_author) ? $item['author-avatar'] : $thumb); + $profile_avatar = (((strlen($item['author-avatar'])) && $diff_author) ? $item['author-avatar'] : $a->get_cached_avatar_image($thumb)); $like = ((x($alike,$item['id'])) ? format_like($alike[$item['id']],$alike[$item['id'] . '-l'],'like',$item['id']) : ''); $dislike = ((x($dlike,$item['id'])) ? format_like($dlike[$item['id']],$dlike[$item['id'] . '-l'],'dislike',$item['id']) : ''); diff --git a/include/datetime.php b/include/datetime.php index 3b1491e4d..58a618610 100644 --- a/include/datetime.php +++ b/include/datetime.php @@ -87,7 +87,7 @@ function datetime_convert($from = 'UTC', $to = 'UTC', $s = 'now', $fmt = "Y-m-d $from = 'UTC'; if($to === '') $to = 'UTC'; - if($s === '') + if( ($s === '') || (! is_string($s)) ) $s = 'now'; // Slight hackish adjustment so that 'zero' datetime actually returns what is intended diff --git a/include/diaspora.php b/include/diaspora.php index 1e6662f04..0ca9163a8 100755 --- a/include/diaspora.php +++ b/include/diaspora.php @@ -1060,45 +1060,64 @@ function diaspora_comment($importer,$xml,$msg) { } $parent_item = $r[0]; - $author_signed_data = $guid . ';' . $parent_guid . ';' . $text . ';' . $diaspora_handle; - $author_signature = base64_decode($author_signature); + /* How Diaspora performs comment signature checking: - if(strcasecmp($diaspora_handle,$msg['author']) == 0) { - $person = $contact; - $key = $msg['key']; - } - else { - $person = find_diaspora_person_by_handle($diaspora_handle); + - If an item has been sent by the comment author to the top-level post owner to relay on + to the rest of the contacts on the top-level post, the top-level post owner should check + the author_signature, then create a parent_author_signature before relaying the comment on + - If an item has been relayed on by the top-level post owner, the contacts who receive it + check only the parent_author_signature. Basically, they trust that the top-level post + owner has already verified the authenticity of anything he/she sends out + - In either case, the signature that get checked is the signature created by the person + who sent the salmon + */ - if(is_array($person) && x($person,'pubkey')) - $key = $person['pubkey']; - else { - logger('diaspora_comment: unable to find author details'); - return; - } - } - - if(! rsa_verify($author_signed_data,$author_signature,$key,'sha256')) { - logger('diaspora_comment: verification failed.'); - return; - } + $signed_data = $guid . ';' . $parent_guid . ';' . $text . ';' . $diaspora_handle; + $key = $msg['key']; if($parent_author_signature) { - $owner_signed_data = $guid . ';' . $parent_guid . ';' . $text . ';' . $diaspora_handle; + // If a parent_author_signature exists, then we've received the comment + // relayed from the top-level post owner. There's no need to check the + // author_signature if the parent_author_signature is valid $parent_author_signature = base64_decode($parent_author_signature); - $key = $msg['key']; + if(! rsa_verify($signed_data,$parent_author_signature,$key,'sha256')) { + logger('diaspora_comment: top-level owner verification failed.'); + return; + } + } + else { + // If there's no parent_author_signature, then we've received the comment + // from the comment creator. In that case, the person is commenting on + // our post, so he/she must be a contact of ours and his/her public key + // should be in $msg['key'] - if(! rsa_verify($owner_signed_data,$parent_author_signature,$key,'sha256')) { - logger('diaspora_comment: owner verification failed.'); + $author_signature = base64_decode($author_signature); + + if(! rsa_verify($signed_data,$author_signature,$key,'sha256')) { + logger('diaspora_comment: comment author verification failed.'); return; } } // Phew! Everything checks out. Now create an item. + // Find the original comment author information. + // We need this to make sure we display the comment author + // information (name and avatar) correctly. + if(strcasecmp($diaspora_handle,$msg['author']) == 0) + $person = $contact; + else { + $person = find_diaspora_person_by_handle($diaspora_handle); + + if(! is_array($person)) { + logger('diaspora_comment: unable to find author details'); + return; + } + } + $body = diaspora2bb($text); $message_id = $diaspora_handle . ':' . $guid; @@ -1613,7 +1632,7 @@ function diaspora_like($importer,$xml,$msg) { intval($r[0]['id']), intval($importer['uid']) );*/ - // FIXME + // FIXME--actually don't unless it turns out that Diaspora does indeed send out "false" likes // send notification via proc_run() return; } @@ -1626,45 +1645,64 @@ function diaspora_like($importer,$xml,$msg) { return; } + + /* How Diaspora performs "like" signature checking: + + - If an item has been sent by the like author to the top-level post owner to relay on + to the rest of the contacts on the top-level post, the top-level post owner should check + the author_signature, then create a parent_author_signature before relaying the like on + - If an item has been relayed on by the top-level post owner, the contacts who receive it + check only the parent_author_signature. Basically, they trust that the top-level post + owner has already verified the authenticity of anything he/she sends out + - In either case, the signature that get checked is the signature created by the person + who sent the salmon + */ + $signed_data = $guid . ';' . $target_type . ';' . $parent_guid . ';' . $positive . ';' . $diaspora_handle; - - $author_signature = base64_decode($author_signature); - - if(strcasecmp($diaspora_handle,$msg['author']) == 0) { - $person = $contact; - $key = $msg['key']; - } - else { - $person = find_diaspora_person_by_handle($diaspora_handle); - if(is_array($person) && x($person,'pubkey')) - $key = $person['pubkey']; - else { - logger('diaspora_like: unable to find author details'); - return; - } - } - - if(! rsa_verify($signed_data,$author_signature,$key,'sha256')) { - logger('diaspora_like: verification failed.'); - return; - } + $key = $msg['key']; if($parent_author_signature) { - - //$owner_signed_data = $guid . ';' . $target_type . ';' . $parent_guid . ';' . $positive . ';' . $diaspora_handle; + // If a parent_author_signature exists, then we've received the like + // relayed from the top-level post owner. There's no need to check the + // author_signature if the parent_author_signature is valid $parent_author_signature = base64_decode($parent_author_signature); - $key = $msg['key']; - if(! rsa_verify($signed_data,$parent_author_signature,$key,'sha256')) { - logger('diaspora_like: owner verification failed.'); + logger('diaspora_like: top-level owner verification failed.'); + return; + } + } + else { + // If there's no parent_author_signature, then we've received the like + // from the like creator. In that case, the person is "like"ing + // our post, so he/she must be a contact of ours and his/her public key + // should be in $msg['key'] + + $author_signature = base64_decode($author_signature); + + if(! rsa_verify($signed_data,$author_signature,$key,'sha256')) { + logger('diaspora_like: like creator verification failed.'); return; } } // Phew! Everything checks out. Now create an item. + // Find the original comment author information. + // We need this to make sure we display the comment author + // information (name and avatar) correctly. + if(strcasecmp($diaspora_handle,$msg['author']) == 0) + $person = $contact; + else { + $person = find_diaspora_person_by_handle($diaspora_handle); + + if(! is_array($person)) { + logger('diaspora_like: unable to find author details'); + return; + } + } + $uri = $diaspora_handle . ':' . $guid; $activity = ACTIVITY_LIKE; @@ -1802,40 +1840,39 @@ function diaspora_signed_retraction($importer,$xml,$msg) { $signed_data = $guid . ';' . $type ; + $key = $msg['key']; - $sig_decode = base64_decode($sig); + /* How Diaspora performs relayable_retraction signature checking: - if(strcasecmp($diaspora_handle,$msg['author']) == 0) { - $person = $contact; - $key = $msg['key']; - } - else { - $person = find_diaspora_person_by_handle($diaspora_handle); - - if(is_array($person) && x($person,'pubkey')) - $key = $person['pubkey']; - else { - logger('diaspora_signed_retraction: unable to find author details'); - return; - } - } - - if(! rsa_verify($signed_data,$sig_decode,$key,'sha256')) { - logger('diaspora_signed_retraction: retraction-owner verification failed.' . print_r($msg,true)); - return; - } + - If an item has been sent by the item author to the top-level post owner to relay on + to the rest of the contacts on the top-level post, the top-level post owner checks + the author_signature, then creates a parent_author_signature before relaying the item on + - If an item has been relayed on by the top-level post owner, the contacts who receive it + check only the parent_author_signature. Basically, they trust that the top-level post + owner has already verified the authenticity of anything he/she sends out + - In either case, the signature that get checked is the signature created by the person + who sent the salmon + */ if($parent_author_signature) { + $parent_author_signature = base64_decode($parent_author_signature); - $key = $msg['key']; - if(! rsa_verify($signed_data,$parent_author_signature,$key,'sha256')) { - logger('diaspora_signed_retraction: failed to verify person relaying the retraction (e.g. owner of a post relaying a retracted comment'); + logger('diaspora_signed_retraction: top-level post owner verification failed'); return; } } + else { + + $sig_decode = base64_decode($sig); + + if(! rsa_verify($signed_data,$sig_decode,$key,'sha256')) { + logger('diaspora_signed_retraction: retraction owner verification failed.' . print_r($msg,true)); + return; + } + } if($type === 'StatusMessage' || $type === 'Comment' || $type === 'Like') { $r = q("select * from item where guid = '%s' and uid = %d and not file like '%%[%%' limit 1", @@ -2113,7 +2150,7 @@ function diaspora_send_followup($item,$owner,$contact,$public_batch = false) { $a = get_app(); $myaddr = $owner['nickname'] . '@' . substr($a->get_baseurl(), strpos($a->get_baseurl(),'://') + 3); - $theiraddr = $contact['addr']; +// $theiraddr = $contact['addr']; // The first item in the `item` table with the parent id is the parent. However, MySQL doesn't always // return the items ordered by `item`.`id`, in which case the wrong item is chosen as the parent. @@ -2176,7 +2213,10 @@ function diaspora_send_relay($item,$owner,$contact,$public_batch = false) { $a = get_app(); $myaddr = $owner['nickname'] . '@' . substr($a->get_baseurl(), strpos($a->get_baseurl(),'://') + 3); - $theiraddr = $contact['addr']; +// $theiraddr = $contact['addr']; + + $body = $item['body']; + $text = html_entity_decode(bb2diaspora($body)); // The first item in the `item` table with the parent id is the parent. However, MySQL doesn't always @@ -2195,26 +2235,30 @@ function diaspora_send_relay($item,$owner,$contact,$public_batch = false) { $relay_retract = false; $sql_sign_id = 'iid'; if( $item['deleted']) { - $tpl = get_markup_template('diaspora_relayable_retraction.tpl'); $relay_retract = true; - $sql_sign_id = 'retract_iid'; + $target_type = ( ($item['verb'] === ACTIVITY_LIKE) ? 'Like' : 'Comment'); + $sender_signed_text = $item['guid'] . ';' . $target_type ; + + $sql_sign_id = 'retract_iid'; + $tpl = get_markup_template('diaspora_relayable_retraction.tpl'); } elseif($item['verb'] === ACTIVITY_LIKE) { - $tpl = get_markup_template('diaspora_like_relay.tpl'); $like = true; + $target_type = 'Post'; // $positive = (($item['deleted']) ? 'false' : 'true'); $positive = 'true'; + $sender_signed_text = $item['guid'] . ';' . $target_type . ';' . $parent_guid . ';' . $positive . ';' . $myaddr; + + $tpl = get_markup_template('diaspora_like_relay.tpl'); } - else { + else { // item is a comment + $sender_signed_text = $item['guid'] . ';' . $parent_guid . ';' . $text . ';' . $myaddr; + $tpl = get_markup_template('diaspora_comment_relay.tpl'); } - $body = $item['body']; - - $text = html_entity_decode(bb2diaspora($body)); - // fetch the original signature if the relayable was created by a Diaspora // or DFRN user. Relayables for other networks are not supported. @@ -2235,51 +2279,20 @@ function diaspora_send_relay($item,$owner,$contact,$public_batch = false) { // function is called logger('diaspora_send_relay: original author signature not found, cannot send relayable'); return; -/* - $itemcontact = q("select * from contact where `id` = %d limit 1", - intval($item['contact-id']) - ); - if(count($itemcontact)) { - if(! $itemcontact[0]['self']) { - $prefix = sprintf( t('[Relayed] Comment authored by %s from network %s'), - '['. $item['author-name'] . ']' . '(' . $item['author-link'] . ')', - network_to_name($itemcontact['network'])) . "\n"; - // "$body" was assigned to "$text" above. It isn't used after that, so I don't think - // the following change will do anything - $body = $prefix . $body; - - // I think this comment will fail upon reaching Diaspora, because "$signed_text" is not defined - } - } - else { - // I'm confused about this "else." Since it sets "$handle = $myaddr," it seems like it should be for the case - // where the top-level post owner commented on his own post, i.e. "$itemcontact[0]['self']" is true. But it's - // positioned to be for the case where "count($itemcontact)" is 0. - - $handle = $myaddr; - - if($like) - $signed_text = $item['guid'] . ';' . $target_type . ';' . $parent_guid . ';' . $positive . ';' . $handle; - elseif($relay_retract) - $signed_text = $item['guid'] . ';' . $target_type; - else - $signed_text = $item['guid'] . ';' . $parent_guid . ';' . $text . ';' . $handle; - - $authorsig = base64_encode(rsa_sign($signed_text,$owner['uprvkey'],'sha256')); - - q("insert into sign (`" . $sql_sign_id . "`,`signed_text`,`signature`,`signer`) values (%d,'%s','%s','%s') ", - intval($item['id']), - dbesc($signed_text), - dbesc($authorsig), - dbesc($handle) - ); - } -*/ } - // sign it with the top-level owner's signature + // Sign the relayable with the top-level owner's signature + // + // We'll use the $sender_signed_text that we just created, instead of the $signed_text + // stored in the database, because that provides the best chance that Diaspora will + // be able to reconstruct the signed text the same way we did. This is particularly a + // concern for the comment, whose signed text includes the text of the comment. The + // smallest change in the text of the comment, including removing whitespace, will + // make the signature verification fail. Since we translate from BB code to Diaspora's + // markup at the top of this function, which is AFTER we placed the original $signed_text + // in the database, it's hazardous to trust the original $signed_text. - $parentauthorsig = base64_encode(rsa_sign($signed_text,$owner['uprvkey'],'sha256')); + $parentauthorsig = base64_encode(rsa_sign($sender_signed_text,$owner['uprvkey'],'sha256')); $msg = replace_macros($tpl,array( '$guid' => xmlify($item['guid']), diff --git a/include/enotify.php b/include/enotify.php index fe0f128b6..134e42f8e 100644 --- a/include/enotify.php +++ b/include/enotify.php @@ -41,8 +41,8 @@ function notification($params) { $subject = sprintf( t('[Friendica:Notify] New mail received at %s'),$sitename); - $preamble = sprintf( t('%s sent you a new private message at %s.'),$params['source_name'],$sitename); - $epreamble = sprintf( t('%s sent you %s.'),'[url=' . $params['source_link'] . ']' . $params['source_name'] . '[/url]', '[url=$itemlink]' . t('a private message') . '[/url]'); + $preamble = sprintf( t('%1$s sent you a new private message at %2$s.'),$params['source_name'],$sitename); + $epreamble = sprintf( t('%1$s sent you %2$s.'),'[url=' . $params['source_link'] . ']' . $params['source_name'] . '[/url]', '[url=$itemlink]' . t('a private message') . '[/url]'); $sitelink = t('Please visit %s to view and/or reply to your private messages.'); $tsitelink = sprintf( $sitelink, $siteurl . '/message/' . $params['item']['id'] ); $hsitelink = sprintf( $sitelink, '' . $sitename . ''); @@ -66,27 +66,38 @@ function notification($params) { ); } - $possess_desc = str_replace('',item_post_type($p[0]),$possess_desc); + $item_post_type = item_post_type($p[0]); + //$possess_desc = str_replace('',$possess_desc); // "a post" - $dest_str = sprintf($possess_desc,'a'); + $dest_str = sprintf(t('%1$s commented on [url=%2$s]a %3$s[/url]'), + '[url=' . $params['source_link'] . ']' . $params['source_name'] . '[/url]', + $itemlink, + $item_post_type); // "George Bull's post" if($p) - $dest_str = sprintf($possess_desc,sprintf( t("%s's"),$p[0]['author-name'])); + $dest_str = sprintf(t('%1$s commented on [url=%2$s]%3$s\'s %4$s[/url]'), + '[url=' . $params['source_link'] . ']' . $params['source_name'] . '[/url]', + $itemlink, + $p[0]['author-name'], + $item_post_type); // "your post" if($p[0]['owner-name'] == $p[0]['author-name'] && $p[0]['wall']) - $dest_str = sprintf($possess_desc, t('your') ); + $dest_str = sprintf(t('%1$s commented on [url=%2$s]your %3$s[/url]'), + '[url=' . $params['source_link'] . ']' . $params['source_name'] . '[/url]', + $itemlink, + $item_post_type); // Some mail softwares relies on subject field for threading. // So, we cannot have different subjects for notifications of the same thread. // Before this we have the name of the replier on the subject rendering // differents subjects for messages on the same thread. - $subject = sprintf( t('[Friendica:Notify] Comment to conversation #%d by %s'), $parent_id, $params['source_name']); + $subject = sprintf( t('[Friendica:Notify] Comment to conversation #%1$d by %2$s'), $parent_id, $params['source_name']); $preamble = sprintf( t('%s commented on an item/conversation you have been following.'), $params['source_name']); - $epreamble = sprintf( t('%s commented on %s.'), '[url=' . $params['source_link'] . ']' . $params['source_name'] . '[/url]', '[url=$itemlink]' . $dest_str . '[/url]'); + $epreamble = $dest_str; $sitelink = t('Please visit %s to view and/or reply to the conversation.'); $tsitelink = sprintf( $sitelink, $siteurl ); @@ -97,9 +108,11 @@ function notification($params) { if($params['type'] == NOTIFY_WALL) { $subject = sprintf( t('[Friendica:Notify] %s posted to your profile wall') , $params['source_name']); - $preamble = sprintf( t('%s posted to your profile wall at %s') , $params['source_name'], $sitename); + $preamble = sprintf( t('%1$s posted to your profile wall at %2$s') , $params['source_name'], $sitename); - $epreamble = sprintf( t('%s posted to %s') , '[url=' . $params['source_link'] . ']' . $params['source_name'] . '[/url]', '[url=$itemlink]' . t('your profile wall.') . '[/url]'); + $epreamble = sprintf( t('%1$s posted to [url=%2s]your wall[/url]') , + '[url=' . $params['source_link'] . ']' . $params['source_name'] . '[/url]', + $itemlink); $sitelink = t('Please visit %s to view and/or reply to the conversation.'); $tsitelink = sprintf( $sitelink, $siteurl ); @@ -109,8 +122,10 @@ function notification($params) { if($params['type'] == NOTIFY_TAGSELF) { $subject = sprintf( t('[Friendica:Notify] %s tagged you') , $params['source_name']); - $preamble = sprintf( t('%s tagged you at %s') , $params['source_name'], $sitename); - $epreamble = sprintf( t('%s %s.') , '[url=' . $params['source_link'] . ']' . $params['source_name'] . '[/url]', '[url=' . $params['link'] . ']' . t('tagged you') . '[/url]'); + $preamble = sprintf( t('%1$s tagged you at %2$s') , $params['source_name'], $sitename); + $epreamble = sprintf( t('%1$s [url=%2$s]tagged you[/url].') , + '[url=' . $params['source_link'] . ']' . $params['source_name'] . '[/url]', + $params['link']); $sitelink = t('Please visit %s to view and/or reply to the conversation.'); $tsitelink = sprintf( $sitelink, $siteurl ); @@ -120,8 +135,10 @@ function notification($params) { if($params['type'] == NOTIFY_TAGSHARE) { $subject = sprintf( t('[Friendica:Notify] %s tagged your post') , $params['source_name']); - $preamble = sprintf( t('%s tagged your post at %s') , $params['source_name'], $sitename); - $epreamble = sprintf( t('%s tagged %s') , '[url=' . $params['source_link'] . ']' . $params['source_name'] . '[/url]', '[url=$itemlink]' . t('your post') . '[/url]' ); + $preamble = sprintf( t('%1$s tagged your post at %2$s') , $params['source_name'], $sitename); + $epreamble = sprintf( t('%1$s tagged [url=%2$s]your post[/url]') , + '[url=' . $params['source_link'] . ']' . $params['source_name'] . '[/url]', + $itemlink); $sitelink = t('Please visit %s to view and/or reply to the conversation.'); $tsitelink = sprintf( $sitelink, $siteurl ); @@ -131,8 +148,10 @@ function notification($params) { if($params['type'] == NOTIFY_INTRO) { $subject = sprintf( t('[Friendica:Notify] Introduction received')); - $preamble = sprintf( t('You\'ve received an introduction from \'%s\' at %s'), $params['source_name'], $sitename); - $epreamble = sprintf( t('You\'ve received %s from %s.'), '[url=$itemlink]' . t('an introduction') . '[/url]' , '[url=' . $params['source_link'] . ']' . $params['source_name'] . '[/url]'); + $preamble = sprintf( t('You\'ve received an introduction from \'%1$s\' at %2$s'), $params['source_name'], $sitename); + $epreamble = sprintf( t('You\'ve received [url=%1$s]an introduction[/url] from %2$s.'), + $itemlink, + '[url=' . $params['source_link'] . ']' . $params['source_name'] . '[/url]'); $body = sprintf( t('You may visit their profile at %s'),$params['source_link']); $sitelink = t('Please visit %s to approve or reject the introduction.'); @@ -143,11 +162,12 @@ function notification($params) { if($params['type'] == NOTIFY_SUGGEST) { $subject = sprintf( t('[Friendica:Notify] Friend suggestion received')); - $preamble = sprintf( t('You\'ve received a friend suggestion from \'%s\' at %s'), $params['source_name'], $sitename); - $epreamble = sprintf( t('You\'ve received %s for %s from %s.'), - '[url=$itemlink]' . t('a friend suggestion') . '[/url]', - '[url=' . $params['item']['url'] . ']' . $params['item']['name'] . '[/url]', - '[url=' . $params['source_link'] . ']' . $params['source_name'] . '[/url]'); + $preamble = sprintf( t('You\'ve received a friend suggestion from \'%1$s\' at %2$s'), $params['source_name'], $sitename); + $epreamble = sprintf( t('You\'ve received [url=%1$s]a friend suggestion[/url] for %2$s from %3$s.'), + $itemlink, + '[url=' . $params['item']['url'] . ']' . $params['item']['name'] . '[/url]', + '[url=' . $params['source_link'] . ']' . $params['source_name'] . '[/url]'); + $body = t('Name:') . ' ' . $params['item']['name'] . "\n"; $body .= t('Photo:') . ' ' . $params['item']['photo'] . "\n"; $body .= sprintf( t('You may visit their profile at %s'),$params['item']['url']); diff --git a/include/items.php b/include/items.php index 95a885a1b..a0dd1c815 100755 --- a/include/items.php +++ b/include/items.php @@ -22,8 +22,6 @@ function get_feed_for(&$a, $dfrn_id, $owner_nick, $last_update, $direction = 0) if($a->argv[$x] === 'category' && $a->argc > ($x + 1) && strlen($a->argv[$x+1])) $category = $a->argv[$x+1]; } - - } @@ -448,6 +446,8 @@ function get_atom_elements($feed,$item) { $res['body'] = $purifier->purify($res['body']); $res['body'] = @html2bbcode($res['body']); + + } elseif(! $have_real_body) { @@ -816,6 +816,12 @@ function item_store($arr,$force_parent = false) { if($r[0]['private']) $arr['private'] = 1; + // Edge case. We host a public forum that was originally posted to privately. + // The original author commented, but as this is a comment, the permissions + // weren't fixed up so it will still show the comment as private unless we fix it here. + + if((intval($r[0]['forum_mode']) == 1) && (! $r[0]['private'])) + $arr['private'] = 0; } else { @@ -910,6 +916,16 @@ function item_store($arr,$force_parent = false) { intval($current_post) ); + $arr['id'] = $current_post; + $arr['parent'] = $parent_id; + $arr['allow_cid'] = $allow_cid; + $arr['allow_gid'] = $allow_gid; + $arr['deny_cid'] = $deny_cid; + $arr['deny_gid'] = $deny_gid; + $arr['private'] = $private; + $arr['deleted'] = $parent_deleted; + call_hooks('post_remote_end',$arr); + // update the commented timestamp on the parent q("UPDATE `item` set `commented` = '%s', `changed` = '%s' WHERE `id` = %d LIMIT 1", @@ -1250,6 +1266,12 @@ function dfrn_deliver($owner,$contact,$atom, $dissolve = false) { return 3; } + if($contact['term-date'] != '0000-00-00 00:00:00') { + logger("dfrn_deliver: $url back from the dead - removing mark for death"); + require_once('include/Contact.php'); + unmark_for_death($contact); + } + $res = parse_xml_string($xml); return $res->status; @@ -1645,6 +1667,11 @@ function consume_feed($xml,$importer,&$contact, &$hub, $datedir = 0, $pass = 0) if(count($r)) { if((x($datarray,'edited') !== false) && (datetime_convert('UTC','UTC',$datarray['edited']) !== $r[0]['edited'])) { + + // do not accept (ignore) an earlier edit than one we currently have. + if(datetime_convert('UTC','UTC',$datarray['edited']) < $r[0]['edited']) + continue; + $r = q("UPDATE `item` SET `title` = '%s', `body` = '%s', `tag` = '%s', `edited` = '%s' WHERE `uri` = '%s' AND `uid` = %d LIMIT 1", dbesc($datarray['title']), dbesc($datarray['body']), @@ -1791,6 +1818,11 @@ function consume_feed($xml,$importer,&$contact, &$hub, $datedir = 0, $pass = 0) if(count($r)) { if((x($datarray,'edited') !== false) && (datetime_convert('UTC','UTC',$datarray['edited']) !== $r[0]['edited'])) { + + // do not accept (ignore) an earlier edit than one we currently have. + if(datetime_convert('UTC','UTC',$datarray['edited']) < $r[0]['edited']) + continue; + $r = q("UPDATE `item` SET `title` = '%s', `body` = '%s', `tag` = '%s', `edited` = '%s' WHERE `uri` = '%s' AND `uid` = %d LIMIT 1", dbesc($datarray['title']), dbesc($datarray['body']), @@ -1845,13 +1877,12 @@ function consume_feed($xml,$importer,&$contact, &$hub, $datedir = 0, $pass = 0) $datarray['last-child'] = 1; } - if($contact['network'] === NETWORK_FEED) { - if(! strlen($contact['notify'])) { + if(($contact['network'] === NETWORK_FEED) || (! strlen($contact['notify']))) { // one way feed - no remote comment ability $datarray['last-child'] = 0; - } - $datarray['private'] = 1; } + if($contact['network'] === NETWORK_FEED) + $datarray['private'] = 1; // This is my contact on another system, but it's really me. // Turn this into a wall post. @@ -2277,7 +2308,12 @@ function local_delivery($importer,$data) { if(count($r)) { $iid = $r[0]['id']; - if((x($datarray,'edited') !== false) && (datetime_convert('UTC','UTC',$datarray['edited']) !== $r[0]['edited'])) { + if((x($datarray,'edited') !== false) && (datetime_convert('UTC','UTC',$datarray['edited']) !== $r[0]['edited'])) { + + // do not accept (ignore) an earlier edit than one we currently have. + if(datetime_convert('UTC','UTC',$datarray['edited']) < $r[0]['edited']) + continue; + logger('received updated comment' , LOGGER_DEBUG); $r = q("UPDATE `item` SET `title` = '%s', `body` = '%s', `tag` = '%s', `edited` = '%s' WHERE `uri` = '%s' AND `uid` = %d LIMIT 1", dbesc($datarray['title']), @@ -2456,6 +2492,11 @@ function local_delivery($importer,$data) { if(count($r)) { if((x($datarray,'edited') !== false) && (datetime_convert('UTC','UTC',$datarray['edited']) !== $r[0]['edited'])) { + + // do not accept (ignore) an earlier edit than one we currently have. + if(datetime_convert('UTC','UTC',$datarray['edited']) < $r[0]['edited']) + continue; + $r = q("UPDATE `item` SET `title` = '%s', `body` = '%s', `tag` = '%s', `edited` = '%s' WHERE `uri` = '%s' AND `uid` = %d LIMIT 1", dbesc($datarray['title']), dbesc($datarray['body']), @@ -2622,6 +2663,11 @@ function local_delivery($importer,$data) { if(count($r)) { if((x($datarray,'edited') !== false) && (datetime_convert('UTC','UTC',$datarray['edited']) !== $r[0]['edited'])) { + + // do not accept (ignore) an earlier edit than one we currently have. + if(datetime_convert('UTC','UTC',$datarray['edited']) < $r[0]['edited']) + continue; + $r = q("UPDATE `item` SET `title` = '%s', `body` = '%s', `tag` = '%s', `edited` = '%s' WHERE `uri` = '%s' AND `uid` = %d LIMIT 1", dbesc($datarray['title']), dbesc($datarray['body']), @@ -3358,3 +3404,69 @@ function drop_item($id,$interactive = true) { } } + + +function first_post_date($uid,$wall = false) { + $r = q("select id, created from item + where uid = %d and wall = %d and deleted = 0 and visible = 1 AND moderated = 0 + and id = parent + order by created asc limit 1", + intval($uid), + intval($wall ? 1 : 0) + ); + if(count($r)) { +// logger('first_post_date: ' . $r[0]['id'] . ' ' . $r[0]['created'], LOGGER_DATA); + return substr(datetime_convert('',date_default_timezone_get(),$r[0]['created']),0,10); + } + return false; +} + +function posted_dates($uid,$wall) { + $dnow = datetime_convert('',date_default_timezone_get(),'now','Y-m-d'); + + $dthen = first_post_date($uid,$wall); + if(! $dthen) + return array(); + + // If it's near the end of a long month, backup to the 28th so that in + // consecutive loops we'll always get a whole month difference. + + if(intval(substr($dnow,8)) > 28) + $dnow = substr($dnow,0,8) . '28'; + if(intval(substr($dthen,8)) > 28) + $dnow = substr($dthen,0,8) . '28'; + + $ret = array(); + while($dnow >= $dthen) { + $dstart = substr($dnow,0,8) . '01'; + $dend = substr($dnow,0,8) . get_dim(intval($dnow),intval(substr($dnow,5))); + $start_month = datetime_convert('','',$dstart,'Y-m-d'); + $end_month = datetime_convert('','',$dend,'Y-m-d'); + $str = day_translate(datetime_convert('','',$dnow,'F Y')); + $ret[] = array($str,$end_month,$start_month); + $dnow = datetime_convert('','',$dnow . ' -1 month', 'Y-m-d'); + } + return $ret; +} + + +function posted_date_widget($url,$uid,$wall) { + $o = ''; + + // For former Facebook folks that left because of "timeline" + + if($wall && intval(get_pconfig($uid,'system','no_wall_archive_widget'))) + return $o; + + $ret = posted_dates($uid,$wall); + if(! count($ret)) + return $o; + + $o = replace_macros(get_markup_template('posted_date_widget.tpl'),array( + '$title' => t('Archives'), + '$size' => ((count($ret) > 6) ? 6 : count($ret)), + '$url' => $url, + '$dates' => $ret + )); + return $o; +} \ No newline at end of file diff --git a/include/nav.php b/include/nav.php index 909ba9b54..a67a8b614 100644 --- a/include/nav.php +++ b/include/nav.php @@ -55,7 +55,7 @@ function nav(&$a) { // user info $r = q("SELECT micro FROM contact WHERE uid=%d AND self=1", intval($a->user['uid'])); $userinfo = array( - 'icon' => (count($r) ? $r[0]['micro']: $a->get_baseurl($ssl_state)."/images/person-48.jpg"), + 'icon' => (count($r) ? $a->get_cached_avatar_image($r[0]['micro']) : $a->get_baseurl($ssl_state)."/images/person-48.jpg"), 'name' => $a->user['username'], ); diff --git a/include/onepoll.php b/include/onepoll.php index ba7d5ebaf..d68f26883 100644 --- a/include/onepoll.php +++ b/include/onepoll.php @@ -36,11 +36,6 @@ function onepoll_run($argv, $argc){ logger('onepoll: start'); - $abandon_days = intval(get_config('system','account_abandon_days')); - if($abandon_days < 1) - $abandon_days = 0; - - $manual_id = 0; $generation = 0; $hub_update = false; @@ -54,9 +49,7 @@ function onepoll_run($argv, $argc){ logger('onepoll: no contact'); return; } - - if(was_recently_delayed($contact_id)) - return; + $d = datetime_convert(); @@ -64,11 +57,6 @@ function onepoll_run($argv, $argc){ // and which have a polling address and ignore Diaspora since // we are unable to match those posts with a Diaspora GUID and prevent duplicates. - $abandon_sql = (($abandon_days) - ? sprintf(" AND `user`.`login_date` > UTC_TIMESTAMP() - INTERVAL %d DAY ", intval($abandon_days)) - : '' - ); - $contacts = q("SELECT `contact`.* FROM `contact` WHERE ( `rel` = %d OR `rel` = %d ) AND `poll` != '' AND NOT `network` IN ( '%s', '%s' ) @@ -88,14 +76,13 @@ function onepoll_run($argv, $argc){ $contact = $contacts[0]; - $xml = false; $t = $contact['last-update']; if($contact['subhub']) { - $interval = get_config('system','pushpoll_frequency'); - $contact['priority'] = (($interval !== false) ? intval($interval) : 3); + $poll_interval = get_config('system','pushpoll_frequency'); + $contact['priority'] = (($poll_interval !== false) ? intval($poll_interval) : 3); $hub_update = false; if(datetime_convert('UTC','UTC', 'now') > datetime_convert('UTC','UTC', $t . " + 1 day")) @@ -139,15 +126,18 @@ function onepoll_run($argv, $argc){ . '&perm=' . $perm ; $handshake_xml = fetch_url($url); + $html_code = $a->get_curl_code(); logger('onepoll: handshake with url ' . $url . ' returns xml: ' . $handshake_xml, LOGGER_DATA); - if(! $handshake_xml) { + if((! strlen($handshake_xml)) || ($html_code >= 400) || (! $html_code)) { logger("poller: $url appears to be dead - marking for death "); + // dead connection - might be a transient event, or this might // mean the software was uninstalled or the domain expired. // Will keep trying for one month. + mark_for_death($contact); // set the last-update so we don't keep polling @@ -161,6 +151,9 @@ function onepoll_run($argv, $argc){ if(! strstr($handshake_xml,'hooks[] = array($rr['hook'], $rr['file'], $rr['function']); + if(! array_key_exists($rr['hook'],$a->hooks)) + $a->hooks[$rr['hook']] = array(); + $a->hooks[$rr['hook']][] = array($rr['file'],$rr['function']); } } }} @@ -158,25 +160,24 @@ if(! function_exists('call_hooks')) { function call_hooks($name, &$data = null) { $a = get_app(); - if(count($a->hooks)) { - foreach($a->hooks as $hook) { - if($hook[HOOK_HOOK] === $name) { - @include_once($hook[HOOK_FILE]); - if(function_exists($hook[HOOK_FUNCTION])) { - $func = $hook[HOOK_FUNCTION]; - $func($a,$data); - } - else { - // remove orphan hooks - q("delete from hook where hook = '%s' and file = '$s' and function = '%s' limit 1", - dbesc($hook[HOOK_HOOK]), - dbesc($hook[HOOK_FILE]), - dbesc($hook[HOOK_FUNCTION]) - ); - } + if((is_array($a->hooks)) && (array_key_exists($name,$a->hooks))) { + foreach($a->hooks[$name] as $hook) { + @include_once($hook[0]); + if(function_exists($hook[1])) { + $func = $hook[1]; + $func($a,$data); + } + else { + // remove orphan hooks + q("delete from hook where hook = '%s' and file = '$s' and function = '%s' limit 1", + dbesc($name), + dbesc($hook[0]), + dbesc($hook[1]) + ); } } } + }} diff --git a/include/poller.php b/include/poller.php index 6b12445d1..fefc9b381 100644 --- a/include/poller.php +++ b/include/poller.php @@ -201,8 +201,8 @@ function poller_run($argv, $argc){ if($contact['subhub']) { - $interval = get_config('system','pushpoll_frequency'); - $contact['priority'] = (($interval !== false) ? intval($interval) : 3); + $poll_interval = get_config('system','pushpoll_frequency'); + $contact['priority'] = (($poll_interval !== false) ? intval($poll_interval) : 3); $hub_update = false; if((datetime_convert('UTC','UTC', 'now') > datetime_convert('UTC','UTC', $t . " + 1 day")) || $force) diff --git a/include/queue_fn.php b/include/queue_fn.php index 2aca338f5..e43912431 100644 --- a/include/queue_fn.php +++ b/include/queue_fn.php @@ -23,6 +23,13 @@ function was_recently_delayed($cid) { ); if(count($r)) return true; + + $r = q("select `term-date` from contact where id = %d and `term-date` != '' and `term-date` != '0000-00-00 00:00:00' limit 1", + intval($cid) + ); + if(count($r)) + return true; + return false; } diff --git a/include/text.php b/include/text.php index d4a4d5580..cc4bee268 100644 --- a/include/text.php +++ b/include/text.php @@ -1059,7 +1059,7 @@ function feed_salmonlinks($nick) { if(! function_exists('get_plink')) { function get_plink($item) { $a = get_app(); - if (x($item,'plink') && (! $item['private'])){ + if (x($item,'plink') && ((! $item['private']) || ($item['network'] === NETWORK_FEED))){ return array( 'href' => $item['plink'], 'title' => t('link to source'), @@ -1255,13 +1255,13 @@ function bb_translate_video($s) { function html2bb_video($s) { - $s = preg_replace('#]+>(.*?)https+://www.youtube.com/((?:v|cp)/[A-Za-z0-9\-_=]+)(.*?)#ism', + $s = preg_replace('#]+>(.*?)https?://www.youtube.com/((?:v|cp)/[A-Za-z0-9\-_=]+)(.*?)#ism', '[youtube]$2[/youtube]', $s); - $s = preg_replace('#](.*?)https+://www.youtube.com/embed/([A-Za-z0-9\-_=]+)(.*?)#ism', + $s = preg_replace('#](.*?)https?://www.youtube.com/embed/([A-Za-z0-9\-_=]+)(.*?)#ism', '[youtube]$2[/youtube]', $s); - $s = preg_replace('#](.*?)https+://player.vimeo.com/video/([0-9]+)(.*?)#ism', + $s = preg_replace('#](.*?)https?://player.vimeo.com/video/([0-9]+)(.*?)#ism', '[vimeo]$2[/vimeo]', $s); return $s; @@ -1541,3 +1541,16 @@ function protect_sprintf($s) { return(str_replace('%','%%',$s)); } + +function is_a_date_arg($s) { + $i = intval($s); + if($i > 1900) { + $y = date('Y'); + if($i <= $y+1 && strpos($s,'-') == 4) { + $m = intval(substr($s,5)); + if($m > 0 && $m <= 12) + return true; + } + } + return false; +} diff --git a/index.php b/index.php index 94329eedc..61f3562b5 100644 --- a/index.php +++ b/index.php @@ -59,8 +59,7 @@ if(! $install) { /** * * Important stuff we always need to do. - * Initialise authentication and date and time. - * Create the HTML head for the page, even if we may not use it (xml, etc.) + * * The order of these may be important so use caution if you think they're all * intertwingled with no logical order and decide to sort it out. Some of the * dependencies have changed, but at least at one time in the recent past - the @@ -68,12 +67,6 @@ if(! $install) { * */ -require_once("datetime.php"); - -$a->timezone = (($default_timezone) ? $default_timezone : 'UTC'); - -date_default_timezone_set($a->timezone); - session_start(); /** @@ -253,7 +246,10 @@ if(! $install) if($a->module_loaded) { $a->page['page_title'] = $a->module; + $placeholder = ''; + if(function_exists($a->module . '_init')) { + call_hooks($a->module . '_mod_init', $placeholder); $func = $a->module . '_init'; $func($a); } @@ -273,18 +269,25 @@ if($a->module_loaded) { if(($_SERVER['REQUEST_METHOD'] === 'POST') && (! $a->error) && (function_exists($a->module . '_post')) && (! x($_POST,'auth-params'))) { + call_hooks($a->module . '_mod_post', $_POST); $func = $a->module . '_post'; $func($a); } if((! $a->error) && (function_exists($a->module . '_afterpost'))) { + call_hooks($a->module . '_mod_afterpost',$placeholder); $func = $a->module . '_afterpost'; $func($a); } if((! $a->error) && (function_exists($a->module . '_content'))) { + $arr = array('content' => $a->page['content']); + call_hooks($a->module . '_mod_content', $arr); + $a->page['content'] = $arr['content']; $func = $a->module . '_content'; - $a->page['content'] .= $func($a); + $arr = array('content' => $func($a)); + call_hooks($a->module . '_mod_aftercontent', $arr); + $a->page['content'] .= $arr['content']; } } diff --git a/library/simplepie/simplepie.inc b/library/simplepie/simplepie.inc index 8a2739f52..96ad06678 100644 --- a/library/simplepie/simplepie.inc +++ b/library/simplepie/simplepie.inc @@ -709,7 +709,7 @@ class SimplePie * @see SimplePie::strip_htmltags() * @access private */ - var $strip_htmltags = array('base', 'blink', 'body', 'doctype', 'embed', 'font', 'form', 'frame', 'frameset', 'html', 'iframe', 'input', 'marquee', 'meta', 'noscript', 'object', 'param', 'script', 'style'); + var $strip_htmltags = array('base', 'blink', 'body', 'doctype', 'embed', 'font', 'form', 'frame', 'frameset', 'html', 'input', 'marquee', 'meta', 'noscript', 'object', 'param', 'script', 'style'); /** * The SimplePie class contains feed level data and options @@ -14803,7 +14803,7 @@ class SimplePie_Sanitize // Options var $remove_div = true; var $image_handler = ''; - var $strip_htmltags = array('base', 'blink', 'body', 'doctype', 'embed', 'font', 'form', 'frame', 'frameset', 'html', 'iframe', 'input', 'marquee', 'meta', 'noscript', 'object', 'param', 'script', 'style'); + var $strip_htmltags = array('base', 'blink', 'body', 'doctype', 'embed', 'font', 'form', 'frame', 'frameset', 'html', 'input', 'marquee', 'meta', 'noscript', 'object', 'param', 'script', 'style'); var $encode_instead_of_strip = false; var $strip_attributes = array('bgsound', 'class', 'expr', 'id', 'style', 'onclick', 'onerror', 'onfinish', 'onmouseover', 'onmouseout', 'onfocus', 'onblur', 'lowsrc', 'dynsrc'); var $strip_comments = false; @@ -14892,7 +14892,7 @@ class SimplePie_Sanitize } } - function strip_htmltags($tags = array('base', 'blink', 'body', 'doctype', 'embed', 'font', 'form', 'frame', 'frameset', 'html', 'iframe', 'input', 'marquee', 'meta', 'noscript', 'object', 'param', 'script', 'style')) + function strip_htmltags($tags = array('base', 'blink', 'body', 'doctype', 'embed', 'font', 'form', 'frame', 'frameset', 'html', 'input', 'marquee', 'meta', 'noscript', 'object', 'param', 'script', 'style')) { if ($tags) { diff --git a/mod/contacts.php b/mod/contacts.php index a3e3f409b..fb4595739 100644 --- a/mod/contacts.php +++ b/mod/contacts.php @@ -335,6 +335,7 @@ function contacts_content(&$a) { $tab_tpl = get_markup_template('common_tabs.tpl'); $tab_str = replace_macros($tab_tpl, array('$tabs' => $tabs)); + $lost_contact = (($contact['archive'] && $contact['term-date'] != '0000-00-00 00:00:00' && $contact['term-date'] < datetime_convert('','','now')) ? t('Communications lost with this contact!') : ''); $o .= replace_macros($tpl,array( '$header' => t('Contact Editor'), @@ -359,6 +360,7 @@ function contacts_content(&$a) { '$poll_interval' => contact_poll_interval($contact['priority'],(! $poll_enabled)), '$poll_enabled' => $poll_enabled, '$lastupdtext' => t('Last update:'), + '$lost_contact' => $lost_contact, '$updpub' => t('Update public posts'), '$last_update' => $last_update, '$udnow' => t('Update now'), @@ -477,12 +479,13 @@ function contacts_content(&$a) { - + $searching = false; if($search) { $search_hdr = $search; - $search = dbesc($search.'*'); + $search_txt = dbesc(protect_sprintf(preg_quote($search))); + $searching = true; } - $sql_extra .= ((strlen($search)) ? " AND MATCH `name` AGAINST ('$search' IN BOOLEAN MODE) " : ""); + $sql_extra .= (($searching) ? " AND `name` REGEXP '$search_txt' " : ""); if($nets) $sql_extra .= sprintf(" AND network = '%s' ", dbesc($nets)); @@ -499,7 +502,6 @@ function contacts_content(&$a) { } - $r = q("SELECT * FROM `contact` WHERE `uid` = %d AND `self` = 0 AND `pending` = 0 $sql_extra $sql_extra2 ORDER BY `name` ASC LIMIT %d , %d ", intval($_SESSION['uid']), intval($a->pager['start']), @@ -566,7 +568,7 @@ function contacts_content(&$a) { '$total' => $total, '$search' => $search_hdr, '$desc' => t('Search your contacts'), - '$finding' => (strlen($search) ? t('Finding: ') . "'" . $search . "'" : ""), + '$finding' => (($searching) ? t('Finding: ') . "'" . $search . "'" : ""), '$submit' => t('Find'), '$cmd' => $a->cmd, '$contacts' => $contacts, diff --git a/mod/dfrn_poll.php b/mod/dfrn_poll.php index 436727a78..f3c145410 100644 --- a/mod/dfrn_poll.php +++ b/mod/dfrn_poll.php @@ -443,7 +443,7 @@ function dfrn_poll_content(&$a) { $encrypted_id = ''; $id_str = $my_id . '.' . mt_rand(1000,9999); - if($r[0]['duplex'] && strlen($r[0]['pubkey'])) { + if(($r[0]['duplex'] && strlen($r[0]['pubkey'])) || (! strlen($r[0]['prvkey']))) { openssl_public_encrypt($hash,$challenge,$r[0]['pubkey']); openssl_public_encrypt($id_str,$encrypted_id,$r[0]['pubkey']); } diff --git a/mod/dfrn_request.php b/mod/dfrn_request.php index 896fe1792..cec2d7f8b 100644 --- a/mod/dfrn_request.php +++ b/mod/dfrn_request.php @@ -170,6 +170,21 @@ function dfrn_request_post(&$a) { info( t("Introduction complete.") . EOL); } + $r = q("select id from contact where uid = %d and url = '%s' and `site-pubkey` = '%s' limit 1", + intval(local_user()), + dbesc($dfrn_url), + $parms['key'] // this was already escaped + ); + if(count($r)) { + $g = q("select def_gid from user where uid = %d limit 1", + intval(local_user()) + ); + if($g && intval($g[0]['def_gid'])) { + require_once('include/group.php'); + group_add_member(local_user(),'',$r[0]['id'],$g[0]['def_gid']); + } + } + /** * Allow the blocked remote notification to complete */ diff --git a/mod/directory.php b/mod/directory.php index 367438845..930a575b6 100644 --- a/mod/directory.php +++ b/mod/directory.php @@ -116,7 +116,7 @@ function directory_content(&$a) { $entry = replace_macros($tpl,array( '$id' => $rr['id'], '$profile-link' => $profile_link, - '$photo' => $rr[$photo], + '$photo' => $a->get_cached_avatar_image($rr[$photo]), '$alt-text' => $rr['name'], '$name' => $rr['name'], '$details' => $pdesc . $details diff --git a/mod/manage.php b/mod/manage.php index 84dfa6917..96d420c78 100644 --- a/mod/manage.php +++ b/mod/manage.php @@ -96,7 +96,7 @@ function manage_content(&$a) { $o .= '
' . "\r\n"; $o .= '
' . "\r\n"; - $o .= '' . "\r\n"; foreach($a->identities as $rr) { $selected = (($rr['nickname'] === $a->user['nickname']) ? ' selected="selected" ' : ''); @@ -106,7 +106,8 @@ function manage_content(&$a) { $o .= '' . "\r\n"; $o .= '
' . "\r\n"; - $o .= '
' . "\r\n"; +// $o .= ''; + $o .= '' . "\r\n"; return $o; diff --git a/mod/message.php b/mod/message.php index d5bb3dfe4..519634be5 100644 --- a/mod/message.php +++ b/mod/message.php @@ -407,6 +407,7 @@ function message_content(&$a) { '$parent' => $parent, '$upload' => t('Upload photo'), '$insert' => t('Insert web link'), + '$submit' => t('Submit'), '$wait' => t('Please wait') )); diff --git a/mod/network.php b/mod/network.php index bd5946619..5f009dacd 100644 --- a/mod/network.php +++ b/mod/network.php @@ -7,13 +7,28 @@ function network_init(&$a) { return; } - + $is_a_date_query = false; + + if($a->argc > 1) { + for($x = 1; $x < $a->argc; $x ++) { + if(is_a_date_arg($a->argv[$x])) { + $is_a_date_query = true; + break; + } + } + } + + // convert query string to array and remove first element (wich is friendica args) + $query_array = array(); + parse_str($a->query_string, $query_array); + array_shift($query_array); + // fetch last used tab and redirect if needed $sel_tabs = network_query_get_sel_tab($a); $last_sel_tabs = get_pconfig(local_user(), 'network.view','tab.selected'); if (is_array($last_sel_tabs)){ $tab_urls = array( - '/network?f=&order=comment', //all + '/network?f=&order=comment',//all '/network?f=&order=post', //postord '/network?f=&conv=1', //conv '/network/new', //new @@ -24,10 +39,24 @@ function network_init(&$a) { // redirect if current selected tab is 'no_active' and // last selected tab is _not_ 'all_active'. - if ($sel_tabs[0] == 'active' && $last_sel_tabs[0]!='active') { + // and this isn't a date query + + if ($sel_tabs[0] == 'active' && $last_sel_tabs[0]!='active' && (! $is_a_date_query)) { $k = array_search('active', $last_sel_tabs); - //echo "
"; var_dump($sel_tabs, $last_sel_tabs, $tab_urlsm, $k, $tab_urls[$k]); killme();
-			goaway($a->get_baseurl() . $tab_urls[$k]);
+          
+            // merge tab querystring with request querystring
+            $dest_qa = array();
+            list($dest_url,$dest_qs) = explode("?", $tab_urls[$k]);
+            parse_str( $dest_qs, $dest_qa);
+            $dest_qa = array_merge($query_array, $dest_qa);
+            $dest_qs = build_querystring($dest_qa);
+            
+            // groups filter is in form of "network/nnn". Add it to $dest_url, if it's possible
+            if ($a->argc==2 && is_numeric($a->argv[1]) && strpos($dest_url, "/",1)===false){
+                $dest_url .= "/".$a->argv[1];
+            }
+
+			goaway($a->get_baseurl() . $dest_url."?".$dest_qs);
 		}
 	}
 	
@@ -35,6 +64,7 @@ function network_init(&$a) {
 		  
 	require_once('include/group.php');
 	require_once('include/contact_widgets.php');
+	require_once('include/items.php');
 
 	if(! x($a->page,'aside'))
 		$a->page['aside'] = '';
@@ -66,8 +96,9 @@ function network_init(&$a) {
 	if(x($_GET,'search')) {
 		$a->page['content'] .= '

' . t('Search Results For:') . ' ' . $search . '

'; } - + $a->page['aside'] .= group_side('network','network',true,$group_id); + $a->page['aside'] .= posted_date_widget($a->get_baseurl() . '/network',local_user(),false); $a->page['aside'] .= networks_widget($a->get_baseurl(true) . '/network',(x($_GET, 'nets') ? $_GET['nets'] : '')); $a->page['aside'] .= saved_searches($search); $a->page['aside'] .= fileas_widget($a->get_baseurl(true) . '/network',(x($_GET, 'file') ? $_GET['file'] : '')); @@ -208,6 +239,34 @@ function network_content(&$a, $update = 0) { call_hooks('network_content_init', $arr); + + $datequery = $datequery2 = ''; + + $group = 0; + + $nouveau = false; + + if($a->argc > 1) { + for($x = 1; $x < $a->argc; $x ++) { + if(is_a_date_arg($a->argv[$x])) { + if($datequery) + $datequery2 = escape_tags($a->argv[$x]); + else { + $datequery = escape_tags($a->argv[$x]); + $_GET['order'] = 'post'; + } + } + elseif($a->argv[$x] === 'new') { + $nouveau = true; + } + elseif(intval($a->argv[$x])) { + $group = intval($a->argv[$x]); + $def_acl = array('allow_gid' => '<' . $group . '>'); + } + } + } + + $o = ''; // item filter tabs @@ -218,43 +277,46 @@ function network_content(&$a, $update = 0) { // if no tabs are selected, defaults to comments if ($no_active=='active') $all_active='active'; //echo "
"; var_dump($no_active, $all_active, $postord_active, $conv_active, $new_active, $starred_active, $bookmarked_active, $spam_active); killme();
-	
+
+	$cmd = (($datequery) ? '' : $a->cmd);
+	$len_naked_cmd = strlen(str_replace('/new','',$cmd));		
+
 	// tabs
 	$tabs = array(
 		array(
 			'label' => t('Commented Order'),
-			'url'=>$a->get_baseurl(true) . '/' . str_replace('/new', '', $a->cmd) . '?f=&order=comment' . ((x($_GET,'cid')) ? '&cid=' . $_GET['cid'] : ''), 
+			'url'=>$a->get_baseurl(true) . '/' . str_replace('/new', '', $cmd) . '?f=&order=comment' . ((x($_GET,'cid')) ? '&cid=' . $_GET['cid'] : ''), 
 			'sel'=>$all_active,
 			'title'=> t('Sort by Comment Date'),
 		),
 		array(
 			'label' => t('Posted Order'),
-			'url'=>$a->get_baseurl(true) . '/' . str_replace('/new', '', $a->cmd) . '?f=&order=post' . ((x($_GET,'cid')) ? '&cid=' . $_GET['cid'] : ''), 
+			'url'=>$a->get_baseurl(true) . '/' . str_replace('/new', '', $cmd) . '?f=&order=post' . ((x($_GET,'cid')) ? '&cid=' . $_GET['cid'] : ''), 
 			'sel'=>$postord_active,
 			'title' => t('Sort by Post Date'),
 		),
 
 		array(
 			'label' => t('Personal'),
-			'url' => $a->get_baseurl(true) . '/' . str_replace('/new', '', $a->cmd) . ((x($_GET,'cid')) ? '/?f=&cid=' . $_GET['cid'] : '') . '&conv=1',
+			'url' => $a->get_baseurl(true) . '/' . str_replace('/new', '', $cmd) . ((x($_GET,'cid')) ? '/?f=&cid=' . $_GET['cid'] : '') . '&conv=1',
 			'sel' => $conv_active,
 			'title' => t('Posts that mention or involve you'),
 		),
 		array(
 			'label' => t('New'),
-			'url' => $a->get_baseurl(true) . '/' . str_replace('/new', '', $a->cmd) . '/new' . ((x($_GET,'cid')) ? '/?f=&cid=' . $_GET['cid'] : ''),
+			'url' => $a->get_baseurl(true) . '/' . str_replace('/new', '', $cmd) . ($len_naked_cmd ? '/' : '') . 'new' . ((x($_GET,'cid')) ? '/?f=&cid=' . $_GET['cid'] : ''),
 			'sel' => $new_active,
 			'title' => t('Activity Stream - by date'),
 		),
 		array(
 			'label' => t('Starred'),
-			'url'=>$a->get_baseurl(true) . '/' . str_replace('/new', '', $a->cmd) . ((x($_GET,'cid')) ? '/?f=&cid=' . $_GET['cid'] : '') . '&star=1',
+			'url'=>$a->get_baseurl(true) . '/' . str_replace('/new', '', $cmd) . ((x($_GET,'cid')) ? '/?f=&cid=' . $_GET['cid'] : '') . '&star=1',
 			'sel'=>$starred_active,
 			'title' => t('Favourite Posts'),
 		),
 		array(
 			'label' => t('Shared Links'),
-			'url'=>$a->get_baseurl(true) . '/' . str_replace('/new', '', $a->cmd) . ((x($_GET,'cid')) ? '/?f=&cid=' . $_GET['cid'] : '') . '&bmark=1',
+			'url'=>$a->get_baseurl(true) . '/' . str_replace('/new', '', $cmd) . ((x($_GET,'cid')) ? '/?f=&cid=' . $_GET['cid'] : '') . '&bmark=1',
 			'sel'=>$bookmarked_active,
 			'title'=> t('Interesting Links'),
 		),	
@@ -285,9 +347,6 @@ function network_content(&$a, $update = 0) {
 
 	$contact_id = $a->cid;
 
-	$group = 0;
-
-	$nouveau = false;
 	require_once('include/acl_selectors.php');
 
 	$cid = ((x($_GET,'cid')) ? intval($_GET['cid']) : 0);
@@ -302,17 +361,7 @@ function network_content(&$a, $update = 0) {
 	$cmax = ((x($_GET,'cmax')) ? intval($_GET['cmax']) : 99);
 	$file = ((x($_GET,'file')) ? $_GET['file'] : '');
 
-	if(($a->argc > 2) && $a->argv[2] === 'new')
-		$nouveau = true;
 
-	if($a->argc > 1) {
-		if($a->argv[1] === 'new')
-			$nouveau = true;
-		else {
-			$group = intval($a->argv[1]);
-			$def_acl = array('allow_gid' => '<' . $group . '>');
-		}
-	}
 
 	if(x($_GET,'search') || x($_GET,'file'))
 		$nouveau = true;
@@ -452,7 +501,17 @@ function network_content(&$a, $update = 0) {
 			. "'; var profile_page = " . $a->pager['page'] . "; \r\n";
 	}
 
+	$sql_extra3 = '';
+
+	if($datequery) {
+		$sql_extra3 .= protect_sprintf(sprintf(" AND item.created <= '%s' ", dbesc(datetime_convert(date_default_timezone_get(),'',$datequery))));
+	}
+	if($datequery2) {
+		$sql_extra3 .= protect_sprintf(sprintf(" AND item.created >= '%s' ", dbesc(datetime_convert(date_default_timezone_get(),'',$datequery2))));
+	}
+
 	$sql_extra2 = (($nouveau) ? '' : " AND `item`.`parent` = `item`.`id` ");
+	$sql_extra3 = (($nouveau) ? '' : $sql_extra3);
 
 	if(x($_GET,'search')) {
 		$search = escape_tags($_GET['search']);
@@ -508,7 +567,7 @@ function network_content(&$a, $update = 0) {
 			FROM `item` LEFT JOIN `contact` ON `contact`.`id` = `item`.`contact-id`
 			WHERE `item`.`uid` = %d AND `item`.`visible` = 1 AND `item`.`deleted` = 0
 			AND `contact`.`blocked` = 0 AND `contact`.`pending` = 0
-			$sql_extra2
+			$sql_extra2 $sql_extra3
 			$sql_extra $sql_nets ",
 			intval($_SESSION['uid'])
 		);
@@ -560,7 +619,7 @@ function network_content(&$a, $update = 0) {
 				WHERE `item`.`uid` = %d AND `item`.`visible` = 1 AND `item`.`deleted` = 0
 				and `item`.`moderated` = 0 and `item`.`unseen` = 1
 				AND `contact`.`blocked` = 0 AND `contact`.`pending` = 0
-				$sql_extra $sql_nets ",
+				$sql_extra3 $sql_extra $sql_nets ",
 				intval(local_user())
 			);
 		}
@@ -570,7 +629,7 @@ function network_content(&$a, $update = 0) {
 				WHERE `item`.`uid` = %d AND `item`.`visible` = 1 AND `item`.`deleted` = 0
 				AND `item`.`moderated` = 0 AND `contact`.`blocked` = 0 AND `contact`.`pending` = 0
 				AND `item`.`parent` = `item`.`id`
-				$sql_extra $sql_nets
+				$sql_extra3 $sql_extra $sql_nets
 				ORDER BY `item`.$ordering DESC $pager_sql ",
 				intval(local_user())
 			);
diff --git a/mod/photos.php b/mod/photos.php
index efeab8fa3..d96bc135e 100644
--- a/mod/photos.php
+++ b/mod/photos.php
@@ -36,7 +36,7 @@ function photos_init(&$a) {
 
 			$o .= '
'; $o .= '
' . $a->data['user']['username'] . '
'; - $o .= '
' . $a->data['user']['username'] . '
'; + $o .= '
' . $a->data['user']['username'] . '
'; $o .= '
'; if(! intval($a->data['user']['hidewall'])) { @@ -306,7 +306,8 @@ function photos_post(&$a) { $albname = datetime_convert('UTC',date_default_timezone_get(),'now', 'Y'); - if((x($_POST,'rotate') !== false) && (intval($_POST['rotate']) == 1)) { + if((x($_POST,'rotate') !== false) && + ( (intval($_POST['rotate']) == 1) || (intval($_POST['rotate']) == 2) )) { logger('rotate'); $r = q("select * from photo where `resource-id` = '%s' and uid = %d and scale = 0 limit 1", @@ -316,7 +317,8 @@ function photos_post(&$a) { if(count($r)) { $ph = new Photo($r[0]['data'], $r[0]['type']); if($ph->is_valid()) { - $ph->rotate(270); + $rotate_deg = ( (intval($_POST['rotate']) == 1) ? 270 : 90 ); + $ph->rotate($rotate_deg); $width = $ph->getWidth(); $height = $ph->getHeight(); @@ -325,8 +327,8 @@ function photos_post(&$a) { dbesc($ph->imageString()), intval($height), intval($width), - dbesc($resource_id), - intval($page_owner_uid) + dbesc($resource_id), + intval($page_owner_uid) ); if($width > 640 || $height > 640) { @@ -338,8 +340,8 @@ function photos_post(&$a) { dbesc($ph->imageString()), intval($height), intval($width), - dbesc($resource_id), - intval($page_owner_uid) + dbesc($resource_id), + intval($page_owner_uid) ); } @@ -352,8 +354,8 @@ function photos_post(&$a) { dbesc($ph->imageString()), intval($height), intval($width), - dbesc($resource_id), - intval($page_owner_uid) + dbesc($resource_id), + intval($page_owner_uid) ); } } @@ -718,6 +720,7 @@ function photos_post(&$a) { killme(); } + $ph->orient($src); @unlink($src); $width = $ph->getWidth(); @@ -1250,7 +1253,8 @@ function photos_content(&$a) { $edit_tpl = get_markup_template('photo_edit.tpl'); $edit = replace_macros($edit_tpl, array( '$id' => $ph[0]['id'], - '$rotate' => t('Rotate CW'), + '$rotatecw' => t('Rotate CW (right)'), + '$rotateccw' => t('Rotate CCW (left)'), '$album' => template_escape($ph[0]['album']), '$newalbum' => t('New album name'), '$nickname' => $a->data['user']['nickname'], diff --git a/mod/profile.php b/mod/profile.php index 7658a9647..24e03d6ea 100644 --- a/mod/profile.php +++ b/mod/profile.php @@ -67,11 +67,23 @@ function profile_init(&$a) { function profile_content(&$a, $update = 0) { - if (x($a->category)) { - $category = $a->category; + $category = $datequery = $datequery2 = ''; + + if($a->argc > 2) { + for($x = 2; $x < $a->argc; $x ++) { + if(is_a_date_arg($a->argv[$x])) { + if($datequery) + $datequery2 = escape_tags($a->argv[$x]); + else + $datequery = escape_tags($a->argv[$x]); + } + else + $category = $a->argv[$x]; + } } - else { - $category = ((x($_GET,'category')) ? $_GET['category'] : ''); + + if(! x($category)) { + $category = ((x($_GET,'category')) ? $_GET['category'] : ''); } if(get_config('system','block_public') && (! local_user()) && (! remote_user())) { @@ -82,6 +94,8 @@ function profile_content(&$a, $update = 0) { require_once('include/security.php'); require_once('include/conversation.php'); require_once('include/acl_selectors.php'); + require_once('include/items.php'); + $groups = array(); $tab = 'posts'; @@ -97,6 +111,7 @@ function profile_content(&$a, $update = 0) { } } + $contact = null; $remote_contact = false; @@ -155,6 +170,7 @@ function profile_content(&$a, $update = 0) { $celeb = ((($a->profile['page-flags'] == PAGE_SOAPBOX) || ($a->profile['page-flags'] == PAGE_COMMUNITY)) ? true : false); + $a->page['aside'] .= posted_date_widget($a->get_baseurl(true) . '/profile/' . $a->profile['nickname'],$a->profile['profile_uid'],true); $a->page['aside'] .= categories_widget($a->get_baseurl(true) . '/profile/' . $a->profile['nickname'],(x($category) ? xmlify($category) : '')); if(can_write_wall($a,$a->profile['profile_uid'])) { @@ -200,16 +216,24 @@ function profile_content(&$a, $update = 0) { } else { - if(x($category)) { - $sql_extra .= file_tag_file_query('item',$category,'category'); + if(x($category)) { + $sql_extra .= protect_sprintf(file_tag_file_query('item',$category,'category')); } + if($datequery) { + $sql_extra2 .= protect_sprintf(sprintf(" AND item.created <= '%s' ", dbesc(datetime_convert(date_default_timezone_get(),'',$datequery)))); + } + if($datequery2) { + $sql_extra2 .= protect_sprintf(sprintf(" AND item.created >= '%s' ", dbesc(datetime_convert(date_default_timezone_get(),'',$datequery2)))); + } + + $r = q("SELECT COUNT(*) AS `total` FROM `item` LEFT JOIN `contact` ON `contact`.`id` = `item`.`contact-id` WHERE `item`.`uid` = %d AND `item`.`visible` = 1 AND `item`.`deleted` = 0 and `item`.`moderated` = 0 AND `contact`.`blocked` = 0 AND `contact`.`pending` = 0 AND `item`.`id` = `item`.`parent` AND `item`.`wall` = 1 - $sql_extra ", + $sql_extra $sql_extra2 ", intval($a->profile['profile_uid']) ); @@ -225,7 +249,7 @@ function profile_content(&$a, $update = 0) { WHERE `item`.`uid` = %d AND `item`.`visible` = 1 AND `item`.`deleted` = 0 and `item`.`moderated` = 0 AND `contact`.`blocked` = 0 AND `contact`.`pending` = 0 AND `item`.`id` = `item`.`parent` AND `item`.`wall` = 1 - $sql_extra + $sql_extra $sql_extra2 ORDER BY `item`.`created` DESC $pager_sql ", intval($a->profile['profile_uid']) diff --git a/mod/profiles.php b/mod/profiles.php index 6a8ce9e1e..a9da5454c 100644 --- a/mod/profiles.php +++ b/mod/profiles.php @@ -652,7 +652,7 @@ function profiles_content(&$a) { foreach($r as $rr) { $o .= replace_macros($tpl, array( - '$photo' => $rr['thumb'], + '$photo' => $a->get_cached_avatar_image($rr['thumb']), '$id' => $rr['id'], '$alt' => t('Profile Image'), '$profile_name' => $rr['profile-name'], diff --git a/mod/share.php b/mod/share.php index 6c6098c83..c7525113e 100644 --- a/mod/share.php +++ b/mod/share.php @@ -8,10 +8,10 @@ function share_init(&$a) { if((! $post_id) || (! local_user())) killme(); - $r = q("SELECT * FROM `item` WHERE `id` = %d LIMIT 1", + $r = q("SELECT item.*, contact.network FROM `item` left join contact on `item`.`contact-id` = `contact`.`id` WHERE `item`.`id` = %d LIMIT 1", intval($post_id) ); - if(! count($r) || $r[0]['private']) + if(! count($r) || ($r[0]['private'] && ($r[0]['network'] != NETWORK_FEED))) killme(); $o = ''; diff --git a/spec/zot-2012.txt b/spec/zot-2012.txt new file mode 100644 index 000000000..2e1f3c3c4 --- /dev/null +++ b/spec/zot-2012.txt @@ -0,0 +1,182 @@ + +Initial cut at Zot-2012 protocol. This is a very rough draft of some very rough ideas and concepts. +It is not yet intended to be a definitive specification and many things like the security handshakes are yet to be specified precisely. + +All communications are https + + +First create a global unique userid + + +Site userid: +https://macgirvin.com/1 + +$guuid = base64url_encode(hash('whirlpool','https://macgirvin.com/1.' . mt_rand(1000000,9999999),1); + + +Then create a hashed site destination. + +$gduid = base64url_encode(hash('whirlpool', $guuid . 'https://macgirvin.com',1); + +These two keys will identify you as a person+site pair in the future. +You will also obtain a password upon introducing yourself to a site. +This can be used to edit locations in the future. You will always keep your global unique userid + + +The steps to connect with somebody are to first register your location with their site. +Then introduce yourself to the person. This contains flags for the desired relationship. +At some future time, they may confirm and adjust the relationship based on their comfort level. +Lack of confirmation is tantamount to denial. + +You can set either or both of FOLLOW and SHARE which indicates the relationship from your viewpoint. +They may do likewise. + +A relationship is based on you as a person and provided you register new locations with the site you can post from anywhere. +You do not need to register locations with each person, only with the site. + + +Introduce yourself to a site: + + +POST https://example.com/post + +{ +'type' => 'register' +'person' => $guuid +'address' => $gduid +'site' => 'https://macgirvin.com' +'info' => 'mike@macgirvin.com' +} + +Returns: + +{ +'success' => 'true' +'pass' => me_encrypt($random_string) +} + +--- +Add location +--- + +POST https://example.com/post + +{ +'type' => 'location' +'person' => $guuid +'address' => $new_gduid +'site' => 'https://newsite.com' +'info' => 'mike@newsite.com' +'pass' => me_encrypt($gduid . '.' . $pass) +} + +Returns: + +{ +'success' => 'true' +'pass' => me_encrypt($random_string) +} + +--- +Remove location +--- + +POST https://example.com/post + +{ +'type' => 'remove_location' +'person' => $guuid +'address' => $gduid +'pass' => me_encrypt($pass) +} + +Returns: + +{ +'success' => 'true' +'message' => 'OK' +} + + +------------ +Make friends +------------ +This message may be reversed/repeated by the destination site to confirm. +flags is the desired friendship bits. The same message may be used with different flags +to edit or remove a relationship. + + +POST https://example.com/post + +{ +'type' => 'contact' +'person' => $gduid +'address' => $guuid +'target' => 'bobjones@example.com' +'flags' => HIDDEN=0,FOLLOW=1,SHARE=1,NOHIDDEN=1,NOFOLLOW=0,NOSHARE=0 +'confirm' => me_encrypt($guuid . '.' . $pass) +} + +Returns: + +{ +'success' => 'true' +'message' => 'OK' +'flags' => PENDING=1 +} + + + + + + + +------- +Message +------- + +Passing messages is done asynchronously. This may (potentially) relieve a lot of the burden of distribution from the posting site. If you're on site 'A' and make a post, site 'A' just contacts any downstream sites and informs them that there is new content (via a $post_id). The downstream site initiates the actual data transfer. + + + + + +POST https://example.com/post + +{ +'type' => 'post' +'person' => $guuid +'address' => $gduid +'post' => $post_id +} + +Returns: +{ +'success' => 'true' +'message' => 'OK' +} + + +-------- +Callback +-------- + +POST https://macgirvin.com/post + +{ +'type' => 'retrieve' +'retrieve' => $post_id +'challenge' => you_encrypt('abc123') +'verify' => me_encrypt('xyz456' . '.' . $gduid) +} + +Returns: + +{ +'success' => 'true' +'message' => 'OK' +'response' => 'abc123' +'data' => encrypted or raw structured post +} + + diff --git a/util/messages.po b/util/messages.po index 1a30447b9..416e30ef8 100644 --- a/util/messages.po +++ b/util/messages.po @@ -6,9 +6,9 @@ #, fuzzy msgid "" msgstr "" -"Project-Id-Version: 3.0.1370\n" +"Project-Id-Version: 3.0.1382\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2012-06-10 10:00-0700\n" +"POT-Creation-Date: 2012-06-22 10:00-0700\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -36,7 +36,7 @@ msgstr "" #: ../../mod/crepair.php:115 ../../mod/wall_attach.php:44 #: ../../mod/fsuggest.php:78 ../../mod/events.php:138 ../../mod/api.php:26 -#: ../../mod/api.php:31 ../../mod/photos.php:133 ../../mod/photos.php:928 +#: ../../mod/api.php:31 ../../mod/photos.php:133 ../../mod/photos.php:931 #: ../../mod/editpost.php:10 ../../mod/install.php:151 #: ../../mod/notifications.php:66 ../../mod/contacts.php:145 #: ../../mod/settings.php:106 ../../mod/settings.php:537 @@ -54,9 +54,9 @@ msgstr "" #: ../../mod/follow.php:9 ../../mod/display.php:138 ../../mod/profiles.php:7 #: ../../mod/profiles.php:385 ../../mod/delegate.php:6 #: ../../mod/suggest.php:28 ../../mod/invite.php:13 ../../mod/invite.php:81 -#: ../../mod/dfrn_confirm.php:53 ../../addon/facebook/facebook.php:503 -#: ../../addon/dav/layout.fnk.php:387 ../../include/items.php:3342 -#: ../../index.php:306 +#: ../../mod/dfrn_confirm.php:53 ../../addon/facebook/facebook.php:507 +#: ../../addon/dav/layout.fnk.php:353 ../../include/items.php:3401 +#: ../../index.php:309 msgid "Permission denied." msgstr "" @@ -123,25 +123,27 @@ msgid "New photo from this URL" msgstr "" #: ../../mod/crepair.php:166 ../../mod/fsuggest.php:107 -#: ../../mod/events.php:428 ../../mod/photos.php:963 ../../mod/photos.php:1021 -#: ../../mod/photos.php:1266 ../../mod/photos.php:1306 -#: ../../mod/photos.php:1346 ../../mod/photos.php:1377 +#: ../../mod/events.php:428 ../../mod/photos.php:966 ../../mod/photos.php:1024 +#: ../../mod/photos.php:1270 ../../mod/photos.php:1310 +#: ../../mod/photos.php:1350 ../../mod/photos.php:1381 #: ../../mod/install.php:246 ../../mod/install.php:284 -#: ../../mod/localtime.php:45 ../../mod/contacts.php:342 +#: ../../mod/localtime.php:45 ../../mod/contacts.php:343 #: ../../mod/settings.php:555 ../../mod/settings.php:701 #: ../../mod/settings.php:762 ../../mod/settings.php:969 -#: ../../mod/manage.php:109 ../../mod/group.php:85 ../../mod/message.php:216 +#: ../../mod/group.php:85 ../../mod/message.php:216 ../../mod/message.php:410 #: ../../mod/admin.php:420 ../../mod/admin.php:656 ../../mod/admin.php:792 #: ../../mod/admin.php:991 ../../mod/admin.php:1078 ../../mod/profiles.php:554 -#: ../../mod/invite.php:119 ../../addon/facebook/facebook.php:605 +#: ../../mod/invite.php:119 ../../addon/facebook/facebook.php:609 #: ../../addon/snautofollow/snautofollow.php:64 #: ../../addon/yourls/yourls.php:76 ../../addon/ljpost/ljpost.php:93 -#: ../../addon/nsfw/nsfw.php:57 ../../addon/planets/planets.php:158 +#: ../../addon/nsfw/nsfw.php:57 ../../addon/page/page.php:164 +#: ../../addon/planets/planets.php:158 #: ../../addon/uhremotestorage/uhremotestorage.php:89 #: ../../addon/randplace/randplace.php:177 ../../addon/dwpost/dwpost.php:93 #: ../../addon/drpost/drpost.php:110 ../../addon/startpage/startpage.php:92 #: ../../addon/geonames/geonames.php:187 ../../addon/oembed.old/oembed.php:41 -#: ../../addon/impressum/impressum.php:82 ../../addon/blockem/blockem.php:57 +#: ../../addon/impressum/impressum.php:82 +#: ../../addon/notimeline/notimeline.php:64 ../../addon/blockem/blockem.php:57 #: ../../addon/qcomment/qcomment.php:61 #: ../../addon/openstreetmap/openstreetmap.php:70 #: ../../addon/libertree/libertree.php:90 ../../addon/mathjax/mathjax.php:42 @@ -173,16 +175,16 @@ msgstr "" msgid "Help:" msgstr "" -#: ../../mod/help.php:34 ../../addon/dav/layout.fnk.php:112 +#: ../../mod/help.php:34 ../../addon/dav/layout.fnk.php:116 #: ../../include/nav.php:86 msgid "Help" msgstr "" -#: ../../mod/help.php:38 ../../index.php:225 +#: ../../mod/help.php:38 ../../index.php:218 msgid "Not Found" msgstr "" -#: ../../mod/help.php:41 ../../index.php:228 +#: ../../mod/help.php:41 ../../index.php:221 msgid "Page not found." msgstr "" @@ -225,7 +227,7 @@ msgid "link to source" msgstr "" #: ../../mod/events.php:324 ../../view/theme/diabook/theme.php:131 -#: ../../include/nav.php:52 ../../boot.php:1525 +#: ../../include/nav.php:52 ../../boot.php:1546 msgid "Events" msgstr "" @@ -233,12 +235,12 @@ msgstr "" msgid "Create New Event" msgstr "" -#: ../../mod/events.php:326 ../../addon/dav/layout.fnk.php:147 +#: ../../mod/events.php:326 ../../addon/dav/layout.fnk.php:154 msgid "Previous" msgstr "" #: ../../mod/events.php:327 ../../mod/install.php:205 -#: ../../addon/dav/layout.fnk.php:150 +#: ../../addon/dav/layout.fnk.php:157 msgid "Next" msgstr "" @@ -276,7 +278,7 @@ msgid "Description:" msgstr "" #: ../../mod/events.php:423 ../../include/event.php:37 -#: ../../include/bb2diaspora.php:265 ../../boot.php:1105 +#: ../../include/bb2diaspora.php:265 ../../boot.php:1126 msgid "Location:" msgstr "" @@ -285,7 +287,7 @@ msgid "Share this event" msgstr "" #: ../../mod/tagrm.php:11 ../../mod/tagrm.php:94 -#: ../../mod/dfrn_request.php:830 ../../mod/settings.php:556 +#: ../../mod/dfrn_request.php:845 ../../mod/settings.php:556 #: ../../mod/settings.php:582 ../../addon/js_upload/js_upload.php:45 msgid "Cancel" msgstr "" @@ -329,7 +331,7 @@ msgid "" "and/or create new posts for you?" msgstr "" -#: ../../mod/api.php:105 ../../mod/dfrn_request.php:818 +#: ../../mod/api.php:105 ../../mod/dfrn_request.php:833 #: ../../mod/settings.php:879 ../../mod/settings.php:885 #: ../../mod/settings.php:893 ../../mod/settings.php:897 #: ../../mod/settings.php:902 ../../mod/settings.php:908 @@ -341,7 +343,7 @@ msgstr "" msgid "Yes" msgstr "" -#: ../../mod/api.php:106 ../../mod/dfrn_request.php:819 +#: ../../mod/api.php:106 ../../mod/dfrn_request.php:834 #: ../../mod/settings.php:879 ../../mod/settings.php:885 #: ../../mod/settings.php:893 ../../mod/settings.php:897 #: ../../mod/settings.php:902 ../../mod/settings.php:908 @@ -353,19 +355,19 @@ msgstr "" msgid "No" msgstr "" -#: ../../mod/photos.php:44 ../../boot.php:1519 +#: ../../mod/photos.php:44 ../../boot.php:1540 msgid "Photo Albums" msgstr "" -#: ../../mod/photos.php:52 ../../mod/photos.php:154 ../../mod/photos.php:942 -#: ../../mod/photos.php:1013 ../../mod/photos.php:1028 -#: ../../mod/photos.php:1455 ../../mod/photos.php:1467 +#: ../../mod/photos.php:52 ../../mod/photos.php:154 ../../mod/photos.php:945 +#: ../../mod/photos.php:1016 ../../mod/photos.php:1031 +#: ../../mod/photos.php:1459 ../../mod/photos.php:1471 #: ../../addon/communityhome/communityhome.php:110 #: ../../view/theme/diabook/theme.php:598 msgid "Contact Photos" msgstr "" -#: ../../mod/photos.php:59 ../../mod/photos.php:1038 ../../mod/photos.php:1505 +#: ../../mod/photos.php:59 ../../mod/photos.php:1041 ../../mod/photos.php:1509 msgid "Upload New Photos" msgstr "" @@ -377,8 +379,8 @@ msgstr "" msgid "Contact information unavailable" msgstr "" -#: ../../mod/photos.php:154 ../../mod/photos.php:656 ../../mod/photos.php:1013 -#: ../../mod/photos.php:1028 ../../mod/profile_photo.php:60 +#: ../../mod/photos.php:154 ../../mod/photos.php:658 ../../mod/photos.php:1016 +#: ../../mod/photos.php:1031 ../../mod/profile_photo.php:60 #: ../../mod/profile_photo.php:67 ../../mod/profile_photo.php:74 #: ../../mod/profile_photo.php:176 ../../mod/profile_photo.php:254 #: ../../mod/profile_photo.php:263 @@ -392,192 +394,196 @@ msgstr "" msgid "Album not found." msgstr "" -#: ../../mod/photos.php:182 ../../mod/photos.php:1022 +#: ../../mod/photos.php:182 ../../mod/photos.php:1025 msgid "Delete Album" msgstr "" -#: ../../mod/photos.php:245 ../../mod/photos.php:1267 +#: ../../mod/photos.php:245 ../../mod/photos.php:1271 msgid "Delete Photo" msgstr "" -#: ../../mod/photos.php:587 +#: ../../mod/photos.php:589 msgid "was tagged in a" msgstr "" -#: ../../mod/photos.php:587 ../../mod/like.php:185 ../../mod/tagger.php:70 +#: ../../mod/photos.php:589 ../../mod/like.php:185 ../../mod/tagger.php:70 #: ../../addon/communityhome/communityhome.php:163 #: ../../view/theme/diabook/theme.php:570 ../../include/text.php:1316 -#: ../../include/diaspora.php:1671 ../../include/conversation.php:53 +#: ../../include/diaspora.php:1709 ../../include/conversation.php:53 #: ../../include/conversation.php:126 msgid "photo" msgstr "" -#: ../../mod/photos.php:587 +#: ../../mod/photos.php:589 msgid "by" msgstr "" -#: ../../mod/photos.php:692 ../../addon/js_upload/js_upload.php:315 +#: ../../mod/photos.php:694 ../../addon/js_upload/js_upload.php:315 msgid "Image exceeds size limit of " msgstr "" -#: ../../mod/photos.php:700 +#: ../../mod/photos.php:702 msgid "Image file is empty." msgstr "" -#: ../../mod/photos.php:714 ../../mod/profile_photo.php:126 +#: ../../mod/photos.php:716 ../../mod/profile_photo.php:126 #: ../../mod/wall_upload.php:86 msgid "Unable to process image." msgstr "" -#: ../../mod/photos.php:734 ../../mod/profile_photo.php:259 +#: ../../mod/photos.php:737 ../../mod/profile_photo.php:259 #: ../../mod/wall_upload.php:105 msgid "Image upload failed." msgstr "" -#: ../../mod/photos.php:820 ../../mod/community.php:16 -#: ../../mod/dfrn_request.php:744 ../../mod/viewcontacts.php:17 +#: ../../mod/photos.php:823 ../../mod/community.php:16 +#: ../../mod/dfrn_request.php:759 ../../mod/viewcontacts.php:17 #: ../../mod/display.php:7 ../../mod/search.php:71 ../../mod/directory.php:29 msgid "Public access denied." msgstr "" -#: ../../mod/photos.php:830 +#: ../../mod/photos.php:833 msgid "No photos selected" msgstr "" -#: ../../mod/photos.php:909 +#: ../../mod/photos.php:912 msgid "Access to this item is restricted." msgstr "" -#: ../../mod/photos.php:970 +#: ../../mod/photos.php:973 msgid "Upload Photos" msgstr "" -#: ../../mod/photos.php:973 ../../mod/photos.php:1017 +#: ../../mod/photos.php:976 ../../mod/photos.php:1020 msgid "New album name: " msgstr "" -#: ../../mod/photos.php:974 +#: ../../mod/photos.php:977 msgid "or existing album name: " msgstr "" -#: ../../mod/photos.php:975 +#: ../../mod/photos.php:978 msgid "Do not show a status post for this upload" msgstr "" -#: ../../mod/photos.php:977 ../../mod/photos.php:1262 +#: ../../mod/photos.php:980 ../../mod/photos.php:1266 msgid "Permissions" msgstr "" -#: ../../mod/photos.php:1032 +#: ../../mod/photos.php:1035 msgid "Edit Album" msgstr "" -#: ../../mod/photos.php:1056 ../../mod/photos.php:1488 +#: ../../mod/photos.php:1059 ../../mod/photos.php:1492 msgid "View Photo" msgstr "" -#: ../../mod/photos.php:1091 +#: ../../mod/photos.php:1094 msgid "Permission denied. Access to this item may be restricted." msgstr "" -#: ../../mod/photos.php:1093 +#: ../../mod/photos.php:1096 msgid "Photo not available" msgstr "" -#: ../../mod/photos.php:1143 +#: ../../mod/photos.php:1146 msgid "View photo" msgstr "" -#: ../../mod/photos.php:1143 +#: ../../mod/photos.php:1146 msgid "Edit photo" msgstr "" -#: ../../mod/photos.php:1144 +#: ../../mod/photos.php:1147 msgid "Use as profile photo" msgstr "" -#: ../../mod/photos.php:1150 ../../include/conversation.php:490 +#: ../../mod/photos.php:1153 ../../include/conversation.php:490 msgid "Private Message" msgstr "" -#: ../../mod/photos.php:1172 +#: ../../mod/photos.php:1175 msgid "View Full Size" msgstr "" -#: ../../mod/photos.php:1240 +#: ../../mod/photos.php:1243 msgid "Tags: " msgstr "" -#: ../../mod/photos.php:1243 +#: ../../mod/photos.php:1246 msgid "[Remove any tag]" msgstr "" -#: ../../mod/photos.php:1253 -msgid "Rotate CW" +#: ../../mod/photos.php:1256 +msgid "Rotate CW (right)" msgstr "" -#: ../../mod/photos.php:1255 +#: ../../mod/photos.php:1257 +msgid "Rotate CCW (left)" +msgstr "" + +#: ../../mod/photos.php:1259 msgid "New album name" msgstr "" -#: ../../mod/photos.php:1258 +#: ../../mod/photos.php:1262 msgid "Caption" msgstr "" -#: ../../mod/photos.php:1260 +#: ../../mod/photos.php:1264 msgid "Add a Tag" msgstr "" -#: ../../mod/photos.php:1264 +#: ../../mod/photos.php:1268 msgid "Example: @bob, @Barbara_Jensen, @jim@example.com, #California, #camping" msgstr "" -#: ../../mod/photos.php:1284 ../../include/conversation.php:554 +#: ../../mod/photos.php:1288 ../../include/conversation.php:554 msgid "I like this (toggle)" msgstr "" -#: ../../mod/photos.php:1285 ../../include/conversation.php:555 +#: ../../mod/photos.php:1289 ../../include/conversation.php:555 msgid "I don't like this (toggle)" msgstr "" -#: ../../mod/photos.php:1286 ../../include/conversation.php:989 +#: ../../mod/photos.php:1290 ../../include/conversation.php:989 msgid "Share" msgstr "" -#: ../../mod/photos.php:1287 ../../mod/editpost.php:104 +#: ../../mod/photos.php:1291 ../../mod/editpost.php:104 #: ../../mod/wallmessage.php:145 ../../mod/message.php:215 -#: ../../mod/message.php:410 ../../include/conversation.php:371 +#: ../../mod/message.php:411 ../../include/conversation.php:371 #: ../../include/conversation.php:731 ../../include/conversation.php:1008 msgid "Please wait" msgstr "" -#: ../../mod/photos.php:1303 ../../mod/photos.php:1343 -#: ../../mod/photos.php:1374 ../../include/conversation.php:577 +#: ../../mod/photos.php:1307 ../../mod/photos.php:1347 +#: ../../mod/photos.php:1378 ../../include/conversation.php:577 msgid "This is you" msgstr "" -#: ../../mod/photos.php:1305 ../../mod/photos.php:1345 -#: ../../mod/photos.php:1376 ../../include/conversation.php:579 -#: ../../boot.php:519 +#: ../../mod/photos.php:1309 ../../mod/photos.php:1349 +#: ../../mod/photos.php:1380 ../../include/conversation.php:579 +#: ../../boot.php:518 msgid "Comment" msgstr "" -#: ../../mod/photos.php:1307 ../../mod/editpost.php:125 +#: ../../mod/photos.php:1311 ../../mod/editpost.php:125 #: ../../include/conversation.php:589 ../../include/conversation.php:1026 msgid "Preview" msgstr "" -#: ../../mod/photos.php:1404 ../../mod/settings.php:618 +#: ../../mod/photos.php:1408 ../../mod/settings.php:618 #: ../../mod/settings.php:699 ../../mod/group.php:168 ../../mod/admin.php:663 #: ../../include/conversation.php:328 ../../include/conversation.php:609 msgid "Delete" msgstr "" -#: ../../mod/photos.php:1494 +#: ../../mod/photos.php:1498 msgid "View Album" msgstr "" -#: ../../mod/photos.php:1503 +#: ../../mod/photos.php:1507 msgid "Recent Photos" msgstr "" @@ -707,19 +713,19 @@ msgstr "" msgid "This introduction has already been accepted." msgstr "" -#: ../../mod/dfrn_request.php:118 ../../mod/dfrn_request.php:497 +#: ../../mod/dfrn_request.php:118 ../../mod/dfrn_request.php:512 msgid "Profile location is not valid or does not contain profile information." msgstr "" -#: ../../mod/dfrn_request.php:123 ../../mod/dfrn_request.php:502 +#: ../../mod/dfrn_request.php:123 ../../mod/dfrn_request.php:517 msgid "Warning: profile location has no identifiable owner name." msgstr "" -#: ../../mod/dfrn_request.php:125 ../../mod/dfrn_request.php:504 +#: ../../mod/dfrn_request.php:125 ../../mod/dfrn_request.php:519 msgid "Warning: profile location has no profile photo." msgstr "" -#: ../../mod/dfrn_request.php:128 ../../mod/dfrn_request.php:507 +#: ../../mod/dfrn_request.php:128 ../../mod/dfrn_request.php:522 #, php-format msgid "%d required parameter was not found at the given location" msgid_plural "%d required parameters were not found at the given location" @@ -730,165 +736,165 @@ msgstr[1] "" msgid "Introduction complete." msgstr "" -#: ../../mod/dfrn_request.php:194 +#: ../../mod/dfrn_request.php:209 msgid "Unrecoverable protocol error." msgstr "" -#: ../../mod/dfrn_request.php:222 +#: ../../mod/dfrn_request.php:237 msgid "Profile unavailable." msgstr "" -#: ../../mod/dfrn_request.php:247 +#: ../../mod/dfrn_request.php:262 #, php-format msgid "%s has received too many connection requests today." msgstr "" -#: ../../mod/dfrn_request.php:248 +#: ../../mod/dfrn_request.php:263 msgid "Spam protection measures have been invoked." msgstr "" -#: ../../mod/dfrn_request.php:249 +#: ../../mod/dfrn_request.php:264 msgid "Friends are advised to please try again in 24 hours." msgstr "" -#: ../../mod/dfrn_request.php:311 +#: ../../mod/dfrn_request.php:326 msgid "Invalid locator" msgstr "" -#: ../../mod/dfrn_request.php:320 +#: ../../mod/dfrn_request.php:335 msgid "Invalid email address." msgstr "" -#: ../../mod/dfrn_request.php:346 +#: ../../mod/dfrn_request.php:361 msgid "This account has not been configured for email. Request failed." msgstr "" -#: ../../mod/dfrn_request.php:442 +#: ../../mod/dfrn_request.php:457 msgid "Unable to resolve your name at the provided location." msgstr "" -#: ../../mod/dfrn_request.php:455 +#: ../../mod/dfrn_request.php:470 msgid "You have already introduced yourself here." msgstr "" -#: ../../mod/dfrn_request.php:459 +#: ../../mod/dfrn_request.php:474 #, php-format msgid "Apparently you are already friends with %s." msgstr "" -#: ../../mod/dfrn_request.php:480 +#: ../../mod/dfrn_request.php:495 msgid "Invalid profile URL." msgstr "" -#: ../../mod/dfrn_request.php:486 ../../include/follow.php:27 +#: ../../mod/dfrn_request.php:501 ../../include/follow.php:27 msgid "Disallowed profile URL." msgstr "" -#: ../../mod/dfrn_request.php:555 ../../mod/contacts.php:122 +#: ../../mod/dfrn_request.php:570 ../../mod/contacts.php:122 msgid "Failed to update contact record." msgstr "" -#: ../../mod/dfrn_request.php:576 +#: ../../mod/dfrn_request.php:591 msgid "Your introduction has been sent." msgstr "" -#: ../../mod/dfrn_request.php:629 +#: ../../mod/dfrn_request.php:644 msgid "Please login to confirm introduction." msgstr "" -#: ../../mod/dfrn_request.php:643 +#: ../../mod/dfrn_request.php:658 msgid "" "Incorrect identity currently logged in. Please login to this profile." msgstr "" -#: ../../mod/dfrn_request.php:654 +#: ../../mod/dfrn_request.php:669 msgid "Hide this contact" msgstr "" -#: ../../mod/dfrn_request.php:657 +#: ../../mod/dfrn_request.php:672 #, php-format msgid "Welcome home %s." msgstr "" -#: ../../mod/dfrn_request.php:658 +#: ../../mod/dfrn_request.php:673 #, php-format msgid "Please confirm your introduction/connection request to %s." msgstr "" -#: ../../mod/dfrn_request.php:659 +#: ../../mod/dfrn_request.php:674 msgid "Confirm" msgstr "" -#: ../../mod/dfrn_request.php:700 ../../include/items.php:2738 +#: ../../mod/dfrn_request.php:715 ../../include/items.php:2797 msgid "[Name Withheld]" msgstr "" -#: ../../mod/dfrn_request.php:793 +#: ../../mod/dfrn_request.php:808 msgid "" "Please enter your 'Identity Address' from one of the following supported " "communications networks:" msgstr "" -#: ../../mod/dfrn_request.php:809 +#: ../../mod/dfrn_request.php:824 msgid "Connect as an email follower (Coming soon)" msgstr "" -#: ../../mod/dfrn_request.php:811 +#: ../../mod/dfrn_request.php:826 msgid "" "If you are not yet a member of the free social web, follow this link to find a public Friendica site " "and join us today." msgstr "" -#: ../../mod/dfrn_request.php:814 +#: ../../mod/dfrn_request.php:829 msgid "Friend/Connection Request" msgstr "" -#: ../../mod/dfrn_request.php:815 +#: ../../mod/dfrn_request.php:830 msgid "" "Examples: jojo@demo.friendica.com, http://demo.friendica.com/profile/jojo, " "testuser@identi.ca" msgstr "" -#: ../../mod/dfrn_request.php:816 +#: ../../mod/dfrn_request.php:831 msgid "Please answer the following:" msgstr "" -#: ../../mod/dfrn_request.php:817 +#: ../../mod/dfrn_request.php:832 #, php-format msgid "Does %s know you?" msgstr "" -#: ../../mod/dfrn_request.php:820 +#: ../../mod/dfrn_request.php:835 msgid "Add a personal note:" msgstr "" -#: ../../mod/dfrn_request.php:822 ../../include/contact_selectors.php:76 +#: ../../mod/dfrn_request.php:837 ../../include/contact_selectors.php:76 msgid "Friendica" msgstr "" -#: ../../mod/dfrn_request.php:823 +#: ../../mod/dfrn_request.php:838 msgid "StatusNet/Federated Social Web" msgstr "" -#: ../../mod/dfrn_request.php:824 ../../mod/settings.php:652 +#: ../../mod/dfrn_request.php:839 ../../mod/settings.php:652 #: ../../include/contact_selectors.php:80 msgid "Diaspora" msgstr "" -#: ../../mod/dfrn_request.php:825 +#: ../../mod/dfrn_request.php:840 #, php-format msgid "" " - please do not use this form. Instead, enter %s into your Diaspora search " "bar." msgstr "" -#: ../../mod/dfrn_request.php:826 +#: ../../mod/dfrn_request.php:841 msgid "Your Identity Address:" msgstr "" -#: ../../mod/dfrn_request.php:829 +#: ../../mod/dfrn_request.php:844 msgid "Submit Request" msgstr "" @@ -1192,7 +1198,7 @@ msgid "is interested in:" msgstr "" #: ../../mod/match.php:58 ../../mod/suggest.php:59 -#: ../../include/contact_widgets.php:9 ../../boot.php:1049 +#: ../../include/contact_widgets.php:9 ../../boot.php:1070 msgid "Connect" msgstr "" @@ -1224,7 +1230,7 @@ msgstr "" #: ../../mod/notifications.php:51 ../../mod/notifications.php:160 #: ../../mod/notifications.php:206 ../../mod/contacts.php:316 -#: ../../mod/contacts.php:368 +#: ../../mod/contacts.php:370 msgid "Ignore" msgstr "" @@ -1236,7 +1242,7 @@ msgstr "" msgid "Network" msgstr "" -#: ../../mod/notifications.php:85 ../../mod/network.php:188 +#: ../../mod/notifications.php:85 ../../mod/network.php:300 msgid "Personal" msgstr "" @@ -1276,7 +1282,7 @@ msgid "suggested by %s" msgstr "" #: ../../mod/notifications.php:153 ../../mod/notifications.php:200 -#: ../../mod/contacts.php:374 +#: ../../mod/contacts.php:376 msgid "Hide this contact from others" msgstr "" @@ -1489,12 +1495,12 @@ msgstr[1] "" msgid "View all contacts" msgstr "" -#: ../../mod/contacts.php:310 ../../mod/contacts.php:367 +#: ../../mod/contacts.php:310 ../../mod/contacts.php:369 #: ../../mod/admin.php:665 msgid "Unblock" msgstr "" -#: ../../mod/contacts.php:310 ../../mod/contacts.php:367 +#: ../../mod/contacts.php:310 ../../mod/contacts.php:369 #: ../../mod/admin.php:664 msgid "Block" msgstr "" @@ -1503,7 +1509,7 @@ msgstr "" msgid "Toggle Blocked status" msgstr "" -#: ../../mod/contacts.php:316 ../../mod/contacts.php:368 +#: ../../mod/contacts.php:316 ../../mod/contacts.php:370 msgid "Unignore" msgstr "" @@ -1531,170 +1537,174 @@ msgstr "" msgid "Advanced Contact Settings" msgstr "" -#: ../../mod/contacts.php:340 +#: ../../mod/contacts.php:338 +msgid "Communications lost with this contact!" +msgstr "" + +#: ../../mod/contacts.php:341 msgid "Contact Editor" msgstr "" -#: ../../mod/contacts.php:343 +#: ../../mod/contacts.php:344 msgid "Profile Visibility" msgstr "" -#: ../../mod/contacts.php:344 +#: ../../mod/contacts.php:345 #, php-format msgid "" "Please choose the profile you would like to display to %s when viewing your " "profile securely." msgstr "" -#: ../../mod/contacts.php:345 +#: ../../mod/contacts.php:346 msgid "Contact Information / Notes" msgstr "" -#: ../../mod/contacts.php:346 +#: ../../mod/contacts.php:347 msgid "Edit contact notes" msgstr "" -#: ../../mod/contacts.php:351 ../../mod/contacts.php:542 +#: ../../mod/contacts.php:352 ../../mod/contacts.php:544 #: ../../mod/viewcontacts.php:62 ../../mod/nogroup.php:40 #, php-format msgid "Visit %s's profile [%s]" msgstr "" -#: ../../mod/contacts.php:352 +#: ../../mod/contacts.php:353 msgid "Block/Unblock contact" msgstr "" -#: ../../mod/contacts.php:353 +#: ../../mod/contacts.php:354 msgid "Ignore contact" msgstr "" -#: ../../mod/contacts.php:354 +#: ../../mod/contacts.php:355 msgid "Repair URL settings" msgstr "" -#: ../../mod/contacts.php:355 +#: ../../mod/contacts.php:356 msgid "View conversations" msgstr "" -#: ../../mod/contacts.php:357 +#: ../../mod/contacts.php:358 msgid "Delete contact" msgstr "" -#: ../../mod/contacts.php:361 +#: ../../mod/contacts.php:362 msgid "Last update:" msgstr "" -#: ../../mod/contacts.php:362 +#: ../../mod/contacts.php:364 msgid "Update public posts" msgstr "" -#: ../../mod/contacts.php:364 ../../mod/admin.php:1136 +#: ../../mod/contacts.php:366 ../../mod/admin.php:1136 msgid "Update now" msgstr "" -#: ../../mod/contacts.php:371 +#: ../../mod/contacts.php:373 msgid "Currently blocked" msgstr "" -#: ../../mod/contacts.php:372 +#: ../../mod/contacts.php:374 msgid "Currently ignored" msgstr "" -#: ../../mod/contacts.php:373 +#: ../../mod/contacts.php:375 msgid "Currently archived" msgstr "" -#: ../../mod/contacts.php:374 +#: ../../mod/contacts.php:376 msgid "" "Replies/likes to your public posts may still be visible" msgstr "" -#: ../../mod/contacts.php:427 +#: ../../mod/contacts.php:429 msgid "Suggestions" msgstr "" -#: ../../mod/contacts.php:430 +#: ../../mod/contacts.php:432 msgid "Suggest potential friends" msgstr "" -#: ../../mod/contacts.php:433 ../../mod/group.php:191 +#: ../../mod/contacts.php:435 ../../mod/group.php:191 msgid "All Contacts" msgstr "" -#: ../../mod/contacts.php:436 +#: ../../mod/contacts.php:438 msgid "Show all contacts" msgstr "" -#: ../../mod/contacts.php:439 +#: ../../mod/contacts.php:441 msgid "Unblocked" msgstr "" -#: ../../mod/contacts.php:442 +#: ../../mod/contacts.php:444 msgid "Only show unblocked contacts" msgstr "" -#: ../../mod/contacts.php:446 +#: ../../mod/contacts.php:448 msgid "Blocked" msgstr "" -#: ../../mod/contacts.php:449 +#: ../../mod/contacts.php:451 msgid "Only show blocked contacts" msgstr "" -#: ../../mod/contacts.php:453 +#: ../../mod/contacts.php:455 msgid "Ignored" msgstr "" -#: ../../mod/contacts.php:456 +#: ../../mod/contacts.php:458 msgid "Only show ignored contacts" msgstr "" -#: ../../mod/contacts.php:460 +#: ../../mod/contacts.php:462 msgid "Archived" msgstr "" -#: ../../mod/contacts.php:463 +#: ../../mod/contacts.php:465 msgid "Only show archived contacts" msgstr "" -#: ../../mod/contacts.php:467 +#: ../../mod/contacts.php:469 msgid "Hidden" msgstr "" -#: ../../mod/contacts.php:470 +#: ../../mod/contacts.php:472 msgid "Only show hidden contacts" msgstr "" -#: ../../mod/contacts.php:518 +#: ../../mod/contacts.php:520 msgid "Mutual Friendship" msgstr "" -#: ../../mod/contacts.php:522 +#: ../../mod/contacts.php:524 msgid "is a fan of yours" msgstr "" -#: ../../mod/contacts.php:526 +#: ../../mod/contacts.php:528 msgid "you are a fan of" msgstr "" -#: ../../mod/contacts.php:543 ../../mod/nogroup.php:41 +#: ../../mod/contacts.php:545 ../../mod/nogroup.php:41 msgid "Edit contact" msgstr "" -#: ../../mod/contacts.php:564 ../../view/theme/diabook/theme.php:129 +#: ../../mod/contacts.php:566 ../../view/theme/diabook/theme.php:129 #: ../../include/nav.php:139 msgid "Contacts" msgstr "" -#: ../../mod/contacts.php:568 +#: ../../mod/contacts.php:570 msgid "Search your contacts" msgstr "" -#: ../../mod/contacts.php:569 ../../mod/directory.php:57 +#: ../../mod/contacts.php:571 ../../mod/directory.php:57 msgid "Finding: " msgstr "" -#: ../../mod/contacts.php:570 ../../mod/directory.php:59 +#: ../../mod/contacts.php:572 ../../mod/directory.php:59 #: ../../include/contact_widgets.php:33 msgid "Find" msgstr "" @@ -1715,11 +1725,11 @@ msgstr "" #: ../../mod/lostpass.php:45 ../../mod/lostpass.php:107 #: ../../mod/register.php:90 ../../mod/register.php:144 #: ../../mod/regmod.php:54 ../../mod/dfrn_confirm.php:752 -#: ../../addon/facebook/facebook.php:688 -#: ../../addon/facebook/facebook.php:1178 +#: ../../addon/facebook/facebook.php:692 +#: ../../addon/facebook/facebook.php:1182 #: ../../addon/public_server/public_server.php:62 -#: ../../addon/testdrive/testdrive.php:67 ../../include/items.php:2747 -#: ../../boot.php:699 +#: ../../addon/testdrive/testdrive.php:67 ../../include/items.php:2806 +#: ../../boot.php:720 msgid "Administrator" msgstr "" @@ -1729,7 +1739,7 @@ msgid "" "Password reset failed." msgstr "" -#: ../../mod/lostpass.php:83 ../../boot.php:831 +#: ../../mod/lostpass.php:83 ../../boot.php:852 msgid "Password Reset" msgstr "" @@ -1802,7 +1812,7 @@ msgid "Remove account" msgstr "" #: ../../mod/settings.php:89 ../../mod/admin.php:751 ../../mod/admin.php:956 -#: ../../addon/dav/layout.fnk.php:112 ../../addon/mathjax/mathjax.php:36 +#: ../../addon/dav/layout.fnk.php:116 ../../addon/mathjax/mathjax.php:36 #: ../../view/theme/diabook/theme.php:643 #: ../../view/theme/diabook/theme.php:773 ../../include/nav.php:137 msgid "Settings" @@ -1864,7 +1874,7 @@ msgstr "" msgid "Private forum has no privacy permissions and no default privacy group." msgstr "" -#: ../../mod/settings.php:484 ../../addon/facebook/facebook.php:488 +#: ../../mod/settings.php:484 ../../addon/facebook/facebook.php:492 #: ../../addon/impressum/impressum.php:77 #: ../../addon/openstreetmap/openstreetmap.php:80 #: ../../addon/mathjax/mathjax.php:66 ../../addon/piwik/piwik.php:105 @@ -2308,67 +2318,67 @@ msgstr "" msgid "Select an identity to manage: " msgstr "" -#: ../../mod/network.php:43 +#: ../../mod/network.php:97 msgid "Search Results For:" msgstr "" -#: ../../mod/network.php:82 ../../mod/search.php:16 +#: ../../mod/network.php:137 ../../mod/search.php:16 msgid "Remove term" msgstr "" -#: ../../mod/network.php:91 ../../mod/search.php:13 +#: ../../mod/network.php:146 ../../mod/search.php:13 msgid "Saved Searches" msgstr "" -#: ../../mod/network.php:92 ../../include/group.php:244 +#: ../../mod/network.php:147 ../../include/group.php:244 msgid "add" msgstr "" -#: ../../mod/network.php:175 +#: ../../mod/network.php:287 msgid "Commented Order" msgstr "" -#: ../../mod/network.php:178 +#: ../../mod/network.php:290 msgid "Sort by Comment Date" msgstr "" -#: ../../mod/network.php:181 +#: ../../mod/network.php:293 msgid "Posted Order" msgstr "" -#: ../../mod/network.php:184 +#: ../../mod/network.php:296 msgid "Sort by Post Date" msgstr "" -#: ../../mod/network.php:191 +#: ../../mod/network.php:303 msgid "Posts that mention or involve you" msgstr "" -#: ../../mod/network.php:194 +#: ../../mod/network.php:306 msgid "New" msgstr "" -#: ../../mod/network.php:197 +#: ../../mod/network.php:309 msgid "Activity Stream - by date" msgstr "" -#: ../../mod/network.php:200 +#: ../../mod/network.php:312 msgid "Starred" msgstr "" -#: ../../mod/network.php:203 +#: ../../mod/network.php:315 msgid "Favourite Posts" msgstr "" -#: ../../mod/network.php:206 +#: ../../mod/network.php:318 msgid "Shared Links" msgstr "" -#: ../../mod/network.php:209 +#: ../../mod/network.php:321 msgid "Interesting Links" msgstr "" -#: ../../mod/network.php:285 +#: ../../mod/network.php:388 #, php-format msgid "Warning: This group contains %s member from an insecure network." msgid_plural "" @@ -2376,42 +2386,42 @@ msgid_plural "" msgstr[0] "" msgstr[1] "" -#: ../../mod/network.php:288 +#: ../../mod/network.php:391 msgid "Private messages to this group are at risk of public disclosure." msgstr "" -#: ../../mod/network.php:333 +#: ../../mod/network.php:436 msgid "No such group" msgstr "" -#: ../../mod/network.php:344 +#: ../../mod/network.php:447 msgid "Group is empty" msgstr "" -#: ../../mod/network.php:348 +#: ../../mod/network.php:451 msgid "Group: " msgstr "" -#: ../../mod/network.php:358 +#: ../../mod/network.php:461 msgid "Contact: " msgstr "" -#: ../../mod/network.php:360 +#: ../../mod/network.php:463 msgid "Private messages to this person are at risk of public disclosure." msgstr "" -#: ../../mod/network.php:365 +#: ../../mod/network.php:468 msgid "Invalid contact." msgstr "" -#: ../../mod/notes.php:44 ../../boot.php:1531 +#: ../../mod/notes.php:44 ../../boot.php:1552 msgid "Personal Notes" msgstr "" #: ../../mod/notes.php:63 ../../mod/filer.php:30 -#: ../../addon/facebook/facebook.php:756 +#: ../../addon/facebook/facebook.php:760 #: ../../addon/privacy_image_cache/privacy_image_cache.php:185 -#: ../../addon/dav/layout.fnk.php:418 ../../include/text.php:652 +#: ../../addon/dav/layout.fnk.php:384 ../../include/text.php:652 msgid "Save" msgstr "" @@ -2613,7 +2623,7 @@ msgstr "" msgid "Group name changed." msgstr "" -#: ../../mod/group.php:72 ../../mod/profperm.php:19 ../../index.php:305 +#: ../../mod/group.php:72 ../../mod/profperm.php:19 ../../index.php:308 msgid "Permission denied" msgstr "" @@ -2655,7 +2665,7 @@ msgstr "" #: ../../mod/profperm.php:103 ../../view/theme/diabook/theme.php:128 #: ../../include/profile_advanced.php:7 ../../include/profile_advanced.php:79 -#: ../../include/nav.php:50 ../../boot.php:1510 +#: ../../include/nav.php:50 ../../boot.php:1531 msgid "Profile" msgstr "" @@ -2759,7 +2769,7 @@ msgstr "" msgid "Choose a nickname: " msgstr "" -#: ../../mod/register.php:269 ../../include/nav.php:81 ../../boot.php:797 +#: ../../mod/register.php:269 ../../include/nav.php:81 ../../boot.php:818 msgid "Register" msgstr "" @@ -2768,19 +2778,19 @@ msgid "People Search" msgstr "" #: ../../mod/like.php:185 ../../mod/like.php:259 ../../mod/tagger.php:70 -#: ../../addon/facebook/facebook.php:1572 +#: ../../addon/facebook/facebook.php:1576 #: ../../addon/communityhome/communityhome.php:158 #: ../../addon/communityhome/communityhome.php:167 #: ../../view/theme/diabook/theme.php:565 -#: ../../view/theme/diabook/theme.php:574 ../../include/diaspora.php:1671 +#: ../../view/theme/diabook/theme.php:574 ../../include/diaspora.php:1709 #: ../../include/conversation.php:48 ../../include/conversation.php:57 #: ../../include/conversation.php:121 ../../include/conversation.php:130 msgid "status" msgstr "" -#: ../../mod/like.php:202 ../../addon/facebook/facebook.php:1576 +#: ../../mod/like.php:202 ../../addon/facebook/facebook.php:1580 #: ../../addon/communityhome/communityhome.php:172 -#: ../../view/theme/diabook/theme.php:579 ../../include/diaspora.php:1687 +#: ../../view/theme/diabook/theme.php:579 ../../include/diaspora.php:1725 #: ../../include/conversation.php:65 #, php-format msgid "%1$s likes %2$s's %3$s" @@ -2793,7 +2803,7 @@ msgstr "" #: ../../mod/notice.php:15 ../../mod/viewsrc.php:15 ../../mod/admin.php:159 #: ../../mod/admin.php:700 ../../mod/admin.php:899 ../../mod/display.php:37 -#: ../../mod/display.php:142 ../../include/items.php:3189 +#: ../../mod/display.php:142 ../../include/items.php:3248 msgid "Item not found." msgstr "" @@ -2802,7 +2812,7 @@ msgid "Access denied." msgstr "" #: ../../mod/fbrowser.php:25 ../../view/theme/diabook/theme.php:130 -#: ../../include/nav.php:51 ../../boot.php:1516 +#: ../../include/nav.php:51 ../../boot.php:1537 msgid "Photos" msgstr "" @@ -3605,15 +3615,15 @@ msgstr "" msgid "FTP Password" msgstr "" -#: ../../mod/profile.php:21 ../../boot.php:962 +#: ../../mod/profile.php:21 ../../boot.php:983 msgid "Requested profile is not available." msgstr "" -#: ../../mod/profile.php:126 ../../mod/display.php:75 +#: ../../mod/profile.php:141 ../../mod/display.php:75 msgid "Access to this profile has been restricted." msgstr "" -#: ../../mod/profile.php:151 +#: ../../mod/profile.php:166 msgid "Tips for New Members" msgstr "" @@ -3758,7 +3768,7 @@ msgstr "" msgid "Address" msgstr "" -#: ../../mod/profiles.php:194 +#: ../../mod/profiles.php:194 ../../addon/dav/layout.fnk.php:310 msgid "Location" msgstr "" @@ -3980,23 +3990,23 @@ msgstr "" msgid "Edit/Manage Profiles" msgstr "" -#: ../../mod/profiles.php:645 ../../boot.php:1071 +#: ../../mod/profiles.php:645 ../../boot.php:1092 msgid "Change profile photo" msgstr "" -#: ../../mod/profiles.php:646 ../../boot.php:1072 +#: ../../mod/profiles.php:646 ../../boot.php:1093 msgid "Create New Profile" msgstr "" -#: ../../mod/profiles.php:657 ../../boot.php:1082 +#: ../../mod/profiles.php:657 ../../boot.php:1103 msgid "Profile Image" msgstr "" -#: ../../mod/profiles.php:659 ../../boot.php:1085 +#: ../../mod/profiles.php:659 ../../boot.php:1106 msgid "visible to everybody" msgstr "" -#: ../../mod/profiles.php:660 ../../boot.php:1086 +#: ../../mod/profiles.php:660 ../../boot.php:1107 msgid "Edit visibility" msgstr "" @@ -4254,83 +4264,83 @@ msgstr "" msgid "%1$s has joined %2$s" msgstr "" -#: ../../addon/facebook/facebook.php:509 +#: ../../addon/facebook/facebook.php:513 msgid "Facebook disabled" msgstr "" -#: ../../addon/facebook/facebook.php:514 +#: ../../addon/facebook/facebook.php:518 msgid "Updating contacts" msgstr "" -#: ../../addon/facebook/facebook.php:537 +#: ../../addon/facebook/facebook.php:541 msgid "Facebook API key is missing." msgstr "" -#: ../../addon/facebook/facebook.php:544 +#: ../../addon/facebook/facebook.php:548 msgid "Facebook Connect" msgstr "" -#: ../../addon/facebook/facebook.php:550 +#: ../../addon/facebook/facebook.php:554 msgid "Install Facebook connector for this account." msgstr "" -#: ../../addon/facebook/facebook.php:557 +#: ../../addon/facebook/facebook.php:561 msgid "Remove Facebook connector" msgstr "" -#: ../../addon/facebook/facebook.php:562 +#: ../../addon/facebook/facebook.php:566 msgid "" "Re-authenticate [This is necessary whenever your Facebook password is " "changed.]" msgstr "" -#: ../../addon/facebook/facebook.php:569 +#: ../../addon/facebook/facebook.php:573 msgid "Post to Facebook by default" msgstr "" -#: ../../addon/facebook/facebook.php:575 +#: ../../addon/facebook/facebook.php:579 msgid "" "Facebook friend linking has been disabled on this site. The following " "settings will have no effect." msgstr "" -#: ../../addon/facebook/facebook.php:579 +#: ../../addon/facebook/facebook.php:583 msgid "" "Facebook friend linking has been disabled on this site. If you disable it, " "you will be unable to re-enable it." msgstr "" -#: ../../addon/facebook/facebook.php:582 +#: ../../addon/facebook/facebook.php:586 msgid "Link all your Facebook friends and conversations on this website" msgstr "" -#: ../../addon/facebook/facebook.php:584 +#: ../../addon/facebook/facebook.php:588 msgid "" "Facebook conversations consist of your profile wall and your friend " "stream." msgstr "" -#: ../../addon/facebook/facebook.php:585 +#: ../../addon/facebook/facebook.php:589 msgid "On this website, your Facebook friend stream is only visible to you." msgstr "" -#: ../../addon/facebook/facebook.php:586 +#: ../../addon/facebook/facebook.php:590 msgid "" "The following settings determine the privacy of your Facebook profile wall " "on this website." msgstr "" -#: ../../addon/facebook/facebook.php:590 +#: ../../addon/facebook/facebook.php:594 msgid "" "On this website your Facebook profile wall conversations will only be " "visible to you" msgstr "" -#: ../../addon/facebook/facebook.php:595 +#: ../../addon/facebook/facebook.php:599 msgid "Do not import your Facebook profile wall conversations" msgstr "" -#: ../../addon/facebook/facebook.php:597 +#: ../../addon/facebook/facebook.php:601 msgid "" "If you choose to link conversations and leave both of these boxes unchecked, " "your Facebook profile wall will be merged with your profile wall on this " @@ -4338,120 +4348,120 @@ msgid "" "who may see the conversations." msgstr "" -#: ../../addon/facebook/facebook.php:602 +#: ../../addon/facebook/facebook.php:606 msgid "Comma separated applications to ignore" msgstr "" -#: ../../addon/facebook/facebook.php:686 +#: ../../addon/facebook/facebook.php:690 msgid "Problems with Facebook Real-Time Updates" msgstr "" -#: ../../addon/facebook/facebook.php:714 +#: ../../addon/facebook/facebook.php:718 #: ../../include/contact_selectors.php:81 msgid "Facebook" msgstr "" -#: ../../addon/facebook/facebook.php:715 +#: ../../addon/facebook/facebook.php:719 msgid "Facebook Connector Settings" msgstr "" -#: ../../addon/facebook/facebook.php:730 +#: ../../addon/facebook/facebook.php:734 msgid "Facebook API Key" msgstr "" -#: ../../addon/facebook/facebook.php:740 +#: ../../addon/facebook/facebook.php:744 msgid "" "Error: it appears that you have specified the App-ID and -Secret in your ." "htconfig.php file. As long as they are specified there, they cannot be set " "using this form.

" msgstr "" -#: ../../addon/facebook/facebook.php:745 +#: ../../addon/facebook/facebook.php:749 msgid "" "Error: the given API Key seems to be incorrect (the application access token " "could not be retrieved)." msgstr "" -#: ../../addon/facebook/facebook.php:747 +#: ../../addon/facebook/facebook.php:751 msgid "The given API Key seems to work correctly." msgstr "" -#: ../../addon/facebook/facebook.php:749 +#: ../../addon/facebook/facebook.php:753 msgid "" "The correctness of the API Key could not be detected. Somthing strange's " "going on." msgstr "" -#: ../../addon/facebook/facebook.php:752 +#: ../../addon/facebook/facebook.php:756 msgid "App-ID / API-Key" msgstr "" -#: ../../addon/facebook/facebook.php:753 +#: ../../addon/facebook/facebook.php:757 msgid "Application secret" msgstr "" -#: ../../addon/facebook/facebook.php:754 +#: ../../addon/facebook/facebook.php:758 #, php-format msgid "Polling Interval in minutes (minimum %1$s minutes)" msgstr "" -#: ../../addon/facebook/facebook.php:755 +#: ../../addon/facebook/facebook.php:759 msgid "" "Synchronize comments (no comments on Facebook are missed, at the cost of " "increased system load)" msgstr "" -#: ../../addon/facebook/facebook.php:759 +#: ../../addon/facebook/facebook.php:763 msgid "Real-Time Updates" msgstr "" -#: ../../addon/facebook/facebook.php:763 +#: ../../addon/facebook/facebook.php:767 msgid "Real-Time Updates are activated." msgstr "" -#: ../../addon/facebook/facebook.php:764 +#: ../../addon/facebook/facebook.php:768 msgid "Deactivate Real-Time Updates" msgstr "" -#: ../../addon/facebook/facebook.php:766 +#: ../../addon/facebook/facebook.php:770 msgid "Real-Time Updates not activated." msgstr "" -#: ../../addon/facebook/facebook.php:766 +#: ../../addon/facebook/facebook.php:770 msgid "Activate Real-Time Updates" msgstr "" -#: ../../addon/facebook/facebook.php:785 ../../addon/dav/layout.fnk.php:394 +#: ../../addon/facebook/facebook.php:789 ../../addon/dav/layout.fnk.php:360 msgid "The new values have been saved." msgstr "" -#: ../../addon/facebook/facebook.php:809 +#: ../../addon/facebook/facebook.php:813 msgid "Post to Facebook" msgstr "" -#: ../../addon/facebook/facebook.php:907 +#: ../../addon/facebook/facebook.php:911 msgid "" "Post to Facebook cancelled because of multi-network access permission " "conflict." msgstr "" -#: ../../addon/facebook/facebook.php:1127 +#: ../../addon/facebook/facebook.php:1131 msgid "View on Friendica" msgstr "" -#: ../../addon/facebook/facebook.php:1160 +#: ../../addon/facebook/facebook.php:1164 msgid "Facebook post failed. Queued for retry." msgstr "" -#: ../../addon/facebook/facebook.php:1200 +#: ../../addon/facebook/facebook.php:1204 msgid "Your Facebook connection became invalid. Please Re-authenticate." msgstr "" -#: ../../addon/facebook/facebook.php:1201 +#: ../../addon/facebook/facebook.php:1205 msgid "Facebook connection became invalid" msgstr "" -#: ../../addon/facebook/facebook.php:1202 +#: ../../addon/facebook/facebook.php:1206 #, php-format msgid "" "Hi %1$s,\n" @@ -4610,16 +4620,32 @@ msgstr "" msgid "%s - Click to open/close" msgstr "" -#: ../../addon/page/page.php:48 +#: ../../addon/page/page.php:58 ../../addon/page/page.php:88 msgid "Forums" msgstr "" -#: ../../addon/page/page.php:63 ../../addon/showmore/showmore.php:87 -#: ../../include/contact_widgets.php:188 ../../include/conversation.php:476 -#: ../../boot.php:520 +#: ../../addon/page/page.php:73 ../../addon/page/page.php:107 +#: ../../addon/showmore/showmore.php:87 ../../include/contact_widgets.php:188 +#: ../../include/conversation.php:476 ../../boot.php:519 msgid "show more" msgstr "" +#: ../../addon/page/page.php:125 +msgid "Page settings updated." +msgstr "" + +#: ../../addon/page/page.php:151 +msgid "Page Settings" +msgstr "" + +#: ../../addon/page/page.php:153 +msgid "How many forums to display on sidebar without paging" +msgstr "" + +#: ../../addon/page/page.php:156 +msgid "Randomise Page/Forum list" +msgstr "" + #: ../../addon/planets/planets.php:150 msgid "Planets Settings" msgstr "" @@ -4632,7 +4658,7 @@ msgstr "" #: ../../addon/communityhome/communityhome.php:34 #: ../../addon/communityhome/twillingham/communityhome.php:28 #: ../../addon/communityhome/twillingham/communityhome.php:34 -#: ../../include/nav.php:64 ../../boot.php:818 +#: ../../include/nav.php:64 ../../boot.php:839 msgid "Login" msgstr "" @@ -4673,98 +4699,116 @@ msgstr "" msgid "German Time Format (dd.mm.YYYY)" msgstr "" -#: ../../addon/dav/common/calendar.fnk.php:507 -#: ../../addon/dav/common/calendar.fnk.php:576 -#: ../../addon/dav/common/calendar.fnk.php:603 -#: ../../addon/dav/layout.fnk.php:266 +#: ../../addon/dav/common/calendar.fnk.php:517 +#: ../../addon/dav/common/calendar.fnk.php:533 +#: ../../addon/dav/layout.fnk.php:200 +msgid "Error" +msgstr "" + +#: ../../addon/dav/common/calendar.fnk.php:568 +#: ../../addon/dav/common/calendar.fnk.php:637 +#: ../../addon/dav/common/calendar.fnk.php:664 +#: ../../addon/dav/layout.fnk.php:231 msgid "No access" msgstr "" -#: ../../addon/dav/layout.fnk.php:116 +#: ../../addon/dav/layout.fnk.php:119 +msgid "New event" +msgstr "" + +#: ../../addon/dav/layout.fnk.php:123 msgid "Today" msgstr "" #: ../../addon/dav/layout.fnk.php:132 -msgid "Week" +msgid "Day" msgstr "" #: ../../addon/dav/layout.fnk.php:139 +msgid "Week" +msgstr "" + +#: ../../addon/dav/layout.fnk.php:146 msgid "Month" msgstr "" -#: ../../addon/dav/layout.fnk.php:144 +#: ../../addon/dav/layout.fnk.php:151 msgid "Reload" msgstr "" -#: ../../addon/dav/layout.fnk.php:155 +#: ../../addon/dav/layout.fnk.php:162 msgid "Date" msgstr "" -#: ../../addon/dav/layout.fnk.php:193 ../../addon/dav/layout.fnk.php:237 -msgid "Error" -msgstr "" - -#: ../../addon/dav/layout.fnk.php:259 +#: ../../addon/dav/layout.fnk.php:224 msgid "Not found" msgstr "" -#: ../../addon/dav/layout.fnk.php:326 ../../addon/dav/layout.fnk.php:399 +#: ../../addon/dav/layout.fnk.php:292 ../../addon/dav/layout.fnk.php:365 msgid "Go back to the calendar" msgstr "" -#: ../../addon/dav/layout.fnk.php:346 +#: ../../addon/dav/layout.fnk.php:300 +msgid "Starts" +msgstr "" + +#: ../../addon/dav/layout.fnk.php:305 +msgid "Ends" +msgstr "" + +#: ../../addon/dav/layout.fnk.php:312 msgid "Description" msgstr "" -#: ../../addon/dav/layout.fnk.php:349 +#: ../../addon/dav/layout.fnk.php:315 msgid "Notification" msgstr "" -#: ../../addon/dav/layout.fnk.php:358 +#: ../../addon/dav/layout.fnk.php:324 msgid "Minutes" msgstr "" -#: ../../addon/dav/layout.fnk.php:361 +#: ../../addon/dav/layout.fnk.php:327 msgid "Hours" msgstr "" -#: ../../addon/dav/layout.fnk.php:364 +#: ../../addon/dav/layout.fnk.php:330 msgid "Days" msgstr "" -#: ../../addon/dav/layout.fnk.php:365 +#: ../../addon/dav/layout.fnk.php:331 msgid "before" msgstr "" -#: ../../addon/dav/layout.fnk.php:401 +#: ../../addon/dav/layout.fnk.php:367 msgid "Calendar Settings" msgstr "" -#: ../../addon/dav/layout.fnk.php:407 +#: ../../addon/dav/layout.fnk.php:373 msgid "Date format" msgstr "" -#: ../../addon/dav/layout.fnk.php:416 +#: ../../addon/dav/layout.fnk.php:382 msgid "Time zone" msgstr "" -#: ../../addon/dav/layout.fnk.php:421 +#: ../../addon/dav/layout.fnk.php:387 msgid "Limitations" msgstr "" -#: ../../addon/dav/layout.fnk.php:425 +#: ../../addon/dav/layout.fnk.php:391 msgid "Warning" msgstr "" -#: ../../addon/dav/layout.fnk.php:429 +#: ../../addon/dav/layout.fnk.php:395 msgid "Synchronization (iPhone, Thunderbird Lightning, Android, ...)" msgstr "" -#: ../../addon/dav/layout.fnk.php:436 +#: ../../addon/dav/layout.fnk.php:402 msgid "Synchronizing this calendar with the iPhone" msgstr "" -#: ../../addon/dav/layout.fnk.php:447 +#: ../../addon/dav/layout.fnk.php:413 msgid "Synchronizing your Friendica-Contacts with the iPhone" msgstr "" @@ -4776,71 +4820,71 @@ msgstr "" msgid "Your Friendica-Contacts" msgstr "" -#: ../../addon/dav/main.php:229 +#: ../../addon/dav/main.php:244 msgid "Calendar" msgstr "" -#: ../../addon/dav/main.php:232 +#: ../../addon/dav/main.php:247 msgid "Extended calendar with CalDAV-support" msgstr "" -#: ../../addon/dav/main.php:248 +#: ../../addon/dav/main.php:263 msgid "The database tables have been installed." msgstr "" -#: ../../addon/dav/main.php:249 +#: ../../addon/dav/main.php:264 msgid "An error occurred during the installation." msgstr "" -#: ../../addon/dav/main.php:265 +#: ../../addon/dav/main.php:280 msgid "No system-wide settings yet." msgstr "" -#: ../../addon/dav/main.php:268 +#: ../../addon/dav/main.php:283 msgid "Database status" msgstr "" -#: ../../addon/dav/main.php:271 +#: ../../addon/dav/main.php:286 msgid "Installed" msgstr "" -#: ../../addon/dav/main.php:274 +#: ../../addon/dav/main.php:289 msgid "Upgrade needed" msgstr "" -#: ../../addon/dav/main.php:274 +#: ../../addon/dav/main.php:289 msgid "Upgrade" msgstr "" -#: ../../addon/dav/main.php:277 +#: ../../addon/dav/main.php:292 msgid "Not installed" msgstr "" -#: ../../addon/dav/main.php:277 +#: ../../addon/dav/main.php:292 msgid "Install" msgstr "" -#: ../../addon/dav/main.php:282 +#: ../../addon/dav/main.php:297 msgid "Troubleshooting" msgstr "" -#: ../../addon/dav/main.php:283 +#: ../../addon/dav/main.php:298 msgid "Manual creation of the database tables:" msgstr "" -#: ../../addon/dav/main.php:284 +#: ../../addon/dav/main.php:299 msgid "Show SQL-statements" msgstr "" -#: ../../addon/dav/calendar.friendica.fnk.php:128 +#: ../../addon/dav/calendar.friendica.fnk.php:151 msgid "Private Calendar" msgstr "" -#: ../../addon/dav/calendar.friendica.fnk.php:135 +#: ../../addon/dav/calendar.friendica.fnk.php:158 msgid "Friendica Events: Mine" msgstr "" -#: ../../addon/dav/calendar.friendica.fnk.php:138 +#: ../../addon/dav/calendar.friendica.fnk.php:161 msgid "Friendica Events: Contacts" msgstr "" @@ -5147,6 +5191,18 @@ msgstr "" msgid "Report Bug" msgstr "" +#: ../../addon/notimeline/notimeline.php:32 +msgid "No Timeline settings updated." +msgstr "" + +#: ../../addon/notimeline/notimeline.php:56 +msgid "No Timeline Settings" +msgstr "" + +#: ../../addon/notimeline/notimeline.php:58 +msgid "Disable Archive selector on profile wall" +msgstr "" + #: ../../addon/blockem/blockem.php:51 msgid "\"Blockem\" Settings" msgstr "" @@ -6016,7 +6072,7 @@ msgstr "" msgid "Set colour scheme" msgstr "" -#: ../../include/profile_advanced.php:17 ../../boot.php:1107 +#: ../../include/profile_advanced.php:17 ../../boot.php:1128 msgid "Gender:" msgstr "" @@ -6029,7 +6085,7 @@ msgid "j F" msgstr "" #: ../../include/profile_advanced.php:30 ../../include/datetime.php:450 -#: ../../include/items.php:1428 +#: ../../include/items.php:1460 msgid "Birthday:" msgstr "" @@ -6037,7 +6093,7 @@ msgstr "" msgid "Age:" msgstr "" -#: ../../include/profile_advanced.php:37 ../../boot.php:1110 +#: ../../include/profile_advanced.php:37 ../../boot.php:1131 msgid "Status:" msgstr "" @@ -6046,7 +6102,7 @@ msgstr "" msgid "for %1$d %2$s" msgstr "" -#: ../../include/profile_advanced.php:48 ../../boot.php:1112 +#: ../../include/profile_advanced.php:48 ../../boot.php:1133 msgid "Homepage:" msgstr "" @@ -6419,6 +6475,10 @@ msgstr "" msgid "noreply" msgstr "" +#: ../../include/Scrape.php:572 +msgid " on Last.fm" +msgstr "" + #: ../../include/text.php:243 msgid "prev" msgstr "" @@ -6574,7 +6634,7 @@ msgstr "" msgid "Sharing notification from Diaspora network" msgstr "" -#: ../../include/diaspora.php:2037 +#: ../../include/diaspora.php:2074 msgid "Attachments:" msgstr "" @@ -6625,7 +6685,7 @@ msgstr "" msgid "Contacts not in any group" msgstr "" -#: ../../include/nav.php:46 ../../boot.php:817 +#: ../../include/nav.php:46 ../../boot.php:838 msgid "Logout" msgstr "" @@ -6633,7 +6693,7 @@ msgstr "" msgid "End this session" msgstr "" -#: ../../include/nav.php:49 ../../boot.php:1504 +#: ../../include/nav.php:49 ../../boot.php:1525 msgid "Status" msgstr "" @@ -6713,11 +6773,11 @@ msgstr "" msgid "Manage other pages" msgstr "" -#: ../../include/nav.php:138 ../../boot.php:1065 +#: ../../include/nav.php:138 ../../boot.php:1086 msgid "Profiles" msgstr "" -#: ../../include/nav.php:138 ../../boot.php:1065 +#: ../../include/nav.php:138 ../../boot.php:1086 msgid "Manage/edit profiles" msgstr "" @@ -6879,7 +6939,7 @@ msgstr "" msgid "%1$d %2$s ago" msgstr "" -#: ../../include/onepoll.php:406 +#: ../../include/onepoll.php:399 msgid "From: " msgstr "" @@ -6929,12 +6989,12 @@ msgstr "" #: ../../include/enotify.php:44 #, php-format -msgid "%s sent you a new private message at %s." +msgid "%1$s sent you a new private message at %2$s." msgstr "" #: ../../include/enotify.php:45 #, php-format -msgid "%s sent you %s." +msgid "%1$s sent you %2$s." msgstr "" #: ../../include/enotify.php:45 @@ -6946,148 +7006,129 @@ msgstr "" msgid "Please visit %s to view and/or reply to your private messages." msgstr "" -#: ../../include/enotify.php:76 +#: ../../include/enotify.php:73 #, php-format -msgid "%s's" +msgid "%1$s commented on [url=%2$s]a %3$s[/url]" msgstr "" #: ../../include/enotify.php:80 -msgid "your" -msgstr "" - -#: ../../include/enotify.php:87 #, php-format -msgid "[Friendica:Notify] Comment to conversation #%d by %s" +msgid "%1$s commented on [url=%2$s]%3$s's %4$s[/url]" msgstr "" #: ../../include/enotify.php:88 #, php-format -msgid "%s commented on an item/conversation you have been following." -msgstr "" - -#: ../../include/enotify.php:89 -#, php-format -msgid "%s commented on %s." -msgstr "" - -#: ../../include/enotify.php:91 ../../include/enotify.php:104 -#: ../../include/enotify.php:115 ../../include/enotify.php:126 -#, php-format -msgid "Please visit %s to view and/or reply to the conversation." +msgid "%1$s commented on [url=%2$s]your %3$s[/url]" msgstr "" #: ../../include/enotify.php:98 #, php-format +msgid "[Friendica:Notify] Comment to conversation #%1$d by %2$s" +msgstr "" + +#: ../../include/enotify.php:99 +#, php-format +msgid "%s commented on an item/conversation you have been following." +msgstr "" + +#: ../../include/enotify.php:102 ../../include/enotify.php:117 +#: ../../include/enotify.php:130 ../../include/enotify.php:143 +#, php-format +msgid "Please visit %s to view and/or reply to the conversation." +msgstr "" + +#: ../../include/enotify.php:109 +#, php-format msgid "[Friendica:Notify] %s posted to your profile wall" msgstr "" -#: ../../include/enotify.php:100 -#, php-format -msgid "%s posted to your profile wall at %s" -msgstr "" - -#: ../../include/enotify.php:102 -#, php-format -msgid "%s posted to %s" -msgstr "" - -#: ../../include/enotify.php:102 -msgid "your profile wall." -msgstr "" - #: ../../include/enotify.php:111 #, php-format +msgid "%1$s posted to your profile wall at %2$s" +msgstr "" + +#: ../../include/enotify.php:113 +#, php-format +msgid "%1$s posted to [url=%2s]your wall[/url]" +msgstr "" + +#: ../../include/enotify.php:124 +#, php-format msgid "[Friendica:Notify] %s tagged you" msgstr "" -#: ../../include/enotify.php:112 +#: ../../include/enotify.php:125 #, php-format -msgid "%s tagged you at %s" +msgid "%1$s tagged you at %2$s" msgstr "" -#: ../../include/enotify.php:113 +#: ../../include/enotify.php:126 #, php-format -msgid "%s %s." +msgid "%1$s [url=%2$s]tagged you[/url]." msgstr "" -#: ../../include/enotify.php:113 -msgid "tagged you" -msgstr "" - -#: ../../include/enotify.php:122 +#: ../../include/enotify.php:137 #, php-format msgid "[Friendica:Notify] %s tagged your post" msgstr "" -#: ../../include/enotify.php:123 +#: ../../include/enotify.php:138 #, php-format -msgid "%s tagged your post at %s" +msgid "%1$s tagged your post at %2$s" msgstr "" -#: ../../include/enotify.php:124 +#: ../../include/enotify.php:139 #, php-format -msgid "%s tagged %s" +msgid "%1$s tagged [url=%2$s]your post[/url]" msgstr "" -#: ../../include/enotify.php:124 -msgid "your post" -msgstr "" - -#: ../../include/enotify.php:133 +#: ../../include/enotify.php:150 msgid "[Friendica:Notify] Introduction received" msgstr "" -#: ../../include/enotify.php:134 +#: ../../include/enotify.php:151 #, php-format -msgid "You've received an introduction from '%s' at %s" +msgid "You've received an introduction from '%1$s' at %2$s" msgstr "" -#: ../../include/enotify.php:135 +#: ../../include/enotify.php:152 #, php-format -msgid "You've received %s from %s." +msgid "You've received [url=%1$s]an introduction[/url] from %2$s." msgstr "" -#: ../../include/enotify.php:135 -msgid "an introduction" -msgstr "" - -#: ../../include/enotify.php:136 ../../include/enotify.php:153 +#: ../../include/enotify.php:155 ../../include/enotify.php:173 #, php-format msgid "You may visit their profile at %s" msgstr "" -#: ../../include/enotify.php:138 +#: ../../include/enotify.php:157 #, php-format msgid "Please visit %s to approve or reject the introduction." msgstr "" -#: ../../include/enotify.php:145 +#: ../../include/enotify.php:164 msgid "[Friendica:Notify] Friend suggestion received" msgstr "" -#: ../../include/enotify.php:146 +#: ../../include/enotify.php:165 #, php-format -msgid "You've received a friend suggestion from '%s' at %s" +msgid "You've received a friend suggestion from '%1$s' at %2$s" msgstr "" -#: ../../include/enotify.php:147 +#: ../../include/enotify.php:166 #, php-format -msgid "You've received %s for %s from %s." +msgid "You've received [url=%1$s]a friend suggestion[/url] for %2$s from %3$s." msgstr "" -#: ../../include/enotify.php:148 -msgid "a friend suggestion" -msgstr "" - -#: ../../include/enotify.php:151 +#: ../../include/enotify.php:171 msgid "Name:" msgstr "" -#: ../../include/enotify.php:152 +#: ../../include/enotify.php:172 msgid "Photo:" msgstr "" -#: ../../include/enotify.php:155 +#: ../../include/enotify.php:175 #, php-format msgid "Please visit %s to approve or reject the suggestion." msgstr "" @@ -7147,14 +7188,18 @@ msgstr "" msgid "following" msgstr "" -#: ../../include/items.php:2745 +#: ../../include/items.php:2804 msgid "A new person is sharing with you at " msgstr "" -#: ../../include/items.php:2745 +#: ../../include/items.php:2804 msgid "You have a new follower at " msgstr "" +#: ../../include/items.php:3466 +msgid "Archives" +msgstr "" + #: ../../include/bb2diaspora.php:102 ../../include/bb2diaspora.php:112 #: ../../include/bb2diaspora.php:113 msgid "image/photo" @@ -7254,29 +7299,29 @@ msgstr "" msgid "stopped following" msgstr "" -#: ../../include/Contact.php:203 ../../include/conversation.php:842 +#: ../../include/Contact.php:218 ../../include/conversation.php:842 msgid "View Status" msgstr "" -#: ../../include/Contact.php:204 ../../include/conversation.php:843 +#: ../../include/Contact.php:219 ../../include/conversation.php:843 msgid "View Profile" msgstr "" -#: ../../include/Contact.php:205 ../../include/conversation.php:844 +#: ../../include/Contact.php:220 ../../include/conversation.php:844 msgid "View Photos" msgstr "" -#: ../../include/Contact.php:206 ../../include/Contact.php:219 +#: ../../include/Contact.php:221 ../../include/Contact.php:234 #: ../../include/conversation.php:845 msgid "Network Posts" msgstr "" -#: ../../include/Contact.php:207 ../../include/Contact.php:219 +#: ../../include/Contact.php:222 ../../include/Contact.php:234 #: ../../include/conversation.php:846 msgid "Edit Contact" msgstr "" -#: ../../include/Contact.php:208 ../../include/Contact.php:219 +#: ../../include/Contact.php:223 ../../include/Contact.php:234 #: ../../include/conversation.php:847 msgid "Send PM" msgstr "" @@ -7503,96 +7548,96 @@ msgstr "" msgid "permissions" msgstr "" -#: ../../boot.php:518 +#: ../../boot.php:517 msgid "Delete this item?" msgstr "" -#: ../../boot.php:521 +#: ../../boot.php:520 msgid "show fewer" msgstr "" -#: ../../boot.php:694 +#: ../../boot.php:715 #, php-format msgid "Update %s failed. See error logs." msgstr "" -#: ../../boot.php:696 +#: ../../boot.php:717 #, php-format msgid "Update Error at %s" msgstr "" -#: ../../boot.php:796 +#: ../../boot.php:817 msgid "Create a New Account" msgstr "" -#: ../../boot.php:820 +#: ../../boot.php:841 msgid "Nickname or Email address: " msgstr "" -#: ../../boot.php:821 +#: ../../boot.php:842 msgid "Password: " msgstr "" -#: ../../boot.php:824 +#: ../../boot.php:845 msgid "Or login using OpenID: " msgstr "" -#: ../../boot.php:830 +#: ../../boot.php:851 msgid "Forgot your password?" msgstr "" -#: ../../boot.php:997 +#: ../../boot.php:1018 msgid "Edit profile" msgstr "" -#: ../../boot.php:1057 +#: ../../boot.php:1078 msgid "Message" msgstr "" -#: ../../boot.php:1173 ../../boot.php:1249 +#: ../../boot.php:1194 ../../boot.php:1270 msgid "g A l F d" msgstr "" -#: ../../boot.php:1174 ../../boot.php:1250 +#: ../../boot.php:1195 ../../boot.php:1271 msgid "F d" msgstr "" -#: ../../boot.php:1219 ../../boot.php:1290 +#: ../../boot.php:1240 ../../boot.php:1311 msgid "[today]" msgstr "" -#: ../../boot.php:1231 +#: ../../boot.php:1252 msgid "Birthday Reminders" msgstr "" -#: ../../boot.php:1232 +#: ../../boot.php:1253 msgid "Birthdays this week:" msgstr "" -#: ../../boot.php:1283 +#: ../../boot.php:1304 msgid "[No description]" msgstr "" -#: ../../boot.php:1301 +#: ../../boot.php:1322 msgid "Event Reminders" msgstr "" -#: ../../boot.php:1302 +#: ../../boot.php:1323 msgid "Events this week:" msgstr "" -#: ../../boot.php:1507 +#: ../../boot.php:1528 msgid "Status Messages and Posts" msgstr "" -#: ../../boot.php:1513 +#: ../../boot.php:1534 msgid "Profile Details" msgstr "" -#: ../../boot.php:1528 +#: ../../boot.php:1549 msgid "Events and Calendar" msgstr "" -#: ../../boot.php:1534 +#: ../../boot.php:1555 msgid "Only You Can See This" msgstr "" diff --git a/view/categories_widget.tpl b/view/categories_widget.tpl index 061821beb..5dbd871a8 100644 --- a/view/categories_widget.tpl +++ b/view/categories_widget.tpl @@ -1,4 +1,3 @@ -

$title

$desc
diff --git a/view/contact_block.tpl b/view/contact_block.tpl index eb46c6c43..a79648712 100644 --- a/view/contact_block.tpl +++ b/view/contact_block.tpl @@ -9,3 +9,4 @@
{{ endif }} +
diff --git a/view/contact_edit.tpl b/view/contact_edit.tpl index eeedda3a4..c68ca7f1d 100644 --- a/view/contact_edit.tpl +++ b/view/contact_edit.tpl @@ -17,6 +17,9 @@
  • $relation_text
  • $nettype
  • + {{ if $lost_contact }} +
  • $lost_contact
  • + {{ endif }} {{ if $insecure }}
  • $insecure
  • {{ endif }} diff --git a/view/conversation.tpl b/view/conversation.tpl index 43bb1dd47..fccd9a8bb 100644 --- a/view/conversation.tpl +++ b/view/conversation.tpl @@ -16,6 +16,8 @@ {{ endfor }} +
    + {{ if $dropping }}
-
- $sitelocation +
+ User Menu
+ + {{ if $userinfo }} {{ endif }} @@ -110,9 +114,9 @@ {{ if $nav.messages }} {{ endif }} - {{if $nav.introductions }} - - {{ endif }} + {{if $nav.introductions }} + + {{ endif }}
@@ -124,18 +128,18 @@ $langselector diff --git a/view/theme/dispy/wall_item.tpl b/view/theme/dispy/wall_item.tpl index 6263eef51..115f05ad7 100644 --- a/view/theme/dispy/wall_item.tpl +++ b/view/theme/dispy/wall_item.tpl @@ -1,4 +1,4 @@ - +
diff --git a/view/theme/dispy/wallwall_item.tpl b/view/theme/dispy/wallwall_item.tpl index e2a972790..da5fa13b3 100644 --- a/view/theme/dispy/wallwall_item.tpl +++ b/view/theme/dispy/wallwall_item.tpl @@ -1,4 +1,4 @@ - +
@@ -88,6 +88,7 @@ class="icon recycle wall-item-share-buttons" title="$item.vote.share.0" onclick
$item.dislike
+
$item.comment
diff --git a/view/theme/duepuntozero/style.css b/view/theme/duepuntozero/style.css index ab660888f..be755d411 100644 --- a/view/theme/duepuntozero/style.css +++ b/view/theme/duepuntozero/style.css @@ -1608,7 +1608,7 @@ input#dfrn-url { .contact-photo-menu li a:hover { color: #FFFFFF; background: #3465A4; text-decoration: none; } -#block-message, #ignore-message, #archive-message { +#block-message, #ignore-message, #archive-message, #lost-contact-message { color: #FF0000; } @@ -3226,3 +3226,7 @@ ul.menu-popup { .autocomplete { color:#000; border:1px solid #999; background:#FFF; cursor:default; text-align:left; max-height:350px; overflow:auto; margin:-6px 6px 6px -6px; /* IE6 specific: */ _height:350px; _margin:0; _overflow-x:hidden; } .autocomplete .selected { background:#F0F0F0; } .autocomplete div { padding:2px 5px; white-space:nowrap; overflow:hidden; } + +#datebrowse-sidebar select { + margin-left: 25px; +} diff --git a/view/theme/facepark/conversation.tpl b/view/theme/facepark/conversation.tpl index 43bb1dd47..fccd9a8bb 100644 --- a/view/theme/facepark/conversation.tpl +++ b/view/theme/facepark/conversation.tpl @@ -16,6 +16,8 @@
{{ endfor }} +
+ {{ if $dropping }}