diff options
Diffstat (limited to 'include')
-rw-r--r-- | include/api_zot.php | 9 | ||||
-rw-r--r-- | include/attach.php | 4 | ||||
-rw-r--r-- | include/bbcode.php | 12 | ||||
-rw-r--r-- | include/channel.php | 123 | ||||
-rw-r--r-- | include/cli_startup.php | 2 | ||||
-rw-r--r-- | include/feedutils.php | 20 | ||||
-rw-r--r-- | include/items.php | 62 | ||||
-rw-r--r-- | include/nav.php | 9 | ||||
-rw-r--r-- | include/text.php | 2 |
9 files changed, 157 insertions, 86 deletions
diff --git a/include/api_zot.php b/include/api_zot.php index 8f621d998..9beaaa19c 100644 --- a/include/api_zot.php +++ b/include/api_zot.php @@ -87,12 +87,13 @@ return false; } $sections = (($_REQUEST['sections']) ? explode(',',$_REQUEST['sections']) : ''); + $codebase = ((isset($_REQUEST['zap_compat']) && $_REQUEST['zap_compat']) ? true : false); if($_REQUEST['posts']) { $sections = get_default_export_sections(); $sections[] = 'items'; } - json_return_and_die(identity_basic_export(api_user(),$sections)); + json_return_and_die(identity_basic_export(api_user(),$sections,$codebase)); } function api_item_export_page($type) { @@ -111,8 +112,9 @@ $start = datetime_convert(date_default_timezone_get(),'UTC', $_REQUEST['since']); } $finish = datetime_convert(date_default_timezone_get(),'UTC', (($_REQUEST['until']) ? $_REQUEST['until'] : 'now')); + $codebase = ((isset($_REQUEST['zap_compat']) && $_REQUEST['zap_compat']) ? true : false); - json_return_and_die(channel_export_items_page(api_user(),$start,$finish,$page,$records)); + json_return_and_die(channel_export_items_page(api_user(),$start,$finish,$page,$records,$codebase)); } @@ -289,10 +291,11 @@ return false; if(! $_REQUEST['file_id']) return false; + $codebase = ((isset($_REQUEST['zap_compat']) && $_REQUEST['zap_compat']) ? true : false); $channel = channelx_by_n(api_user()); - $ret = attach_export_data($channel,$_REQUEST['file_id']); + $ret = attach_export_data($channel,$_REQUEST['file_id'],false,$codebase); if($ret) { json_return_and_die($ret); diff --git a/include/attach.php b/include/attach.php index 9ba6be109..db7046ef0 100644 --- a/include/attach.php +++ b/include/attach.php @@ -2339,7 +2339,7 @@ function filepath_macro($s) { } -function attach_export_data($channel, $resource_id, $deleted = false) { +function attach_export_data($channel, $resource_id, $deleted = false, $zap_compat = false) { $ret = array(); @@ -2429,7 +2429,7 @@ function attach_export_data($channel, $resource_id, $deleted = false) { xchan_query($items); $items = fetch_post_tags($items,true); foreach($items as $rr) - $ret['item'][] = encode_item($rr,true); + $ret['item'][] = encode_item($rr,true,$zap_compat); } } } diff --git a/include/bbcode.php b/include/bbcode.php index 5a71ada0c..a5ef6760b 100644 --- a/include/bbcode.php +++ b/include/bbcode.php @@ -1530,18 +1530,18 @@ function bbcode($Text, $options = []) { // html5 video and audio if (strpos($Text,'[/video]') !== false) { - $Text = preg_replace_callback("/\[video (.*?)\](.*?\.(ogg|ogv|oga|ogm|webm|mp4|mpeg|mpg))\[\/video\]/ism", 'videowithopts', $Text); - $Text = preg_replace_callback("/\[video\](.*?\.(ogg|ogv|oga|ogm|webm|mp4|mpeg|mpg))\[\/video\]/ism", 'tryzrlvideo', $Text); + $Text = preg_replace_callback("/\[video (.*?)\](.*?)\[\/video\]/ism", 'videowithopts', $Text); + $Text = preg_replace_callback("/\[video\](.*?)\[\/video\]/ism", 'tryzrlvideo', $Text); } if (strpos($Text,'[/audio]') !== false) { - $Text = preg_replace_callback("/\[audio\](.*?\.(ogg|ogv|oga|ogm|webm|mp4|mp3|opus|m4a))\[\/audio\]/ism", 'tryzrlaudio', $Text); + $Text = preg_replace_callback("/\[audio\](.*?)\[\/audio\]/ism", 'tryzrlaudio', $Text); } if (strpos($Text,'[/zvideo]') !== false) { - $Text = preg_replace_callback("/\[zvideo (.*?)\](.*?\.(ogg|ogv|oga|ogm|webm|mp4|mpeg|mpg))\[\/zvideo\]/ism", 'videowithopts', $Text); - $Text = preg_replace_callback("/\[zvideo\](.*?\.(ogg|ogv|oga|ogm|webm|mp4|mpeg|mpg))\[\/zvideo\]/ism", 'tryzrlvideo', $Text); + $Text = preg_replace_callback("/\[zvideo (.*?)\](.*?)\[\/zvideo\]/ism", 'videowithopts', $Text); + $Text = preg_replace_callback("/\[zvideo\](.*?)\[\/zvideo\]/ism", 'tryzrlvideo', $Text); } if (strpos($Text,'[/zaudio]') !== false) { - $Text = preg_replace_callback("/\[zaudio\](.*?\.(ogg|ogv|oga|ogm|webm|mp4|mp3|opus|m4a))\[\/zaudio\]/ism", 'tryzrlaudio', $Text); + $Text = preg_replace_callback("/\[zaudio\](.*?)\[\/zaudio\]/ism", 'tryzrlaudio', $Text); } // SVG stuff diff --git a/include/channel.php b/include/channel.php index 08b5ee889..c6ca673eb 100644 --- a/include/channel.php +++ b/include/channel.php @@ -891,20 +891,27 @@ function identity_basic_export($channel_id, $sections = null, $zap_compat = fals unset($ret['channel']['channel_salt']); } if ($zap_compat) { - $channel['channel_guid_sig'] = 'sha256.' . $channel['channel_guid_sig']; - $channel['channel_hash'] = $channel['channel_portable_id']; - unset($channel['channel_portable_id']); + unset($ret['channel']['channel_portable_id']); } - - } if(in_array('channel',$sections) || in_array('profile',$sections)) { $r = q("select * from profile where uid = %d", intval($channel_id) ); - if($r) + if($r) { $ret['profile'] = $r; + if ($zap_compat) { + // zap only supports one profile + foreach ($r as $rv) { + if ($rv['is_default']) { + $ret['profile'] = [ $rv ]; + break; + } + } + } + } + $r = q("select mimetype, content, os_storage from photo where imgscale = 4 and photo_usage = %d and uid = %d limit 1", @@ -937,50 +944,47 @@ function identity_basic_export($channel_id, $sections = null, $zap_compat = fals $newconfig = []; $abconfig = load_abconfig($channel_id,$ret['abook'][$x]['abook_xchan']); - // Partly revert of commit 85cf25a2a8bfbbfe10de485d4affd54626fbbfa4 if($abconfig) { - $ret['abook'][$x]['abconfig'] = $abconfig; - } + if ($zap_compat) { + foreach ($abconfig as $abc) { + + if ($abc['cat'] === 'my_perms') { + if (intval($abc['v'])) { + $my_perms[] = $abc['k']; + } + continue; + } + if ($abc['cat'] === 'their_perms') { + if (intval($abc['v'])) { + $their_perms[] = $abc['k']; + } + continue; + } + if (preg_match('|^a:[0-9]+:{.*}$|s', $abc['v'])) { + $abc['v'] = serialise(unserialize($abc['v'])); + } + $newconfig[] = $abc; + } - /* This was added in commit 85cf25a2a8bfbbfe10de485d4affd54626fbbfa4 - * Seems unfinished work on zap compatibility for cloning. - * It breaks cloning of abconfig for hubzilla - reverted to the above code. + $ret['abook'][$x]['abconfig'] = $newconfig; - if($abconfig) { - foreach ($abconfig as $abc) { + $ret['abook'][$x]['abconfig'][] = [ 'chan' => $channel_id, 'xchan' => $ret['abook'][$x]['abook_xchan'], 'cat' => 'system', 'k' => 'my_perms', 'v' => implode(',',$my_perms) ]; + $ret['abook'][$x]['abconfig'][] = [ 'chan' => $channel_id, 'xchan' => $ret['abook'][$x]['abook_xchan'], 'cat' => 'system', 'k' => 'their_perms', 'v' => implode(',',$their_perms) ]; - if ($abc['cat'] === 'my_perms' && intval($abc['v'])) { - $my_perms[] = $abc['k']; - continue; - } - if ($abc['cat'] === 'their_perms' && intval($abc['v'])) { - $their_perms[] = $abc['k']; - continue; - } - if ($zap_compat && preg_match('|^a:[0-9]+:{.*}$|s', $abc['v'])) { - $abc['v'] = serialise(unserialize($abc['v'])); - } - $newconfig[] = $abc; } - - $ret['abook'][$x]['abconfig'] = $newconfig; - - if ($zap_compat) { - $ret['abook'][$x]['abconfig'][] = [ 'chan' => $channel_id, 'xchan' => $ret['abook'][$x]['abook_chan'], 'cat' => 'system', 'k' => 'my_perms', 'v' => implode(',',$my_perms) ]; - $ret['abook'][$x]['abconfig'][] = [ 'chan' => $channel_id, 'xchan' => $ret['abook'][$x]['abook_chan'], 'cat' => 'system', 'k' => 'their_perms', 'v' => implode(',',$their_perms) ]; + else { + $ret['abook'][$x]['abconfig'] = $abconfig; } } - */ + translate_abook_perms_outbound($ret['abook'][$x]); } - - // pick up the zot xchan and hublocs also - if($ret['channel']['channel_portable_id']) { + if($ret['channel']['channel_portable_id'] && ! $zot_compat) { $xchans[] = $ret['channel']['channel_portable_id']; } @@ -1091,13 +1095,24 @@ function identity_basic_export($channel_id, $sections = null, $zap_compat = fals } if(in_array('events',$sections)) { - $r = q("select * from event where uid = %d", + + // @fixme - Not totally certain how to handle $zot_compat for the event timezone which exists + // in Hubzilla but is stored with the item and not the event. In Zap, stored information is + // always UTC and localised on access as per standard conventions for working with global time data. + + // Older Zot (pre-Zot6) records aren't translated correctly w/r/t AS2 so only include events for the last year or so if + // migrating to Zap. + + $sqle = (($zap_compat) ? " and created > '2020-01-01 00:00:00' " : ''); + + $r = q("select * from event where uid = %d $sqle", intval($channel_id) ); - if($r) + if ($r) { $ret['event'] = $r; + } - $r = q("select * from item where resource_type = 'event' and uid = %d", + $r = q("select * from item where resource_type = 'event' and uid = %d $sqle", intval($channel_id) ); if($r) { @@ -1105,7 +1120,7 @@ function identity_basic_export($channel_id, $sections = null, $zap_compat = fals xchan_query($r); $r = fetch_post_tags($r,true); foreach($r as $rr) - $ret['event_item'][] = encode_item($rr,true); + $ret['event_item'][] = encode_item($rr,true, $zap_compat); } } @@ -1128,7 +1143,7 @@ function identity_basic_export($channel_id, $sections = null, $zap_compat = fals xchan_query($r); $r = fetch_post_tags($r,true); foreach($r as $rr) - $ret['webpages'][] = encode_item($rr,true); + $ret['webpages'][] = encode_item($rr,true, $zap_compat); } } @@ -1165,7 +1180,7 @@ function identity_basic_export($channel_id, $sections = null, $zap_compat = fals xchan_query($r); $r = fetch_post_tags($r,true); foreach($r as $rv) { - $ret['wiki'][] = encode_item($rv,true); + $ret['wiki'][] = encode_item($rv,true, $zap_compat); } } } @@ -1190,7 +1205,7 @@ function identity_basic_export($channel_id, $sections = null, $zap_compat = fals xchan_query($r); $r = fetch_post_tags($r,true); foreach($r as $rr) - $ret['item'][] = encode_item($rr,true); + $ret['item'][] = encode_item($rr,true, $zap_compat); } } @@ -1223,7 +1238,7 @@ function identity_basic_export($channel_id, $sections = null, $zap_compat = fals * * \e array \b relocate - (optional) * * \e array \b item - array with items encoded_item() */ -function identity_export_year($channel_id, $year, $month = 0) { +function identity_export_year($channel_id, $year, $month = 0, $zap_compat = false) { if(! $year) return array(); @@ -1241,7 +1256,7 @@ function identity_export_year($channel_id, $year, $month = 0) { else $maxdate = datetime_convert('UTC', 'UTC', $year+1 . '-01-01 00:00:00'); - return channel_export_items_date($channel_id,$mindate,$maxdate); + return channel_export_items_date($channel_id,$mindate,$maxdate, $zap_compat); } @@ -1256,7 +1271,7 @@ function identity_export_year($channel_id, $year, $month = 0) { * @return array */ -function channel_export_items_date($channel_id, $start, $finish) { +function channel_export_items_date($channel_id, $start, $finish, $zap_compat = false) { if(! $start) return array(); @@ -1274,6 +1289,11 @@ function channel_export_items_date($channel_id, $start, $finish) { $ret['relocate'] = [ 'channel_address' => $ch['channel_address'], 'url' => z_root()]; } + if ($zap_compat) { + $ret['compatibility']['codebase'] = 'zap'; + } + + $r = q("select * from item where ( item_wall = 1 or item_type != %d ) and item_deleted = 0 and uid = %d and created >= '%s' and created <= '%s' and resource_type != 'photo' order by created", intval(ITEM_TYPE_POST), intval($channel_id), @@ -1286,7 +1306,7 @@ function channel_export_items_date($channel_id, $start, $finish) { xchan_query($r); $r = fetch_post_tags($r, true); foreach($r as $rr) - $ret['item'][] = encode_item($rr, true); + $ret['item'][] = encode_item($rr, true, $zap_compat); } return $ret; @@ -1304,7 +1324,7 @@ function channel_export_items_date($channel_id, $start, $finish) { * @return array */ -function channel_export_items_page($channel_id, $start, $finish, $page = 0, $limit = 50) { +function channel_export_items_page($channel_id, $start, $finish, $page = 0, $limit = 50, $zap_compat = false) { if(intval($page) < 1) { $page = 0; @@ -1336,6 +1356,11 @@ function channel_export_items_page($channel_id, $start, $finish, $page = 0, $lim $ret['relocate'] = [ 'channel_address' => $ch['channel_address'], 'url' => z_root()]; } + if ($zap_compat) { + $ret['compatibility']['codebase'] = 'zap'; + } + + $r = q("select * from item where ( item_wall = 1 or item_type != %d ) and item_deleted = 0 and uid = %d and resource_type != 'photo' and created >= '%s' and created <= '%s' order by created limit %d offset %d", intval(ITEM_TYPE_POST), intval($channel_id), @@ -1350,7 +1375,7 @@ function channel_export_items_page($channel_id, $start, $finish, $page = 0, $lim xchan_query($r); $r = fetch_post_tags($r, true); foreach($r as $rr) - $ret['item'][] = encode_item($rr, true); + $ret['item'][] = encode_item($rr, true, $zap_compat); } return $ret; diff --git a/include/cli_startup.php b/include/cli_startup.php index a4c1f629a..b9e7d124d 100644 --- a/include/cli_startup.php +++ b/include/cli_startup.php @@ -9,4 +9,4 @@ function cli_startup() { sys_boot(); App::set_baseurl(get_config('system','baseurl')); -}
\ No newline at end of file +} diff --git a/include/feedutils.php b/include/feedutils.php index 352b8f038..9cb645ff8 100644 --- a/include/feedutils.php +++ b/include/feedutils.php @@ -722,17 +722,17 @@ function get_atom_elements($feed, $item) { if(! $type) $type = 'application/octet-stream'; - if($ostatus_protocol) { - if((strpos($type,'image') === 0) && (strpos($res['body'], ']' . $link . '[/img]') === false) && (strpos($link,'http') === 0)) { - $res['body'] .= "\n\n" . '[img]' . $link . '[/img]'; - } - if((strpos($type,'video') === 0) && (strpos($res['body'], ']' . $link . '[/video]') === false) && (strpos($link,'http') === 0)) { - $res['body'] .= "\n\n" . '[video]' . $link . '[/video]'; - } - if((strpos($type,'audio') === 0) && (strpos($res['body'], ']' . $link . '[/audio]') === false) && (strpos($link,'http') === 0)) { - $res['body'] .= "\n\n" . '[audio]' . $link . '[/audio]'; - } + // put media enclosures in bbcode markup + if((strpos($type,'image') === 0) && (strpos($res['body'], ']' . $link . '[/img]') === false) && (strpos($link,'http') === 0)) { + $res['body'] .= "\n\n" . '[img]' . $link . '[/img]'; + } + if((strpos($type,'video') === 0) && (strpos($res['body'], ']' . $link . '[/video]') === false) && (strpos($link,'http') === 0)) { + $res['body'] .= "\n\n" . '[video]' . $link . '[/video]'; + } + if((strpos($type,'audio') === 0) && (strpos($res['body'], ']' . $link . '[/audio]') === false) && (strpos($link,'http') === 0)) { + $res['body'] .= "\n\n" . '[audio]' . $link . '[/audio]'; } + $res['attach'][] = array('href' => $link, 'length' => $len, 'type' => $type, 'title' => $title ); } } diff --git a/include/items.php b/include/items.php index ce1461aba..88f100e60 100644 --- a/include/items.php +++ b/include/items.php @@ -1089,7 +1089,7 @@ function empty_acl($item) { return (($item['allow_cid'] === EMPTY_STR && $item['allow_gid'] === EMPTY_STR && $item['deny_cid'] === EMPTY_STR && $item['deny_gid'] === EMPTY_STR) ? true : false); } -function encode_item($item,$mirror = false) { +function encode_item($item,$mirror = false,$zap_compat = false) { $x = []; $x['type'] = 'activity'; $x['encoding'] = 'zot'; @@ -1167,9 +1167,9 @@ function encode_item($item,$mirror = false) { $x['summary'] = $item['summary']; $x['body'] = $item['body']; $x['app'] = $item['app']; - $x['verb'] = $item['verb']; - $x['object_type'] = $item['obj_type']; - $x['target_type'] = $item['tgt_type']; + $x['verb'] = (($zap_compat) ? Activity::activity_mapper($item['verb']) : $item['verb']); + $x['object_type'] = (($zap_compat && $item['obj_type']) ? Activity::activity_obj_mapper($item['obj_type']) : $item['obj_type']); + $x['target_type'] = (($zap_compat && $item['tgt_type']) ? Activity::activity_obj_mapper($item['tgt_type']) : $item['tgt_type']); $x['permalink'] = $item['plink']; $x['location'] = $item['location']; $x['longlat'] = $item['coord']; @@ -1178,10 +1178,19 @@ function encode_item($item,$mirror = false) { $x['owner'] = encode_item_xchan($item['owner']); $x['author'] = encode_item_xchan($item['author']); - if($item['obj']) - $x['object'] = json_decode($item['obj'],true); + if ($zap_compat) { + $x['object'] = Activity::encode_item_object($item,'obj'); + } + else { + if ($item['obj']) { + $x['object'] = json_decode($item['obj'],true); + } + } + if($item['target']) - $x['target'] = json_decode($item['target'],true); + $x['target'] = (($zap_compat) + ? Activity::encode_item_object($item,'target') + : json_decode($item['target'],true)) ; if($item['attach']) $x['attach'] = json_decode($item['attach'],true); if($y = encode_item_flags($item)) @@ -1200,9 +1209,16 @@ function encode_item($item,$mirror = false) { if($item['term']) $x['tags'] = encode_item_terms($item['term'],$mirror); - if($item['iconfig']) + if($item['iconfig']) { + if ($zap_compat) { + for ($y = 0; $y < count($item['iconfig']); $y ++) { + if (preg_match('|^a:[0-9]+:{.*}$|s', $item['iconfig'][$y]['v'])) { + $item['iconfig'][$y]['v'] = serialise(unserialize($item['iconfig'][$y]['v'])); + } + } + } $x['meta'] = encode_item_meta($item['iconfig'],$mirror); - + } logger('encode_item: ' . print_r($x,true), LOGGER_DATA); @@ -1400,6 +1416,30 @@ function decode_tags($t) { return ''; } + +function purify_imported_object($obj) { + $ret = null; + if (is_array($obj)) { + foreach ( $obj as $k => $v ) { + if (is_array($v)) { + $ret[$k] = purify_imported_object($v); + } + elseif (is_string($v)) { + $ret[$k] = purify_html($v); + } + } + } + elseif (is_string($obj)) { + $ret = purify_html($obj); + } + + return $ret; +} + + + + + /** * @brief Santise a potentially complex array. * @@ -1411,6 +1451,10 @@ function activity_sanitise($arr) { if(is_array($arr)) { $ret = array(); foreach($arr as $k => $x) { + if (in_array($k, [ 'content', 'summary', 'contentMap', 'summaryMap' ])) { + $ret[$k] = purify_imported_object($arr[$k]); + continue; + } if(is_array($x)) $ret[$k] = activity_sanitise($x); else diff --git a/include/nav.php b/include/nav.php index 1ad8dad58..994f7e0c0 100644 --- a/include/nav.php +++ b/include/nav.php @@ -295,11 +295,10 @@ function nav($template = 'default') { foreach ($syslist as $app) { if (isset(App::$nav_sel['name']) && App::$nav_sel['name'] == $app['name']) $app['active'] = true; - if ($is_owner) { $nav_apps[] = Apps::app_render($app, 'nav'); } - elseif (!$is_owner && isset($app['requires']) && strpos($app['requires'], 'local_channel') === false) { + elseif (!$is_owner && (!isset($app['requires']) || (isset($app['requires']) && strpos($app['requires'], 'local_channel') === false))) { $nav_apps[] = Apps::app_render($app, 'nav'); } } @@ -400,9 +399,9 @@ function channel_apps($is_owner = false, $nickname = null) { $sql_options = item_permissions_sql($uid); $r = q("select item.* from item left join iconfig on item.id = iconfig.iid - where item.uid = %d and iconfig.cat = 'system' and iconfig.v = '%s' - and item.item_delayed = 0 and item.item_deleted = 0 - and ( iconfig.k = 'WEBPAGE' and item_type = %d ) + where item.uid = %d and iconfig.cat = 'system' and iconfig.v = '%s' + and item.item_delayed = 0 and item.item_deleted = 0 + and ( iconfig.k = 'WEBPAGE' and item_type = %d ) $sql_options limit 1", intval($uid), dbesc('home'), diff --git a/include/text.php b/include/text.php index b7cc0ba20..ca3453b64 100644 --- a/include/text.php +++ b/include/text.php @@ -2837,7 +2837,7 @@ function handle_tag(&$body, &$str_tags, $profile_uid, $tag, $in_network = true) // replace tag by the link. Make sure to not replace something in the middle of a word - $body = preg_replace('/(?<![a-zA-Z0-9=])'.preg_quote($tag,'/').'/', $newtag, $body); + $body = preg_replace('/(?<![a-zA-Z0-9=\/])'.preg_quote($tag,'/').'/', $newtag, $body); $replaced = true; } |