Beispiel #1
0
/**
 * @brief Create an array representing the important channel information
 * which would be necessary to create a nomadic identity clone. This includes
 * most channel resources and connection information with the exception of content.
 *
 * @param int $channel_id
 *     Channel_id to export
 * @param boolean $items
 *     Include channel posts (wall items), default false
 *
 * @returns array
 *     See function for details
 */
function identity_basic_export($channel_id, $items = false)
{
    /*
     * Red basic channel export
     */
    $ret = array();
    // use constants here as otherwise we will have no idea if we can import from a site
    // with a non-standard platform and version.
    $ret['compatibility'] = array('project' => PLATFORM_NAME, 'version' => STD_VERSION, 'database' => DB_UPDATE_VERSION, 'server_role' => Zotlabs\Lib\System::get_server_role());
    $r = q("select * from channel where channel_id = %d limit 1", intval($channel_id));
    if ($r) {
        translate_channel_perms_outbound($r[0]);
        $ret['channel'] = $r[0];
        $ret['relocate'] = ['channel_address' => $r[0]['channel_address'], 'url' => z_root()];
    }
    $r = q("select * from profile where uid = %d", intval($channel_id));
    if ($r) {
        $ret['profile'] = $r;
    }
    $xchans = array();
    $r = q("select * from abook where abook_channel = %d ", intval($channel_id));
    if ($r) {
        $ret['abook'] = $r;
        for ($x = 0; $x < count($ret['abook']); $x++) {
            $xchans[] = $ret['abook'][$x]['abook_chan'];
            $abconfig = load_abconfig($channel_id, $ret['abook'][$x]['abook_xchan']);
            if ($abconfig) {
                $ret['abook'][$x]['abconfig'] = $abconfig;
            }
            translate_abook_perms_outbound($ret['abook'][$x]);
        }
        stringify_array_elms($xchans);
    }
    if ($xchans) {
        $r = q("select * from xchan where xchan_hash in ( " . implode(',', $xchans) . " ) ");
        if ($r) {
            $ret['xchan'] = $r;
        }
        $r = q("select * from hubloc where hubloc_hash in ( " . implode(',', $xchans) . " ) ");
        if ($r) {
            $ret['hubloc'] = $r;
        }
    }
    $r = q("select * from `groups` where uid = %d ", intval($channel_id));
    if ($r) {
        $ret['group'] = $r;
    }
    $r = q("select * from group_member where uid = %d ", intval($channel_id));
    if ($r) {
        $ret['group_member'] = $r;
    }
    $r = q("select * from pconfig where uid = %d", intval($channel_id));
    if ($r) {
        $ret['config'] = $r;
    }
    $r = q("select mimetype, content, os_storage from photo where imgscale = 4 and photo_usage = %d and uid = %d limit 1", intval(PHOTO_PROFILE), intval($channel_id));
    if ($r) {
        $ret['photo'] = array('type' => $r[0]['mimetype'], 'data' => $r[0]['os_storage'] ? base64url_encode(file_get_contents($r[0]['content'])) : base64url_encode($r[0]['content']));
    }
    // All other term types will be included in items, if requested.
    $r = q("select * from term where ttype in (%d,%d) and uid = %d", intval(TERM_SAVEDSEARCH), intval(TERM_THING), intval($channel_id));
    if ($r) {
        $ret['term'] = $r;
    }
    // add psuedo-column obj_baseurl to aid in relocations
    $r = q("select obj.*, '%s' as obj_baseurl from obj where obj_channel = %d", dbesc(z_root()), intval($channel_id));
    if ($r) {
        $ret['obj'] = $r;
    }
    $r = q("select * from app where app_channel = %d and app_system = 0", intval($channel_id));
    if ($r) {
        for ($x = 0; $x < count($r); $x++) {
            $r[$x]['term'] = q("select * from term where otype = %d and oid = %d", intval(TERM_OBJ_APP), intval($r[$x]['id']));
        }
        $ret['app'] = $r;
    }
    $r = q("select * from chatroom where cr_uid = %d", intval($channel_id));
    if ($r) {
        $ret['chatroom'] = $r;
    }
    $r = q("select * from event where uid = %d", intval($channel_id));
    if ($r) {
        $ret['event'] = $r;
    }
    $r = q("select * from item where resource_type = 'event' and uid = %d", intval($channel_id));
    if ($r) {
        $ret['event_item'] = array();
        xchan_query($r);
        $r = fetch_post_tags($r, true);
        foreach ($r as $rr) {
            $ret['event_item'][] = encode_item($rr, true);
        }
    }
    $x = menu_list($channel_id);
    if ($x) {
        $ret['menu'] = array();
        for ($y = 0; $y < count($x); $y++) {
            $m = menu_fetch($x[$y]['menu_name'], $channel_id, $ret['channel']['channel_hash']);
            if ($m) {
                $ret['menu'][] = menu_element($ret['channel'], $m);
            }
        }
    }
    $addon = array('channel_id' => $channel_id, 'data' => $ret);
    call_hooks('identity_basic_export', $addon);
    $ret = $addon['data'];
    if (!$items) {
        return $ret;
    }
    $r = q("select * from likes where channel_id = %d", intval($channel_id));
    if ($r) {
        $ret['likes'] = $r;
    }
    $r = q("select * from conv where uid = %d", intval($channel_id));
    if ($r) {
        for ($x = 0; $x < count($r); $x++) {
            $r[$x]['subject'] = base64url_decode(str_rot47($r[$x]['subject']));
        }
        $ret['conv'] = $r;
    }
    $r = q("select * from mail where mail.uid = %d", intval($channel_id));
    if ($r) {
        $m = array();
        foreach ($r as $rr) {
            xchan_mail_query($rr);
            $m[] = mail_encode($rr, true);
        }
        $ret['mail'] = $m;
    }
    /** @warning this may run into memory limits on smaller systems */
    /** export three months of posts. If you want to export and import all posts you have to start with 
     * the first year and export/import them in ascending order. 
     *
     * Don't export linked resource items. we'll have to pull those out separately.
     */
    $r = q("select * from item where item_wall = 1 and item_deleted = 0 and uid = %d and created > %s - INTERVAL %s and resource_type = '' order by created", intval($channel_id), db_utcnow(), db_quoteinterval('3 MONTH'));
    if ($r) {
        $ret['item'] = array();
        xchan_query($r);
        $r = fetch_post_tags($r, true);
        foreach ($r as $rr) {
            $ret['item'][] = encode_item($rr, true);
        }
    }
    return $ret;
}
Beispiel #2
0
/**
 * Send a zot packet to all hubs where this channel is duplicated, refreshing
 * such things as personal settings, channel permissions, address book updates, etc.
 *
 * @param int $uid
 * @param array $packet (optional) default null
 * @param boolean $groups_changed (optional) default false
 */
