aboutsummaryrefslogtreecommitdiffstats
path: root/include
diff options
context:
space:
mode:
authorMario Vavti <mario@mariovavti.com>2019-06-04 10:19:04 +0200
committerMario Vavti <mario@mariovavti.com>2019-06-04 10:19:04 +0200
commite4ca3609d90bb437061e4b8db95ed0424b25eb76 (patch)
treeaa070e40ab01cb1354cbf879a0fb8b2f570631d5 /include
parent071fba2f7121aeb9690a21398935a53deac09af8 (diff)
parentbc092d8d7815195d62299c0ea54caa4759e6f2e7 (diff)
downloadvolse-hubzilla-4.2.tar.gz
volse-hubzilla-4.2.tar.bz2
volse-hubzilla-4.2.zip
Merge branch '4.2RC'4.2
Diffstat (limited to 'include')
-rw-r--r--include/attach.php11
-rw-r--r--include/bbcode.php34
-rw-r--r--include/connections.php33
-rw-r--r--include/datetime.php3
-rwxr-xr-xinclude/dba/dba_driver.php25
-rwxr-xr-xinclude/dba/dba_pdo.php2
-rw-r--r--include/event.php98
-rw-r--r--include/features.php34
-rw-r--r--include/follow.php15
-rw-r--r--include/import.php52
-rwxr-xr-xinclude/items.php2
-rw-r--r--include/js_strings.php1
-rw-r--r--include/markdown.php4
-rwxr-xr-xinclude/oembed.php31
-rw-r--r--include/photos.php9
-rw-r--r--include/text.php34
-rw-r--r--include/zot.php82
17 files changed, 321 insertions, 149 deletions
diff --git a/include/attach.php b/include/attach.php
index f6594b154..f169e0669 100644
--- a/include/attach.php
+++ b/include/attach.php
@@ -1521,6 +1521,17 @@ function attach_drop_photo($channel_id,$resource) {
if($x) {
drop_item($x[0]['id'],false,(($x[0]['item_hidden']) ? DROPITEM_NORMAL : DROPITEM_PHASE1),true);
}
+
+ $r = q("SELECT content FROM photo WHERE resource_id = '%s' AND uid = %d AND os_storage = 1",
+ dbesc($resource),
+ intval($channel_id)
+ );
+ if($r) {
+ foreach($r as $i) {
+ @unlink(dbunescbin($i['content']));
+ }
+ }
+
q("DELETE FROM photo WHERE uid = %d AND resource_id = '%s'",
intval($channel_id),
dbesc($resource)
diff --git a/include/bbcode.php b/include/bbcode.php
index 36f943e46..485a1f5b2 100644
--- a/include/bbcode.php
+++ b/include/bbcode.php
@@ -87,12 +87,11 @@ function nakedoembed($match) {
$strip_url = strip_escaped_zids($url);
- $o = oembed_fetch_url($strip_url);
-
- if ($o['type'] == 'error')
- return str_replace($url,$strip_url,$match[0]);
-
- return '[embed]' . $strip_url . '[/embed]';
+ // this function no longer performs oembed on naked links
+ // because they author may have created naked links intentionally.
+ // Now it just strips zids on naked links.
+
+ return str_replace($url,$strip_url,$match[0]);
}
function tryzrlaudio($match) {
@@ -986,17 +985,22 @@ function bbcode($Text, $options = []) {
// leave open the posibility of [map=something]
// this is replaced in prepare_body() which has knowledge of the item location
-
- if (strpos($Text,'[/map]') !== false) {
- $Text = preg_replace_callback("/\[map\](.*?)\[\/map\]/ism", 'bb_map_location', $Text);
- }
- if (strpos($Text,'[map=') !== false) {
- $Text = preg_replace_callback("/\[map=(.*?)\]/ism", 'bb_map_coords', $Text);
+ if ($cache) {
+ $Text = str_replace([ '[map]','[/map]' ], [ '','' ], $Text);
+ $Text = preg_replace('/\[map=(.*?)\]/ism','$1',$Text);
}
- if (strpos($Text,'[map]') !== false) {
- $Text = preg_replace("/\[map\]/", '<div class="map"></div>', $Text);
+ else {
+ if (strpos($Text,'[/map]') !== false) {
+ $Text = preg_replace_callback("/\[map\](.*?)\[\/map\]/ism", 'bb_map_location', $Text);
+ }
+ if (strpos($Text,'[map=') !== false) {
+ $Text = preg_replace_callback("/\[map=(.*?)\]/ism", 'bb_map_coords', $Text);
+ }
+ if (strpos($Text,'[map]') !== false) {
+ $Text = preg_replace("/\[map\]/", '<div class="map"></div>', $Text);
+ }
}
-
+
// Check for bold text
if (strpos($Text,'[b]') !== false) {
$Text = preg_replace("(\[b\](.*?)\[\/b\])ism", '<strong>$1</strong>', $Text);
diff --git a/include/connections.php b/include/connections.php
index d97ea3887..e942503f0 100644
--- a/include/connections.php
+++ b/include/connections.php
@@ -373,19 +373,46 @@ function contact_remove($channel_id, $abook_id) {
if(intval($abook['abook_self']))
return false;
- $r = q("select id from item where (owner_xchan = '%s' or author_xchan = '%s') and uid = %d and item_retained = 0 and item_starred = 0",
+ $r = q("select id, parent from item where (owner_xchan = '%s' or author_xchan = '%s') and uid = %d and item_retained = 0 and item_starred = 0",
dbesc($abook['abook_xchan']),
dbesc($abook['abook_xchan']),
intval($channel_id)
);
if($r) {
+ $already_saved = [];
foreach($r as $rr) {
- $x = q("select uid from term where otype = %d and oid = %d and ttype = %d limit 1",
+ $w = $x = $y = null;
+
+ // optimise so we only process newly seen parent items
+ if (in_array($rr['parent'],$already_saved)) {
+ continue;
+ }
+ // if this isn't the parent, fetch the parent's item_retained and item_starred to see if the conversation
+ // should be retained
+ if($rr['id'] != $rr['parent']) {
+ $w = q("select id, item_retained, item_starred from item where id = %d",
+ intval($rr['parent'])
+ );
+ if($w) {
+ // see if the conversation was filed
+ $x = q("select uid from term where otype = %d and oid = %d and ttype = %d limit 1",
+ intval(TERM_OBJ_POST),
+ intval($w[0]['id']),
+ intval(TERM_FILE)
+ );
+ if (intval($w[0]['item_retained']) || intval($w[0]['item_starred']) || $x) {
+ $already_saved[] = $rr['parent'];
+ continue;
+ }
+ }
+ }
+ // see if this item was filed
+ $y = q("select uid from term where otype = %d and oid = %d and ttype = %d limit 1",
intval(TERM_OBJ_POST),
intval($rr['id']),
intval(TERM_FILE)
);
- if($x) {
+ if ($y) {
continue;
}
drop_item($rr['id'],false);
diff --git a/include/datetime.php b/include/datetime.php
index 3a07f1ccf..ef0927ea4 100644
--- a/include/datetime.php
+++ b/include/datetime.php
@@ -516,13 +516,14 @@ function update_birthdays() {
'event_xchan' => $rr['xchan_hash'],
'dtstart' => datetime_convert('UTC', 'UTC', $rr['abook_dob']),
'dtend' => datetime_convert('UTC', 'UTC', $rr['abook_dob'] . ' + 1 day '),
- 'adjust' => intval(feature_enabled($rr['abook_channel'],'smart_birthdays')),
+ 'adjust' => 0,
'summary' => sprintf( t('%1$s\'s birthday'), $rr['xchan_name']),
'description' => sprintf( t('Happy Birthday %1$s'), '[zrl=' . $rr['xchan_url'] . ']' . $rr['xchan_name'] . '[/zrl]'),
'etype' => 'birthday',
];
$z = event_store_event($ev);
+
if ($z) {
$item_id = event_store_item($ev, $z);
q("update abook set abook_dob = '%s' where abook_id = %d",
diff --git a/include/dba/dba_driver.php b/include/dba/dba_driver.php
index ee0e06a91..cfb208e2d 100755
--- a/include/dba/dba_driver.php
+++ b/include/dba/dba_driver.php
@@ -485,3 +485,28 @@ function db_columns($table) {
return [];
}
+
+
+function db_indexes($table) {
+
+ if($table) {
+ if(ACTIVE_DBTYPE === DBTYPE_POSTGRES) {
+ $r = q("SELECT indexname from pg_indexes where tablename = '%s'",
+ dbesc($table)
+ );
+ if($r) {
+ return ids_to_array($r,'indexname');
+ }
+ }
+ else {
+ $r = q("show index from %s",
+ dbesc($table)
+ );
+ if($r) {
+ return ids_to_array($r,'Key_name');
+ }
+ }
+ }
+
+ return [];
+}
diff --git a/include/dba/dba_pdo.php b/include/dba/dba_pdo.php
index ef8063428..0279342ec 100755
--- a/include/dba/dba_pdo.php
+++ b/include/dba/dba_pdo.php
@@ -19,7 +19,7 @@ class dba_pdo extends dba_driver {
$this->driver_dbtype = $scheme;
if(strpbrk($server,':;')) {
- $dsn = $server;
+ $dsn = $this->driver_dbtype . ':unix_socket=' . trim($server, ':;');
}
else {
$dsn = $this->driver_dbtype . ':host=' . $server . (intval($port) ? ';port=' . $port : '');
diff --git a/include/event.php b/include/event.php
index 77118c329..6689919cf 100644
--- a/include/event.php
+++ b/include/event.php
@@ -27,6 +27,7 @@ function format_event_html($ev) {
if(! ((is_array($ev)) && count($ev)))
return '';
+ $tz = (($ev['timezone']) ? $ev['timezone'] : 'UTC');
$bd_format = t('l F d, Y \@ g:i A') ; // Friday January 18, 2011 @ 8:01 AM
@@ -39,7 +40,7 @@ function format_event_html($ev) {
$o .= '<div class="event-start"><span class="event-label">' . t('Starts:') . '</span>&nbsp;<span class="dtstart" title="'
. datetime_convert('UTC', 'UTC', $ev['dtstart'], (($ev['adjust']) ? ATOM_TIME : 'Y-m-d\TH:i:s' ))
. '" >'
- . (($ev['adjust']) ? day_translate(datetime_convert('UTC', date_default_timezone_get(),
+ . (($ev['adjust']) ? day_translate(datetime_convert($tz, date_default_timezone_get(),
$ev['dtstart'] , $bd_format ))
: day_translate(datetime_convert('UTC', 'UTC',
$ev['dtstart'] , $bd_format)))
@@ -49,7 +50,7 @@ function format_event_html($ev) {
$o .= '<div class="event-end" ><span class="event-label">' . t('Finishes:') . '</span>&nbsp;<span class="dtend" title="'
. datetime_convert('UTC','UTC',$ev['dtend'], (($ev['adjust']) ? ATOM_TIME : 'Y-m-d\TH:i:s' ))
. '" >'
- . (($ev['adjust']) ? day_translate(datetime_convert('UTC', date_default_timezone_get(),
+ . (($ev['adjust']) ? day_translate(datetime_convert($tz, date_default_timezone_get(),
$ev['dtend'] , $bd_format ))
: day_translate(datetime_convert('UTC', 'UTC',
$ev['dtend'] , $bd_format )))
@@ -75,17 +76,35 @@ function format_event_obj($jobject) {
//ensure compatibility with older items - this check can be removed at a later point
if(array_key_exists('description', $object)) {
- $bd_format = t('l F d, Y \@ g:i A'); // Friday January 18, 2011 @ 8:01 AM
+ $tz = (($object['timezone']) ? $object['timezone'] : 'UTC');
+ $allday = (($object['adjust']) ? false : true);
+
+ $dtstart = new DateTime($object['dtstart']);
+ $dtend = new DateTime($object['dtend']);
+ $dtdiff = $dtstart->diff($dtend);
+
+ if($allday && ($dtdiff->days < 2))
+ $oneday = true;
+
+ if($allday && !$oneday) {
+ // Subtract one day from the end date so we can use the "first day - last day" format for display.
+ $dtend->modify('-1 day');
+ $object['dtend'] = datetime_convert('UTC', 'UTC', $dtend->format('Y-m-d H:i:s'));
+ }
+
+ $bd_format = (($allday) ? t('l F d, Y') : t('l F d, Y \@ g:i A')); // Friday January 18, 2011 @ 8:01 AM or Friday January 18, 2011 for allday events
$event['header'] = replace_macros(get_markup_template('event_item_header.tpl'),array(
'$title' => zidify_links(smilies(bbcode($object['title']))),
- '$dtstart_label' => t('Starts:'),
- '$dtstart_title' => datetime_convert('UTC', 'UTC', $object['dtstart'], (($object['adjust']) ? ATOM_TIME : 'Y-m-d\TH:i:s' )),
- '$dtstart_dt' => (($object['adjust']) ? day_translate(datetime_convert('UTC', date_default_timezone_get(), $object['dtstart'] , $bd_format )) : day_translate(datetime_convert('UTC', 'UTC', $object['dtstart'] , $bd_format))),
+ '$dtstart_label' => t('Start:'),
+ '$dtstart_title' => datetime_convert($tz, date_default_timezone_get(), $object['dtstart'], (($object['adjust']) ? ATOM_TIME : 'Y-m-d\TH:i:s' )),
+ '$dtstart_dt' => (($object['adjust']) ? day_translate(datetime_convert($tz, date_default_timezone_get(), $object['dtstart'] , $bd_format )) : day_translate(datetime_convert('UTC', 'UTC', $object['dtstart'] , $bd_format))),
'$finish' => (($object['nofinish']) ? false : true),
- '$dtend_label' => t('Finishes:'),
- '$dtend_title' => datetime_convert('UTC','UTC',$object['dtend'], (($object['adjust']) ? ATOM_TIME : 'Y-m-d\TH:i:s' )),
- '$dtend_dt' => (($object['adjust']) ? day_translate(datetime_convert('UTC', date_default_timezone_get(), $object['dtend'] , $bd_format )) : day_translate(datetime_convert('UTC', 'UTC', $object['dtend'] , $bd_format )))
+ '$dtend_label' => t('End:'),
+ '$dtend_title' => datetime_convert($tz, date_default_timezone_get(), $object['dtend'], (($object['adjust']) ? ATOM_TIME : 'Y-m-d\TH:i:s' )),
+ '$dtend_dt' => (($object['adjust']) ? day_translate(datetime_convert($tz, date_default_timezone_get(), $object['dtend'] , $bd_format )) : day_translate(datetime_convert('UTC', 'UTC', $object['dtend'] , $bd_format ))),
+ '$allday' => $allday,
+ '$oneday' => $oneday
));
$event['content'] = replace_macros(get_markup_template('event_item_content.tpl'),array(
@@ -125,6 +144,12 @@ function format_event_ical($ev) {
if($ev['etype'] === 'task')
return format_todo_ical($ev);
+ $tz = get_iconfig($ev['item_id'], 'event', 'timezone');
+ if(! $tz)
+ $tz = 'UTC';
+
+ $tzid = ';TZID=' . $tz;
+
$o = '';
$o .= "\r\nBEGIN:VEVENT";
@@ -132,10 +157,19 @@ function format_event_ical($ev) {
$o .= "\r\nCREATED:" . datetime_convert('UTC','UTC', $ev['created'],'Ymd\\THis\\Z');
$o .= "\r\nLAST-MODIFIED:" . datetime_convert('UTC','UTC', $ev['edited'],'Ymd\\THis\\Z');
$o .= "\r\nDTSTAMP:" . datetime_convert('UTC','UTC', $ev['edited'],'Ymd\\THis\\Z');
- if($ev['dtstart'])
- $o .= "\r\nDTSTART:" . datetime_convert('UTC','UTC', $ev['dtstart'],'Ymd\\THis' . (($ev['adjust']) ? '\\Z' : ''));
- if($ev['dtend'] && ! $ev['nofinish'])
- $o .= "\r\nDTEND:" . datetime_convert('UTC','UTC', $ev['dtend'],'Ymd\\THis' . (($ev['adjust']) ? '\\Z' : ''));
+
+ if($ev['adjust']) {
+ if($ev['dtstart'])
+ $o .= "\r\nDTSTART$tzid:" . datetime_convert($tz,'UTC', $ev['dtstart'],'Ymd\\THis\\Z');
+ if($ev['dtend'] && ! $ev['nofinish'])
+ $o .= "\r\nDTEND$tzid:" . datetime_convert($tz,'UTC', $ev['dtend'],'Ymd\\THis\\Z');
+ }
+ else {
+ if($ev['dtstart'])
+ $o .= "\r\nDTSTART;VALUE=DATE:" . datetime_convert('UTC','UTC', $ev['dtstart'],'Ymd');
+ if($ev['dtend'] && ! $ev['nofinish'])
+ $o .= "\r\nDTEND;VALUE=DATE:" . datetime_convert('UTC','UTC', $ev['dtend'],'Ymd');
+ }
if($ev['summary']) {
$o .= "\r\nSUMMARY:" . format_ical_text($ev['summary']);
$o .= "\r\nX-ZOT-SUMMARY:" . format_ical_sourcetext($ev['summary']);
@@ -723,17 +757,9 @@ function parse_vobject($ical, $type) {
function parse_ical_file($f,$uid) {
- require_once('vendor/autoload.php');
$s = @file_get_contents($f);
- // Change the current timezone to something besides UTC.
- // Doesn't matter what it is, as long as it isn't UTC.
- // Save the current timezone so we can reset it when we're done processing.
-
- $saved_timezone = date_default_timezone_get();
- date_default_timezone_set('Australia/Sydney');
-
$ical = VObject\Reader::read($s);
if($ical) {
@@ -749,8 +775,6 @@ function parse_ical_file($f,$uid) {
}
}
- date_default_timezone_set($saved_timezone);
-
if($ical)
return true;
@@ -782,12 +806,23 @@ function event_import_ical($ical, $uid) {
// logger('dtstart: ' . var_export($dtstart,true));
- $ev['dtstart'] = datetime_convert((($ev['adjust']) ? 'UTC' : date_default_timezone_get()),'UTC',
+ $ev['timezone'] = 'UTC';
+
+ // Try to get an usable olson format timezone
+ if($ev['adjust']) {
+ //TODO: we should pass the vcalendar to getTimeZone() to be more accurate
+ // we do not have it here since parse_ical_file() is passing the vevent only.
+ $timezone_obj = \Sabre\VObject\TimeZoneUtil::getTimeZone($ical->DTSTART['TZID']);
+ $timezone = $timezone_obj->getName();
+ $ev['timezone'] = $timezone;
+ }
+
+ $ev['dtstart'] = datetime_convert((($ev['adjust']) ? 'UTC' : date_default_timezone_get()),$ev['timezone'],
$dtstart->format(\DateTime::W3C));
if(isset($ical->DTEND)) {
$dtend = $ical->DTEND->getDateTime();
- $ev['dtend'] = datetime_convert((($ev['adjust']) ? 'UTC' : date_default_timezone_get()),'UTC',
+ $ev['dtend'] = datetime_convert((($ev['adjust']) ? 'UTC' : date_default_timezone_get()),$ev['timezone'],
$dtend->format(\DateTime::W3C));
}
else {
@@ -1042,6 +1077,7 @@ function event_store_item($arr, $event) {
'type' => ACTIVITY_OBJ_EVENT,
'id' => z_root() . '/event/' . $r[0]['resource_id'],
'title' => $arr['summary'],
+ 'timezone' => $arr['timezone'],
'dtstart' => $arr['dtstart'],
'dtend' => $arr['dtend'],
'nofinish' => $arr['nofinish'],
@@ -1107,6 +1143,8 @@ function event_store_item($arr, $event) {
}
$item_id = $r[0]['id'];
+ set_iconfig($item_id, 'event', 'timezone', $arr['timezone'], true);
+
/**
* @hooks event_updated
* Called when an event record is modified.
@@ -1163,7 +1201,7 @@ function event_store_item($arr, $event) {
$item_arr['item_thread_top'] = $item_thread_top;
$attach = array(array(
- 'href' => z_root() . '/events/ical/' . urlencode($event['event_hash']),
+ 'href' => z_root() . '/channel_calendar/ical/' . urlencode($event['event_hash']),
'length' => 0,
'type' => 'text/calendar',
'title' => t('event') . '-' . $event['event_hash'],
@@ -1185,7 +1223,7 @@ function event_store_item($arr, $event) {
// otherwise we'll fallback to /display/$message_id
if($wall)
- $item_arr['plink'] = z_root() . '/channel/' . $z[0]['channel_address'] . '/?f=&mid=' . urlencode($item_arr['mid']);
+ $item_arr['plink'] = z_root() . '/channel/' . $z[0]['channel_address'] . '/?f=&mid=' . gen_link_id($item_arr['mid']);
else
$item_arr['plink'] = z_root() . '/display/' . gen_link_id($item_arr['mid']);
@@ -1197,6 +1235,7 @@ function event_store_item($arr, $event) {
'type' => ACTIVITY_OBJ_EVENT,
'id' => z_root() . '/event/' . $event['event_hash'],
'title' => $arr['summary'],
+ 'timezone' => $arr['timezone'],
'dtstart' => $arr['dtstart'],
'dtend' => $arr['dtend'],
'nofinish' => $arr['nofinish'],
@@ -1223,6 +1262,7 @@ function event_store_item($arr, $event) {
// activities refer to the item message_id as the parent.
set_iconfig($item_arr, 'system','event_id',$event['event_hash'],true);
+ set_iconfig($item_arr, 'event','timezone',$arr['timezone'],true);
$res = item_store($item_arr);
@@ -1284,6 +1324,10 @@ function cdav_principal($uri) {
}
function cdav_perms($needle, $haystack, $check_rw = false) {
+
+ if($needle == 'channel_calendar')
+ return true;
+
foreach ($haystack as $item) {
if($check_rw) {
if(is_array($item['id'])) {
diff --git a/include/features.php b/include/features.php
index d021f9394..9528d3418 100644
--- a/include/features.php
+++ b/include/features.php
@@ -79,7 +79,7 @@ function get_features($filtered = true, $level = (-1)) {
'calendar' => [
- t('CalDAV'),
+ t('Calendar'),
[
'cal_first_day',
@@ -87,6 +87,14 @@ function get_features($filtered = true, $level = (-1)) {
t('Default is Sunday'),
false,
get_config('feature_lock','cal_first_day')
+ ],
+
+ [
+ 'event_tz_select',
+ t('Event Timezone Selection'),
+ t('Allow event creation in timezones other than your own.'),
+ false,
+ get_config('feature_lock','event_tz_select'),
]
],
@@ -167,6 +175,14 @@ function get_features($filtered = true, $level = (-1)) {
t('Ability to mark special posts with a star indicator'),
false,
get_config('feature_lock','star_posts'),
+ ],
+
+ [
+ 'reply_to',
+ t('Reply on comment'),
+ t('Ability to reply on selected comment'),
+ false,
+ get_config('feature_lock','reply_to'),
]
],
@@ -274,22 +290,6 @@ function get_features($filtered = true, $level = (-1)) {
t('Default is Sunday'),
false,
get_config('feature_lock','events_cal_first_day')
- ],
-
- [
- 'smart_birthdays',
- t('Smart Birthdays'),
- t('Make birthday events timezone aware in case your friends are scattered across the planet.'),
- true,
- get_config('feature_lock','smart_birthdays'),
- ],
-
- [
- 'event_tz_select',
- t('Event Timezone Selection'),
- t('Allow event creation in timezones other than your own.'),
- false,
- get_config('feature_lock','event_tz_select'),
]
],
diff --git a/include/follow.php b/include/follow.php
index 1b35f1b32..50b952881 100644
--- a/include/follow.php
+++ b/include/follow.php
@@ -142,7 +142,7 @@ function new_contact($uid,$url,$channel,$interactive = false, $confirm = false)
$sql_options = (($protocol) ? " and xchan_network = '" . dbesc($protocol) . "' " : '');
- $r = q("select * from xchan where xchan_hash = '%s' or xchan_url = '%s' $sql_options limit 1",
+ $r = q("select * from xchan where xchan_hash = '%s' or xchan_url = '%s' $sql_options ",
dbesc($url),
dbesc($url)
);
@@ -169,18 +169,19 @@ function new_contact($uid,$url,$channel,$interactive = false, $confirm = false)
}
if($wf || $d) {
- $r = q("select * from xchan where xchan_hash = '%s' or xchan_url = '%s' limit 1",
+ $r = q("select * from xchan where xchan_hash = '%s' or xchan_url = '%s'",
dbesc(($wf) ? $wf : $url),
dbesc($url)
);
}
}
+ $xchan = zot_record_preferred($r,'xchan_network');
+
// if discovery was a success we should have an xchan record in $r
- if($r) {
- $xchan = $r[0];
- $xchan_hash = $r[0]['xchan_hash'];
+ if($xchan) {
+ $xchan_hash = $xchan['xchan_hash'];
$their_perms = 0;
}
}
@@ -191,9 +192,9 @@ function new_contact($uid,$url,$channel,$interactive = false, $confirm = false)
return $result;
}
- $allowed = (($is_zot || in_array($r[0]['xchan_network'],['rss','zot6'])) ? 1 : 0);
+ $allowed = (($is_zot || in_array($xchan['xchan_network'],['rss','zot6'])) ? 1 : 0);
- $x = array('channel_id' => $uid, 'follow_address' => $url, 'xchan' => $r[0], 'allowed' => $allowed, 'singleton' => 0);
+ $x = array('channel_id' => $uid, 'follow_address' => $url, 'xchan' => $xchan, 'allowed' => $allowed, 'singleton' => 0);
call_hooks('follow_allow',$x);
diff --git a/include/import.php b/include/import.php
index 7a1e9aa55..4da0d1a0b 100644
--- a/include/import.php
+++ b/include/import.php
@@ -94,7 +94,8 @@ function import_channel($channel, $account_id, $seize, $newname = '') {
'channel_w_comment', 'channel_w_mail', 'channel_w_like', 'channel_w_tagwall',
'channel_w_chat', 'channel_w_storage', 'channel_w_pages', 'channel_a_republish',
'channel_a_delegate', 'perm_limits', 'channel_password', 'channel_salt',
- 'channel_moved', 'channel_removed', 'channel_deleted', 'channel_system'
+ 'channel_moved', 'channel_removed', 'channel_deleted', 'channel_system',
+ 'channel_r_photos', 'channel_w_photos'
];
$clean = array();
@@ -896,9 +897,9 @@ function import_menus($channel, $menus) {
$m['menu_name'] = $menu['pagetitle'];
$m['menu_desc'] = $menu['desc'];
if($menu['created'])
- $m['menu_created'] = datetime_convert($menu['created']);
+ $m['menu_created'] = datetime_convert('UTC','UTC',$menu['created']);
if($menu['edited'])
- $m['menu_edited'] = datetime_convert($menu['edited']);
+ $m['menu_edited'] = datetime_convert('UTC','UTC',$menu['edited']);
$m['menu_flags'] = 0;
if($menu['flags']) {
@@ -954,9 +955,9 @@ function sync_menus($channel, $menus) {
$m['menu_name'] = $menu['pagetitle'];
$m['menu_desc'] = $menu['desc'];
if($menu['created'])
- $m['menu_created'] = datetime_convert($menu['created']);
+ $m['menu_created'] = datetime_convert('UTC','UTC',$menu['created']);
if($menu['edited'])
- $m['menu_edited'] = datetime_convert($menu['edited']);
+ $m['menu_edited'] = datetime_convert('UTC','UTC',$menu['edited']);
$m['menu_flags'] = 0;
if($menu['flags']) {
@@ -1345,6 +1346,7 @@ function sync_files($channel, $files) {
logger('attachment store failed',LOGGER_NORMAL,LOG_ERR);
}
if($f['photo']) {
+
foreach($f['photo'] as $p) {
unset($p['id']);
$p['aid'] = $channel['channel_account_id'];
@@ -1366,6 +1368,7 @@ function sync_files($channel, $files) {
dbesc($p['resource_id']),
intval($channel['channel_id'])
);
+ $update_xchan = $p['edited'];
}
// same for cover photos
@@ -1385,19 +1388,20 @@ function sync_files($channel, $files) {
else
$p['content'] = (($p['content'])? base64_decode($p['content']) : '');
- if(intval($p['imgscale']) && (! $p['content'])) {
+ if(intval($p['imgscale']) && (! empty($p['content']))) {
$time = datetime_convert();
- $parr = array('hash' => $channel['channel_hash'],
+ $parr = array(
+ 'hash' => $channel['channel_hash'],
'time' => $time,
- 'resource' => $att['hash'],
+ 'resource' => $p['resource_id'],
'revision' => 0,
'signature' => base64url_encode(rsa_sign($channel['channel_hash'] . '.' . $time, $channel['channel_prvkey'])),
- 'resolution' => $p['imgscale']
+ 'resolution' => intval($p['imgscale'])
);
- $stored_image = $newfname . '-' . intval($p['imgscale']);
+ $stored_image = $newfname . '-' . $p['imgscale'];
$fp = fopen($stored_image,'w');
if(! $fp) {
@@ -1406,7 +1410,6 @@ function sync_files($channel, $files) {
}
$redirects = 0;
-
$headers = [];
$headers['Accept'] = 'application/x-zot+json' ;
$headers['Sigtoken'] = random_string();
@@ -1414,8 +1417,17 @@ function sync_files($channel, $files) {
$x = z_post_url($fetch_url,$parr,$redirects,[ 'filep' => $fp, 'headers' => $headers]);
fclose($fp);
- $p['content'] = file_get_contents($stored_image);
- unlink($stored_image);
+
+ // Override remote hub thumbnails storage settings
+ if(! boolval(get_config('system','filesystem_storage_thumbnails', 0))) {
+ $p['os_storage'] = 0;
+ $p['content'] = file_get_contents($stored_image);
+ @unlink($stored_image);
+ }
+ else {
+ $p['os_storage'] = 1;
+ $p['content'] = $stored_image;
+ }
}
if(!isset($p['display_path']))
@@ -1447,6 +1459,16 @@ function sync_files($channel, $files) {
create_table_from_array('photo',$p, [ 'content' ] );
}
}
+
+ }
+
+ // Set xchan photo date to prevent thumbnails fetch for clones on profile update packet recieve
+ if(isset($update_xchan)) {
+
+ $x = q("UPDATE xchan SET xchan_photo_date = '%s' WHERE xchan_hash = '%s'",
+ dbescdate($update_xchan),
+ dbesc($channel['channel_hash'])
+ );
}
\Zotlabs\Daemon\Master::Summon([ 'Thumbnail' , $att['hash'] ]);
@@ -1621,12 +1643,12 @@ function import_webpage_element($element, $channel, $type) {
$arr['created'] = $iteminfo[0]['created'];
}
else { // otherwise, generate the creation times and unique id
- $arr['created'] = datetime_convert('UTC', 'UTC');
+ $arr['created'] = datetime_convert();
$arr['uuid'] = item_message_id();
$arr['mid'] = $arr['parent_mid'] = z_root() . '/item/' . $arr['uuid'];
}
// Update the edited time whether or not the element already exists
- $arr['edited'] = datetime_convert('UTC', 'UTC');
+ $arr['edited'] = datetime_convert();
// Import the actual element content
$arr['body'] = file_get_contents($element['path']);
// The element owner is the channel importing the elements
diff --git a/include/items.php b/include/items.php
index c08deb3a0..95b696034 100755
--- a/include/items.php
+++ b/include/items.php
@@ -4278,7 +4278,7 @@ function items_fetch($arr,$channel = null,$observer_hash = null,$client_mode = C
if($arr['mid'])
$sql_options .= " and parent_mid = '" . dbesc($arr['mid']) . "' ";
- $sql_extra = " AND item.parent IN ( SELECT parent FROM item WHERE item_thread_top = 1 $sql_options $item_normal ) ";
+ $sql_extra = " AND item.parent IN ( SELECT parent FROM item WHERE $item_uids and item_thread_top = 1 $sql_options $item_normal ) ";
if($arr['since_id'])
$sql_extra .= " and item.id > " . $since_id . " ";
diff --git a/include/js_strings.php b/include/js_strings.php
index c053e5666..f01fa87ae 100644
--- a/include/js_strings.php
+++ b/include/js_strings.php
@@ -33,6 +33,7 @@ function js_strings() {
'$name_empty' => t('A channel name is required.'),
'$name_ok1' => t('This is a '),
'$name_ok2' => t(' channel name'),
+ '$to_reply' => t('Back to reply'),
// translatable prefix and suffix strings for jquery.timeago -
// using the defaults set below if left untranslated, empty strings if
diff --git a/include/markdown.php b/include/markdown.php
index 2513a7d77..7d1f16958 100644
--- a/include/markdown.php
+++ b/include/markdown.php
@@ -76,6 +76,8 @@ function markdown_to_bb($s, $use_zrl = false, $options = []) {
$s = html2bbcode($s);
+ $s = bb_code_protect($s);
+
// Convert everything that looks like a link to a link
if($use_zrl) {
if (strpos($s,'[/img]') !== false) {
@@ -88,6 +90,8 @@ function markdown_to_bb($s, $use_zrl = false, $options = []) {
$s = preg_replace("/([^\]\=\{\/]|^)(https?\:\/\/)([a-zA-Z0-9\pL\:\/\-\?\&\;\.\=\_\~\#\%\$\!\+\,\@\(\)]+)/ismu", '$1[url=$2$3]$2$3[/url]',$s);
}
+ $s = bb_code_unprotect($s);
+
// remove duplicate adjacent code tags
$s = preg_replace("/(\[code\])+(.*?)(\[\/code\])+/ism","[code]$2[/code]", $s);
diff --git a/include/oembed.php b/include/oembed.php
index 426197c5f..ee9e57c3f 100755
--- a/include/oembed.php
+++ b/include/oembed.php
@@ -1,6 +1,6 @@
<?php /** @file */
-use Zotlabs\Lib as Zlib;
+use Zotlabs\Lib\Cache;
function oembed_replacecb($matches){
@@ -133,7 +133,6 @@ function oembed_fetch_url($embedurl){
}
}
-
$txt = null;
// we should try to cache this and avoid a lookup on each render
@@ -143,10 +142,22 @@ function oembed_fetch_url($embedurl){
$furl = ((local_channel() && $zrl) ? zid($embedurl) : $embedurl);
- if($action !== 'block') {
- $txt = Zlib\Cache::get('[' . App::$videowidth . '] ' . $furl);
+ if($action !== 'block' && (! get_config('system','oembed_cache_disable'))) {
+ $txt = Cache::get('[' . App::$videowidth . '] ' . $furl);
}
+
+ if(strpos(strtolower($embedurl),'.pdf') !== false) {
+ $action = 'allow';
+ $j = [
+ 'html' => '<object data="' . $embedurl . '" type="application/pdf" style="width: 100%; height: 300px;"></object>',
+ 'title' => t('View PDF'),
+ 'type' => 'pdf'
+ ];
+ // set $txt to something so that we don't attempt to fetch what could be a lengthy pdf.
+ $txt = EMPTY_STR;
+ }
+
if(is_null($txt)) {
$txt = "";
@@ -215,20 +226,10 @@ function oembed_fetch_url($embedurl){
// save in cache
if(! get_config('system','oembed_cache_disable'))
- Zlib\Cache::set('[' . App::$videowidth . '] ' . $furl, $txt);
+ Cache::set('[' . App::$videowidth . '] ' . $furl, $txt);
}
- if(strpos(strtolower($embedurl),'.pdf') !== false) {
- $action = 'allow';
- $j = [
- 'html' => '<object data="' . $embedurl . '" type="application/pdf" style="width: 100%; height: 300px;"></object>',
- 'title' => t('View PDF'),
- 'type' => 'pdf'
- ];
-
- }
-
if(! $j) {
$j = json_decode($txt,true);
}
diff --git a/include/photos.php b/include/photos.php
index 44406e0b0..7ea2729ae 100644
--- a/include/photos.php
+++ b/include/photos.php
@@ -277,8 +277,7 @@ function photo_upload($channel, $observer, $args) {
if(($width > 1024 || $height > 1024) && (! $errors))
$ph->scaleImage(1024);
- $p['imgscale'] = 1;
- $r1 = $ph->save($p);
+ $r1 = $ph->storeThumbnail($p, PHOTO_RES_1024);
$link[1] = array(
'rel' => 'alternate',
'type' => 'text/html',
@@ -292,8 +291,7 @@ function photo_upload($channel, $observer, $args) {
if(($width > 640 || $height > 640) && (! $errors))
$ph->scaleImage(640);
- $p['imgscale'] = 2;
- $r2 = $ph->save($p);
+ $r2 = $ph->storeThumbnail($p, PHOTO_RES_640);
$link[2] = array(
'rel' => 'alternate',
'type' => 'text/html',
@@ -307,8 +305,7 @@ function photo_upload($channel, $observer, $args) {
if(($width > 320 || $height > 320) && (! $errors))
$ph->scaleImage(320);
- $p['imgscale'] = 3;
- $r3 = $ph->save($p);
+ $r3 = $ph->storeThumbnail($p, PHOTO_RES_320);
$link[3] = array(
'rel' => 'alternate',
'type' => 'text/html',
diff --git a/include/text.php b/include/text.php
index 41603f6e4..a2dfda952 100644
--- a/include/text.php
+++ b/include/text.php
@@ -409,7 +409,8 @@ function autoname($len) {
* @return string Escaped text.
*/
function xmlify($str) {
- $buffer = '';
+
+ //$buffer = '';
if(is_array($str)) {
@@ -418,7 +419,7 @@ function xmlify($str) {
btlogger('xmlify called with array: ' . print_r($str,true), LOGGER_NORMAL, LOG_WARNING);
}
-
+/*
$len = mb_strlen($str);
for($x = 0; $x < $len; $x ++) {
$char = mb_substr($str,$x,1);
@@ -452,6 +453,11 @@ function xmlify($str) {
$buffer = trim($buffer);
return($buffer);
+*/
+ $buffer = htmlspecialchars($str, ENT_QUOTES, "UTF-8");
+ $buffer = trim($buffer);
+ return $buffer;
+
}
/**
@@ -464,10 +470,23 @@ function xmlify($str) {
* @return string
*/
function unxmlify($s) {
+/*
$ret = str_replace('&amp;', '&', $s);
$ret = str_replace(array('&lt;', '&gt;', '&quot;', '&apos;'), array('<', '>', '"', "'"), $ret);
return $ret;
+*/
+
+ if(is_array($s)) {
+
+ // allow to fall through so we ge a PHP error, as the log statement will
+ // probably get lost in the noise unless we're specifically looking for it.
+
+ btlogger('unxmlify called with array: ' . print_r($s,true), LOGGER_NORMAL, LOG_WARNING);
+ }
+
+ $ret = htmlspecialchars_decode($s, ENT_QUOTES);
+ return $ret;
}
/**
@@ -3071,13 +3090,12 @@ function item_url_replace($channel,&$item,$old,$new,$oldnick = '') {
if($oldnick)
json_url_replace('/' . $oldnick . '/' ,'/' . $channel['channel_address'] . '/' ,$item['target']);
}
+
+ $item['body'] = preg_replace("/(\[zrl=".preg_quote($old,'/')."\/(photo|photos|gallery)\/".$channel['channel_address'].".+\]\[zmg=\d+x\d+\])".preg_quote($old,'/')."\/(.+\[\/zmg\])/", '${1}'.$new.'/${3}', $item['body']);
+ $item['body'] = preg_replace("/".preg_quote($old,'/')."\/(search|\w+\/".$channel['channel_address'].")/", $new.'/${1}', $item['body']);
- $x = preg_replace("/".preg_quote($old,'/')."\/(search|\w+\/".$channel['channel_address'].")/", $new.'/${1}', $item['body']);
- if($x) {
- $item['body'] = $x;
- $item['sig'] = base64url_encode(rsa_sign($item['body'],$channel['channel_prvkey']));
- $item['item_verified'] = 1;
- }
+ $item['sig'] = base64url_encode(rsa_sign($item['body'],$channel['channel_prvkey']));
+ $item['item_verified'] = 1;
$item['plink'] = str_replace($old,$new,$item['plink']);
if($oldnick)
diff --git a/include/zot.php b/include/zot.php
index 5ced4ee8c..a37b7cdb5 100644
--- a/include/zot.php
+++ b/include/zot.php
@@ -925,46 +925,62 @@ function import_xchan($arr, $ud_flags = UPDATE_FLAGS_UPDATED, $ud_arr = null) {
$local = q("select channel_account_id, channel_id from channel where channel_hash = '%s' limit 1",
dbesc($xchan_hash)
);
+
if($local) {
+ // @FIXME This should be removed in future when profile photo update by file sync procedure will be applied
+ // on most hubs in the network
+ // <---
$ph = z_fetch_url($arr['photo'], true);
+
if($ph['success']) {
+
+ // Do not fetch already received thumbnails
+ $x = q("SELECT resource_id FROM photo WHERE uid = %d AND imgscale = %d AND filesize = %d LIMIT 1",
+ intval($local[0]['channel_id']),
+ intval(PHOTO_RES_PROFILE_300),
+ strlen($ph['body'])
+ );
+
+ if($x)
+ $hash = $x[0]['resource_id'];
+ else
+ $hash = import_channel_photo($ph['body'], $arr['photo_mimetype'], $local[0]['channel_account_id'], $local[0]['channel_id']);
+ }
+
+ if($hash) {
+ // unless proven otherwise
+ $is_default_profile = 1;
+
+ $profile = q("select is_default from profile where aid = %d and uid = %d limit 1",
+ intval($local[0]['channel_account_id']),
+ intval($local[0]['channel_id'])
+ );
+ if($profile) {
+ if(! intval($profile[0]['is_default']))
+ $is_default_profile = 0;
+ }
- $hash = import_channel_photo($ph['body'], $arr['photo_mimetype'], $local[0]['channel_account_id'], $local[0]['channel_id']);
-
- if($hash) {
- // unless proven otherwise
- $is_default_profile = 1;
-
- $profile = q("select is_default from profile where aid = %d and uid = %d limit 1",
+ // If setting for the default profile, unset the profile photo flag from any other photos I own
+ if($is_default_profile) {
+ q("UPDATE photo SET photo_usage = %d WHERE photo_usage = %d AND resource_id != '%s' AND aid = %d AND uid = %d",
+ intval(PHOTO_NORMAL),
+ intval(PHOTO_PROFILE),
+ dbesc($hash),
intval($local[0]['channel_account_id']),
intval($local[0]['channel_id'])
);
- if($profile) {
- if(! intval($profile[0]['is_default']))
- $is_default_profile = 0;
- }
-
- // If setting for the default profile, unset the profile photo flag from any other photos I own
- if($is_default_profile) {
- q("UPDATE photo SET photo_usage = %d WHERE photo_usage = %d AND resource_id != '%s' AND aid = %d AND uid = %d",
- intval(PHOTO_NORMAL),
- intval(PHOTO_PROFILE),
- dbesc($hash),
- intval($local[0]['channel_account_id']),
- intval($local[0]['channel_id'])
- );
- }
}
-
- // reset the names in case they got messed up when we had a bug in this function
- $photos = array(
- z_root() . '/photo/profile/l/' . $local[0]['channel_id'],
- z_root() . '/photo/profile/m/' . $local[0]['channel_id'],
- z_root() . '/photo/profile/s/' . $local[0]['channel_id'],
- $arr['photo_mimetype'],
- false
- );
}
+ // --->
+
+ // reset the names in case they got messed up when we had a bug in this function
+ $photos = array(
+ z_root() . '/photo/profile/l/' . $local[0]['channel_id'],
+ z_root() . '/photo/profile/m/' . $local[0]['channel_id'],
+ z_root() . '/photo/profile/s/' . $local[0]['channel_id'],
+ $arr['photo_mimetype'],
+ false
+ );
}
else {
$photos = import_xchan_photo($arr['photo'], $xchan_hash);
@@ -3634,7 +3650,7 @@ function process_channel_sync_delivery($sender, $arr, $deliveries) {
'channel_r_storage', 'channel_r_pages', 'channel_w_stream', 'channel_w_wall',
'channel_w_comment', 'channel_w_mail', 'channel_w_like', 'channel_w_tagwall',
'channel_w_chat', 'channel_w_storage', 'channel_w_pages', 'channel_a_republish',
- 'channel_a_delegate', 'channel_moved'
+ 'channel_a_delegate', 'channel_moved', 'channel_r_photos', 'channel_w_photos'
];
$clean = array();
@@ -4414,7 +4430,7 @@ function zotinfo($arr) {
$profile['description'] = $p[0]['pdesc'];
$profile['birthday'] = $p[0]['dob'];
- if(($profile['birthday'] != '0000-00-00') && (($bd = z_birthday($p[0]['dob'],$e['channel_timezone'])) !== ''))
+ if(($profile['birthday'] != '0000-00-00') && (($bd = z_birthday($p[0]['dob'],'UTC')) !== ''))
$profile['next_birthday'] = $bd;
if($age = age($p[0]['dob'],$e['channel_timezone'],''))