Beispiel #1
0
function import_account(&$a, $account_id)
{
    if (!$account_id) {
        logger("import_account: No account ID supplied");
        return;
    }
    $max_identities = account_service_class_fetch($account_id, 'total_identities');
    $max_friends = account_service_class_fetch($account_id, 'total_channels');
    $max_feeds = account_service_class_fetch($account_id, 'total_feeds');
    if ($max_identities !== false) {
        $r = q("select channel_id from channel where channel_account_id = %d", intval($account_id));
        if ($r && count($r) > $max_identities) {
            notice(sprintf(t('Your service plan only allows %d channels.'), $max_identities) . EOL);
            return;
        }
    }
    $data = null;
    $seize = x($_REQUEST, 'make_primary') ? intval($_REQUEST['make_primary']) : 0;
    $import_posts = x($_REQUEST, 'import_posts') ? intval($_REQUEST['import_posts']) : 0;
    $src = $_FILES['filename']['tmp_name'];
    $filename = basename($_FILES['filename']['name']);
    $filesize = intval($_FILES['filename']['size']);
    $filetype = $_FILES['filename']['type'];
    $completed = array_key_exists('import_step', $_SESSION) ? intval($_SESSION['import_step']) : 0;
    if ($completed) {
        logger('saved import step: ' . $_SESSION['import_step']);
    }
    if ($src) {
        // This is OS specific and could also fail if your tmpdir isn't very large
        // mostly used for Diaspora which exports gzipped files.
        if (strpos($filename, '.gz')) {
            @rename($src, $src . '.gz');
            @system('gunzip ' . escapeshellarg($src . '.gz'));
        }
        if ($filesize) {
            $data = @file_get_contents($src);
        }
        unlink($src);
    }
    if (!$src) {
        $old_address = x($_REQUEST, 'old_address') ? $_REQUEST['old_address'] : '';
        if (!$old_address) {
            logger('mod_import: nothing to import.');
            notice(t('Nothing to import.') . EOL);
            return;
        }
        $email = x($_REQUEST, 'email') ? $_REQUEST['email'] : '';
        $password = x($_REQUEST, 'password') ? $_REQUEST['password'] : '';
        $channelname = substr($old_address, 0, strpos($old_address, '@'));
        $servername = substr($old_address, strpos($old_address, '@') + 1);
        $scheme = 'https://';
        $api_path = '/api/red/channel/export/basic?f=&channel=' . $channelname;
        if ($import_posts) {
            $api_path .= '&posts=1';
        }
        $binary = false;
        $redirects = 0;
        $opts = array('http_auth' => $email . ':' . $password);
        $url = $scheme . $servername . $api_path;
        $ret = z_fetch_url($url, $binary, $redirects, $opts);
        if (!$ret['success']) {
            $ret = z_fetch_url('http://' . $servername . $api_path, $binary, $redirects, $opts);
        }
        if ($ret['success']) {
            $data = $ret['body'];
        } else {
            notice(t('Unable to download data from old server') . EOL);
        }
    }
    if (!$data) {
        logger('mod_import: empty file.');
        notice(t('Imported file is empty.') . EOL);
        return;
    }
    $data = json_decode($data, true);
    //	logger('import: data: ' . print_r($data,true));
    //	print_r($data);
    if (array_key_exists('user', $data) && array_key_exists('version', $data)) {
        require_once 'include/Import/import_diaspora.php';
        import_diaspora($data);
        return;
    }
    if (array_key_exists('compatibility', $data) && array_key_exists('database', $data['compatibility'])) {
        $v1 = substr($data['compatibility']['database'], -4);
        $v2 = substr(DB_UPDATE_VERSION, -4);
        if ($v2 > $v1) {
            $t = sprintf(t('Warning: Database versions differ by %1$d updates.'), $v2 - $v1);
            notice($t);
        }
    }
    // import channel
    if (array_key_exists('channel', $data)) {
        if ($completed < 1) {
            $channel = import_channel($data['channel'], $account_id);
        } else {
            $r = q("select * from channel where channel_account_id = %d and channel_guid = '%s' limit 1", intval($account_id), dbesc($channel['channel_guid']));
            if ($r) {
                $channel = $r[0];
            }
        }
        if (!$channel) {
            logger('mod_import: channel not found. ', print_r($channel, true));
            notice(t('Cloned channel not found. Import failed.') . EOL);
            return;
        }
    }
    if (!$channel) {
        $channel = $a->get_channel();
    }
    if (!$channel) {
        logger('mod_import: channel not found. ', print_r($channel, true));
        notice(t('No channel. Import failed.') . EOL);
        return;
    }
    if ($completed < 2) {
        if (is_array($data['config'])) {
            import_config($channel, $data['config']);
        }
        logger('import step 2');
        $_SESSION['import_step'] = 2;
        ref_session_write(session_id(), serialize($_SESSION));
    }
    if ($completed < 3) {
        if ($data['photo']) {
            require_once 'include/photo/photo_driver.php';
            import_channel_photo(base64url_decode($data['photo']['data']), $data['photo']['type'], $account_id, $channel['channel_id']);
        }
        if (is_array($data['profile'])) {
            import_profiles($channel, $data['profile']);
        }
        logger('import step 3');
        $_SESSION['import_step'] = 3;
        ref_session_write(session_id(), serialize($_SESSION));
    }
    if ($completed < 4) {
        if (is_array($data['hubloc'])) {
            import_hublocs($channel, $data['hubloc'], $seize);
        }
        logger('import step 4');
        $_SESSION['import_step'] = 4;
        ref_session_write(session_id(), serialize($_SESSION));
    }
    if ($completed < 5) {
        // create new hubloc for the new channel at this site
        $r = q("insert into hubloc ( hubloc_guid, hubloc_guid_sig, hubloc_hash, hubloc_addr, hubloc_network, hubloc_primary, \n\t\t\thubloc_url, hubloc_url_sig, hubloc_host, hubloc_callback, hubloc_sitekey )\n\t\t\tvalues ( '%s', '%s', '%s', '%s', '%s', %d, '%s', '%s', '%s', '%s', '%s' )", dbesc($channel['channel_guid']), dbesc($channel['channel_guid_sig']), dbesc($channel['channel_hash']), dbesc($channel['channel_address'] . '@' . get_app()->get_hostname()), dbesc('zot'), intval($seize ? 1 : 0), dbesc(z_root()), dbesc(base64url_encode(rsa_sign(z_root(), $channel['channel_prvkey']))), dbesc(get_app()->get_hostname()), dbesc(z_root() . '/post'), dbesc(get_config('system', 'pubkey')));
        // reset the original primary hubloc if it is being seized
        if ($seize) {
            $r = q("update hubloc set hubloc_primary = 0 where hubloc_primary = 1 and hubloc_hash = '%s' and hubloc_url != '%s' ", dbesc($channel['channel_hash']), dbesc(z_root()));
        }
        logger('import step 5');
        $_SESSION['import_step'] = 5;
        ref_session_write(session_id(), serialize($_SESSION));
    }
    if ($completed < 6) {
        // import xchans and contact photos
        if ($seize) {
            // replace any existing xchan we may have on this site if we're seizing control
            $r = q("delete from xchan where xchan_hash = '%s'", dbesc($channel['channel_hash']));
            $r = q("insert into xchan ( xchan_hash, xchan_guid, xchan_guid_sig, xchan_pubkey, xchan_photo_l, xchan_photo_m, xchan_photo_s, xchan_addr, xchan_url, xchan_follow, xchan_connurl, xchan_name, xchan_network, xchan_photo_date, xchan_name_date, xchan_hidden, xchan_orphan, xchan_censored, xchan_selfcensored, xchan_system, xchan_pubforum, xchan_deleted ) values ('%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', %d, %d, %d, %d, %d, %d, %d )", dbesc($channel['channel_hash']), dbesc($channel['channel_guid']), dbesc($channel['channel_guid_sig']), dbesc($channel['channel_pubkey']), dbesc($a->get_baseurl() . "/photo/profile/l/" . $channel['channel_id']), dbesc($a->get_baseurl() . "/photo/profile/m/" . $channel['channel_id']), dbesc($a->get_baseurl() . "/photo/profile/s/" . $channel['channel_id']), dbesc($channel['channel_address'] . '@' . get_app()->get_hostname()), dbesc(z_root() . '/channel/' . $channel['channel_address']), dbesc(z_root() . '/follow?f=&url=%s'), dbesc(z_root() . '/poco/' . $channel['channel_address']), dbesc($channel['channel_name']), dbesc('zot'), dbesc(datetime_convert()), dbesc(datetime_convert()), 0, 0, 0, 0, 0, 0, 0);
        }
        logger('import step 6');
        $_SESSION['import_step'] = 6;
        ref_session_write(session_id(), serialize($_SESSION));
    }
    if ($completed < 7) {
        $xchans = $data['xchan'];
        if ($xchans) {
            foreach ($xchans as $xchan) {
                $hash = make_xchan_hash($xchan['xchan_guid'], $xchan['xchan_guid_sig']);
                if ($xchan['xchan_network'] === 'zot' && $hash !== $xchan['xchan_hash']) {
                    logger('forged xchan: ' . print_r($xchan, true));
                    continue;
                }
                if (!array_key_exists('xchan_hidden', $xchan)) {
                    $xchan['xchan_hidden'] = $xchan['xchan_flags'] & 0x1 ? 1 : 0;
                    $xchan['xchan_orphan'] = $xchan['xchan_flags'] & 0x2 ? 1 : 0;
                    $xchan['xchan_censored'] = $xchan['xchan_flags'] & 0x4 ? 1 : 0;
                    $xchan['xchan_selfcensored'] = $xchan['xchan_flags'] & 0x8 ? 1 : 0;
                    $xchan['xchan_system'] = $xchan['xchan_flags'] & 0x10 ? 1 : 0;
                    $xchan['xchan_pubforum'] = $xchan['xchan_flags'] & 0x20 ? 1 : 0;
                    $xchan['xchan_deleted'] = $xchan['xchan_flags'] & 0x1000 ? 1 : 0;
                }
                $r = q("select xchan_hash from xchan where xchan_hash = '%s' limit 1", dbesc($xchan['xchan_hash']));
                if ($r) {
                    continue;
                }
                dbesc_array($xchan);
                $r = dbq("INSERT INTO xchan (`" . implode("`, `", array_keys($xchan)) . "`) VALUES ('" . implode("', '", array_values($xchan)) . "')");
                require_once 'include/photo/photo_driver.php';
                $photos = import_xchan_photo($xchan['xchan_photo_l'], $xchan['xchan_hash']);
                if ($photos[4]) {
                    $photodate = NULL_DATE;
                } else {
                    $photodate = $xchan['xchan_photo_date'];
                }
                $r = q("update xchan set xchan_photo_l = '%s', xchan_photo_m = '%s', xchan_photo_s = '%s', xchan_photo_mimetype = '%s', xchan_photo_date = '%s'\n\t\t\t\t\twhere xchan_hash = '%s'", dbesc($photos[0]), dbesc($photos[1]), dbesc($photos[2]), dbesc($photos[3]), dbesc($photodate), dbesc($xchan['xchan_hash']));
            }
        }
        logger('import step 7');
        $_SESSION['import_step'] = 7;
        ref_session_write(session_id(), serialize($_SESSION));
    }
    // FIXME - ensure we have an xchan if somebody is trying to pull a fast one
    if ($completed < 8) {
        $friends = 0;
        $feeds = 0;
        // import contacts
        $abooks = $data['abook'];
        if ($abooks) {
            foreach ($abooks as $abook) {
                unset($abook['abook_id']);
                unset($abook['abook_rating']);
                unset($abook['abook_rating_text']);
                $abook['abook_account'] = $account_id;
                $abook['abook_channel'] = $channel['channel_id'];
                if (!array_key_exists('abook_blocked', $abook)) {
                    $abook['abook_blocked'] = $abook['abook_flags'] & 0x1 ? 1 : 0;
                    $abook['abook_ignored'] = $abook['abook_flags'] & 0x2 ? 1 : 0;
                    $abook['abook_hidden'] = $abook['abook_flags'] & 0x4 ? 1 : 0;
                    $abook['abook_archived'] = $abook['abook_flags'] & 0x8 ? 1 : 0;
                    $abook['abook_pending'] = $abook['abook_flags'] & 0x10 ? 1 : 0;
                    $abook['abook_unconnected'] = $abook['abook_flags'] & 0x20 ? 1 : 0;
                    $abook['abook_self'] = $abook['abook_flags'] & 0x80 ? 1 : 0;
                    $abook['abook_feed'] = $abook['abook_flags'] & 0x100 ? 1 : 0;
                }
                if ($abook['abook_self']) {
                    $role = get_pconfig($channel['channel_id'], 'system', 'permissions_role');
                    if ($role === 'forum' || $abook['abook_my_perms'] & PERMS_W_TAGWALL) {
                        q("update xchan set xchan_pubforum = 1 where xchan_hash = '%s' ", dbesc($abook['abook_xchan']));
                    }
                } else {
                    if ($max_friends !== false && $friends > $max_friends) {
                        continue;
                    }
                    if ($max_feeds !== false && intval($abook['abook_feed']) && $feeds > $max_feeds) {
                        continue;
                    }
                }
                dbesc_array($abook);
                $r = dbq("INSERT INTO abook (`" . implode("`, `", array_keys($abook)) . "`) VALUES ('" . implode("', '", array_values($abook)) . "')");
                $friends++;
                if (intval($abook['abook_feed'])) {
                    $feeds++;
                }
            }
        }
        logger('import step 8');
        $_SESSION['import_step'] = 8;
        ref_session_write(session_id(), serialize($_SESSION));
    }
    if ($completed < 9) {
        $groups = $data['group'];
        if ($groups) {
            $saved = array();
            foreach ($groups as $group) {
                $saved[$group['hash']] = array('old' => $group['id']);
                unset($group['id']);
                $group['uid'] = $channel['channel_id'];
                dbesc_array($group);
                $r = dbq("INSERT INTO groups (`" . implode("`, `", array_keys($group)) . "`) VALUES ('" . implode("', '", array_values($group)) . "')");
            }
            $r = q("select * from `groups` where uid = %d", intval($channel['channel_id']));
            if ($r) {
                foreach ($r as $rr) {
                    $saved[$rr['hash']]['new'] = $rr['id'];
                }
            }
        }
        $group_members = $data['group_member'];
        if ($group_members) {
            foreach ($group_members as $group_member) {
                unset($group_member['id']);
                $group_member['uid'] = $channel['channel_id'];
                foreach ($saved as $x) {
                    if ($x['old'] == $group_member['gid']) {
                        $group_member['gid'] = $x['new'];
                    }
                }
                dbesc_array($group_member);
                $r = dbq("INSERT INTO group_member (`" . implode("`, `", array_keys($group_member)) . "`) VALUES ('" . implode("', '", array_values($group_member)) . "')");
            }
        }
        logger('import step 9');
        $_SESSION['import_step'] = 9;
        ref_session_write(session_id(), serialize($_SESSION));
    }
    if (is_array($data['obj'])) {
        import_objs($channel, $data['obj']);
    }
    if (is_array($data['likes'])) {
        import_likes($channel, $data['likes']);
    }
    if (is_array($data['app'])) {
        import_apps($channel, $data['app']);
    }
    if (is_array($data['chatroom'])) {
        import_chatrooms($channel, $data['chatroom']);
    }
    if (is_array($data['conv'])) {
        import_conv($channel, $data['conv']);
    }
    if (is_array($data['mail'])) {
        import_mail($channel, $data['mail']);
    }
    if (is_array($data['event'])) {
        import_events($channel, $data['event']);
    }
    if (is_array($data['event_item'])) {
        import_items($channel, $data['event_item']);
    }
    if (is_array($data['menu'])) {
        import_menus($channel, $data['menu']);
    }
    $addon = array('channel' => $channel, 'data' => $data);
    call_hooks('import_channel', $addon);
    $saved_notification_flags = notifications_off($channel['channel_id']);
    if ($import_posts && array_key_exists('item', $data) && $data['item']) {
        import_items($channel, $data['item']);
    }
    notifications_on($channel['channel_id'], $saved_notification_flags);
    if (array_key_exists('item_id', $data) && $data['item_id']) {
        import_item_ids($channel, $data['item_id']);
    }
    // FIXME - ensure we have a self entry if somebody is trying to pull a fast one
    // send out refresh requests
    // notify old server that it may no longer be primary.
    proc_run('php', 'include/notifier.php', 'location', $channel['channel_id']);
    // This will indirectly perform a refresh_all *and* update the directory
    proc_run('php', 'include/directory.php', $channel['channel_id']);
    notice(t('Import completed.') . EOL);
    change_channel($channel['channel_id']);
    unset($_SESSION['import_step']);
    goaway(z_root() . '/network');
}
Beispiel #2
0
function import_channel($channel, $account_id)
{
    if (!array_key_exists('channel_system', $channel)) {
        $channel['channel_system'] = $channel['channel_pageflags'] & 0x1000 ? 1 : 0;
        $channel['channel_removed'] = $channel['channel_pageflags'] & 0x8000 ? 1 : 0;
    }
    $r = q("select * from channel where (channel_guid = '%s' or channel_hash = '%s' or channel_address = '%s' ) limit 1", dbesc($channel['channel_guid']), dbesc($channel['channel_hash']), dbesc($channel['channel_address']));
    // We should probably also verify the hash
    if ($r) {
        if ($r[0]['channel_guid'] === $channel['channel_guid'] || $r[0]['channel_hash'] === $channel['channel_hash']) {
            logger('mod_import: duplicate channel. ', print_r($channel, true));
            notice(t('Cannot create a duplicate channel identifier on this system. Import failed.') . EOL);
            return false;
        } else {
            // try at most ten times to generate a unique address.
            $x = 0;
            $found_unique = false;
            do {
                $tmp = $channel['channel_address'] . mt_rand(1000, 9999);
                $r = q("select * from channel where channel_address = '%s' limit 1", dbesc($tmp));
                if (!$r) {
                    $channel['channel_address'] = $tmp;
                    $found_unique = true;
                    break;
                }
                $x++;
            } while ($x < 10);
            if (!$found_unique) {
                logger('mod_import: duplicate channel. randomisation failed.', print_r($channel, true));
                notice(t('Unable to create a unique channel address. Import failed.') . EOL);
                return false;
            }
        }
    }
    unset($channel['channel_id']);
    $channel['channel_account_id'] = $account_id;
    $channel['channel_primary'] = $seize ? 1 : 0;
    if ($channel['channel_pageflags'] & PAGE_ALLOWCODE) {
        if (!is_site_admin()) {
            $channel['channel_pageflags'] = $channel['channel_pageflags'] ^ PAGE_ALLOWCODE;
        }
    }
    dbesc_array($channel);
    $r = dbq("INSERT INTO channel (`" . implode("`, `", array_keys($channel)) . "`) VALUES ('" . implode("', '", array_values($channel)) . "')");
    if (!$r) {
        logger('mod_import: channel clone failed. ', print_r($channel, true));
        notice(t('Channel clone failed. Import failed.') . EOL);
        return false;
    }
    $r = q("select * from channel where channel_account_id = %d and channel_guid = '%s' limit 1", intval($account_id), $channel['channel_guid']);
    if (!$r) {
        logger('mod_import: channel not found. ', print_r($channel, true));
        notice(t('Cloned channel not found. Import failed.') . EOL);
        return false;
    }
    // reset
    $channel = $r[0];
    set_default_login_identity($account_id, $channel['channel_id'], false);
    logger('import step 1');
    $_SESSION['import_step'] = 1;
    ref_session_write(session_id(), serialize($_SESSION));
    return $channel;
}