function build_sync_packet($uid = 0, $packet = null, $groups_changed = false)
{
    if (get_config('system', 'server_role') === 'basic') {
        return;
    }
    logger('build_sync_packet');
    if ($packet) {
        logger('packet: ' . print_r($packet, true), LOGGER_DATA, LOG_DEBUG);
    }
    if (!$uid) {
        $uid = local_channel();
    }
    if (!$uid) {
        return;
    }
    $r = q("select * from channel where channel_id = %d limit 1", intval($uid));
    if (!$r) {
        return;
    }
    $channel = $r[0];
    translate_channel_perms_outbound($channel);
    if ($packet && array_key_exists('abook', $packet) && $packet['abook']) {
        for ($x = 0; $x < count($packet['abook']); $x++) {
            translate_abook_perms_outbound($packet['abook'][$x]);
        }
    }
    if (intval($channel['channel_removed'])) {
        return;
    }
    $h = q("select * from hubloc where hubloc_hash = '%s' and hubloc_deleted = 0", dbesc($channel['channel_hash']));
    if (!$h) {
        return;
    }
    $synchubs = array();
    foreach ($h as $x) {
        if ($x['hubloc_host'] == App::get_hostname()) {
            continue;
        }
        $y = q("select site_dead from site where site_url = '%s' limit 1", dbesc($x['hubloc_url']));
        if (!$y || $y[0]['site_dead'] == 0) {
            $synchubs[] = $x;
        }
    }
    if (!$synchubs) {
        return;
    }
    $r = q("select xchan_guid, xchan_guid_sig from xchan where xchan_hash  = '%s' limit 1", dbesc($channel['channel_hash']));
    if (!$r) {
        return;
    }
    $env_recips = array();
    $env_recips[] = array('guid' => $r[0]['xchan_guid'], 'guid_sig' => $r[0]['xchan_guid_sig']);
    $info = $packet ? $packet : array();
    $info['type'] = 'channel_sync';
    $info['encoding'] = 'red';
    // note: not zot, this packet is very platform specific
    $info['relocate'] = ['channel_address' => $channel['channel_address'], 'url' => z_root()];
    if (array_key_exists($uid, App::$config) && array_key_exists('transient', App::$config[$uid])) {
        $settings = App::$config[$uid]['transient'];
        if ($settings) {
            $info['config'] = $settings;
        }
    }
    if ($channel) {
        $info['channel'] = array();
        foreach ($channel as $k => $v) {
            // filter out any joined tables like xchan
            if (strpos($k, 'channel_') !== 0) {
                continue;
            }
            // don't pass these elements, they should not be synchronised
            $disallowed = array('channel_id', 'channel_account_id', 'channel_primary', 'channel_prvkey', 'channel_address', 'channel_deleted', 'channel_removed', 'channel_system');
            if (in_array($k, $disallowed)) {
                continue;
            }
            $info['channel'][$k] = $v;
        }
    }
    if ($groups_changed) {
        $r = q("select hash as collection, visible, deleted, gname as name from groups where uid = %d", intval($uid));
        if ($r) {
            $info['collections'] = $r;
        }
        $r = q("select groups.hash as collection, group_member.xchan as member from groups left join group_member on groups.id = group_member.gid where group_member.uid = %d", intval($uid));
        if ($r) {
            $info['collection_members'] = $r;
        }
    }
    $interval = get_config('system', 'delivery_interval') !== false ? intval(get_config('system', 'delivery_interval')) : 2;
    logger('build_sync_packet: packet: ' . print_r($info, true), LOGGER_DATA, LOG_DEBUG);
    $total = count($synchubs);
    foreach ($synchubs as $hub) {
        $hash = random_string();
        $n = zot_build_packet($channel, 'notify', $env_recips, $hub['hubloc_sitekey'], $hash);
        queue_insert(array('hash' => $hash, 'account_id' => $channel['channel_account_id'], 'channel_id' => $channel['channel_id'], 'posturl' => $hub['hubloc_callback'], 'notify' => $n, 'msg' => json_encode($info)));
        Zotlabs\Daemon\Master::Summon(array('Deliver', $hash));
        $total = $total - 1;
        if ($interval && $total) {
            @time_sleep_until(microtime(true) + (double) $interval);
        }
    }
}