aboutsummaryrefslogtreecommitdiffstats
path: root/Zotlabs
diff options
context:
space:
mode:
Diffstat (limited to 'Zotlabs')
-rw-r--r--Zotlabs/Daemon/Cron.php23
-rw-r--r--Zotlabs/Lib/Activity.php391
-rw-r--r--Zotlabs/Lib/Enotify.php1
-rw-r--r--Zotlabs/Lib/Libzot.php8
-rw-r--r--Zotlabs/Module/Import.php9
-rw-r--r--Zotlabs/Module/Item.php6
-rw-r--r--Zotlabs/Module/Like.php3
-rw-r--r--Zotlabs/Module/Pconfig.php5
-rw-r--r--Zotlabs/Module/Photo.php87
-rw-r--r--Zotlabs/Module/Ping.php8
-rw-r--r--Zotlabs/Module/Wfinger.php3
-rw-r--r--Zotlabs/Update/_1228.php4
-rw-r--r--Zotlabs/Update/_1229.php32
-rw-r--r--Zotlabs/Widget/Notifications.php8
14 files changed, 472 insertions, 116 deletions
diff --git a/Zotlabs/Daemon/Cron.php b/Zotlabs/Daemon/Cron.php
index 25e49b817..8b6b42c8a 100644
--- a/Zotlabs/Daemon/Cron.php
+++ b/Zotlabs/Daemon/Cron.php
@@ -94,6 +94,29 @@ class Cron {
@time_sleep_until(microtime(true) + (float) $interval);
}
}
+
+ // Clean expired photos from cache
+
+ $age = get_config('system','active_expire_days', '30');
+ $r = q("SELECT DISTINCT xchan, content FROM photo WHERE photo_usage = %d AND expires < %s - INTERVAL %s",
+ intval(PHOTO_CACHE),
+ db_utcnow(),
+ db_quoteinterval($age . ' DAY')
+ );
+ if($r) {
+ foreach($r as $rr) {
+ $file = dbunescbin($rr['content']);
+ if(is_file($file)) {
+ @unlink($file);
+ logger('info: deleted cached photo file ' . $file, LOGGER_DEBUG);
+ }
+ }
+ }
+ q("DELETE FROM photo WHERE photo_usage = %d AND expires < %s - INTERVAL %s",
+ intval(PHOTO_CACHE),
+ db_utcnow(),
+ db_quoteinterval($age . ' DAY')
+ );
// publish any applicable items that were set to be published in the future
// (time travel posts). Restrict to items that have come of age in the last
diff --git a/Zotlabs/Lib/Activity.php b/Zotlabs/Lib/Activity.php
index 6ddbbb9db..8cef41c42 100644
--- a/Zotlabs/Lib/Activity.php
+++ b/Zotlabs/Lib/Activity.php
@@ -11,9 +11,15 @@ class Activity {
static function encode_object($x) {
+
if(($x) && (! is_array($x)) && (substr(trim($x),0,1)) === '{' ) {
$x = json_decode($x,true);
}
+
+ if(is_array($x) && array_key_exists('asld',$x)) {
+ $x = $x['asld'];
+ }
+
if($x['type'] === ACTIVITY_OBJ_PERSON) {
return self::fetch_person($x);
}
@@ -1149,7 +1155,7 @@ class Activity {
}
if($act->obj['type'] === 'Note' && $s['attach']) {
- $s['body'] .= self::bb_attach($s['attach']);
+ $s['body'] .= self::bb_attach($s['attach'],$s['body']);
}
// we will need a hook here to extract magnet links e.g. peertube
@@ -1233,19 +1239,20 @@ class Activity {
static function decode_note($act) {
- $s = [];
-
-
+ $response_activity = false;
- $content = self::get_content($act->obj);
+ $s = [];
+ if(is_array($act->obj)) {
+ $content = self::get_content($act->obj);
+ }
+
$s['owner_xchan'] = $act->actor['id'];
$s['author_xchan'] = $act->actor['id'];
- $s['mid'] = $act->id;
+ $s['mid'] = $act->obj['id'];
$s['parent_mid'] = $act->parent_id;
-
if($act->data['published']) {
$s['created'] = datetime_convert('UTC','UTC',$act->data['published']);
}
@@ -1259,43 +1266,60 @@ class Activity {
$s['edited'] = datetime_convert('UTC','UTC',$act->obj['updated']);
}
- if(! $s['created'])
- $s['created'] = datetime_convert();
- if(! $s['edited'])
- $s['edited'] = $s['created'];
+ if(in_array($act->type, [ 'Like', 'Dislike', 'Flag', 'Block', 'Announce', 'Accept', 'Reject', 'TentativeAccept' ])) {
- if(in_array($act->type,['Announce'])) {
- $root_content = self::get_content($act->raw);
+ $response_activity = true;
- $s['title'] = self::bb_content($root_content,'name');
- $s['summary'] = self::bb_content($root_content,'summary');
- $s['body'] = (self::bb_content($root_content,'bbcode') ? : self::bb_content($root_content,'content'));
+ $s['mid'] = $act->id;
+ $s['parent_mid'] = $act->obj['id'];
- if(strpos($s['body'],'[share') === false) {
+ // over-ride the object timestamp with the activity
- // @fixme - error check and set defaults
+ if($act->data['published']) {
+ $s['created'] = datetime_convert('UTC','UTC',$act->data['published']);
+ }
+
+ if($act->data['updated']) {
+ $s['edited'] = datetime_convert('UTC','UTC',$act->data['updated']);
+ }
- $name = urlencode($act->obj['actor']['name']);
- $profile = $act->obj['actor']['id'];
- $photo = $act->obj['icon']['url'];
+ $obj_actor = ((isset($act->obj['actor'])) ? $act->obj['actor'] : $act->get_actor('attributedTo', $act->obj));
+ // ensure we store the original actor
+ self::actor_store($obj_actor['id'],$obj_actor);
- $s['body'] .= "\r\n[share author='" . $name .
- "' profile='" . $profile .
- "' avatar='" . $photo .
- "' link='" . $act->obj['id'] .
- "' auth='" . ((is_matrix_url($act->obj['id'])) ? 'true' : 'false' ) .
- "' posted='" . $act->obj['published'] .
- "' message_id='" . $act->obj['id'] .
- "']";
+ $mention = self::get_actor_bbmention($obj_actor['id']);
+
+ if($act->type === 'Like') {
+ $content['content'] = sprintf( t('Likes %1$s\'s %2$s'),$mention,$act->obj['type']) . "\n\n" . $content['content'];
+ }
+ if($act->type === 'Dislike') {
+ $content['content'] = sprintf( t('Doesn\'t like %1$s\'s %2$s'),$mention,$act->obj['type']) . "\n\n" . $content['content'];
+ }
+ if($act->type === 'Accept' && $act->obj['type'] === 'Event' ) {
+ $content['content'] = sprintf( t('Will attend %1$s\'s %2$s'),$mention,$act->obj['type']) . "\n\n" . $content['content'];
+ }
+ if($act->type === 'Reject' && $act->obj['type'] === 'Event' ) {
+ $content['content'] = sprintf( t('Will not attend %1$s\'s %2$s'),$mention,$act->obj['type']) . "\n\n" . $content['content'];
+ }
+ if($act->type === 'TentativeAccept' && $act->obj['type'] === 'Event' ) {
+ $content['content'] = sprintf( t('May attend %1$s\'s %2$s'),$mention,$act->obj['type']) . "\n\n" . $content['content'];
+ }
+ if($act->type === 'Announce') {
+ $content['content'] = sprintf( t('&#x1f501; Repeated %1$s\'s %2$s'), $mention, $act->obj['type']);
}
- }
- else {
- $s['title'] = self::bb_content($content,'name');
- $s['summary'] = self::bb_content($content,'summary');
- $s['body'] = (self::bb_content($content,'bbcode') ? : self::bb_content($content,'content'));
}
+ if(! $s['created'])
+ $s['created'] = datetime_convert();
+
+ if(! $s['edited'])
+ $s['edited'] = $s['created'];
+
+ $s['title'] = self::bb_content($content,'name');
+ $s['summary'] = self::bb_content($content,'summary');
+ $s['body'] = ((self::bb_content($content,'bbcode') && (! $response_activity)) ? self::bb_content($content,'bbcode') : self::bb_content($content,'content'));
+
$s['verb'] = self::activity_mapper($act->type);
if($act->type === 'Tombstone') {
@@ -1306,58 +1330,229 @@ class Activity {
$s['obj'] = $act->obj;
$instrument = $act->get_property_obj('instrument');
- if(! $instrument)
+ if((! $instrument) && (! $response_activity)) {
$instrument = $act->get_property_obj('instrument',$act->obj);
+ }
if($instrument && array_key_exists('type',$instrument)
&& $instrument['type'] === 'Service' && array_key_exists('name',$instrument)) {
$s['app'] = escape_tags($instrument['name']);
}
- $a = self::decode_taxonomy($act->obj);
- if($a) {
- $s['term'] = $a;
+
+ if(! $response_activity) {
+ $a = self::decode_taxonomy($act->obj);
+ if($a) {
+ $s['term'] = $a;
+ foreach($a as $b) {
+ if($b['ttype'] === TERM_EMOJI) {
+ $s['title'] = str_replace($b['term'],'[img=16x16]' . $b['url'] . '[/img]',$s['title']);
+ $s['summary'] = str_replace($b['term'],'[img=16x16]' . $b['url'] . '[/img]',$s['summary']);
+ $s['body'] = str_replace($b['term'],'[img=16x16]' . $b['url'] . '[/img]',$s['body']);
+ }
+ }
+ }
+
+ $a = self::decode_attachment($act->obj);
+ if($a) {
+ $s['attach'] = $a;
+ }
}
- $a = self::decode_attachment($act->obj);
- if($a) {
- $s['attach'] = $a;
+ if($act->obj['type'] === 'Note' && $s['attach']) {
+ $s['body'] .= self::bb_attach($s['attach'],$s['body']);
}
+
// we will need a hook here to extract magnet links e.g. peertube
// right now just link to the largest mp4 we find that will fit in our
// standard content region
- if($act->obj['type'] === 'Video') {
+ if(! $response_activity) {
+ if($act->obj['type'] === 'Video') {
- $vtypes = [
- 'video/mp4',
- 'video/ogg',
- 'video/webm'
- ];
+ $vtypes = [
+ 'video/mp4',
+ 'video/ogg',
+ 'video/webm'
+ ];
- $mps = [];
- if(array_key_exists('url',$act->obj) && is_array($act->obj['url'])) {
- foreach($act->obj['url'] as $vurl) {
- if(in_array($vurl['mimeType'], $vtypes)) {
- if(! array_key_exists('width',$vurl)) {
- $vurl['width'] = 0;
+ $mps = [];
+ $ptr = null;
+
+ if(array_key_exists('url',$act->obj)) {
+ if(is_array($act->obj['url'])) {
+ if(array_key_exists(0,$act->obj['url'])) {
+ $ptr = $act->obj['url'];
+ }
+ else {
+ $ptr = [ $act->obj['url'] ];
+ }
+ foreach($ptr as $vurl) {
+ // peertube uses the non-standard element name 'mimeType' here
+ if(array_key_exists('mimeType',$vurl)) {
+ if(in_array($vurl['mimeType'], $vtypes)) {
+ if(! array_key_exists('width',$vurl)) {
+ $vurl['width'] = 0;
+ }
+ $mps[] = $vurl;
+ }
+ }
+ elseif(array_key_exists('mediaType',$vurl)) {
+ if(in_array($vurl['mediaType'], $vtypes)) {
+ if(! array_key_exists('width',$vurl)) {
+ $vurl['width'] = 0;
+ }
+ $mps[] = $vurl;
+ }
+ }
}
- $mps[] = $vurl;
+ }
+ if($mps) {
+ usort($mps,[ __CLASS__, 'vid_sort' ]);
+ foreach($mps as $m) {
+ if(intval($m['width']) < 500 && self::media_not_in_body($m['href'],$s['body'])) {
+ $s['body'] .= "\n\n" . '[video]' . $m['href'] . '[/video]';
+ break;
+ }
+ }
+ }
+ elseif(is_string($act->obj['url']) && self::media_not_in_body($act->obj['url'],$s['body'])) {
+ $s['body'] .= "\n\n" . '[video]' . $act->obj['url'] . '[/video]';
}
}
}
- if($mps) {
- usort($mps,'as_vid_sort');
- foreach($mps as $m) {
- if(intval($m['width']) < 500) {
- $s['body'] .= "\n\n" . '[video]' . $m['href'] . '[/video]';
- break;
+
+ if($act->obj['type'] === 'Audio') {
+
+ $atypes = [
+ 'audio/mpeg',
+ 'audio/ogg',
+ 'audio/wav'
+ ];
+
+ $ptr = null;
+
+ if(array_key_exists('url',$act->obj)) {
+ if(is_array($act->obj['url'])) {
+ if(array_key_exists(0,$act->obj['url'])) {
+ $ptr = $act->obj['url'];
+ }
+ else {
+ $ptr = [ $act->obj['url'] ];
+ }
+ foreach($ptr as $vurl) {
+ if(in_array($vurl['mediaType'], $atypes) && self::media_not_in_body($vurl['href'],$s['body'])) {
+ $s['body'] .= "\n\n" . '[audio]' . $vurl['href'] . '[/audio]';
+ break;
+ }
+ }
+ }
+ elseif(is_string($act->obj['url']) && self::media_not_in_body($act->obj['url'],$s['body'])) {
+ $s['body'] .= "\n\n" . '[audio]' . $act->obj['url'] . '[/audio]';
+ }
+ }
+
+ }
+
+ if($act->obj['type'] === 'Image') {
+
+ $ptr = null;
+
+ if(array_key_exists('url',$act->obj)) {
+ if(is_array($act->obj['url'])) {
+ if(array_key_exists(0,$act->obj['url'])) {
+ $ptr = $act->obj['url'];
+ }
+ else {
+ $ptr = [ $act->obj['url'] ];
+ }
+ foreach($ptr as $vurl) {
+ if(strpos($s['body'],$vurl['href']) === false) {
+ $s['body'] .= "\n\n" . '[zmg]' . $vurl['href'] . '[/zmg]';
+ break;
+ }
+ }
+ }
+ elseif(is_string($act->obj['url'])) {
+ if(strpos($s['body'],$act->obj['url']) === false) {
+ $s['body'] .= "\n\n" . '[zmg]' . $act->obj['url'] . '[/zmg]';
+ }
+ }
+ }
+ }
+
+
+ if($act->obj['type'] === 'Page' && ! $s['body']) {
+
+ $ptr = null;
+ $purl = EMPTY_STR;
+
+ if(array_key_exists('url',$act->obj)) {
+ if(is_array($act->obj['url'])) {
+ if(array_key_exists(0,$act->obj['url'])) {
+ $ptr = $act->obj['url'];
+ }
+ else {
+ $ptr = [ $act->obj['url'] ];
+ }
+ foreach($ptr as $vurl) {
+ if(array_key_exists('mediaType',$vurl) && $vurl['mediaType'] === 'text/html') {
+ $purl = $vurl['href'];
+ break;
+ }
+ elseif(array_key_exists('mimeType',$vurl) && $vurl['mimeType'] === 'text/html') {
+ $purl = $vurl['href'];
+ break;
+ }
+ }
+ }
+ elseif(is_string($act->obj['url'])) {
+ $purl = $act->obj['url'];
+ }
+ if($purl) {
+ $li = z_fetch_url(z_root() . '/linkinfo?binurl=' . bin2hex($purl));
+ if($li['success'] && $li['body']) {
+ $s['body'] .= "\n" . $li['body'];
+ }
+ else {
+ $s['body'] .= "\n\n" . $purl;
+ }
+ }
+ }
+ }
+ }
+
+
+
+ if(in_array($act->obj['type'],[ 'Note','Article','Page' ])) {
+ $ptr = null;
+
+ if(array_key_exists('url',$act->obj)) {
+ if(is_array($act->obj['url'])) {
+ if(array_key_exists(0,$act->obj['url'])) {
+ $ptr = $act->obj['url'];
}
+ else {
+ $ptr = [ $act->obj['url'] ];
+ }
+ foreach($ptr as $vurl) {
+ if(array_key_exists('mediaType',$vurl) && $vurl['mediaType'] === 'text/html') {
+ $s['plink'] = $vurl['href'];
+ break;
+ }
+ }
+ }
+ elseif(is_string($act->obj['url'])) {
+ $s['plink'] = $act->obj['url'];
}
}
}
+ if(! $s['plink']) {
+ $s['plink'] = $s['mid'];
+ }
+
if($act->recips && (! in_array(ACTIVITY_PUBLIC_INBOX,$act->recips)))
$s['item_private'] = 1;
@@ -1371,8 +1566,6 @@ class Activity {
}
-
-
static function announce_note($channel,$observer_hash,$act) {
$s = [];
@@ -1464,7 +1657,7 @@ class Activity {
$body .= self::bb_content($content,'content');
if($act->obj['type'] === 'Note' && $s['attach']) {
- $body .= self::bb_attach($s['attach']);
+ $body .= self::bb_attach($s['attach'],$body);
}
$body .= "[/share]";
@@ -1642,19 +1835,26 @@ class Activity {
}
- static function bb_attach($attach) {
+
+ static function bb_attach($attach,$body) {
$ret = false;
foreach($attach as $a) {
if(strpos($a['type'],'image') !== false) {
- $ret .= "\n\n" . '[img]' . $a['href'] . '[/img]';
+ if(self::media_not_in_body($a['href'],$body)) {
+ $ret .= "\n\n" . '[img]' . $a['href'] . '[/img]';
+ }
}
if(array_key_exists('type',$a) && strpos($a['type'], 'video') === 0) {
- $ret .= "\n\n" . '[video]' . $a['href'] . '[/video]';
+ if(self::media_not_in_body($a['href'],$body)) {
+ $ret .= "\n\n" . '[video]' . $a['href'] . '[/video]';
+ }
}
if(array_key_exists('type',$a) && strpos($a['type'], 'audio') === 0) {
- $ret .= "\n\n" . '[audio]' . $a['href'] . '[/audio]';
+ if(self::media_not_in_body($a['href'],$body)) {
+ $ret .= "\n\n" . '[audio]' . $a['href'] . '[/audio]';
+ }
}
}
@@ -1662,16 +1862,31 @@ class Activity {
}
+ // check for the existence of existing media link in body
+
+ static function media_not_in_body($s,$body) {
+
+ if((strpos($body,']' . $s . '[/img]') === false) &&
+ (strpos($body,']' . $s . '[/zmg]') === false) &&
+ (strpos($body,']' . $s . '[/video]') === false) &&
+ (strpos($body,']' . $s . '[/audio]') === false)) {
+ return true;
+ }
+ return false;
+ }
+
static function bb_content($content,$field) {
require_once('include/html2bbcode.php');
-
+ require_once('include/event.php');
$ret = false;
if(is_array($content[$field])) {
foreach($content[$field] as $k => $v) {
- $ret .= '[language=' . $k . ']' . html2bbcode($v) . '[/language]';
+ $ret .= html2bbcode($v);
+ // save this for auto-translate or dynamic filtering
+ // $ret .= '[language=' . $k . ']' . html2bbcode($v) . '[/language]';
}
}
else {
@@ -1682,6 +1897,9 @@ class Activity {
$ret = html2bbcode($content[$field]);
}
}
+ if($field === 'content' && $content['event'] && (! strpos($ret,'[event'))) {
+ $ret .= format_event_bbcode($content['event']);
+ }
return $ret;
}
@@ -1690,21 +1908,52 @@ class Activity {
static function get_content($act) {
$content = [];
- if (! $act) {
+ $event = null;
+
+ if ((! $act) || (! is_array($act))) {
return $content;
}
+ if($act['type'] === 'Event') {
+ $adjust = false;
+ $event = [];
+ $event['event_hash'] = $act['id'];
+ if(array_key_exists('startTime',$act) && strpos($act['startTime'],-1,1) === 'Z') {
+ $adjust = true;
+ $event['adjust'] = 1;
+ $event['dtstart'] = datetime_convert('UTC','UTC',$event['startTime'] . (($adjust) ? '' : 'Z'));
+ }
+ if(array_key_exists('endTime',$act)) {
+ $event['dtend'] = datetime_convert('UTC','UTC',$event['endTime'] . (($adjust) ? '' : 'Z'));
+ }
+ else {
+ $event['nofinish'] = true;
+ }
+ }
+
foreach ([ 'name', 'summary', 'content' ] as $a) {
if (($x = self::get_textfield($act,$a)) !== false) {
$content[$a] = $x;
}
}
+
+ if($event) {
+ $event['summary'] = html2bbcode($content['summary']);
+ $event['description'] = html2bbcode($content['content']);
+ if($event['summary'] && $event['dtstart']) {
+ $content['event'] = $event;
+ }
+ }
+
if (array_key_exists('source',$act) && array_key_exists('mediaType',$act['source'])) {
if ($act['source']['mediaType'] === 'text/bbcode') {
$content['bbcode'] = purify_html($act['source']['content']);
}
}
+
+
+
return $content;
}
@@ -1722,4 +1971,6 @@ class Activity {
}
return $content;
}
+
+
} \ No newline at end of file
diff --git a/Zotlabs/Lib/Enotify.php b/Zotlabs/Lib/Enotify.php
index 25c96d9cc..5e5798cac 100644
--- a/Zotlabs/Lib/Enotify.php
+++ b/Zotlabs/Lib/Enotify.php
@@ -828,6 +828,7 @@ class Enotify {
$x = array(
'notify_link' => $item['llink'],
'name' => $item['author']['xchan_name'],
+ 'addr' => (($item['author']['xchan_addr']) ? $item['author']['xchan_addr'] : $item['author']['xchan_url']),
'url' => $item['author']['xchan_url'],
'photo' => $item['author']['xchan_photo_s'],
'when' => relative_date(($edit)? $item['edited'] : $item['created']),
diff --git a/Zotlabs/Lib/Libzot.php b/Zotlabs/Lib/Libzot.php
index 70f013eb7..0fbde9765 100644
--- a/Zotlabs/Lib/Libzot.php
+++ b/Zotlabs/Lib/Libzot.php
@@ -1418,7 +1418,7 @@ logger('4');
$DR = new DReport(z_root(),$sender,$d,$arr['mid']);
- $channel = channelx_by_hash($d);
+ $channel = channelx_by_portid($d);
if (! $channel) {
$DR->update('recipient not found');
@@ -1505,8 +1505,10 @@ logger('4');
}
}
- if($arr['mid'] != $arr['parent_mid']) {
+logger('item: ' . print_r($arr,true), LOGGER_DATA);
+ if($arr['mid'] !== $arr['parent_mid']) {
+logger('checking source: "' . $arr['mid'] . '" != "' . $arr['parent_mid'] . '"');
// check source route.
// We are only going to accept comments from this sender if the comment has the same route as the top-level-post,
// this is so that permissions mismatches between senders apply to the entire conversation
@@ -1591,7 +1593,7 @@ logger('4');
$arr['route'] = $last_prior_route;
}
}
-
+logger('hey');
$ab = q("select * from abook where abook_channel = %d and abook_xchan = '%s'",
intval($channel['channel_id']),
dbesc($arr['owner_xchan'])
diff --git a/Zotlabs/Module/Import.php b/Zotlabs/Module/Import.php
index 6016328a5..0daf28aa9 100644
--- a/Zotlabs/Module/Import.php
+++ b/Zotlabs/Module/Import.php
@@ -127,6 +127,15 @@ class Import extends \Zotlabs\Web\Controller {
//
// }
+
+ // prevent incompatible osada or zap data from horking your database
+
+ if(array_path_exists('compatibility/codebase',$data)) {
+ notice('Data export format is not compatible with this software');
+ return;
+ }
+
+
if($moving)
$seize = 1;
diff --git a/Zotlabs/Module/Item.php b/Zotlabs/Module/Item.php
index 1d64ef60c..24949c626 100644
--- a/Zotlabs/Module/Item.php
+++ b/Zotlabs/Module/Item.php
@@ -760,7 +760,7 @@ class Item extends Controller {
// fix permalinks for cards
if($webpage == ITEM_TYPE_CARD) {
- $plink = z_root() . '/cards/' . $channel['channel_address'] . '/' . (($pagetitle) ? $pagetitle : substr($mid,0,16));
+ $plink = z_root() . '/cards/' . $channel['channel_address'] . '/' . (($pagetitle) ? $pagetitle : $uuid);
}
if(($parent_item) && ($parent_item['item_type'] == ITEM_TYPE_CARD)) {
$r = q("select v from iconfig where iconfig.cat = 'system' and iconfig.k = 'CARD' and iconfig.iid = %d limit 1",
@@ -772,7 +772,7 @@ class Item extends Controller {
}
if($webpage == ITEM_TYPE_ARTICLE) {
- $plink = z_root() . '/articles/' . $channel['channel_address'] . '/' . (($pagetitle) ? $pagetitle : substr($mid,0,16));
+ $plink = z_root() . '/articles/' . $channel['channel_address'] . '/' . (($pagetitle) ? $pagetitle : $uuid);
}
if(($parent_item) && ($parent_item['item_type'] == ITEM_TYPE_ARTICLE)) {
$r = q("select v from iconfig where iconfig.cat = 'system' and iconfig.k = 'ARTICLE' and iconfig.iid = %d limit 1",
@@ -784,7 +784,7 @@ class Item extends Controller {
}
if ((! $plink) && ($item_thread_top)) {
- $plink = z_root() . '/channel/' . $channel['channel_address'] . '/?f=&mid=' . $mid;
+ $plink = z_root() . '/channel/' . $channel['channel_address'] . '/?f=&mid=' . gen_link_id($mid);
$plink = substr($plink,0,190);
}
diff --git a/Zotlabs/Module/Like.php b/Zotlabs/Module/Like.php
index c39726b88..d19154eb4 100644
--- a/Zotlabs/Module/Like.php
+++ b/Zotlabs/Module/Like.php
@@ -1,6 +1,8 @@
<?php
namespace Zotlabs\Module;
+use Zotlabs\Lib\Activity;
+
require_once('include/security.php');
require_once('include/bbcode.php');
require_once('include/items.php');
@@ -400,6 +402,7 @@ class Like extends \Zotlabs\Web\Controller {
$object = json_encode(array(
'type' => $objtype,
'id' => $item['mid'],
+ 'asld' => Activity::fetch_item( [ 'id' => $item['mid'] ] ),
'parent' => (($item['thr_parent']) ? $item['thr_parent'] : $item['parent_mid']),
'link' => $links,
'title' => $item['title'],
diff --git a/Zotlabs/Module/Pconfig.php b/Zotlabs/Module/Pconfig.php
index 44fe5d9a9..f31d5fdf6 100644
--- a/Zotlabs/Module/Pconfig.php
+++ b/Zotlabs/Module/Pconfig.php
@@ -22,6 +22,11 @@ class Pconfig extends \Zotlabs\Web\Controller {
$k = trim(escape_tags($_POST['k']));
$v = trim($_POST['v']);
$aj = intval($_POST['aj']);
+
+ // Do not store "serialized" data received in the $_POST
+ if (preg_match('|^a:[0-9]+:{.*}$|s',$v) || preg_match('O:8:"stdClass":[0-9]+:{.*}$|s',$v)) {
+ return;
+ }
if(in_array(argv(2),$this->disallowed_pconfig())) {
notice( t('This setting requires special processing and editing has been blocked.') . EOL);
diff --git a/Zotlabs/Module/Photo.php b/Zotlabs/Module/Photo.php
index 30e8340e2..ddff3a68e 100644
--- a/Zotlabs/Module/Photo.php
+++ b/Zotlabs/Module/Photo.php
@@ -1,19 +1,20 @@
<?php
+
+
namespace Zotlabs\Module;
require_once('include/security.php');
require_once('include/attach.php');
require_once('include/photo/photo_driver.php');
-
class Photo extends \Zotlabs\Web\Controller {
function init() {
- $prvcachecontrol = false;
$streaming = null;
$channel = null;
$person = 0;
+ $renew = false;
switch(argc()) {
case 4:
@@ -29,7 +30,15 @@ class Photo extends \Zotlabs\Web\Controller {
killme();
// NOTREACHED
}
-
+
+ $cache_mode = array(
+ 'on' => get_config('system','photo_cache_enable', 0),
+ 'age' => 86400,
+ 'exp' => true,
+ 'leak' => false
+ );
+ call_hooks('cache_mode_hook', $cache_mode);
+
$observer_xchan = get_observer_hash();
$ismodified = $_SERVER['HTTP_IF_MODIFIED_SINCE'];
@@ -106,13 +115,14 @@ class Photo extends \Zotlabs\Web\Controller {
License link: http://creativecommons.org/licenses/by/3.0/
*/
+ // @FIXME It seems this part doesn't work because we are not setting such cookie
$cookie_value = false;
if (isset($_COOKIE['devicePixelRatio'])) {
$cookie_value = intval($_COOKIE['devicePixelRatio']);
}
else {
// Force revalidation of cache on next request
- $cache_directive = 'no-cache';
+ // $prvcachecontrol = 'no-cache';
$status = 'no cookie';
}
@@ -129,27 +139,40 @@ class Photo extends \Zotlabs\Web\Controller {
$resolution = 1;
}
- $r = q("SELECT uid, photo_usage FROM photo WHERE resource_id = '%s' AND imgscale = %d LIMIT 1",
+ $r = q("SELECT uid, photo_usage, display_path FROM photo WHERE resource_id = '%s' AND imgscale = %d LIMIT 1",
dbesc($photo),
intval($resolution)
);
if($r) {
-
$allowed = (-1);
- if(intval($r[0]['photo_usage'])) {
+ $u = intval($r[0]['photo_usage']);
+ if($u) {
$allowed = 1;
- if(intval($r[0]['photo_usage']) === PHOTO_COVER)
+ if($u === PHOTO_COVER)
if($resolution < PHOTO_RES_COVER_1200)
$allowed = (-1);
- if(intval($r[0]['photo_usage']) === PHOTO_PROFILE)
+ if($u === PHOTO_PROFILE)
if(! in_array($resolution,[4,5,6]))
$allowed = (-1);
+ if($u === PHOTO_CACHE) {
+ // Validate cache
+ $cache = array(
+ 'resid' => $photo,
+ 'uid' => $r[0]['uid'],
+ 'status' => false
+ );
+ if($cache_mode['on'])
+ call_hooks('cache_url_hook', $cache);
+ if(! $cache['status']) {
+ header("Location: " . htmlspecialchars_decode($r[0]['display_path']));
+ killme();
+ }
+ }
}
- if($allowed === (-1)) {
+ if($allowed === (-1))
$allowed = attach_can_view($r[0]['uid'],$observer_xchan,$photo);
- }
$channel = channelx_by_n($r[0]['uid']);
@@ -158,18 +181,21 @@ class Photo extends \Zotlabs\Web\Controller {
dbesc($photo),
intval($resolution)
);
-
+
$exists = (($e) ? true : false);
-
+
if($exists && $allowed) {
+ $expires = strtotime($e[0]['expires'] . 'Z');
$data = dbunescbin($e[0]['content']);
$filesize = $e[0]['filesize'];
$mimetype = $e[0]['mimetype'];
$modified = strtotime($e[0]['edited'] . 'Z');
- if(intval($e[0]['os_storage']))
+
+ if(intval($e[0]['os_storage'])) {
$streaming = $data;
+ }
if($e[0]['allow_cid'] != '' || $e[0]['allow_gid'] != '' || $e[0]['deny_gid'] != '' || $e[0]['deny_gid'] != '')
- $prvcachecontrol = true;
+ $prvcachecontrol = 'no-store, no-cache, must-revalidate';
}
else {
if(! $allowed) {
@@ -180,9 +206,9 @@ class Photo extends \Zotlabs\Web\Controller {
}
}
- } else {
+ }
+ else
http_status_exit(404,'not found');
- }
}
header_remove('Pragma');
@@ -225,24 +251,14 @@ class Photo extends \Zotlabs\Web\Controller {
$mimetype = $ph->getType();
}
}
-
- // @FIXME Seems never invoked
- // Writing in cachefile
- if (isset($cachefile) && $cachefile != '') {
- file_put_contents($cachefile, $data);
- $modified = filemtime($cachefile);
- }
-
- header("Content-type: " . $mimetype);
-
- if($prvcachecontrol) {
+ if(isset($prvcachecontrol)) {
// it is a private photo that they have no permission to view.
// tell the browser not to cache it, in case they authenticate
// and subsequently have permission to see it
- header("Cache-Control: no-store, no-cache, must-revalidate");
+ header("Cache-Control: " . $prvcachecontrol);
}
else {
@@ -255,18 +271,23 @@ class Photo extends \Zotlabs\Web\Controller {
// This has performance considerations but we highly recommend you
// leave it alone.
- $cache = get_config('system','photo_cache_time', 86400); // 1 day by default
+ $maxage = $cache_mode['age'];
- header("Expires: " . gmdate("D, d M Y H:i:s", time() + $cache) . " GMT");
- header("Cache-Control: max-age=" . $cache);
+ if($cache_mode['exp'] || (! isset($expires)) || (isset($expires) && $expires - 60 < time()))
+ $expires = time() + $maxage;
+ else
+ $maxage = $expires - time();
+
+ header("Expires: " . gmdate("D, d M Y H:i:s", $expires) . " GMT");
+ header("Cache-Control: max-age=" . $maxage);
}
+ header("Content-type: " . $mimetype);
header("Last-Modified: " . gmdate("D, d M Y H:i:s", $modified) . " GMT");
header("Content-Length: " . (isset($filesize) ? $filesize : strlen($data)));
// If it's a file resource, stream it.
-
if($streaming && $channel) {
if(strpos($streaming,'store') !== false)
$istream = fopen($streaming,'rb');
diff --git a/Zotlabs/Module/Ping.php b/Zotlabs/Module/Ping.php
index f660c3b55..12244d88c 100644
--- a/Zotlabs/Module/Ping.php
+++ b/Zotlabs/Module/Ping.php
@@ -330,6 +330,7 @@ class Ping extends \Zotlabs\Web\Controller {
$notifs[] = array(
'notify_link' => z_root() . '/mail/' . $zz['id'],
'name' => $zz['xchan_name'],
+ 'addr' => $zz['xchan_addr'],
'url' => $zz['xchan_url'],
'photo' => $zz['xchan_photo_s'],
'when' => relative_date($zz['created']),
@@ -383,6 +384,7 @@ class Ping extends \Zotlabs\Web\Controller {
$result[] = array(
'notify_link' => z_root() . '/connections/ifpending',
'name' => $rr['xchan_name'],
+ 'addr' => $rr['xchan_addr'],
'url' => $rr['xchan_url'],
'photo' => $rr['xchan_photo_s'],
'when' => relative_date($rr['abook_created']),
@@ -407,6 +409,7 @@ class Ping extends \Zotlabs\Web\Controller {
$result[] = array(
'notify_link' => z_root() . '/admin/accounts',
'name' => $rr['account_email'],
+ 'addr' => $rr['account_email'],
'url' => '',
'photo' => z_root() . '/' . get_default_profile_photo(48),
'when' => relative_date($rr['account_created']),
@@ -444,6 +447,7 @@ class Ping extends \Zotlabs\Web\Controller {
$result[] = array(
'notify_link' => z_root() . '/events', /// @FIXME this takes you to an edit page and it may not be yours, we really want to just view the single event --> '/events/event/' . $rr['event_hash'],
'name' => $rr['xchan_name'],
+ 'addr' => $rr['xchan_addr'],
'url' => $rr['xchan_url'],
'photo' => $rr['xchan_photo_s'],
'when' => $when,
@@ -460,7 +464,7 @@ class Ping extends \Zotlabs\Web\Controller {
if(argc() > 1 && (argv(1) === 'files')) {
$result = array();
- $r = q("SELECT item.created, xchan.xchan_name, xchan.xchan_url, xchan.xchan_photo_s FROM item
+ $r = q("SELECT item.created, xchan.xchan_name, xchan.xchan_addr, xchan.xchan_url, xchan.xchan_photo_s FROM item
LEFT JOIN xchan on author_xchan = xchan_hash
WHERE item.verb = '%s'
AND item.obj_type = '%s'
@@ -477,6 +481,7 @@ class Ping extends \Zotlabs\Web\Controller {
$result[] = array(
'notify_link' => z_root() . '/sharedwithme',
'name' => $rr['xchan_name'],
+ 'addr' => $rr['xchan_addr'],
'url' => $rr['xchan_url'],
'photo' => $rr['xchan_photo_s'],
'when' => relative_date($rr['created']),
@@ -658,6 +663,7 @@ class Ping extends \Zotlabs\Web\Controller {
if($r[0]['unseen']) {
$forums[$x]['notify_link'] = (($forums[$x]['private_forum']) ? $forums[$x]['xchan_url'] : z_root() . '/network/?f=&pf=1&unseen=1&cid=' . $forums[$x]['abook_id']);
$forums[$x]['name'] = $forums[$x]['xchan_name'];
+ $forums[$x]['addr'] = $forums[$x]['xchan_addr'];
$forums[$x]['url'] = $forums[$x]['xchan_url'];
$forums[$x]['photo'] = $forums[$x]['xchan_photo_s'];
$forums[$x]['unseen'] = $r[0]['unseen'];
diff --git a/Zotlabs/Module/Wfinger.php b/Zotlabs/Module/Wfinger.php
index e4591df12..03275abbc 100644
--- a/Zotlabs/Module/Wfinger.php
+++ b/Zotlabs/Module/Wfinger.php
@@ -43,6 +43,9 @@ class Wfinger extends \Zotlabs\Web\Controller {
if(strpos($resource,'acct:') === 0) {
$channel = str_replace('acct:','',$resource);
+ if(substr($channel,0,1) === '@' && strpos(substr($channel,1),'@')) {
+ $channel = substr($channel,1);
+ }
if(strpos($channel,'@') !== false) {
$host = substr($channel,strpos($channel,'@')+1);
diff --git a/Zotlabs/Update/_1228.php b/Zotlabs/Update/_1228.php
index f8a506bb4..9e6bf8047 100644
--- a/Zotlabs/Update/_1228.php
+++ b/Zotlabs/Update/_1228.php
@@ -11,8 +11,8 @@ class _1228 {
if(ACTIVE_DBTYPE == DBTYPE_POSTGRES) {
$r1 = q("ALTER TABLE item ADD uuid text NOT NULL DEFAULT '' ");
- $r2 = q("create index \"uuid_idx\" on channel (\"uuid\")");
- $r3 = q("ALTER TABLE item add summary TEXT NOT NULL");
+ $r2 = q("create index \"uuid_idx\" on item (\"uuid\")");
+ $r3 = q("ALTER TABLE item add summary TEXT NOT NULL DEFAULT ''");
$r = ($r1 && $r2 && $r3);
}
diff --git a/Zotlabs/Update/_1229.php b/Zotlabs/Update/_1229.php
new file mode 100644
index 000000000..8e8711644
--- /dev/null
+++ b/Zotlabs/Update/_1229.php
@@ -0,0 +1,32 @@
+<?php
+
+namespace Zotlabs\Update;
+
+class _1229 {
+
+ function run() {
+
+ q("START TRANSACTION");
+
+ if(ACTIVE_DBTYPE == DBTYPE_POSTGRES) {
+ $r1 = q("ALTER TABLE photo ADD expires timestamp NOT NULL DEFAULT '0001-01-01 00:00:00' ");
+ $r2 = q("create index \"photo_expires_idx\" on photo (\"expires\")");
+
+ $r = ($r1 && $r2);
+ }
+ else {
+ $r = q("ALTER TABLE `photo` ADD `expires` datetime NOT NULL DEFAULT '0001-01-01 00:00:00' ,
+ ADD INDEX `expires` (`expires`)");
+ }
+
+ if($r) {
+ q("COMMIT");
+ return UPDATE_SUCCESS;
+ }
+
+ q("ROLLBACK");
+ return UPDATE_FAILED;
+
+ }
+
+}
diff --git a/Zotlabs/Widget/Notifications.php b/Zotlabs/Widget/Notifications.php
index 0f9f609e4..37d9139ec 100644
--- a/Zotlabs/Widget/Notifications.php
+++ b/Zotlabs/Widget/Notifications.php
@@ -24,7 +24,7 @@ class Notifications {
],
'filter' => [
'posts_label' => t('Show new posts only'),
- 'name_label' => t('Filter by name')
+ 'name_label' => t('Filter by name or address')
]
];
@@ -43,7 +43,7 @@ class Notifications {
],
'filter' => [
'posts_label' => t('Show new posts only'),
- 'name_label' => t('Filter by name')
+ 'name_label' => t('Filter by name or address')
]
];
@@ -119,7 +119,7 @@ class Notifications {
'label' => t('Forums'),
'title' => t('Forums'),
'filter' => [
- 'name_label' => t('Filter by name')
+ 'name_label' => t('Filter by name or address')
]
];
}
@@ -150,7 +150,7 @@ class Notifications {
],
'filter' => [
'posts_label' => t('Show new posts only'),
- 'name_label' => t('Filter by name')
+ 'name_label' => t('Filter by name or address')
]
];
}