Merge branch 'origin' into 'master'

Update 4.2

See merge request harukin/core!56
This commit is contained in:
harukin
2019-06-09 11:19:02 +09:00
668 changed files with 55338 additions and 50483 deletions

View File

@@ -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)

View File

@@ -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 ($cache) {
$Text = str_replace([ '[map]','[/map]' ], [ '','' ], $Text);
$Text = preg_replace('/\[map=(.*?)\]/ism','$1',$Text);
}
if (strpos($Text,'[map=') !== false) {
$Text = preg_replace_callback("/\[map=(.*?)\]/ism", 'bb_map_coords', $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);
}
}
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);

View File

@@ -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);

View File

@@ -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",

View File

@@ -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 [];
}

View File

@@ -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 : '');

View File

@@ -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'])) {

View File

@@ -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'),
]
],

View File

@@ -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);

View File

@@ -219,8 +219,7 @@ function html2bbcode($message)
$message = $doc->saveHTML();
// I'm removing something really disturbing
// Don't know exactly what it is
// I'm removing the UTF-8 encoding of a NO-BREAK SPACE codepoint
$message = str_replace(chr(194).chr(160), ' ', $message);
$message = str_replace("&nbsp;", " ", $message);

View File

@@ -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

View File

@@ -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 . " ";

View File

@@ -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

View File

@@ -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);

View File

@@ -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);
}

View File

@@ -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',

View File

@@ -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,9 +470,22 @@ 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;
}
@@ -3079,13 +3098,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)

View File

@@ -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'])
);
$hash = import_channel_photo($ph['body'], $arr['photo_mimetype'], $local[0]['channel_account_id'], $local[0]['channel_id']);
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;
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;
}
$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'],''))