示例#1
1
function create_user($arr)
{
    // Required: { username, nickname, email } or { openid_url }
    $a = get_app();
    $result = array('success' => false, 'user' => null, 'password' => '', 'message' => '');
    $using_invites = get_config('system', 'invitation_only');
    $num_invites = get_config('system', 'number_invites');
    $invite_id = x($arr, 'invite_id') ? notags(trim($arr['invite_id'])) : '';
    $username = x($arr, 'username') ? notags(trim($arr['username'])) : '';
    $nickname = x($arr, 'nickname') ? notags(trim($arr['nickname'])) : '';
    $email = x($arr, 'email') ? notags(trim($arr['email'])) : '';
    $openid_url = x($arr, 'openid_url') ? notags(trim($arr['openid_url'])) : '';
    $photo = x($arr, 'photo') ? notags(trim($arr['photo'])) : '';
    $password = x($arr, 'password') ? trim($arr['password']) : '';
    $blocked = x($arr, 'blocked') ? intval($arr['blocked']) : 0;
    $verified = x($arr, 'verified') ? intval($arr['verified']) : 0;
    $publish = x($arr, 'profile_publish_reg') && intval($arr['profile_publish_reg']) ? 1 : 0;
    $netpublish = strlen(get_config('system', 'directory_submit_url')) ? $publish : 0;
    $tmp_str = $openid_url;
    if ($using_invites) {
        if (!$invite_id) {
            $result['message'] .= t('An invitation is required.') . EOL;
            return $result;
        }
        $r = q("select * from register where `hash` = '%s' limit 1", dbesc($invite_id));
        if (!results($r)) {
            $result['message'] .= t('Invitation could not be verified.') . EOL;
            return $result;
        }
    }
    if (!x($username) || !x($email) || !x($nickname)) {
        if ($openid_url) {
            if (!validate_url($tmp_str)) {
                $result['message'] .= t('Invalid OpenID url') . EOL;
                return $result;
            }
            $_SESSION['register'] = 1;
            $_SESSION['openid'] = $openid_url;
            require_once 'library/openid.php';
            $openid = new LightOpenID();
            $openid->identity = $openid_url;
            $openid->returnUrl = $a->get_baseurl() . '/openid';
            $openid->required = array('namePerson/friendly', 'contact/email', 'namePerson');
            $openid->optional = array('namePerson/first', 'media/image/aspect11', 'media/image/default');
            try {
                $authurl = $openid->authUrl();
            } catch (Exception $e) {
                $result['message'] .= t("We encountered a problem while logging in with the OpenID you provided. Please check the correct spelling of the ID.") . EOL . EOL . t("The error message was:") . $e->getMessage() . EOL;
                return $result;
            }
            goaway($authurl);
            // NOTREACHED
        }
        notice(t('Please enter the required information.') . EOL);
        return;
    }
    if (!validate_url($tmp_str)) {
        $openid_url = '';
    }
    $err = '';
    // collapse multiple spaces in name
    $username = preg_replace('/ +/', ' ', $username);
    if (mb_strlen($username) > 48) {
        $result['message'] .= t('Please use a shorter name.') . EOL;
    }
    if (mb_strlen($username) < 3) {
        $result['message'] .= t('Name too short.') . EOL;
    }
    // I don't really like having this rule, but it cuts down
    // on the number of auto-registrations by Russian spammers
    //  Using preg_match was completely unreliable, due to mixed UTF-8 regex support
    //	$no_utf = get_config('system','no_utf');
    //	$pat = (($no_utf) ? '/^[a-zA-Z]* [a-zA-Z]*$/' : '/^\p{L}* \p{L}*$/u' );
    // So now we are just looking for a space in the full name.
    $loose_reg = get_config('system', 'no_regfullname');
    if (!$loose_reg) {
        $username = mb_convert_case($username, MB_CASE_TITLE, 'UTF-8');
        if (!strpos($username, ' ')) {
            $result['message'] .= t("That doesn't appear to be your full (First Last) name.") . EOL;
        }
    }
    if (!allowed_email($email)) {
        $result['message'] .= t('Your email domain is not among those allowed on this site.') . EOL;
    }
    if (!valid_email($email) || !validate_email($email)) {
        $result['message'] .= t('Not a valid email address.') . EOL;
    }
    // Disallow somebody creating an account using openid that uses the admin email address,
    // since openid bypasses email verification. We'll allow it if there is not yet an admin account.
    $adminlist = explode(",", str_replace(" ", "", strtolower($a->config['admin_email'])));
    //if((x($a->config,'admin_email')) && (strcasecmp($email,$a->config['admin_email']) == 0) && strlen($openid_url)) {
    if (x($a->config, 'admin_email') && in_array(strtolower($email), $adminlist) && strlen($openid_url)) {
        $r = q("SELECT * FROM `user` WHERE `email` = '%s' LIMIT 1", dbesc($email));
        if (count($r)) {
            $result['message'] .= t('Cannot use that email.') . EOL;
        }
    }
    $nickname = $arr['nickname'] = strtolower($nickname);
    if (!preg_match("/^[a-z][a-z0-9\\-\\_]*\$/", $nickname)) {
        $result['message'] .= t('Your "nickname" can only contain "a-z", "0-9", "-", and "_", and must also begin with a letter.') . EOL;
    }
    $r = q("SELECT `uid` FROM `user`\n               \tWHERE `nickname` = '%s' LIMIT 1", dbesc($nickname));
    if (count($r)) {
        $result['message'] .= t('Nickname is already registered. Please choose another.') . EOL;
    }
    // Check deleted accounts that had this nickname. Doesn't matter to us,
    // but could be a security issue for federated platforms.
    $r = q("SELECT * FROM `userd`\n               \tWHERE `username` = '%s' LIMIT 1", dbesc($nickname));
    if (count($r)) {
        $result['message'] .= t('Nickname was once registered here and may not be re-used. Please choose another.') . EOL;
    }
    if (strlen($result['message'])) {
        return $result;
    }
    $new_password = strlen($password) ? $password : autoname(6) . mt_rand(100, 9999);
    $new_password_encoded = hash('whirlpool', $new_password);
    $result['password'] = $new_password;
    require_once 'include/crypto.php';
    $keys = new_keypair(4096);
    if ($keys === false) {
        $result['message'] .= t('SERIOUS ERROR: Generation of security keys failed.') . EOL;
        return $result;
    }
    $default_service_class = get_config('system', 'default_service_class');
    if (!$default_service_class) {
        $default_service_class = '';
    }
    $prvkey = $keys['prvkey'];
    $pubkey = $keys['pubkey'];
    /**
     *
     * Create another keypair for signing/verifying
     * salmon protocol messages. We have to use a slightly
     * less robust key because this won't be using openssl
     * but the phpseclib. Since it is PHP interpreted code
     * it is not nearly as efficient, and the larger keys
     * will take several minutes each to process.
     *
     */
    $sres = new_keypair(512);
    $sprvkey = $sres['prvkey'];
    $spubkey = $sres['pubkey'];
    $r = q("INSERT INTO `user` ( `guid`, `username`, `password`, `email`, `openid`, `nickname`,\n\t\t`pubkey`, `prvkey`, `spubkey`, `sprvkey`, `register_date`, `verified`, `blocked`, `timezone`, `service_class`, `default-location` )\n\t\tVALUES ( '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', %d, %d, 'UTC', '%s', '' )", dbesc(generate_user_guid()), dbesc($username), dbesc($new_password_encoded), dbesc($email), dbesc($openid_url), dbesc($nickname), dbesc($pubkey), dbesc($prvkey), dbesc($spubkey), dbesc($sprvkey), dbesc(datetime_convert()), intval($verified), intval($blocked), dbesc($default_service_class));
    if ($r) {
        $r = q("SELECT * FROM `user`\n\t\t\tWHERE `username` = '%s' AND `password` = '%s' LIMIT 1", dbesc($username), dbesc($new_password_encoded));
        if ($r !== false && count($r)) {
            $u = $r[0];
            $newuid = intval($r[0]['uid']);
        }
    } else {
        $result['message'] .= t('An error occurred during registration. Please try again.') . EOL;
        return $result;
    }
    /**
     * if somebody clicked submit twice very quickly, they could end up with two accounts
     * due to race condition. Remove this one.
     */
    $r = q("SELECT `uid` FROM `user`\n               \tWHERE `nickname` = '%s' ", dbesc($nickname));
    if (count($r) > 1 && $newuid) {
        $result['message'] .= t('Nickname is already registered. Please choose another.') . EOL;
        q("DELETE FROM `user` WHERE `uid` = %d", intval($newuid));
        return $result;
    }
    if (x($newuid) !== false) {
        $r = q("INSERT INTO `profile` ( `uid`, `profile-name`, `is-default`, `name`, `photo`, `thumb`, `publish`, `net-publish` )\n\t\t\tVALUES ( %d, '%s', %d, '%s', '%s', '%s', %d, %d ) ", intval($newuid), t('default'), 1, dbesc($username), dbesc($a->get_baseurl() . "/photo/profile/{$newuid}.jpg"), dbesc($a->get_baseurl() . "/photo/avatar/{$newuid}.jpg"), intval($publish), intval($netpublish));
        if ($r === false) {
            $result['message'] .= t('An error occurred creating your default profile. Please try again.') . EOL;
            // Start fresh next time.
            $r = q("DELETE FROM `user` WHERE `uid` = %d", intval($newuid));
            return $result;
        }
        $r = q("INSERT INTO `contact` ( `uid`, `created`, `self`, `name`, `nick`, `photo`, `thumb`, `micro`, `blocked`, `pending`, `url`, `nurl`,\n\t\t\t`request`, `notify`, `poll`, `confirm`, `poco`, `name-date`, `uri-date`, `avatar-date`, `closeness` )\n\t\t\tVALUES ( %d, '%s', 1, '%s', '%s', '%s', '%s', '%s', 0, 0, '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', 0 ) ", intval($newuid), datetime_convert(), dbesc($username), dbesc($nickname), dbesc($a->get_baseurl() . "/photo/profile/{$newuid}.jpg"), dbesc($a->get_baseurl() . "/photo/avatar/{$newuid}.jpg"), dbesc($a->get_baseurl() . "/photo/micro/{$newuid}.jpg"), dbesc($a->get_baseurl() . "/profile/{$nickname}"), dbesc(normalise_link($a->get_baseurl() . "/profile/{$nickname}")), dbesc($a->get_baseurl() . "/dfrn_request/{$nickname}"), dbesc($a->get_baseurl() . "/dfrn_notify/{$nickname}"), dbesc($a->get_baseurl() . "/dfrn_poll/{$nickname}"), dbesc($a->get_baseurl() . "/dfrn_confirm/{$nickname}"), dbesc($a->get_baseurl() . "/poco/{$nickname}"), dbesc(datetime_convert()), dbesc(datetime_convert()), dbesc(datetime_convert()));
        // Create a group with no members. This allows somebody to use it
        // right away as a default group for new contacts.
        require_once 'include/group.php';
        group_add($newuid, t('Friends'));
        $r = q("SELECT id FROM `group` WHERE uid = %d AND name = '%s'", intval($newuid), dbesc(t('Friends')));
        if ($r && count($r)) {
            $def_gid = $r[0]['id'];
            q("UPDATE user SET def_gid = %d WHERE uid = %d", intval($r[0]['id']), intval($newuid));
        }
        if (get_config('system', 'newuser_private') && $def_gid) {
            q("UPDATE user SET allow_gid = '%s' WHERE uid = %d", dbesc("<" . $def_gid . ">"), intval($newuid));
        }
    }
    // if we have no OpenID photo try to look up an avatar
    if (!strlen($photo)) {
        $photo = avatar_img($email);
    }
    // unless there is no avatar-plugin loaded
    if (strlen($photo)) {
        require_once 'include/Photo.php';
        $photo_failure = false;
        $filename = basename($photo);
        $img_str = fetch_url($photo, true);
        // guess mimetype from headers or filename
        $type = guess_image_type($photo, true);
        $img = new Photo($img_str, $type);
        if ($img->is_valid()) {
            $img->scaleImageSquare(175);
            $hash = photo_new_resource();
            $r = $img->store($newuid, 0, $hash, $filename, t('Profile Photos'), 4);
            if ($r === false) {
                $photo_failure = true;
            }
            $img->scaleImage(80);
            $r = $img->store($newuid, 0, $hash, $filename, t('Profile Photos'), 5);
            if ($r === false) {
                $photo_failure = true;
            }
            $img->scaleImage(48);
            $r = $img->store($newuid, 0, $hash, $filename, t('Profile Photos'), 6);
            if ($r === false) {
                $photo_failure = true;
            }
            if (!$photo_failure) {
                q("UPDATE `photo` SET `profile` = 1 WHERE `resource-id` = '%s' ", dbesc($hash));
            }
        }
    }
    call_hooks('register_account', $newuid);
    $result['success'] = true;
    $result['user'] = $u;
    return $result;
}
示例#2
0
function store_photo($a, $uid, $imagedata = "", $url = "")
{
    $r = q("SELECT `user`.`nickname`, `user`.`page-flags`, `contact`.`id` FROM `user` INNER JOIN `contact` on `user`.`uid` = `contact`.`uid`\n\t\tWHERE `user`.`uid` = %d AND `user`.`blocked` = 0 and `contact`.`self` = 1 LIMIT 1", intval($uid));
    if (!count($r)) {
        logger("Can't detect user data for uid " . $uid, LOGGER_DEBUG);
        return array();
    }
    $page_owner_nick = $r[0]['nickname'];
    //	To-Do:
    //	$default_cid      = $r[0]['id'];
    //	$community_page   = (($r[0]['page-flags'] == PAGE_COMMUNITY) ? true : false);
    if (strlen($imagedata) == 0 and $url == "") {
        logger("No image data and no url provided", LOGGER_DEBUG);
        return array();
    } elseif (strlen($imagedata) == 0) {
        logger("Uploading picture from " . $url, LOGGER_DEBUG);
        $imagedata = @file_get_contents($url);
    }
    $maximagesize = get_config('system', 'maximagesize');
    if ($maximagesize && strlen($imagedata) > $maximagesize) {
        logger("Image exceeds size limit of " . $maximagesize, LOGGER_DEBUG);
        return array();
    }
    /*
            $r = q("select sum(octet_length(data)) as total from photo where uid = %d and scale = 0 and album != 'Contact Photos' ",
                    intval($uid)
            );
    
            $limit = service_class_fetch($uid,'photo_upload_limit');
    
            if(($limit !== false) && (($r[0]['total'] + strlen($imagedata)) > $limit)) {
    		logger("Image exceeds personal limit of uid ".$uid, LOGGER_DEBUG);
    		return(array());
            }
    */
    $tempfile = tempnam(get_temppath(), "cache");
    file_put_contents($tempfile, $imagedata);
    $data = getimagesize($tempfile);
    if (!isset($data["mime"])) {
        unlink($tempfile);
        logger("File is no picture", LOGGER_DEBUG);
        return array();
    }
    $ph = new Photo($imagedata, $data["mime"]);
    if (!$ph->is_valid()) {
        unlink($tempfile);
        logger("Picture is no valid picture", LOGGER_DEBUG);
        return array();
    }
    $ph->orient($tempfile);
    unlink($tempfile);
    $max_length = get_config('system', 'max_image_length');
    if (!$max_length) {
        $max_length = MAX_IMAGE_LENGTH;
    }
    if ($max_length > 0) {
        $ph->scaleImage($max_length);
    }
    $width = $ph->getWidth();
    $height = $ph->getHeight();
    $hash = photo_new_resource();
    $smallest = 0;
    // Pictures are always public by now
    //$defperm = '<'.$default_cid.'>';
    $defperm = "";
    $visitor = 0;
    $r = $ph->store($uid, $visitor, $hash, $tempfile, t('Wall Photos'), 0, 0, $defperm);
    if (!$r) {
        logger("Picture couldn't be stored", LOGGER_DEBUG);
        return array();
    }
    $image = array("page" => $a->get_baseurl() . '/photos/' . $page_owner_nick . '/image/' . $hash, "full" => $a->get_baseurl() . "/photo/{$hash}-0." . $ph->getExt());
    if ($width > 800 || $height > 800) {
        $image["large"] = $a->get_baseurl() . "/photo/{$hash}-0." . $ph->getExt();
    }
    if ($width > 640 || $height > 640) {
        $ph->scaleImage(640);
        $r = $ph->store($uid, $visitor, $hash, $tempfile, t('Wall Photos'), 1, 0, $defperm);
        if ($r) {
            $image["medium"] = $a->get_baseurl() . "/photo/{$hash}-1." . $ph->getExt();
        }
    }
    if ($width > 320 || $height > 320) {
        $ph->scaleImage(320);
        $r = $ph->store($uid, $visitor, $hash, $tempfile, t('Wall Photos'), 2, 0, $defperm);
        if ($r) {
            $image["small"] = $a->get_baseurl() . "/photo/{$hash}-2." . $ph->getExt();
        }
    }
    if ($width > 160 and $height > 160) {
        $x = 0;
        $y = 0;
        $min = $ph->getWidth();
        if ($min > 160) {
            $x = ($min - 160) / 2;
        }
        if ($ph->getHeight() < $min) {
            $min = $ph->getHeight();
            if ($min > 160) {
                $y = ($min - 160) / 2;
            }
        }
        $min = 160;
        $ph->cropImage(160, $x, $y, $min, $min);
        $r = $ph->store($uid, $visitor, $hash, $tempfile, t('Wall Photos'), 3, 0, $defperm);
        if ($r) {
            $image["thumb"] = $a->get_baseurl() . "/photo/{$hash}-3." . $ph->getExt();
        }
    }
    // Set the full image as preview image. This will be overwritten, if the picture is larger than 640.
    $image["preview"] = $image["full"];
    // Deactivated, since that would result in a cropped preview, if the picture wasn't larger than 320
    //if (isset($image["thumb"]))
    //	$image["preview"] = $image["thumb"];
    // Unsure, if this should be activated or deactivated
    //if (isset($image["small"]))
    //	$image["preview"] = $image["small"];
    if (isset($image["medium"])) {
        $image["preview"] = $image["medium"];
    }
    return $image;
}
示例#3
0
function wall_upload_post(&$a)
{
    if ($a->argc > 1) {
        if (!x($_FILES, 'media')) {
            $nick = $a->argv[1];
            $r = q("SELECT `user`.*, `contact`.`id` FROM `user` LEFT JOIN `contact` on `user`.`uid` = `contact`.`uid`  WHERE `user`.`nickname` = '%s' AND `user`.`blocked` = 0 and `contact`.`self` = 1 LIMIT 1", dbesc($nick));
            if (!count($r)) {
                return;
            }
        } else {
            $user_info = api_get_user($a);
            $r = q("SELECT `user`.*, `contact`.`id` FROM `user` LEFT JOIN `contact` on `user`.`uid` = `contact`.`uid`  WHERE `user`.`nickname` = '%s' AND `user`.`blocked` = 0 and `contact`.`self` = 1 LIMIT 1", dbesc($user_info['screen_name']));
        }
    } else {
        return;
    }
    $can_post = false;
    $visitor = 0;
    $page_owner_uid = $r[0]['uid'];
    $default_cid = $r[0]['id'];
    $page_owner_nick = $r[0]['nickname'];
    $community_page = $r[0]['page-flags'] == PAGE_COMMUNITY ? true : false;
    if (local_user() && local_user() == $page_owner_uid) {
        $can_post = true;
    } else {
        if ($community_page && remote_user()) {
            $r = q("SELECT `uid` FROM `contact` WHERE `blocked` = 0 AND `pending` = 0 AND `id` = %d AND `uid` = %d LIMIT 1", intval(remote_user()), intval($page_owner_uid));
            if (count($r)) {
                $can_post = true;
                $visitor = remote_user();
                $default_cid = $visitor;
            }
        }
    }
    if (!$can_post) {
        notice(t('Permission denied.') . EOL);
        killme();
    }
    if (!x($_FILES, 'userfile') && !x($_FILES, 'media')) {
        killme();
    }
    if (x($_FILES, 'userfile')) {
        $src = $_FILES['userfile']['tmp_name'];
        $filename = basename($_FILES['userfile']['name']);
        $filesize = intval($_FILES['userfile']['size']);
    } elseif (x($_FILES, 'media')) {
        $src = $_FILES['media']['tmp_name'];
        $filename = basename($_FILES['media']['name']);
        $filesize = intval($_FILES['media']['size']);
    }
    $maximagesize = get_config('system', 'maximagesize');
    if ($maximagesize && $filesize > $maximagesize) {
        echo sprintf(t('Image exceeds size limit of %d'), $maximagesize) . EOL;
        @unlink($src);
        killme();
    }
    $imagedata = @file_get_contents($src);
    $ph = new Photo($imagedata);
    if (!$ph->is_valid()) {
        echo t('Unable to process image.') . EOL;
        @unlink($src);
        killme();
    }
    @unlink($src);
    $width = $ph->getWidth();
    $height = $ph->getHeight();
    $hash = photo_new_resource();
    $smallest = 0;
    $defperm = '<' . $default_cid . '>';
    $r = $ph->store($page_owner_uid, $visitor, $hash, $filename, t('Wall Photos'), 0, 0, $defperm);
    if (!$r) {
        echo t('Image upload failed.') . EOL;
        killme();
    }
    if ($width > 640 || $height > 640) {
        $ph->scaleImage(640);
        $r = $ph->store($page_owner_uid, $visitor, $hash, $filename, t('Wall Photos'), 1, 0, $defperm);
        if ($r) {
            $smallest = 1;
        }
    }
    if ($width > 320 || $height > 320) {
        $ph->scaleImage(320);
        $r = $ph->store($page_owner_uid, $visitor, $hash, $filename, t('Wall Photos'), 2, 0, $defperm);
        if ($r) {
            $smallest = 2;
        }
    }
    $basename = basename($filename);
    /* mod Waitman Gobble NO WARRANTY */
    //if we get the signal then return the image url info in BBCODE, otherwise this outputs the info and bails (for the ajax image uploader on wall post)
    if ($_REQUEST['hush'] != 'yeah') {
        /*existing code*/
        if (local_user() && intval(get_pconfig(local_user(), 'system', 'plaintext'))) {
            echo "\n\n" . '[url=' . $a->get_baseurl() . '/photos/' . $page_owner_nick . '/image/' . $hash . '][img]' . $a->get_baseurl() . "/photo/{$hash}-{$smallest}.jpg[/img][/url]\n\n";
        } else {
            echo '<br /><br /><a href="' . $a->get_baseurl() . '/photos/' . $page_owner_nick . '/image/' . $hash . '" ><img src="' . $a->get_baseurl() . "/photo/{$hash}-{$smallest}.jpg\" alt=\"{$basename}\" /></a><br /><br />";
        }
        /*existing code*/
    } else {
        $m = '[url=' . $a->get_baseurl() . '/photos/' . $page_owner_nick . '/image/' . $hash . '][img]' . $a->get_baseurl() . "/photo/{$hash}-{$smallest}.jpg[/img][/url]";
        return $m;
    }
    /* mod Waitman Gobble NO WARRANTY */
    killme();
    // NOTREACHED
}
function openclipatar_content(&$a)
{
    if (!local_channel()) {
        return;
    }
    $o = '';
    if (argc() == 3 && argv(1) == 'use') {
        $id = argv(2);
        $chan = $a->get_channel();
        $x = z_fetch_url('https://openclipart.org/image/250px/svg_to_png/' . $id . '/' . $id . '.png', true);
        if ($x['success']) {
            $imagedata = $x['body'];
        }
        $ph = photo_factory($imagedata, 'image/png');
        if (!$ph->is_valid()) {
            return t('Unknown error. Please try again later.');
        }
        // create a unique resource_id
        $hash = photo_new_resource();
        // save an original or "scale 0" image
        $p = array('aid' => get_account_id(), 'uid' => local_channel(), 'resource_id' => $hash, 'filename' => $id . '.png', 'album' => t('Profile Photos'), 'scale' => 0);
        $r = $ph->save($p);
        if ($r) {
            // scale 0 success, continue 4, 5, 6
            // we'll skip scales 1,2 (640, 320 rectangular formats as these images are all less than this)
            // ensure squareness at first, subsequent scales keep ratio
            $ph->scaleImageSquare(175);
            $p['scale'] = 4;
            $r = $ph->save($p);
            if ($r === false) {
                $photo_failure = true;
            }
            $ph->scaleImage(80);
            $p['scale'] = 5;
            $r = $ph->save($p);
            if ($r === false) {
                $photo_failure = true;
            }
            $ph->scaleImage(48);
            $p['scale'] = 6;
            $r = $ph->save($p);
            if ($r === false) {
                $photo_failure = true;
            }
        }
        $is_default_profile = 1;
        if ($_REQUEST['profile']) {
            $r = q("select id, is_default from profile where id = %d and uid = %d limit 1", intval($_REQUEST['profile']), intval(local_channel()));
            if ($r && !intval($r[0]['is_default'])) {
                $is_default_profile = 0;
            }
        }
        if ($is_default_profile) {
            // unset any existing profile photos
            $r = q("UPDATE photo SET profile = 0 WHERE profile = 1 AND uid = %d", intval(local_channel()));
            $r = q("UPDATE photo SET photo_flags = (photo_flags & ~%d ) WHERE (photo_flags & %d )>0 AND uid = %d", intval(PHOTO_PROFILE), intval(PHOTO_PROFILE), intval(local_channel()));
            // set all sizes of this one as profile photos
            $r = q("UPDATE photo SET profile = 1 WHERE uid = %d AND resource_id = '%s'", intval(local_channel()), dbesc($hash));
            $r = q("UPDATE photo SET photo_flags = ( photo_flags | %d ) WHERE uid = %d AND resource_id = '%s'", intval(PHOTO_PROFILE), intval(local_channel()), dbesc($hash));
            require_once 'mod/profile_photo.php';
            profile_photo_set_profile_perms();
            //Reset default profile photo permissions to public
            // only the default needs reload since it uses canonical url -- despite the slightly ambiguous message, left it so as to re-use translations
            info(t('Shift-reload the page or clear browser cache if the new photo does not display immediately.') . EOL);
        } else {
            // not the default profile, set the path in the correct entry in the profile DB
            $r = q("update profile set photo = '%s', thumb = '%s' where id = %d and uid = %d", dbesc(get_app()->get_baseurl() . '/photo/' . $hash . '-4'), dbesc(get_app()->get_baseurl() . '/photo/' . $hash . '-5'), intval($_REQUEST['profile']), intval(local_channel()));
            info(t('Profile photo updated successfully.') . EOL);
        }
        // set a new photo_date on our xchan so that we can tell everybody to update their cached copy
        $r = q("UPDATE xchan set xchan_photo_date = '%s' where xchan_hash = '%s'", dbesc(datetime_convert()), dbesc($chan['xchan_hash']));
        // tell everybody
        proc_run('php', 'include/directory.php', local_channel());
        $returnafter = get_config('openclipatar', 'returnafter');
        $returnafter_urls = array(0 => $a->get_baseurl() . '/profile/' . ($_REQUEST['profile'] ? $_REQUEST['profile'] . '/view' : $chan['channel_address']), 1 => $a->get_baseurl() . '/profiles/' . ($_REQUEST['profile'] ? $_REQUEST['profile'] : $a->profile_uid), 2 => $a->get_baseurl() . '/profiles');
        goaway($returnafter_urls[$returnafter]);
    } else {
        //invoked as module, we place in content pane the same as we would for the end of the profile photo page. Also handles json for endless scroll for either invokation.
        openclipatar_profile_photo_content_end($a, $o);
    }
    return $o;
}
示例#5
0
/**
 * @brief
 *
 * @param array $channel
 * @param array $observer
 * @param array $args
 * @return array
 */
function photo_upload($channel, $observer, $args)
{
    $ret = array('success' => false);
    $channel_id = $channel['channel_id'];
    $account_id = $channel['channel_account_id'];
    if (!perm_is_allowed($channel_id, $observer['xchan_hash'], 'post_photos')) {
        $ret['message'] = t('Permission denied.');
        return $ret;
    }
    call_hooks('photo_upload_begin', $args);
    /*
     * Determine the album to use
     */
    $album = $args['album'];
    $newalbum = $args['newalbum'];
    logger('photo_upload: album= ' . $album . ' newalbum= ' . $newalbum, LOGGER_DEBUG);
    if (!$album) {
        if ($newalbum) {
            $album = $newalbum;
        } else {
            $album = datetime_convert('UTC', date_default_timezone_get(), 'now', 'Y-m');
        }
    }
    if (intval($args['visible']) || $args['visible'] === 'true') {
        $visible = 1;
    } else {
        $visible = 0;
    }
    $str_group_allow = perms2str(is_array($args['group_allow']) ? $args['group_allow'] : explode(',', $args['group_allow']));
    $str_contact_allow = perms2str(is_array($args['contact_allow']) ? $args['contact_allow'] : explode(',', $args['contact_allow']));
    $str_group_deny = perms2str(is_array($args['group_deny']) ? $args['group_deny'] : explode(',', $args['group_deny']));
    $str_contact_deny = perms2str(is_array($args['contact_deny']) ? $args['contact_deny'] : explode(',', $args['contact_deny']));
    if ($args['data']) {
        // allow an import from a binary string representing the image.
        // This bypasses the upload step and max size limit checking
        $imagedata = $args['data'];
        $filename = $args['filename'];
        $filesize = strlen($imagedata);
        // this is going to be deleted if it exists
        $src = '/tmp/deletemenow';
        $type = $args['type'];
    } else {
        $f = array('src' => '', 'filename' => '', 'filesize' => 0, 'type' => '');
        call_hooks('photo_upload_file', $f);
        if (x($f, 'src') && x($f, 'filesize')) {
            $src = $f['src'];
            $filename = $f['filename'];
            $filesize = $f['filesize'];
            $type = $f['type'];
        } else {
            $src = $_FILES['userfile']['tmp_name'];
            $filename = basename($_FILES['userfile']['name']);
            $filesize = intval($_FILES['userfile']['size']);
            $type = $_FILES['userfile']['type'];
        }
        if (!$type) {
            $type = guess_image_type($filename);
        }
        logger('photo_upload: received file: ' . $filename . ' as ' . $src . ' (' . $type . ') ' . $filesize . ' bytes', LOGGER_DEBUG);
        $maximagesize = get_config('system', 'maximagesize');
        if ($maximagesize && $filesize > $maximagesize) {
            $ret['message'] = sprintf(t('Image exceeds website size limit of %lu bytes'), $maximagesize);
            @unlink($src);
            call_hooks('photo_upload_end', $ret);
            return $ret;
        }
        if (!$filesize) {
            $ret['message'] = t('Image file is empty.');
            @unlink($src);
            call_hooks('photo_post_end', $ret);
            return $ret;
        }
        logger('photo_upload: loading the contents of ' . $src, LOGGER_DEBUG);
        $imagedata = @file_get_contents($src);
    }
    $r = q("select sum(size) as total from photo where aid = %d and scale = 0 ", intval($account_id));
    $limit = service_class_fetch($channel_id, 'photo_upload_limit');
    if ($r && $limit !== false && $r[0]['total'] + strlen($imagedata) > $limit) {
        $ret['message'] = upgrade_message();
        @unlink($src);
        call_hooks('photo_post_end', $ret);
        return $ret;
    }
    $ph = photo_factory($imagedata, $type);
    if (!$ph->is_valid()) {
        $ret['message'] = t('Unable to process image');
        logger('photo_upload: unable to process image');
        @unlink($src);
        call_hooks('photo_upload_end', $ret);
        return $ret;
    }
    $exif = $ph->orient($src);
    @unlink($src);
    $max_length = get_config('system', 'max_image_length');
    if (!$max_length) {
        $max_length = MAX_IMAGE_LENGTH;
    }
    if ($max_length > 0) {
        $ph->scaleImage($max_length);
    }
    $width = $ph->getWidth();
    $height = $ph->getHeight();
    $smallest = 0;
    $photo_hash = $args['resource_id'] ? $args['resource_id'] : photo_new_resource();
    $visitor = '';
    if ($channel['channel_hash'] !== $observer['xchan_hash']) {
        $visitor = $observer['xchan_hash'];
    }
    $errors = false;
    $p = array('aid' => $account_id, 'uid' => $channel_id, 'xchan' => $visitor, 'resource_id' => $photo_hash, 'filename' => $filename, 'album' => $album, 'scale' => 0, 'photo_flags' => PHOTO_NORMAL, 'allow_cid' => $str_contact_allow, 'allow_gid' => $str_group_allow, 'deny_cid' => $str_contact_deny, 'deny_gid' => $str_group_deny);
    if ($args['created']) {
        $p['created'] = $args['created'];
    }
    if ($args['edited']) {
        $p['edited'] = $args['edited'];
    }
    if ($args['title']) {
        $p['title'] = $args['title'];
    }
    if ($args['description']) {
        $p['description'] = $args['description'];
    }
    $r1 = $ph->save($p);
    if (!$r1) {
        $errors = true;
    }
    if (($width > 640 || $height > 640) && !$errors) {
        $ph->scaleImage(640);
        $p['scale'] = 1;
        $r2 = $ph->save($p);
        $smallest = 1;
        if (!$r2) {
            $errors = true;
        }
    }
    if (($width > 320 || $height > 320) && !$errors) {
        $ph->scaleImage(320);
        $p['scale'] = 2;
        $r3 = $ph->save($p);
        $smallest = 2;
        if (!$r3) {
            $errors = true;
        }
    }
    if ($errors) {
        q("delete from photo where resource_id = '%s' and uid = %d", dbesc($photo_hash), intval($channel_id));
        $ret['message'] = t('Photo storage failed.');
        logger('photo_upload: photo store failed.');
        call_hooks('photo_upload_end', $ret);
        return $ret;
    }
    // This will be the width and height of the smallest representation
    $width_x_height = $ph->getWidth() . 'x' . $ph->getHeight();
    $mid = item_message_id();
    // Create item container
    $lat = $lon = null;
    if ($exif && $exif['GPS']) {
        if (feature_enabled($channel_id, 'photo_location')) {
            $lat = getGps($exif['GPS']['GPSLatitude'], $exif['GPS']['GPSLatitudeRef']);
            $lon = getGps($exif['GPS']['GPSLongitude'], $exif['GPS']['GPSLongitudeRef']);
        }
    }
    $item_flags = ITEM_WALL | ITEM_ORIGIN | ITEM_THREAD_TOP;
    $item_restrict = $visible ? ITEM_VISIBLE : ITEM_HIDDEN;
    $title = '';
    $mid = item_message_id();
    $arr = array();
    if ($lat && $lon) {
        $arr['coord'] = $lat . ' ' . $lon;
    }
    $arr['aid'] = $account_id;
    $arr['uid'] = $channel_id;
    $arr['mid'] = $mid;
    $arr['parent_mid'] = $mid;
    $arr['item_flags'] = $item_flags;
    $arr['item_restrict'] = $item_restrict;
    $arr['resource_type'] = 'photo';
    $arr['resource_id'] = $photo_hash;
    $arr['owner_xchan'] = $channel['channel_hash'];
    $arr['author_xchan'] = $observer['xchan_hash'];
    $arr['title'] = $title;
    $arr['allow_cid'] = $str_contact_allow;
    $arr['allow_gid'] = $str_group_allow;
    $arr['deny_cid'] = $str_contact_deny;
    $arr['deny_gid'] = $str_group_deny;
    $arr['verb'] = ACTIVITY_POST;
    $arr['plink'] = z_root() . '/channel/' . $channel['channel_address'] . '/?f=&mid=' . $arr['mid'];
    // We should also put a width_x_height on large photos. Left as an exercise for
    // devs looking fo simple stuff to fix.
    $larger = feature_enabled($channel['channel_id'], 'large_photos');
    if ($larger) {
        $tag = '[zmg]';
        if ($r2) {
            $smallest = 1;
        } else {
            $smallest = 0;
        }
    } else {
        if ($width_x_height) {
            $tag = '[zmg=' . $width_x_height . ']';
        } else {
            $tag = '[zmg]';
        }
    }
    $arr['body'] = '[zrl=' . z_root() . '/photos/' . $channel['channel_address'] . '/image/' . $photo_hash . ']' . $tag . z_root() . "/photo/{$photo_hash}-{$smallest}." . $ph->getExt() . '[/zmg]' . '[/zrl]';
    $result = item_store($arr);
    $item_id = $result['item_id'];
    if ($visible) {
        proc_run('php', "include/notifier.php", 'wall-new', $item_id);
    }
    $ret['success'] = true;
    $ret['item'] = $arr;
    $ret['body'] = $arr['body'];
    $ret['resource_id'] = $photo_hash;
    $ret['photoitem_id'] = $item_id;
    call_hooks('photo_upload_end', $ret);
    return $ret;
}
示例#6
0
 function profile_photo_crop_ui_head(&$a, $ph)
 {
     $max_length = get_config('system', 'max_image_length');
     if (!$max_length) {
         $max_length = MAX_IMAGE_LENGTH;
     }
     if ($max_length > 0) {
         $ph->scaleImage($max_length);
     }
     $width = $ph->getWidth();
     $height = $ph->getHeight();
     if ($width < 175 || $height < 175) {
         $ph->scaleImageUp(200);
         $width = $ph->getWidth();
         $height = $ph->getHeight();
     }
     $hash = photo_new_resource();
     $smallest = 0;
     $p = array('aid' => get_account_id(), 'uid' => local_channel(), 'resource_id' => $hash, 'filename' => $filename, 'album' => t('Profile Photos'), 'scale' => 0);
     $r = $ph->save($p);
     if ($r) {
         info(t('Image uploaded successfully.') . EOL);
     } else {
         notice(t('Image upload failed.') . EOL);
     }
     if ($width > 640 || $height > 640) {
         $ph->scaleImage(640);
         $p['scale'] = 1;
         $r = $ph->save($p);
         if ($r === false) {
             notice(sprintf(t('Image size reduction [%s] failed.'), "640") . EOL);
         } else {
             $smallest = 1;
         }
     }
     $a->data['imagecrop'] = $hash;
     $a->data['imagecrop_resolution'] = $smallest;
     $a->data['imagecrop_ext'] = $ph->getExt();
     $a->page['htmlhead'] .= replace_macros(get_markup_template("crophead.tpl"), array());
     return;
 }
示例#7
0
function import_channel_photo($photo, $type, $aid, $uid)
{
    logger('import_channel_photo: importing channel photo for ' . $uid, LOGGER_DEBUG);
    $hash = photo_new_resource();
    $photo_failure = false;
    $filename = $hash;
    $img = photo_factory($photo, $type);
    if ($img->is_valid()) {
        $img->scaleImageSquare(300);
        $p = array('aid' => $aid, 'uid' => $uid, 'resource_id' => $hash, 'filename' => $filename, 'album' => t('Profile Photos'), 'photo_usage' => PHOTO_PROFILE, 'imgscale' => 4);
        $r = $img->save($p);
        if ($r === false) {
            $photo_failure = true;
        }
        $img->scaleImage(80);
        $p['imgscale'] = 5;
        $r = $img->save($p);
        if ($r === false) {
            $photo_failure = true;
        }
        $img->scaleImage(48);
        $p['imgscale'] = 6;
        $r = $img->save($p);
        if ($r === false) {
            $photo_failure = true;
        }
    } else {
        logger('import_channel_photo: invalid image.');
        $photo_failure = true;
    }
    //return(($photo_failure)? false : true);
    if ($photo_failure) {
        return false;
    } else {
        return $hash;
    }
}
示例#8
0
 function profile_photo_crop_ui_head(&$a, $ph)
 {
     $max_length = get_config('system', 'max_image_length');
     if (!$max_length) {
         $max_length = MAX_IMAGE_LENGTH;
     }
     if ($max_length > 0) {
         $ph->scaleImage($max_length);
     }
     $width = $ph->getWidth();
     $height = $ph->getHeight();
     if ($width < 175 || $height < 175) {
         $ph->scaleImageUp(200);
         $width = $ph->getWidth();
         $height = $ph->getHeight();
     }
     $hash = photo_new_resource();
     $smallest = 0;
     $r = $ph->store(local_user(), 0, $hash, $filename, t('Profile Photos'), 0);
     if ($r) {
         info(t('Image uploaded successfully.') . EOL);
     } else {
         notice(t('Image upload failed.') . EOL);
     }
     if ($width > 640 || $height > 640) {
         $ph->scaleImage(640);
         $r = $ph->store(local_user(), 0, $hash, $filename, t('Profile Photos'), 1);
         if ($r === false) {
             notice(sprintf(t('Image size reduction [%s] failed.'), "640") . EOL);
         } else {
             $smallest = 1;
         }
     }
     $a->config['imagecrop'] = $hash;
     $a->config['imagecrop_resolution'] = $smallest;
     $a->config['imagecrop_ext'] = $ph->getExt();
     $a->page['htmlhead'] .= replace_macros(get_markup_template("crophead.tpl"), array());
     $a->page['end'] .= replace_macros(get_markup_template("cropend.tpl"), array());
     return;
 }
示例#9
0
 function profile_photo_crop_ui_head(&$a, $ph)
 {
     $width = $ph->getWidth();
     $height = $ph->getHeight();
     if ($width < 175 || $height < 175) {
         $ph->scaleImageUp(200);
         $width = $ph->getWidth();
         $height = $ph->getHeight();
     }
     $hash = photo_new_resource();
     $smallest = 0;
     $r = $ph->store(local_user(), 0, $hash, $filename, t('Profile Photos'), 0);
     if ($r) {
         info(t('Image uploaded successfully.') . EOL);
     } else {
         notice(t('Image upload failed.') . EOL);
     }
     if ($width > 640 || $height > 640) {
         $ph->scaleImage(640);
         $r = $ph->store(local_user(), 0, $hash, $filename, t('Profile Photos'), 1);
         if ($r === false) {
             notice(sprintf(t('Image size reduction [%s] failed.'), "640") . EOL);
         } else {
             $smallest = 1;
         }
     }
     $a->config['imagecrop'] = $hash;
     $a->config['imagecrop_resolution'] = $smallest;
     $a->page['htmlhead'] .= get_markup_template("crophead.tpl");
     return;
 }
示例#10
0
function import_profile_photo($photo, $uid, $cid)
{
    $a = get_app();
    $r = q("select `resource-id` from photo where `uid` = %d and `contact-id` = %d and `scale` = 4 and `album` = 'Contact Photos' limit 1", intval($uid), intval($cid));
    if (count($r) && strlen($r[0]['resource-id'])) {
        $hash = $r[0]['resource-id'];
    } else {
        $hash = photo_new_resource();
    }
    $photo_failure = false;
    $filename = basename($photo);
    $img_str = fetch_url($photo, true);
    $type = guess_image_type($photo, true);
    $img = new Photo($img_str, $type);
    if ($img->is_valid()) {
        $img->scaleImageSquare(175);
        $r = $img->store($uid, $cid, $hash, $filename, 'Contact Photos', 4);
        if ($r === false) {
            $photo_failure = true;
        }
        $img->scaleImage(80);
        $r = $img->store($uid, $cid, $hash, $filename, 'Contact Photos', 5);
        if ($r === false) {
            $photo_failure = true;
        }
        $img->scaleImage(48);
        $r = $img->store($uid, $cid, $hash, $filename, 'Contact Photos', 6);
        if ($r === false) {
            $photo_failure = true;
        }
        $photo = $a->get_baseurl() . '/photo/' . $hash . '-4.' . $img->getExt();
        $thumb = $a->get_baseurl() . '/photo/' . $hash . '-5.' . $img->getExt();
        $micro = $a->get_baseurl() . '/photo/' . $hash . '-6.' . $img->getExt();
    } else {
        $photo_failure = true;
    }
    if ($photo_failure) {
        $photo = $a->get_baseurl() . '/images/person-175.jpg';
        $thumb = $a->get_baseurl() . '/images/person-80.jpg';
        $micro = $a->get_baseurl() . '/images/person-48.jpg';
    }
    return array($photo, $thumb, $micro);
}
示例#11
0
function wall_upload_post(&$a)
{
    if ($a->argc > 1) {
        $nick = $a->argv[1];
        $r = q("SELECT * FROM `user` WHERE `nickname` = '%s' AND `blocked` = 0 LIMIT 1", dbesc($nick));
        if (!count($r)) {
            return;
        }
    } else {
        return;
    }
    $can_post = false;
    $visitor = 0;
    $page_owner_uid = $r[0]['uid'];
    $page_owner_nick = $r[0]['nickname'];
    $community_page = $r[0]['page-flags'] == PAGE_COMMUNITY ? true : false;
    if (local_user() && local_user() == $page_owner_uid) {
        $can_post = true;
    } else {
        if ($community_page && remote_user()) {
            $r = q("SELECT `uid` FROM `contact` WHERE `blocked` = 0 AND `pending` = 0 AND `id` = %d AND `uid` = %d LIMIT 1", intval(remote_user()), intval($page_owner_uid));
            if (count($r)) {
                $can_post = true;
                $visitor = remote_user();
            }
        }
    }
    if (!$can_post) {
        notice(t('Permission denied.') . EOL);
        killme();
    }
    if (!x($_FILES, 'userfile')) {
        killme();
    }
    $src = $_FILES['userfile']['tmp_name'];
    $filename = basename($_FILES['userfile']['name']);
    $filesize = intval($_FILES['userfile']['size']);
    $maximagesize = get_config('system', 'maximagesize');
    if ($maximagesize && $filesize > $maximagesize) {
        echo sprintf(t('Image exceeds size limit of %d'), $maximagesize) . EOL;
        @unlink($src);
        killme();
    }
    $imagedata = @file_get_contents($src);
    $ph = new Photo($imagedata);
    if (!$ph->is_valid()) {
        echo t('Unable to process image.') . EOL;
        @unlink($src);
        killme();
    }
    @unlink($src);
    $width = $ph->getWidth();
    $height = $ph->getHeight();
    $hash = photo_new_resource();
    $smallest = 0;
    $defperm = '<' . $page_owner_uid . '>';
    $r = $ph->store($page_owner_uid, $visitor, $hash, $filename, t('Wall Photos'), 0, 0, $defperm);
    if (!$r) {
        echo t('Image upload failed.') . EOL;
        killme();
    }
    if ($width > 640 || $height > 640) {
        $ph->scaleImage(640);
        $r = $ph->store($page_owner_uid, $visitor, $hash, $filename, t('Wall Photos'), 1, 0, $defperm);
        if ($r) {
            $smallest = 1;
        }
    }
    if ($width > 320 || $height > 320) {
        $ph->scaleImage(320);
        $r = $ph->store($page_owner_uid, $visitor, $hash, $filename, t('Wall Photos'), 2, 0, $defperm);
        if ($r) {
            $smallest = 2;
        }
    }
    $basename = basename($filename);
    echo '<br /><br /><a href="' . $a->get_baseurl() . '/photos/' . $page_owner_nick . '/image/' . $hash . '" ><img src="' . $a->get_baseurl() . "/photo/{$hash}-{$smallest}.jpg\" alt=\"{$basename}\" /></a><br /><br />";
    killme();
    // NOTREACHED
}
示例#12
0
function wall_upload_post(&$a)
{
    logger("wall upload: starting new upload", LOGGER_DEBUG);
    if ($a->argc > 1) {
        if (!x($_FILES, 'media')) {
            $nick = $a->argv[1];
            $r = q("SELECT `user`.*, `contact`.`id` FROM `user` LEFT JOIN `contact` on `user`.`uid` = `contact`.`uid`  WHERE `user`.`nickname` = '%s' AND `user`.`blocked` = 0 and `contact`.`self` = 1 LIMIT 1", dbesc($nick));
            if (!count($r)) {
                return;
            }
        } else {
            $user_info = api_get_user($a);
            $r = q("SELECT `user`.*, `contact`.`id` FROM `user` LEFT JOIN `contact` on `user`.`uid` = `contact`.`uid`  WHERE `user`.`nickname` = '%s' AND `user`.`blocked` = 0 and `contact`.`self` = 1 LIMIT 1", dbesc($user_info['screen_name']));
        }
    } else {
        return;
    }
    $can_post = false;
    $visitor = 0;
    $page_owner_uid = $r[0]['uid'];
    $default_cid = $r[0]['id'];
    $page_owner_nick = $r[0]['nickname'];
    $community_page = $r[0]['page-flags'] == PAGE_COMMUNITY ? true : false;
    if (local_user() && local_user() == $page_owner_uid) {
        $can_post = true;
    } else {
        if ($community_page && remote_user()) {
            $cid = 0;
            if (is_array($_SESSION['remote'])) {
                foreach ($_SESSION['remote'] as $v) {
                    if ($v['uid'] == $page_owner_uid) {
                        $cid = $v['cid'];
                        break;
                    }
                }
            }
            if ($cid) {
                $r = q("SELECT `uid` FROM `contact` WHERE `blocked` = 0 AND `pending` = 0 AND `id` = %d AND `uid` = %d LIMIT 1", intval($cid), intval($page_owner_uid));
                if (count($r)) {
                    $can_post = true;
                    $visitor = $cid;
                }
            }
        }
    }
    if (!$can_post) {
        notice(t('Permission denied.') . EOL);
        killme();
    }
    if (!x($_FILES, 'userfile') && !x($_FILES, 'media')) {
        killme();
    }
    if (x($_FILES, 'userfile')) {
        $src = $_FILES['userfile']['tmp_name'];
        $filename = basename($_FILES['userfile']['name']);
        $filesize = intval($_FILES['userfile']['size']);
        $filetype = $_FILES['userfile']['type'];
    } elseif (x($_FILES, 'media')) {
        $src = $_FILES['media']['tmp_name'];
        $filename = basename($_FILES['media']['name']);
        $filesize = intval($_FILES['media']['size']);
        $filetype = $_FILES['media']['type'];
    }
    if ($filetype == "") {
        $filetype = guess_image_type($filename);
    }
    $maximagesize = get_config('system', 'maximagesize');
    if ($maximagesize && $filesize > $maximagesize) {
        echo sprintf(t('Image exceeds size limit of %d'), $maximagesize) . EOL;
        @unlink($src);
        killme();
    }
    $r = q("select sum(octet_length(data)) as total from photo where uid = %d and scale = 0 and album != 'Contact Photos' ", intval($page_owner_uid));
    $limit = service_class_fetch($page_owner_uid, 'photo_upload_limit');
    if ($limit !== false && $r[0]['total'] + strlen($imagedata) > $limit) {
        echo upgrade_message(true) . EOL;
        @unlink($src);
        killme();
    }
    $imagedata = @file_get_contents($src);
    $ph = new Photo($imagedata, $filetype);
    if (!$ph->is_valid()) {
        echo t('Unable to process image.') . EOL;
        @unlink($src);
        killme();
    }
    $ph->orient($src);
    @unlink($src);
    $max_length = get_config('system', 'max_image_length');
    if (!$max_length) {
        $max_length = MAX_IMAGE_LENGTH;
    }
    if ($max_length > 0) {
        $ph->scaleImage($max_length);
    }
    $width = $ph->getWidth();
    $height = $ph->getHeight();
    $hash = photo_new_resource();
    $smallest = 0;
    $defperm = '<' . $default_cid . '>';
    $r = $ph->store($page_owner_uid, $visitor, $hash, $filename, t('Wall Photos'), 0, 0, $defperm);
    if (!$r) {
        echo t('Image upload failed.') . EOL;
        killme();
    }
    if ($width > 640 || $height > 640) {
        $ph->scaleImage(640);
        $r = $ph->store($page_owner_uid, $visitor, $hash, $filename, t('Wall Photos'), 1, 0, $defperm);
        if ($r) {
            $smallest = 1;
        }
    }
    if ($width > 320 || $height > 320) {
        $ph->scaleImage(320);
        $r = $ph->store($page_owner_uid, $visitor, $hash, $filename, t('Wall Photos'), 2, 0, $defperm);
        if ($r) {
            $smallest = 2;
        }
    }
    $basename = basename($filename);
    /* mod Waitman Gobble NO WARRANTY */
    //if we get the signal then return the image url info in BBCODE, otherwise this outputs the info and bails (for the ajax image uploader on wall post)
    if ($_REQUEST['hush'] != 'yeah') {
        if (local_user() && (!feature_enabled(local_user(), 'richtext') || x($_REQUEST['nomce']))) {
            echo "\n\n" . '[url=' . $a->get_baseurl() . '/photos/' . $page_owner_nick . '/image/' . $hash . '][img]' . $a->get_baseurl() . "/photo/{$hash}-{$smallest}." . $ph->getExt() . "[/img][/url]\n\n";
        } else {
            echo '<br /><br /><a href="' . $a->get_baseurl() . '/photos/' . $page_owner_nick . '/image/' . $hash . '" ><img src="' . $a->get_baseurl() . "/photo/{$hash}-{$smallest}." . $ph->getExt() . "\" alt=\"{$basename}\" /></a><br /><br />";
        }
    } else {
        $m = '[url=' . $a->get_baseurl() . '/photos/' . $page_owner_nick . '/image/' . $hash . '][img]' . $a->get_baseurl() . "/photo/{$hash}-{$smallest}." . $ph->getExt() . "[/img][/url]";
        return $m;
    }
    /* mod Waitman Gobble NO WARRANTY */
    killme();
    // NOTREACHED
}
示例#13
0
function import_profile_photo($photo, $uid, $cid)
{
    $a = get_app();
    $photo_failure = false;
    $filename = basename($photo);
    $img_str = fetch_url($photo, true);
    $img = new Photo($img_str);
    if ($img->is_valid()) {
        $img->scaleImageSquare(175);
        $hash = photo_new_resource();
        $r = $img->store($uid, $cid, $hash, $filename, 'Contact Photos', 4);
        if ($r === false) {
            $photo_failure = true;
        }
        $img->scaleImage(80);
        $r = $img->store($uid, $cid, $hash, $filename, 'Contact Photos', 5);
        if ($r === false) {
            $photo_failure = true;
        }
        $img->scaleImage(48);
        $r = $img->store($uid, $cid, $hash, $filename, 'Contact Photos', 6);
        if ($r === false) {
            $photo_failure = true;
        }
        $photo = $a->get_baseurl() . '/photo/' . $hash . '-4.jpg';
        $thumb = $a->get_baseurl() . '/photo/' . $hash . '-5.jpg';
        $micro = $a->get_baseurl() . '/photo/' . $hash . '-6.jpg';
    } else {
        $photo_failure = true;
    }
    if ($photo_failure) {
        $photo = $a->get_baseurl() . '/images/default-profile.jpg';
        $thumb = $a->get_baseurl() . '/images/default-profile-sm.jpg';
        $micro = $a->get_baseurl() . '/images/default-profile-mm.jpg';
    }
    return array($photo, $thumb, $micro);
}
示例#14
0
/**
 * @brief
 *
 * @param array $channel
 * @param array $observer
 * @param array $args
 * @return array
 */
function photo_upload($channel, $observer, $args)
{
    $ret = array('success' => false);
    $channel_id = $channel['channel_id'];
    $account_id = $channel['channel_account_id'];
    if (!perm_is_allowed($channel_id, $observer['xchan_hash'], 'write_storage')) {
        $ret['message'] = t('Permission denied.');
        return $ret;
    }
    //	call_hooks('photo_upload_begin', $args);
    /*
     * Determine the album to use
     */
    $album = $args['album'];
    if (intval($args['visible']) || $args['visible'] === 'true') {
        $visible = 1;
    } else {
        $visible = 0;
    }
    $deliver = true;
    if (array_key_exists('deliver', $args)) {
        $deliver = intval($args['deliver']);
    }
    // Set to default channel permissions. If the parent directory (album) has permissions set,
    // use those instead. If we have specific permissions supplied, they take precedence over
    // all other settings. 'allow_cid' being passed from an external source takes priority over channel settings.
    // ...messy... needs re-factoring once the photos/files integration stabilises
    $acl = new Zotlabs\Access\AccessList($channel);
    if (array_key_exists('directory', $args) && $args['directory']) {
        $acl->set($args['directory']);
    }
    if (array_key_exists('allow_cid', $args)) {
        $acl->set($args);
    }
    if (array_key_exists('group_allow', $args) || array_key_exists('contact_allow', $args) || array_key_exists('group_deny', $args) || array_key_exists('contact_deny', $args)) {
        $acl->set_from_array($args);
    }
    $ac = $acl->get();
    $os_storage = 0;
    if ($args['os_path'] && $args['getimagesize']) {
        $imagedata = @file_get_contents($args['os_path']);
        $filename = $args['filename'];
        $filesize = strlen($imagedata);
        // this is going to be deleted if it exists
        $src = '/tmp/deletemenow';
        $type = $args['getimagesize']['mime'];
        $os_storage = 1;
    } elseif ($args['data'] || $args['content']) {
        // allow an import from a binary string representing the image.
        // This bypasses the upload step and max size limit checking
        $imagedata = $args['content'] ? $args['content'] : $args['data'];
        $filename = $args['filename'];
        $filesize = strlen($imagedata);
        // this is going to be deleted if it exists
        $src = '/tmp/deletemenow';
        $type = $args['mimetype'] ? $args['mimetype'] : $args['type'];
    } else {
        $f = array('src' => '', 'filename' => '', 'filesize' => 0, 'type' => '');
        //		call_hooks('photo_upload_file',$f);
        if (x($f, 'src') && x($f, 'filesize')) {
            $src = $f['src'];
            $filename = $f['filename'];
            $filesize = $f['filesize'];
            $type = $f['type'];
        } else {
            $src = $_FILES['userfile']['tmp_name'];
            $filename = basename($_FILES['userfile']['name']);
            $filesize = intval($_FILES['userfile']['size']);
            $type = $_FILES['userfile']['type'];
        }
        if (!$type) {
            $type = guess_image_type($filename);
        }
        logger('photo_upload: received file: ' . $filename . ' as ' . $src . ' (' . $type . ') ' . $filesize . ' bytes', LOGGER_DEBUG);
        $maximagesize = get_config('system', 'maximagesize');
        if ($maximagesize && $filesize > $maximagesize) {
            $ret['message'] = sprintf(t('Image exceeds website size limit of %lu bytes'), $maximagesize);
            @unlink($src);
            call_hooks('photo_upload_end', $ret);
            return $ret;
        }
        if (!$filesize) {
            $ret['message'] = t('Image file is empty.');
            @unlink($src);
            call_hooks('photo_post_end', $ret);
            return $ret;
        }
        logger('photo_upload: loading the contents of ' . $src, LOGGER_DEBUG);
        $imagedata = @file_get_contents($src);
    }
    $r = q("select sum(filesize) as total from photo where aid = %d and imgscale = 0 ", intval($account_id));
    $limit = engr_units_to_bytes(service_class_fetch($channel_id, 'photo_upload_limit'));
    if ($r && $limit !== false && $r[0]['total'] + strlen($imagedata) > $limit) {
        $ret['message'] = upgrade_message();
        @unlink($src);
        call_hooks('photo_post_end', $ret);
        return $ret;
    }
    $ph = photo_factory($imagedata, $type);
    if (!$ph->is_valid()) {
        $ret['message'] = t('Unable to process image');
        logger('photo_upload: unable to process image');
        @unlink($src);
        call_hooks('photo_upload_end', $ret);
        return $ret;
    }
    $exif = $ph->orient($args['os_path'] ? $args['os_path'] : $src);
    @unlink($src);
    $max_length = get_config('system', 'max_image_length');
    if (!$max_length) {
        $max_length = MAX_IMAGE_LENGTH;
    }
    if ($max_length > 0) {
        $ph->scaleImage($max_length);
    }
    $width = $ph->getWidth();
    $height = $ph->getHeight();
    $smallest = 0;
    $photo_hash = $args['resource_id'] ? $args['resource_id'] : photo_new_resource();
    $visitor = '';
    if ($channel['channel_hash'] !== $observer['xchan_hash']) {
        $visitor = $observer['xchan_hash'];
    }
    $errors = false;
    $p = array('aid' => $account_id, 'uid' => $channel_id, 'xchan' => $visitor, 'resource_id' => $photo_hash, 'filename' => $filename, 'album' => $album, 'imgscale' => 0, 'photo_usage' => PHOTO_NORMAL, 'allow_cid' => $ac['allow_cid'], 'allow_gid' => $ac['allow_gid'], 'deny_cid' => $ac['deny_cid'], 'deny_gid' => $ac['deny_gid'], 'os_storage' => $os_storage, 'os_path' => $args['os_path']);
    if ($args['created']) {
        $p['created'] = $args['created'];
    }
    if ($args['edited']) {
        $p['edited'] = $args['edited'];
    }
    if ($args['title']) {
        $p['title'] = $args['title'];
    }
    if ($args['description']) {
        $p['description'] = $args['description'];
    }
    $link = array();
    $r0 = $ph->save($p);
    $link[0] = array('rel' => 'alternate', 'type' => 'text/html', 'href' => z_root() . '/photo/' . $photo_hash . '-0.' . $ph->getExt(), 'width' => $ph->getWidth(), 'height' => $ph->getHeight());
    if (!$r0) {
        $errors = true;
    }
    unset($p['os_storage']);
    unset($p['os_path']);
    if (($width > 1024 || $height > 1024) && !$errors) {
        $ph->scaleImage(1024);
    }
    $p['imgscale'] = 1;
    $r1 = $ph->save($p);
    $link[1] = array('rel' => 'alternate', 'type' => 'text/html', 'href' => z_root() . '/photo/' . $photo_hash . '-1.' . $ph->getExt(), 'width' => $ph->getWidth(), 'height' => $ph->getHeight());
    if (!$r1) {
        $errors = true;
    }
    if (($width > 640 || $height > 640) && !$errors) {
        $ph->scaleImage(640);
    }
    $p['imgscale'] = 2;
    $r2 = $ph->save($p);
    $link[2] = array('rel' => 'alternate', 'type' => 'text/html', 'href' => z_root() . '/photo/' . $photo_hash . '-2.' . $ph->getExt(), 'width' => $ph->getWidth(), 'height' => $ph->getHeight());
    if (!$r2) {
        $errors = true;
    }
    if (($width > 320 || $height > 320) && !$errors) {
        $ph->scaleImage(320);
    }
    $p['imgscale'] = 3;
    $r3 = $ph->save($p);
    $link[3] = array('rel' => 'alternate', 'type' => 'text/html', 'href' => z_root() . '/photo/' . $photo_hash . '-3.' . $ph->getExt(), 'width' => $ph->getWidth(), 'height' => $ph->getHeight());
    if (!$r3) {
        $errors = true;
    }
    if ($errors) {
        q("delete from photo where resource_id = '%s' and uid = %d", dbesc($photo_hash), intval($channel_id));
        $ret['message'] = t('Photo storage failed.');
        logger('photo_upload: photo store failed.');
        call_hooks('photo_upload_end', $ret);
        return $ret;
    }
    $item_hidden = $visible ? 0 : 1;
    $lat = $lon = null;
    if ($exif && $exif['GPS']) {
        if (feature_enabled($channel_id, 'photo_location')) {
            $lat = getGps($exif['GPS']['GPSLatitude'], $exif['GPS']['GPSLatitudeRef']);
            $lon = getGps($exif['GPS']['GPSLongitude'], $exif['GPS']['GPSLongitudeRef']);
        }
    }
    $title = $args['description'] ? $args['description'] : $args['filename'];
    $large_photos = feature_enabled($channel['channel_id'], 'large_photos');
    linkify_tags($a, $args['body'], $channel_id);
    if ($large_photos) {
        $scale = 1;
        $width = $link[1]['width'];
        $height = $link[1]['height'];
        $tag = $r1 ? '[zmg=' . $width . 'x' . $height . ']' : '[zmg]';
    } else {
        $scale = 2;
        $width = $link[2]['width'];
        $height = $link[2]['height'];
        $tag = $r2 ? '[zmg=' . $width . 'x' . $height . ']' : '[zmg]';
    }
    $author_link = '[zrl=' . z_root() . '/channel/' . $channel['channel_address'] . ']' . $channel['channel_name'] . '[/zrl]';
    $photo_link = '[zrl=' . z_root() . '/photos/' . $channel['channel_address'] . '/image/' . $photo_hash . ']' . t('a new photo') . '[/zrl]';
    $album_link = '[zrl=' . z_root() . '/photos/' . $channel['channel_address'] . '/album/' . bin2hex($album) . ']' . (strlen($album) ? $album : '/') . '[/zrl]';
    $activity_format = sprintf(t('%1$s posted %2$s to %3$s', 'photo_upload'), $author_link, $photo_link, $album_link);
    $summary = ($args['body'] ? $args['body'] : '') . '[footer]' . $activity_format . '[/footer]';
    $obj_body = '[zrl=' . z_root() . '/photos/' . $channel['channel_address'] . '/image/' . $photo_hash . ']' . $tag . z_root() . "/photo/{$photo_hash}-{$scale}." . $ph->getExt() . '[/zmg]' . '[/zrl]';
    // Create item object
    $object = array('type' => ACTIVITY_OBJ_PHOTO, 'title' => $title, 'created' => $p['created'], 'edited' => $p['edited'], 'id' => z_root() . '/photos/' . $channel['channel_address'] . '/image/' . $photo_hash, 'link' => $link, 'body' => $obj_body);
    $target = array('type' => ACTIVITY_OBJ_ALBUM, 'title' => $album ? $album : '/', 'id' => z_root() . '/photos/' . $channel['channel_address'] . '/album/' . bin2hex($album));
    // Create item container
    if ($args['item']) {
        foreach ($args['item'] as $i) {
            $item = get_item_elements($i);
            $force = false;
            if ($item['mid'] === $item['parent_mid']) {
                $item['body'] = $summary;
                $item['obj_type'] = ACTIVITY_OBJ_PHOTO;
                $item['obj'] = json_encode($object);
                $item['tgt_type'] = ACTIVITY_OBJ_ALBUM;
                $item['target'] = json_encode($target);
                if ($item['author_xchan'] === $channel['channel_hash']) {
                    $item['sig'] = base64url_encode(rsa_sign($item['body'], $channel['channel_prvkey']));
                    $item['item_verified'] = 1;
                } else {
                    $item['sig'] = '';
                }
                $force = true;
            }
            $r = q("select id, edited from item where mid = '%s' and uid = %d limit 1", dbesc($item['mid']), intval($channel['channel_id']));
            if ($r) {
                if ($item['edited'] > $r[0]['edited'] || $force) {
                    $item['id'] = $r[0]['id'];
                    $item['uid'] = $channel['channel_id'];
                    item_store_update($item, false, $deliver);
                    continue;
                }
            } else {
                $item['aid'] = $channel['channel_account_id'];
                $item['uid'] = $channel['channel_id'];
                $item_result = item_store($item, false, $deliver);
            }
        }
    } else {
        $mid = item_message_id();
        $arr = array();
        if ($lat && $lon) {
            $arr['coord'] = $lat . ' ' . $lon;
        }
        $arr['aid'] = $account_id;
        $arr['uid'] = $channel_id;
        $arr['mid'] = $mid;
        $arr['parent_mid'] = $mid;
        $arr['item_hidden'] = $item_hidden;
        $arr['resource_type'] = 'photo';
        $arr['resource_id'] = $photo_hash;
        $arr['owner_xchan'] = $channel['channel_hash'];
        $arr['author_xchan'] = $observer['xchan_hash'];
        $arr['title'] = $title;
        $arr['allow_cid'] = $ac['allow_cid'];
        $arr['allow_gid'] = $ac['allow_gid'];
        $arr['deny_cid'] = $ac['deny_cid'];
        $arr['deny_gid'] = $ac['deny_gid'];
        $arr['verb'] = ACTIVITY_POST;
        $arr['obj_type'] = ACTIVITY_OBJ_PHOTO;
        $arr['obj'] = json_encode($object);
        $arr['tgt_type'] = ACTIVITY_OBJ_ALBUM;
        $arr['target'] = json_encode($target);
        $arr['item_wall'] = 1;
        $arr['item_origin'] = 1;
        $arr['item_thread_top'] = 1;
        $arr['item_private'] = intval($acl->is_private());
        $arr['plink'] = z_root() . '/channel/' . $channel['channel_address'] . '/?f=&mid=' . $arr['mid'];
        $arr['body'] = $summary;
        // this one is tricky because the item and the photo have the same permissions, those of the photo.
        // Use the channel read_stream permissions to get the correct public_policy for the item and recalculate the
        // private flag accordingly. This may cause subtle bugs due to custom permissions roles. We want to use
        // public policy when federating items to other sites, but should probably ignore them when accessing the item
        // in the photos pages - using the photos permissions instead. We need the public policy to keep the photo
        // linked item from leaking into the feed when somebody has a channel with read_stream restrictions.
        $arr['public_policy'] = map_scope($channel['channel_r_stream'], true);
        if ($arr['public_policy']) {
            $arr['item_private'] = 1;
        }
        $result = item_store($arr, false, $deliver);
        $item_id = $result['item_id'];
        if ($visible && $deliver) {
            Zotlabs\Daemon\Master::Summon(array('Notifier', 'wall-new', $item_id));
        }
    }
    $ret['success'] = true;
    $ret['item'] = $arr;
    $ret['body'] = $obj_body;
    $ret['resource_id'] = $photo_hash;
    $ret['photoitem_id'] = $item_id;
    call_hooks('photo_upload_end', $ret);
    return $ret;
}
示例#15
0
function local_delivery($importer, $data)
{
    $a = get_app();
    logger(__FUNCTION__, LOGGER_TRACE);
    if ($importer['readonly']) {
        // We aren't receiving stuff from this person. But we will quietly ignore them
        // rather than a blatant "go away" message.
        logger('local_delivery: ignoring');
        return 0;
        //NOTREACHED
    }
    // Consume notification feed. This may differ from consuming a public feed in several ways
    // - might contain email or friend suggestions
    // - might contain remote followup to our message
    //		- in which case we need to accept it and then notify other conversants
    // - we may need to send various email notifications
    $feed = new SimplePie();
    $feed->set_raw_data($data);
    $feed->enable_order_by_date(false);
    $feed->init();
    if ($feed->error()) {
        logger('local_delivery: Error parsing XML: ' . $feed->error());
    }
    // Check at the feed level for updated contact name and/or photo
    $name_updated = '';
    $new_name = '';
    $photo_timestamp = '';
    $photo_url = '';
    $rawtags = $feed->get_feed_tags(NAMESPACE_DFRN, 'owner');
    // Fallback should not be needed here. If it isn't DFRN it won't have DFRN updated tags
    //	if(! $rawtags)
    //		$rawtags = $feed->get_feed_tags( SIMPLEPIE_NAMESPACE_ATOM_10, 'author');
    if ($rawtags) {
        $elems = $rawtags[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_10];
        if ($elems['name'][0]['attribs'][NAMESPACE_DFRN]['updated']) {
            $name_updated = $elems['name'][0]['attribs'][NAMESPACE_DFRN]['updated'];
            $new_name = $elems['name'][0]['data'];
        }
        if (x($elems, 'link') && $elems['link'][0]['attribs']['']['rel'] === 'photo' && $elems['link'][0]['attribs'][NAMESPACE_DFRN]['updated']) {
            $photo_timestamp = datetime_convert('UTC', 'UTC', $elems['link'][0]['attribs'][NAMESPACE_DFRN]['updated']);
            $photo_url = $elems['link'][0]['attribs']['']['href'];
        }
    }
    if ($photo_timestamp && strlen($photo_url) && $photo_timestamp > $importer['avatar-date']) {
        logger('local_delivery: Updating photo for ' . $importer['name']);
        require_once "include/Photo.php";
        $photo_failure = false;
        $have_photo = false;
        $r = q("SELECT `resource-id` FROM `photo` WHERE `contact-id` = %d AND `uid` = %d LIMIT 1", intval($importer['id']), intval($importer['importer_uid']));
        if (count($r)) {
            $resource_id = $r[0]['resource-id'];
            $have_photo = true;
        } else {
            $resource_id = photo_new_resource();
        }
        $img_str = fetch_url($photo_url, true);
        // guess mimetype from headers or filename
        $type = guess_image_type($photo_url, true);
        $img = new Photo($img_str, $type);
        if ($img->is_valid()) {
            if ($have_photo) {
                q("DELETE FROM `photo` WHERE `resource-id` = '%s' AND `contact-id` = %d AND `uid` = %d", dbesc($resource_id), intval($importer['id']), intval($importer['importer_uid']));
            }
            $img->scaleImageSquare(175);
            $hash = $resource_id;
            $r = $img->store($importer['importer_uid'], $importer['id'], $hash, basename($photo_url), 'Contact Photos', 4);
            $img->scaleImage(80);
            $r = $img->store($importer['importer_uid'], $importer['id'], $hash, basename($photo_url), 'Contact Photos', 5);
            $img->scaleImage(48);
            $r = $img->store($importer['importer_uid'], $importer['id'], $hash, basename($photo_url), 'Contact Photos', 6);
            $a = get_app();
            q("UPDATE `contact` SET `avatar-date` = '%s', `photo` = '%s', `thumb` = '%s', `micro` = '%s'\n\t\t\t\tWHERE `uid` = %d AND `id` = %d LIMIT 1", dbesc(datetime_convert()), dbesc($a->get_baseurl() . '/photo/' . $hash . '-4.' . $img->getExt()), dbesc($a->get_baseurl() . '/photo/' . $hash . '-5.' . $img->getExt()), dbesc($a->get_baseurl() . '/photo/' . $hash . '-6.' . $img->getExt()), intval($importer['importer_uid']), intval($importer['id']));
        }
    }
    if ($name_updated && strlen($new_name) && $name_updated > $importer['name-date']) {
        $r = q("select * from contact where uid = %d and id = %d limit 1", intval($importer['importer_uid']), intval($importer['id']));
        $x = q("UPDATE `contact` SET `name` = '%s', `name-date` = '%s' WHERE `uid` = %d AND `id` = %d LIMIT 1", dbesc(notags(trim($new_name))), dbesc(datetime_convert()), intval($importer['importer_uid']), intval($importer['id']));
        // do our best to update the name on content items
        if (count($r)) {
            q("update item set `author-name` = '%s' where `author-name` = '%s' and `author-link` = '%s' and uid = %d", dbesc(notags(trim($new_name))), dbesc($r[0]['name']), dbesc($r[0]['url']), intval($importer['importer_uid']));
        }
    }
    // Currently unsupported - needs a lot of work
    $reloc = $feed->get_feed_tags(NAMESPACE_DFRN, 'relocate');
    if (isset($reloc[0]['child'][NAMESPACE_DFRN])) {
        $base = $reloc[0]['child'][NAMESPACE_DFRN];
        $newloc = array();
        $newloc['uid'] = $importer['importer_uid'];
        $newloc['cid'] = $importer['id'];
        $newloc['name'] = notags(unxmlify($base['name'][0]['data']));
        $newloc['photo'] = notags(unxmlify($base['photo'][0]['data']));
        $newloc['thumb'] = notags(unxmlify($base['thumb'][0]['data']));
        $newloc['micro'] = notags(unxmlify($base['micro'][0]['data']));
        $newloc['url'] = notags(unxmlify($base['url'][0]['data']));
        $newloc['request'] = notags(unxmlify($base['request'][0]['data']));
        $newloc['confirm'] = notags(unxmlify($base['confirm'][0]['data']));
        $newloc['notify'] = notags(unxmlify($base['notify'][0]['data']));
        $newloc['poll'] = notags(unxmlify($base['poll'][0]['data']));
        $newloc['sitepubkey'] = notags(unxmlify($base['sitepubkey'][0]['data']));
        /** relocated user must have original key pair */
        /*$newloc['pubkey'] = notags(unxmlify($base['pubkey'][0]['data']));
        		$newloc['prvkey'] = notags(unxmlify($base['prvkey'][0]['data']));*/
        logger("items:relocate contact " . print_r($newloc, true) . print_r($importer, true), LOGGER_DEBUG);
        // update contact
        $r = q("SELECT photo, url FROM contact WHERE id=%d AND uid=%d;", intval($importer['id']), intval($importer['importer_uid']));
        if ($r === false) {
            return 1;
        }
        $old = $r[0];
        $x = q("UPDATE contact SET\n                        name = '%s',\n                        photo = '%s',\n                        thumb = '%s',\n                        micro = '%s',\n                        url = '%s',\n                        request = '%s',\n                        confirm = '%s',\n                        notify = '%s',\n                        poll = '%s',\n                        `site-pubkey` = '%s'\n                WHERE id=%d AND uid=%d;", dbesc($newloc['name']), dbesc($newloc['photo']), dbesc($newloc['thumb']), dbesc($newloc['micro']), dbesc($newloc['url']), dbesc($newloc['request']), dbesc($newloc['confirm']), dbesc($newloc['notify']), dbesc($newloc['poll']), dbesc($newloc['sitepubkey']), intval($importer['id']), intval($importer['importer_uid']));
        if ($x === false) {
            return 1;
        }
        // update items
        $fields = array('owner-link' => array($old['url'], $newloc['url']), 'author-link' => array($old['url'], $newloc['url']), 'owner-avatar' => array($old['photo'], $newloc['photo']), 'author-avatar' => array($old['photo'], $newloc['photo']));
        foreach ($fields as $n => $f) {
            $x = q("UPDATE item SET `%s`='%s' WHERE `%s`='%s' AND uid=%d", $n, dbesc($f[1]), $n, dbesc($f[0]), intval($importer['importer_uid']));
            if ($x === false) {
                return 1;
            }
        }
        // TODO
        // merge with current record, current contents have priority
        // update record, set url-updated
        // update profile photos
        // schedule a scan?
        return 0;
    }
    // handle friend suggestion notification
    $sugg = $feed->get_feed_tags(NAMESPACE_DFRN, 'suggest');
    if (isset($sugg[0]['child'][NAMESPACE_DFRN])) {
        $base = $sugg[0]['child'][NAMESPACE_DFRN];
        $fsugg = array();
        $fsugg['uid'] = $importer['importer_uid'];
        $fsugg['cid'] = $importer['id'];
        $fsugg['name'] = notags(unxmlify($base['name'][0]['data']));
        $fsugg['photo'] = notags(unxmlify($base['photo'][0]['data']));
        $fsugg['url'] = notags(unxmlify($base['url'][0]['data']));
        $fsugg['request'] = notags(unxmlify($base['request'][0]['data']));
        $fsugg['body'] = escape_tags(unxmlify($base['note'][0]['data']));
        // Does our member already have a friend matching this description?
        $r = q("SELECT * FROM `contact` WHERE `name` = '%s' AND `nurl` = '%s' AND `uid` = %d LIMIT 1", dbesc($fsugg['name']), dbesc(normalise_link($fsugg['url'])), intval($fsugg['uid']));
        if (count($r)) {
            return 0;
        }
        // Do we already have an fcontact record for this person?
        $fid = 0;
        $r = q("SELECT * FROM `fcontact` WHERE `url` = '%s' AND `name` = '%s' AND `request` = '%s' LIMIT 1", dbesc($fsugg['url']), dbesc($fsugg['name']), dbesc($fsugg['request']));
        if (count($r)) {
            $fid = $r[0]['id'];
            // OK, we do. Do we already have an introduction for this person ?
            $r = q("select id from intro where uid = %d and fid = %d limit 1", intval($fsugg['uid']), intval($fid));
            if (count($r)) {
                return 0;
            }
        }
        if (!$fid) {
            $r = q("INSERT INTO `fcontact` ( `name`,`url`,`photo`,`request` ) VALUES ( '%s', '%s', '%s', '%s' ) ", dbesc($fsugg['name']), dbesc($fsugg['url']), dbesc($fsugg['photo']), dbesc($fsugg['request']));
        }
        $r = q("SELECT * FROM `fcontact` WHERE `url` = '%s' AND `name` = '%s' AND `request` = '%s' LIMIT 1", dbesc($fsugg['url']), dbesc($fsugg['name']), dbesc($fsugg['request']));
        if (count($r)) {
            $fid = $r[0]['id'];
        } else {
            return 0;
        }
        $hash = random_string();
        $r = q("INSERT INTO `intro` ( `uid`, `fid`, `contact-id`, `note`, `hash`, `datetime`, `blocked` )\n\t\t\tVALUES( %d, %d, %d, '%s', '%s', '%s', %d )", intval($fsugg['uid']), intval($fid), intval($fsugg['cid']), dbesc($fsugg['body']), dbesc($hash), dbesc(datetime_convert()), intval(0));
        notification(array('type' => NOTIFY_SUGGEST, 'notify_flags' => $importer['notify-flags'], 'language' => $importer['language'], 'to_name' => $importer['username'], 'to_email' => $importer['email'], 'uid' => $importer['importer_uid'], 'item' => $fsugg, 'link' => $a->get_baseurl() . '/notifications/intros', 'source_name' => $importer['name'], 'source_link' => $importer['url'], 'source_photo' => $importer['photo'], 'verb' => ACTIVITY_REQ_FRIEND, 'otype' => 'intro'));
        return 0;
    }
    $ismail = false;
    $rawmail = $feed->get_feed_tags(NAMESPACE_DFRN, 'mail');
    if (isset($rawmail[0]['child'][NAMESPACE_DFRN])) {
        logger('local_delivery: private message received');
        $ismail = true;
        $base = $rawmail[0]['child'][NAMESPACE_DFRN];
        $msg = array();
        $msg['uid'] = $importer['importer_uid'];
        $msg['from-name'] = notags(unxmlify($base['sender'][0]['child'][NAMESPACE_DFRN]['name'][0]['data']));
        $msg['from-photo'] = notags(unxmlify($base['sender'][0]['child'][NAMESPACE_DFRN]['avatar'][0]['data']));
        $msg['from-url'] = notags(unxmlify($base['sender'][0]['child'][NAMESPACE_DFRN]['uri'][0]['data']));
        $msg['contact-id'] = $importer['id'];
        $msg['title'] = notags(unxmlify($base['subject'][0]['data']));
        $msg['body'] = escape_tags(unxmlify($base['content'][0]['data']));
        $msg['seen'] = 0;
        $msg['replied'] = 0;
        $msg['uri'] = notags(unxmlify($base['id'][0]['data']));
        $msg['parent-uri'] = notags(unxmlify($base['in-reply-to'][0]['data']));
        $msg['created'] = datetime_convert(notags(unxmlify('UTC', 'UTC', $base['sentdate'][0]['data'])));
        dbesc_array($msg);
        $r = dbq("INSERT INTO `mail` (`" . implode("`, `", array_keys($msg)) . "`) VALUES ('" . implode("', '", array_values($msg)) . "')");
        // send notifications.
        require_once 'include/enotify.php';
        $notif_params = array('type' => NOTIFY_MAIL, 'notify_flags' => $importer['notify-flags'], 'language' => $importer['language'], 'to_name' => $importer['username'], 'to_email' => $importer['email'], 'uid' => $importer['importer_uid'], 'item' => $msg, 'source_name' => $msg['from-name'], 'source_link' => $importer['url'], 'source_photo' => $importer['thumb'], 'verb' => ACTIVITY_POST, 'otype' => 'mail');
        notification($notif_params);
        return 0;
        // NOTREACHED
    }
    $community_page = 0;
    $rawtags = $feed->get_feed_tags(NAMESPACE_DFRN, 'community');
    if ($rawtags) {
        $community_page = intval($rawtags[0]['data']);
    }
    if (intval($importer['forum']) != $community_page) {
        q("update contact set forum = %d where id = %d limit 1", intval($community_page), intval($importer['id']));
        $importer['forum'] = (string) $community_page;
    }
    logger('local_delivery: feed item count = ' . $feed->get_item_quantity());
    // process any deleted entries
    $del_entries = $feed->get_feed_tags(NAMESPACE_TOMB, 'deleted-entry');
    if (is_array($del_entries) && count($del_entries)) {
        foreach ($del_entries as $dentry) {
            $deleted = false;
            if (isset($dentry['attribs']['']['ref'])) {
                $uri = $dentry['attribs']['']['ref'];
                $deleted = true;
                if (isset($dentry['attribs']['']['when'])) {
                    $when = $dentry['attribs']['']['when'];
                    $when = datetime_convert('UTC', 'UTC', $when, 'Y-m-d H:i:s');
                } else {
                    $when = datetime_convert('UTC', 'UTC', 'now', 'Y-m-d H:i:s');
                }
            }
            if ($deleted) {
                // check for relayed deletes to our conversation
                $is_reply = false;
                $r = q("select * from item where uri = '%s' and uid = %d limit 1", dbesc($uri), intval($importer['importer_uid']));
                if (count($r)) {
                    $parent_uri = $r[0]['parent-uri'];
                    if ($r[0]['id'] != $r[0]['parent']) {
                        $is_reply = true;
                    }
                }
                if ($is_reply) {
                    $community = false;
                    if ($importer['page-flags'] == PAGE_COMMUNITY || $importer['page-flags'] == PAGE_PRVGROUP) {
                        $sql_extra = '';
                        $community = true;
                        logger('local_delivery: possible community delete');
                    } else {
                        $sql_extra = " and contact.self = 1 and item.wall = 1 ";
                    }
                    // was the top-level post for this reply written by somebody on this site?
                    // Specifically, the recipient?
                    $is_a_remote_delete = false;
                    // POSSIBLE CLEANUP --> Why select so many fields when only forum_mode and wall are used?
                    $r = q("select `item`.`id`, `item`.`uri`, `item`.`tag`, `item`.`forum_mode`,`item`.`origin`,`item`.`wall`, \n\t\t\t\t\t\t`contact`.`name`, `contact`.`url`, `contact`.`thumb` from `item` \n\t\t\t\t\t\tLEFT JOIN `contact` ON `contact`.`id` = `item`.`contact-id` \n\t\t\t\t\t\tWHERE `item`.`uri` = '%s' AND (`item`.`parent-uri` = '%s' or `item`.`thr-parent` = '%s')\n\t\t\t\t\t\tAND `item`.`uid` = %d \n\t\t\t\t\t\t{$sql_extra}\n\t\t\t\t\t\tLIMIT 1", dbesc($parent_uri), dbesc($parent_uri), dbesc($parent_uri), intval($importer['importer_uid']));
                    if ($r && count($r)) {
                        $is_a_remote_delete = true;
                    }
                    // Does this have the characteristics of a community or private group comment?
                    // If it's a reply to a wall post on a community/prvgroup page it's a
                    // valid community comment. Also forum_mode makes it valid for sure.
                    // If neither, it's not.
                    if ($is_a_remote_delete && $community) {
                        if (!$r[0]['forum_mode'] && !$r[0]['wall']) {
                            $is_a_remote_delete = false;
                            logger('local_delivery: not a community delete');
                        }
                    }
                    if ($is_a_remote_delete) {
                        logger('local_delivery: received remote delete');
                    }
                }
                $r = q("SELECT `item`.*, `contact`.`self` FROM `item` left join contact on `item`.`contact-id` = `contact`.`id`\n\t\t\t\t\tWHERE `uri` = '%s' AND `item`.`uid` = %d AND `contact-id` = %d AND NOT `item`.`file` LIKE '%%[%%' LIMIT 1", dbesc($uri), intval($importer['importer_uid']), intval($importer['id']));
                if (count($r)) {
                    $item = $r[0];
                    if ($item['deleted']) {
                        continue;
                    }
                    logger('local_delivery: deleting item ' . $item['id'] . ' uri=' . $item['uri'], LOGGER_DEBUG);
                    if ($item['verb'] === ACTIVITY_TAG && $item['object-type'] === ACTIVITY_OBJ_TAGTERM) {
                        $xo = parse_xml_string($item['object'], false);
                        $xt = parse_xml_string($item['target'], false);
                        if ($xt->type === ACTIVITY_OBJ_NOTE) {
                            $i = q("select * from `item` where uri = '%s' and uid = %d limit 1", dbesc($xt->id), intval($importer['importer_uid']));
                            if (count($i)) {
                                // For tags, the owner cannot remove the tag on the author's copy of the post.
                                $owner_remove = $item['contact-id'] == $i[0]['contact-id'] ? true : false;
                                $author_remove = $item['origin'] && $item['self'] ? true : false;
                                $author_copy = $item['origin'] ? true : false;
                                if ($owner_remove && $author_copy) {
                                    continue;
                                }
                                if ($author_remove || $owner_remove) {
                                    $tags = explode(',', $i[0]['tag']);
                                    $newtags = array();
                                    if (count($tags)) {
                                        foreach ($tags as $tag) {
                                            if (trim($tag) !== trim($xo->body)) {
                                                $newtags[] = trim($tag);
                                            }
                                        }
                                    }
                                    q("update item set tag = '%s' where id = %d limit 1", dbesc(implode(',', $newtags)), intval($i[0]['id']));
                                    create_tags_from_item($i[0]['id']);
                                }
                            }
                        }
                    }
                    if ($item['uri'] == $item['parent-uri']) {
                        $r = q("UPDATE `item` SET `deleted` = 1, `edited` = '%s', `changed` = '%s',\n\t\t\t\t\t\t\t`body` = '', `title` = ''\n\t\t\t\t\t\t\tWHERE `parent-uri` = '%s' AND `uid` = %d", dbesc($when), dbesc(datetime_convert()), dbesc($item['uri']), intval($importer['importer_uid']));
                        create_tags_from_itemuri($item['uri'], $importer['importer_uid']);
                    } else {
                        $r = q("UPDATE `item` SET `deleted` = 1, `edited` = '%s', `changed` = '%s',\n\t\t\t\t\t\t\t`body` = '', `title` = ''\n\t\t\t\t\t\t\tWHERE `uri` = '%s' AND `uid` = %d LIMIT 1", dbesc($when), dbesc(datetime_convert()), dbesc($uri), intval($importer['importer_uid']));
                        create_tags_from_itemuri($uri, $importer['importer_uid']);
                        if ($item['last-child']) {
                            // ensure that last-child is set in case the comment that had it just got wiped.
                            q("UPDATE `item` SET `last-child` = 0, `changed` = '%s' WHERE `parent-uri` = '%s' AND `uid` = %d ", dbesc(datetime_convert()), dbesc($item['parent-uri']), intval($item['uid']));
                            // who is the last child now?
                            $r = q("SELECT `id` FROM `item` WHERE `parent-uri` = '%s' AND `type` != 'activity' AND `deleted` = 0 AND `uid` = %d\n\t\t\t\t\t\t\t\tORDER BY `created` DESC LIMIT 1", dbesc($item['parent-uri']), intval($importer['importer_uid']));
                            if (count($r)) {
                                q("UPDATE `item` SET `last-child` = 1 WHERE `id` = %d LIMIT 1", intval($r[0]['id']));
                            }
                        }
                        // if this is a relayed delete, propagate it to other recipients
                        if ($is_a_remote_delete) {
                            proc_run('php', "include/notifier.php", "drop", $item['id']);
                        }
                    }
                }
            }
        }
    }
    foreach ($feed->get_items() as $item) {
        $is_reply = false;
        $item_id = $item->get_id();
        $rawthread = $item->get_item_tags(NAMESPACE_THREAD, 'in-reply-to');
        if (isset($rawthread[0]['attribs']['']['ref'])) {
            $is_reply = true;
            $parent_uri = $rawthread[0]['attribs']['']['ref'];
        }
        if ($is_reply) {
            $community = false;
            if ($importer['page-flags'] == PAGE_COMMUNITY || $importer['page-flags'] == PAGE_PRVGROUP) {
                $sql_extra = '';
                $community = true;
                logger('local_delivery: possible community reply');
            } else {
                $sql_extra = " and contact.self = 1 and item.wall = 1 ";
            }
            // was the top-level post for this reply written by somebody on this site?
            // Specifically, the recipient?
            $is_a_remote_comment = false;
            $top_uri = $parent_uri;
            $r = q("select `item`.`parent-uri` from `item`\n\t\t\t\tWHERE `item`.`uri` = '%s'\n\t\t\t\tLIMIT 1", dbesc($parent_uri));
            if ($r && count($r)) {
                $top_uri = $r[0]['parent-uri'];
                // POSSIBLE CLEANUP --> Why select so many fields when only forum_mode and wall are used?
                $r = q("select `item`.`id`, `item`.`uri`, `item`.`tag`, `item`.`forum_mode`,`item`.`origin`,`item`.`wall`, \n\t\t\t\t\t`contact`.`name`, `contact`.`url`, `contact`.`thumb` from `item` \n\t\t\t\t\tLEFT JOIN `contact` ON `contact`.`id` = `item`.`contact-id` \n\t\t\t\t\tWHERE `item`.`uri` = '%s' AND (`item`.`parent-uri` = '%s' or `item`.`thr-parent` = '%s')\n\t\t\t\t\tAND `item`.`uid` = %d \n\t\t\t\t\t{$sql_extra}\n\t\t\t\t\tLIMIT 1", dbesc($top_uri), dbesc($top_uri), dbesc($top_uri), intval($importer['importer_uid']));
                if ($r && count($r)) {
                    $is_a_remote_comment = true;
                }
            }
            // Does this have the characteristics of a community or private group comment?
            // If it's a reply to a wall post on a community/prvgroup page it's a
            // valid community comment. Also forum_mode makes it valid for sure.
            // If neither, it's not.
            if ($is_a_remote_comment && $community) {
                if (!$r[0]['forum_mode'] && !$r[0]['wall']) {
                    $is_a_remote_comment = false;
                    logger('local_delivery: not a community reply');
                }
            }
            if ($is_a_remote_comment) {
                logger('local_delivery: received remote comment');
                $is_like = false;
                // remote reply to our post. Import and then notify everybody else.
                $datarray = get_atom_elements($feed, $item);
                $r = q("SELECT `id`, `uid`, `last-child`, `edited`, `body`  FROM `item` WHERE `uri` = '%s' AND `uid` = %d LIMIT 1", dbesc($item_id), intval($importer['importer_uid']));
                // Update content if 'updated' changes
                if (count($r)) {
                    $iid = $r[0]['id'];
                    if (x($datarray, 'edited') !== false && datetime_convert('UTC', 'UTC', $datarray['edited']) !== $r[0]['edited']) {
                        // do not accept (ignore) an earlier edit than one we currently have.
                        if (datetime_convert('UTC', 'UTC', $datarray['edited']) < $r[0]['edited']) {
                            continue;
                        }
                        logger('received updated comment', LOGGER_DEBUG);
                        $r = q("UPDATE `item` SET `title` = '%s', `body` = '%s', `tag` = '%s', `edited` = '%s' WHERE `uri` = '%s' AND `uid` = %d LIMIT 1", dbesc($datarray['title']), dbesc($datarray['body']), dbesc($datarray['tag']), dbesc(datetime_convert('UTC', 'UTC', $datarray['edited'])), dbesc($item_id), intval($importer['importer_uid']));
                        create_tags_from_itemuri($item_id, $importer['importer_uid']);
                        proc_run('php', "include/notifier.php", "comment-import", $iid);
                    }
                    continue;
                }
                $own = q("select name,url,thumb from contact where uid = %d and self = 1 limit 1", intval($importer['importer_uid']));
                $datarray['type'] = 'remote-comment';
                $datarray['wall'] = 1;
                $datarray['parent-uri'] = $parent_uri;
                $datarray['uid'] = $importer['importer_uid'];
                $datarray['owner-name'] = $own[0]['name'];
                $datarray['owner-link'] = $own[0]['url'];
                $datarray['owner-avatar'] = $own[0]['thumb'];
                $datarray['contact-id'] = $importer['id'];
                if ($datarray['verb'] === ACTIVITY_LIKE || $datarray['verb'] === ACTIVITY_DISLIKE) {
                    $is_like = true;
                    $datarray['type'] = 'activity';
                    $datarray['gravity'] = GRAVITY_LIKE;
                    $datarray['last-child'] = 0;
                    // only one like or dislike per person
                    $r = q("select id from item where uid = %d and `contact-id` = %d and verb = '%s' and (`thr-parent` = '%s' or `parent-uri` = '%s') and deleted = 0 limit 1", intval($datarray['uid']), intval($datarray['contact-id']), dbesc($datarray['verb']), dbesc($datarray['parent-uri']), dbesc($datarray['parent-uri']));
                    if ($r && count($r)) {
                        continue;
                    }
                }
                if ($datarray['verb'] === ACTIVITY_TAG && $datarray['object-type'] === ACTIVITY_OBJ_TAGTERM) {
                    $xo = parse_xml_string($datarray['object'], false);
                    $xt = parse_xml_string($datarray['target'], false);
                    if ($xt->type == ACTIVITY_OBJ_NOTE && $xt->id) {
                        // fetch the parent item
                        $tagp = q("select * from item where uri = '%s' and uid = %d limit 1", dbesc($xt->id), intval($importer['importer_uid']));
                        if (!count($tagp)) {
                            continue;
                        }
                        // extract tag, if not duplicate, and this user allows tags, add to parent item
                        if ($xo->id && $xo->content) {
                            $newtag = '#[url=' . $xo->id . ']' . $xo->content . '[/url]';
                            if (!stristr($tagp[0]['tag'], $newtag)) {
                                $i = q("SELECT `blocktags` FROM `user` where `uid` = %d LIMIT 1", intval($importer['importer_uid']));
                                if (count($i) && !intval($i[0]['blocktags'])) {
                                    q("UPDATE item SET tag = '%s', `edited` = '%s' WHERE id = %d LIMIT 1", dbesc($tagp[0]['tag'] . (strlen($tagp[0]['tag']) ? ',' : '') . $newtag), intval($tagp[0]['id']), dbesc(datetime_convert()));
                                    create_tags_from_item($tagp[0]['id']);
                                }
                            }
                        }
                    }
                }
                $posted_id = item_store($datarray);
                $parent = 0;
                if ($posted_id) {
                    $r = q("SELECT `parent`, `parent-uri` FROM `item` WHERE `id` = %d AND `uid` = %d LIMIT 1", intval($posted_id), intval($importer['importer_uid']));
                    if (count($r)) {
                        $parent = $r[0]['parent'];
                        $parent_uri = $r[0]['parent-uri'];
                    }
                    if (!$is_like) {
                        $r1 = q("UPDATE `item` SET `last-child` = 0, `changed` = '%s' WHERE `uid` = %d AND `parent` = %d", dbesc(datetime_convert()), intval($importer['importer_uid']), intval($r[0]['parent']));
                        $r2 = q("UPDATE `item` SET `last-child` = 1, `changed` = '%s' WHERE `uid` = %d AND `id` = %d LIMIT 1", dbesc(datetime_convert()), intval($importer['importer_uid']), intval($posted_id));
                    }
                    if ($posted_id && $parent) {
                        proc_run('php', "include/notifier.php", "comment-import", "{$posted_id}");
                        if (!$is_like && !$importer['self']) {
                            require_once 'include/enotify.php';
                            notification(array('type' => NOTIFY_COMMENT, 'notify_flags' => $importer['notify-flags'], 'language' => $importer['language'], 'to_name' => $importer['username'], 'to_email' => $importer['email'], 'uid' => $importer['importer_uid'], 'item' => $datarray, 'link' => $a->get_baseurl() . '/display/' . $importer['nickname'] . '/' . $posted_id, 'source_name' => stripslashes($datarray['author-name']), 'source_link' => $datarray['author-link'], 'source_photo' => link_compare($datarray['author-link'], $importer['url']) ? $importer['thumb'] : $datarray['author-avatar'], 'verb' => ACTIVITY_POST, 'otype' => 'item', 'parent' => $parent, 'parent_uri' => $parent_uri));
                        }
                    }
                    return 0;
                    // NOTREACHED
                }
            } else {
                // regular comment that is part of this total conversation. Have we seen it? If not, import it.
                $item_id = $item->get_id();
                $datarray = get_atom_elements($feed, $item);
                if ($importer['rel'] == CONTACT_IS_FOLLOWER) {
                    continue;
                }
                $r = q("SELECT `uid`, `last-child`, `edited`, `body` FROM `item` WHERE `uri` = '%s' AND `uid` = %d LIMIT 1", dbesc($item_id), intval($importer['importer_uid']));
                // Update content if 'updated' changes
                if (count($r)) {
                    if (x($datarray, 'edited') !== false && datetime_convert('UTC', 'UTC', $datarray['edited']) !== $r[0]['edited']) {
                        // do not accept (ignore) an earlier edit than one we currently have.
                        if (datetime_convert('UTC', 'UTC', $datarray['edited']) < $r[0]['edited']) {
                            continue;
                        }
                        $r = q("UPDATE `item` SET `title` = '%s', `body` = '%s', `tag` = '%s', `edited` = '%s' WHERE `uri` = '%s' AND `uid` = %d LIMIT 1", dbesc($datarray['title']), dbesc($datarray['body']), dbesc($datarray['tag']), dbesc(datetime_convert('UTC', 'UTC', $datarray['edited'])), dbesc($item_id), intval($importer['importer_uid']));
                        create_tags_from_itemuri($item_id, $importer['importer_uid']);
                    }
                    // update last-child if it changes
                    $allow = $item->get_item_tags(NAMESPACE_DFRN, 'comment-allow');
                    if ($allow && $allow[0]['data'] != $r[0]['last-child']) {
                        $r = q("UPDATE `item` SET `last-child` = 0, `changed` = '%s' WHERE `parent-uri` = '%s' AND `uid` = %d", dbesc(datetime_convert()), dbesc($parent_uri), intval($importer['importer_uid']));
                        $r = q("UPDATE `item` SET `last-child` = %d , `changed` = '%s'  WHERE `uri` = '%s' AND `uid` = %d LIMIT 1", intval($allow[0]['data']), dbesc(datetime_convert()), dbesc($item_id), intval($importer['importer_uid']));
                    }
                    continue;
                }
                $datarray['parent-uri'] = $parent_uri;
                $datarray['uid'] = $importer['importer_uid'];
                $datarray['contact-id'] = $importer['id'];
                if ($datarray['verb'] == ACTIVITY_LIKE || $datarray['verb'] == ACTIVITY_DISLIKE) {
                    $datarray['type'] = 'activity';
                    $datarray['gravity'] = GRAVITY_LIKE;
                    // only one like or dislike per person
                    $r = q("select id from item where uid = %d and `contact-id` = %d and verb ='%s' and deleted = 0 and (`parent-uri` = '%s' OR `thr-parent` = '%s') limit 1", intval($datarray['uid']), intval($datarray['contact-id']), dbesc($datarray['verb']), dbesc($parent_uri), dbesc($parent_uri));
                    if ($r && count($r)) {
                        continue;
                    }
                }
                if ($datarray['verb'] === ACTIVITY_TAG && $datarray['object-type'] === ACTIVITY_OBJ_TAGTERM) {
                    $xo = parse_xml_string($datarray['object'], false);
                    $xt = parse_xml_string($datarray['target'], false);
                    if ($xt->type == ACTIVITY_OBJ_NOTE) {
                        $r = q("select * from item where `uri` = '%s' AND `uid` = %d limit 1", dbesc($xt->id), intval($importer['importer_uid']));
                        if (!count($r)) {
                            continue;
                        }
                        // extract tag, if not duplicate, add to parent item
                        if ($xo->content) {
                            if (!stristr($r[0]['tag'], trim($xo->content))) {
                                q("UPDATE item SET tag = '%s' WHERE id = %d LIMIT 1", dbesc($r[0]['tag'] . (strlen($r[0]['tag']) ? ',' : '') . '#[url=' . $xo->id . ']' . $xo->content . '[/url]'), intval($r[0]['id']));
                                create_tags_from_item($r[0]['id']);
                            }
                        }
                    }
                }
                $posted_id = item_store($datarray);
                // find out if our user is involved in this conversation and wants to be notified.
                if (!x($datarray['type']) || $datarray['type'] != 'activity') {
                    $myconv = q("SELECT `author-link`, `author-avatar`, `parent` FROM `item` WHERE `parent-uri` = '%s' AND `uid` = %d AND `parent` != 0 AND `deleted` = 0", dbesc($top_uri), intval($importer['importer_uid']));
                    if (count($myconv)) {
                        $importer_url = $a->get_baseurl() . '/profile/' . $importer['nickname'];
                        // first make sure this isn't our own post coming back to us from a wall-to-wall event
                        if (!link_compare($datarray['author-link'], $importer_url)) {
                            foreach ($myconv as $conv) {
                                // now if we find a match, it means we're in this conversation
                                if (!link_compare($conv['author-link'], $importer_url)) {
                                    continue;
                                }
                                require_once 'include/enotify.php';
                                $conv_parent = $conv['parent'];
                                notification(array('type' => NOTIFY_COMMENT, 'notify_flags' => $importer['notify-flags'], 'language' => $importer['language'], 'to_name' => $importer['username'], 'to_email' => $importer['email'], 'uid' => $importer['importer_uid'], 'item' => $datarray, 'link' => $a->get_baseurl() . '/display/' . $importer['nickname'] . '/' . $posted_id, 'source_name' => stripslashes($datarray['author-name']), 'source_link' => $datarray['author-link'], 'source_photo' => link_compare($datarray['author-link'], $importer['url']) ? $importer['thumb'] : $datarray['author-avatar'], 'verb' => ACTIVITY_POST, 'otype' => 'item', 'parent' => $conv_parent, 'parent_uri' => $parent_uri));
                                // only send one notification
                                break;
                            }
                        }
                    }
                }
                continue;
            }
        } else {
            // Head post of a conversation. Have we seen it? If not, import it.
            $item_id = $item->get_id();
            $datarray = get_atom_elements($feed, $item);
            if (x($datarray, 'object-type') && $datarray['object-type'] === ACTIVITY_OBJ_EVENT) {
                $ev = bbtoevent($datarray['body']);
                if (x($ev, 'desc') && x($ev, 'start')) {
                    $ev['cid'] = $importer['id'];
                    $ev['uid'] = $importer['uid'];
                    $ev['uri'] = $item_id;
                    $ev['edited'] = $datarray['edited'];
                    $ev['private'] = $datarray['private'];
                    $r = q("SELECT * FROM `event` WHERE `uri` = '%s' AND `uid` = %d LIMIT 1", dbesc($item_id), intval($importer['uid']));
                    if (count($r)) {
                        $ev['id'] = $r[0]['id'];
                    }
                    $xyz = event_store($ev);
                    continue;
                }
            }
            $r = q("SELECT `uid`, `last-child`, `edited`, `body` FROM `item` WHERE `uri` = '%s' AND `uid` = %d LIMIT 1", dbesc($item_id), intval($importer['importer_uid']));
            // Update content if 'updated' changes
            if (count($r)) {
                if (x($datarray, 'edited') !== false && datetime_convert('UTC', 'UTC', $datarray['edited']) !== $r[0]['edited']) {
                    // do not accept (ignore) an earlier edit than one we currently have.
                    if (datetime_convert('UTC', 'UTC', $datarray['edited']) < $r[0]['edited']) {
                        continue;
                    }
                    $r = q("UPDATE `item` SET `title` = '%s', `body` = '%s', `tag` = '%s', `edited` = '%s' WHERE `uri` = '%s' AND `uid` = %d LIMIT 1", dbesc($datarray['title']), dbesc($datarray['body']), dbesc($datarray['tag']), dbesc(datetime_convert('UTC', 'UTC', $datarray['edited'])), dbesc($item_id), intval($importer['importer_uid']));
                    create_tags_from_itemuri($item_id, $importer['importer_uid']);
                }
                // update last-child if it changes
                $allow = $item->get_item_tags(NAMESPACE_DFRN, 'comment-allow');
                if ($allow && $allow[0]['data'] != $r[0]['last-child']) {
                    $r = q("UPDATE `item` SET `last-child` = %d , `changed` = '%s' WHERE `uri` = '%s' AND `uid` = %d LIMIT 1", intval($allow[0]['data']), dbesc(datetime_convert()), dbesc($item_id), intval($importer['importer_uid']));
                }
                continue;
            }
            // This is my contact on another system, but it's really me.
            // Turn this into a wall post.
            if ($importer['remote_self']) {
                $datarray['wall'] = 1;
            }
            $datarray['parent-uri'] = $item_id;
            $datarray['uid'] = $importer['importer_uid'];
            $datarray['contact-id'] = $importer['id'];
            if (!link_compare($datarray['owner-link'], $importer['url'])) {
                // The item owner info is not our contact. It's OK and is to be expected if this is a tgroup delivery,
                // but otherwise there's a possible data mixup on the sender's system.
                // the tgroup delivery code called from item_store will correct it if it's a forum,
                // but we're going to unconditionally correct it here so that the post will always be owned by our contact.
                logger('local_delivery: Correcting item owner.', LOGGER_DEBUG);
                $datarray['owner-name'] = $importer['senderName'];
                $datarray['owner-link'] = $importer['url'];
                $datarray['owner-avatar'] = $importer['thumb'];
            }
            if ($importer['rel'] == CONTACT_IS_FOLLOWER && !tgroup_check($importer['importer_uid'], $datarray)) {
                continue;
            }
            $posted_id = item_store($datarray);
            if (stristr($datarray['verb'], ACTIVITY_POKE)) {
                $verb = urldecode(substr($datarray['verb'], strpos($datarray['verb'], '#') + 1));
                if (!$verb) {
                    continue;
                }
                $xo = parse_xml_string($datarray['object'], false);
                if ($xo->type == ACTIVITY_OBJ_PERSON && $xo->id) {
                    // somebody was poked/prodded. Was it me?
                    $links = parse_xml_string("<links>" . unxmlify($xo->link) . "</links>", false);
                    foreach ($links->link as $l) {
                        $atts = $l->attributes();
                        switch ($atts['rel']) {
                            case "alternate":
                                $Blink = $atts['href'];
                                break;
                            default:
                                break;
                        }
                    }
                    if ($Blink && link_compare($Blink, $a->get_baseurl() . '/profile/' . $importer['nickname'])) {
                        // send a notification
                        require_once 'include/enotify.php';
                        notification(array('type' => NOTIFY_POKE, 'notify_flags' => $importer['notify-flags'], 'language' => $importer['language'], 'to_name' => $importer['username'], 'to_email' => $importer['email'], 'uid' => $importer['importer_uid'], 'item' => $datarray, 'link' => $a->get_baseurl() . '/display/' . $importer['nickname'] . '/' . $posted_id, 'source_name' => stripslashes($datarray['author-name']), 'source_link' => $datarray['author-link'], 'source_photo' => link_compare($datarray['author-link'], $importer['url']) ? $importer['thumb'] : $datarray['author-avatar'], 'verb' => $datarray['verb'], 'otype' => 'person', 'activity' => $verb));
                    }
                }
            }
            continue;
        }
    }
    return 0;
    // NOTREACHED
}
示例#16
0
 function register_post(&$a)
 {
     global $lang;
     $verified = 0;
     $blocked = 1;
     switch ($a->config['register_policy']) {
         case REGISTER_OPEN:
             $blocked = 0;
             $verified = 1;
             break;
         case REGISTER_APPROVE:
             $blocked = 1;
             $verified = 0;
             break;
         default:
         case REGISTER_CLOSED:
             if (!x($_SESSION, 'authenticated') && !x($_SESSION, 'administrator')) {
                 notice(t('Permission denied.') . EOL);
                 return;
             }
             $blocked = 1;
             $verified = 0;
             break;
     }
     $using_invites = get_config('system', 'invitation_only');
     $num_invites = get_config('system', 'number_invites');
     $invite_id = x($_POST, 'invite_id') ? notags(trim($_POST['invite_id'])) : '';
     $username = x($_POST, 'username') ? notags(trim($_POST['username'])) : '';
     $nickname = x($_POST, 'nickname') ? notags(trim($_POST['nickname'])) : '';
     $email = x($_POST, 'email') ? notags(trim($_POST['email'])) : '';
     $openid_url = x($_POST, 'openid_url') ? notags(trim($_POST['openid_url'])) : '';
     $photo = x($_POST, 'photo') ? notags(trim($_POST['photo'])) : '';
     $publish = x($_POST, 'profile_publish_reg') && intval($_POST['profile_publish_reg']) ? 1 : 0;
     $netpublish = strlen(get_config('system', 'directory_submit_url')) ? $publish : 0;
     $tmp_str = $openid_url;
     if ($using_invites) {
         if (!$invite_id) {
             notice(t('An invitation is required.') . EOL);
             return;
         }
         $r = q("select * from register where `hash` = '%s' limit 1", dbesc($invite_id));
         if (!results($r)) {
             notice(t('Invitation could not be verified.') . EOL);
             return;
         }
     }
     if (!x($username) || !x($email) || !x($nickname)) {
         if ($openid_url) {
             if (!validate_url($tmp_str)) {
                 notice(t('Invalid OpenID url') . EOL);
                 return;
             }
             $_SESSION['register'] = 1;
             $_SESSION['openid'] = $openid_url;
             require_once 'library/openid.php';
             $openid = new LightOpenID();
             $openid->identity = $openid_url;
             $openid->returnUrl = $a->get_baseurl() . '/openid';
             $openid->required = array('namePerson/friendly', 'contact/email', 'namePerson');
             $openid->optional = array('namePerson/first', 'media/image/aspect11', 'media/image/default');
             goaway($openid->authUrl());
             // NOTREACHED
         }
         notice(t('Please enter the required information.') . EOL);
         return;
     }
     if (!validate_url($tmp_str)) {
         $openid_url = '';
     }
     $err = '';
     // collapse multiple spaces in name
     $username = preg_replace('/ +/', ' ', $username);
     if (mb_strlen($username) > 48) {
         $err .= t('Please use a shorter name.') . EOL;
     }
     if (mb_strlen($username) < 3) {
         $err .= t('Name too short.') . EOL;
     }
     // I don't really like having this rule, but it cuts down
     // on the number of auto-registrations by Russian spammers
     //  Using preg_match was completely unreliable, due to mixed UTF-8 regex support
     //	$no_utf = get_config('system','no_utf');
     //	$pat = (($no_utf) ? '/^[a-zA-Z]* [a-zA-Z]*$/' : '/^\p{L}* \p{L}*$/u' );
     // So now we are just looking for a space in the full name.
     $loose_reg = get_config('system', 'no_regfullname');
     if (!$loose_reg) {
         $username = mb_convert_case($username, MB_CASE_TITLE, 'UTF-8');
         if (!strpos($username, ' ')) {
             $err .= t("That doesn't appear to be your full (First Last) name.") . EOL;
         }
     }
     if (!allowed_email($email)) {
         $err .= t('Your email domain is not among those allowed on this site.') . EOL;
     }
     if (!valid_email($email) || !validate_email($email)) {
         $err .= t('Not a valid email address.') . EOL;
     }
     // Disallow somebody creating an account using openid that uses the admin email address,
     // since openid bypasses email verification. We'll allow it if there is not yet an admin account.
     if (x($a->config, 'admin_email') && strcasecmp($email, $a->config['admin_email']) == 0 && strlen($openid_url)) {
         $r = q("SELECT * FROM `user` WHERE `email` = '%s' LIMIT 1", dbesc($email));
         if (count($r)) {
             $err .= t('Cannot use that email.') . EOL;
         }
     }
     $nickname = $_POST['nickname'] = strtolower($nickname);
     if (!preg_match("/^[a-z][a-z0-9\\-\\_]*\$/", $nickname)) {
         $err .= t('Your "nickname" can only contain "a-z", "0-9", "-", and "_", and must also begin with a letter.') . EOL;
     }
     $r = q("SELECT `uid` FROM `user`\n               \tWHERE `nickname` = '%s' LIMIT 1", dbesc($nickname));
     if (count($r)) {
         $err .= t('Nickname is already registered. Please choose another.') . EOL;
     }
     if (strlen($err)) {
         notice($err);
         return;
     }
     $new_password = autoname(6) . mt_rand(100, 9999);
     $new_password_encoded = hash('whirlpool', $new_password);
     $res = openssl_pkey_new(array('digest_alg' => 'sha1', 'private_key_bits' => 4096, 'encrypt_key' => false));
     // Get private key
     if (empty($res)) {
         notice(t('SERIOUS ERROR: Generation of security keys failed.') . EOL);
         return;
     }
     $prvkey = '';
     openssl_pkey_export($res, $prvkey);
     // Get public key
     $pkey = openssl_pkey_get_details($res);
     $pubkey = $pkey["key"];
     /**
      *
      * Create another keypair for signing/verifying
      * salmon protocol messages. We have to use a slightly
      * less robust key because this won't be using openssl
      * but the phpseclib. Since it is PHP interpreted code
      * it is not nearly as efficient, and the larger keys
      * will take several minutes each to process.
      *
      */
     $sres = openssl_pkey_new(array('digest_alg' => 'sha1', 'private_key_bits' => 512, 'encrypt_key' => false));
     // Get private key
     $sprvkey = '';
     openssl_pkey_export($sres, $sprvkey);
     // Get public key
     $spkey = openssl_pkey_get_details($sres);
     $spubkey = $spkey["key"];
     $r = q("INSERT INTO `user` ( `guid`, `username`, `password`, `email`, `openid`, `nickname`,\n\t\t`pubkey`, `prvkey`, `spubkey`, `sprvkey`, `register_date`, `verified`, `blocked` )\n\t\tVALUES ( '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', %d, %d )", dbesc(generate_user_guid()), dbesc($username), dbesc($new_password_encoded), dbesc($email), dbesc($openid_url), dbesc($nickname), dbesc($pubkey), dbesc($prvkey), dbesc($spubkey), dbesc($sprvkey), dbesc(datetime_convert()), intval($verified), intval($blocked));
     if ($r) {
         $r = q("SELECT `uid` FROM `user` \n\t\t\tWHERE `username` = '%s' AND `password` = '%s' LIMIT 1", dbesc($username), dbesc($new_password_encoded));
         if ($r !== false && count($r)) {
             $newuid = intval($r[0]['uid']);
         }
     } else {
         notice(t('An error occurred during registration. Please try again.') . EOL);
         return;
     }
     /**
      * if somebody clicked submit twice very quickly, they could end up with two accounts 
      * due to race condition. Remove this one.
      */
     $r = q("SELECT `uid` FROM `user`\n               \tWHERE `nickname` = '%s' ", dbesc($nickname));
     if (count($r) > 1 && $newuid) {
         $err .= t('Nickname is already registered. Please choose another.') . EOL;
         q("DELETE FROM `user` WHERE `uid` = %d LIMIT 1", intval($newuid));
         notice($err);
         return;
     }
     if (x($newuid) !== false) {
         $r = q("INSERT INTO `profile` ( `uid`, `profile-name`, `is-default`, `name`, `photo`, `thumb`, `publish`, `net-publish` )\n\t\t\tVALUES ( %d, '%s', %d, '%s', '%s', '%s', %d, %d ) ", intval($newuid), 'default', 1, dbesc($username), dbesc($a->get_baseurl() . "/photo/profile/{$newuid}.jpg"), dbesc($a->get_baseurl() . "/photo/avatar/{$newuid}.jpg"), intval($publish), intval($netpublish));
         if ($r === false) {
             notice(t('An error occurred creating your default profile. Please try again.') . EOL);
             // Start fresh next time.
             $r = q("DELETE FROM `user` WHERE `uid` = %d", intval($newuid));
             return;
         }
         $r = q("INSERT INTO `contact` ( `uid`, `created`, `self`, `name`, `nick`, `photo`, `thumb`, `micro`, `blocked`, `pending`, `url`, `nurl`,\n\t\t\t`request`, `notify`, `poll`, `confirm`, `poco`, `name-date`, `uri-date`, `avatar-date` )\n\t\t\tVALUES ( %d, '%s', 1, '%s', '%s', '%s', '%s', '%s', 0, 0, '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s' ) ", intval($newuid), datetime_convert(), dbesc($username), dbesc($nickname), dbesc($a->get_baseurl() . "/photo/profile/{$newuid}.jpg"), dbesc($a->get_baseurl() . "/photo/avatar/{$newuid}.jpg"), dbesc($a->get_baseurl() . "/photo/micro/{$newuid}.jpg"), dbesc($a->get_baseurl() . "/profile/{$nickname}"), dbesc(normalise_link($a->get_baseurl() . "/profile/{$nickname}")), dbesc($a->get_baseurl() . "/dfrn_request/{$nickname}"), dbesc($a->get_baseurl() . "/dfrn_notify/{$nickname}"), dbesc($a->get_baseurl() . "/dfrn_poll/{$nickname}"), dbesc($a->get_baseurl() . "/dfrn_confirm/{$nickname}"), dbesc($a->get_baseurl() . "/poco/{$nickname}"), dbesc(datetime_convert()), dbesc(datetime_convert()), dbesc(datetime_convert()));
     }
     $use_gravatar = get_config('system', 'no_gravatar') ? false : true;
     // if we have an openid photo use it.
     // otherwise unless it is disabled, use gravatar
     if ($use_gravatar || strlen($photo)) {
         require_once 'include/Photo.php';
         if ($use_gravatar && !strlen($photo)) {
             $photo = gravatar_img($email);
         }
         $photo_failure = false;
         $filename = basename($photo);
         $img_str = fetch_url($photo, true);
         $img = new Photo($img_str);
         if ($img->is_valid()) {
             $img->scaleImageSquare(175);
             $hash = photo_new_resource();
             $r = $img->store($newuid, 0, $hash, $filename, t('Profile Photos'), 4);
             if ($r === false) {
                 $photo_failure = true;
             }
             $img->scaleImage(80);
             $r = $img->store($newuid, 0, $hash, $filename, t('Profile Photos'), 5);
             if ($r === false) {
                 $photo_failure = true;
             }
             $img->scaleImage(48);
             $r = $img->store($newuid, 0, $hash, $filename, t('Profile Photos'), 6);
             if ($r === false) {
                 $photo_failure = true;
             }
             if (!$photo_failure) {
                 q("UPDATE `photo` SET `profile` = 1 WHERE `resource-id` = '%s' ", dbesc($hash));
             }
         }
     }
     if ($netpublish && $a->config['register_policy'] != REGISTER_APPROVE) {
         $url = $a->get_baseurl() . "/profile/{$nickname}";
         proc_run('php', "include/directory.php", "{$url}");
     }
     call_hooks('register_account', $newuid);
     if ($a->config['register_policy'] == REGISTER_OPEN) {
         if ($using_invites && $invite_id) {
             q("delete * from register where hash = '%s' limit 1", dbesc($invite_id));
             set_pconfig($newuid, 'system', 'invites_remaining', $num_invites);
         }
         $email_tpl = get_intltext_template("register_open_eml.tpl");
         $email_tpl = replace_macros($email_tpl, array('$sitename' => $a->config['sitename'], '$siteurl' => $a->get_baseurl(), '$username' => $username, '$email' => $email, '$password' => $new_password, '$uid' => $newuid));
         $res = mail($email, sprintf(t('Registration details for %s'), $a->config['sitename']), $email_tpl, 'From: ' . t('Administrator') . '@' . $_SERVER['SERVER_NAME'] . "\n" . 'Content-type: text/plain; charset=UTF-8' . "\n" . 'Content-transfer-encoding: 8bit');
         if ($res) {
             info(t('Registration successful. Please check your email for further instructions.') . EOL);
             goaway(z_root());
         } else {
             notice(t('Failed to send email message. Here is the message that failed.') . $email_tpl . EOL);
         }
     } elseif ($a->config['register_policy'] == REGISTER_APPROVE) {
         if (!strlen($a->config['admin_email'])) {
             notice(t('Your registration can not be processed.') . EOL);
             goaway(z_root());
         }
         $hash = random_string();
         $r = q("INSERT INTO `register` ( `hash`, `created`, `uid`, `password`, `language` ) VALUES ( '%s', '%s', %d, '%s', '%s' ) ", dbesc($hash), dbesc(datetime_convert()), intval($newuid), dbesc($new_password), dbesc($lang));
         $r = q("SELECT `language` FROM `user` WHERE `email` = '%s' LIMIT 1", dbesc($a->config['admin_email']));
         if (count($r)) {
             push_lang($r[0]['language']);
         } else {
             push_lang('en');
         }
         if ($using_invites && $invite_id) {
             q("delete * from register where hash = '%s' limit 1", dbesc($invite_id));
             set_pconfig($newuid, 'system', 'invites_remaining', $num_invites);
         }
         $email_tpl = get_intltext_template("register_verify_eml.tpl");
         $email_tpl = replace_macros($email_tpl, array('$sitename' => $a->config['sitename'], '$siteurl' => $a->get_baseurl(), '$username' => $username, '$email' => $email, '$password' => $new_password, '$uid' => $newuid, '$hash' => $hash));
         $res = mail($a->config['admin_email'], sprintf(t('Registration request at %s'), $a->config['sitename']), $email_tpl, 'From: ' . t('Administrator') . '@' . $_SERVER['SERVER_NAME'] . "\n" . 'Content-type: text/plain; charset=UTF-8' . "\n" . 'Content-transfer-encoding: 8bit');
         pop_lang();
         if ($res) {
             info(t('Your registration is pending approval by the site owner.') . EOL);
             goaway(z_root());
         }
     }
     return;
 }
示例#17
0
function cover_photo_post(&$a)
{
    if (!local_channel()) {
        return;
    }
    $channel = App::get_channel();
    check_form_security_token_redirectOnErr('/cover_photo', 'cover_photo');
    if (x($_POST, 'cropfinal') && $_POST['cropfinal'] == 1) {
        // phase 2 - we have finished cropping
        if (argc() != 2) {
            notice(t('Image uploaded but image cropping failed.') . EOL);
            return;
        }
        $image_id = argv(1);
        if (substr($image_id, -2, 1) == '-') {
            $scale = substr($image_id, -1, 1);
            $image_id = substr($image_id, 0, -2);
        }
        $srcX = $_POST['xstart'];
        $srcY = $_POST['ystart'];
        $srcW = $_POST['xfinal'] - $srcX;
        $srcH = $_POST['yfinal'] - $srcY;
        $r = q("select gender from profile where uid = %d and is_default = 1 limit 1", intval(local_channel()));
        if ($r) {
            $profile = $r[0];
        }
        $r = q("SELECT * FROM photo WHERE resource_id = '%s' AND uid = %d AND scale = 0 LIMIT 1", dbesc($image_id), intval(local_channel()));
        if ($r) {
            $base_image = $r[0];
            $base_image['data'] = $r[0]['os_storage'] ? @file_get_contents($base_image['data']) : dbunescbin($base_image['data']);
            $im = photo_factory($base_image['data'], $base_image['type']);
            if ($im->is_valid()) {
                // We are scaling and cropping the relative pixel locations to the original photo instead of the
                // scaled photo we operated on.
                // First load the scaled photo to check its size. (Should probably pass this in the post form and save
                // a query.)
                $g = q("select width, height from photo where resource_id = '%s' and uid = %d and scale = 3", dbesc($image_id), intval(local_channel()));
                $scaled_width = $g[0]['width'];
                $scaled_height = $g[0]['height'];
                if (!$scaled_width || !$scaled_height) {
                    logger('potential divide by zero scaling cover photo');
                    return;
                }
                // unset all other cover photos
                q("update photo set photo_usage = %d where photo_usage = %d and uid = %d", intval(PHOTO_NORMAL), intval(PHOTO_COVER), intval(local_channel()));
                $orig_srcx = $r[0]['width'] / $scaled_width * $srcX;
                $orig_srcy = $r[0]['height'] / $scaled_height * $srcY;
                $orig_srcw = $srcW / $scaled_width * $r[0]['width'];
                $orig_srch = $srcH / $scaled_height * $r[0]['height'];
                $im->cropImageRect(1200, 435, $orig_srcx, $orig_srcy, $orig_srcw, $orig_srch);
                $aid = get_account_id();
                $p = array('aid' => $aid, 'uid' => local_channel(), 'resource_id' => $base_image['resource_id'], 'filename' => $base_image['filename'], 'album' => t('Cover Photos'));
                $p['scale'] = 7;
                $p['photo_usage'] = PHOTO_COVER;
                $r1 = $im->save($p);
                $im->doScaleImage(850, 310);
                $p['scale'] = 8;
                $r2 = $im->save($p);
                $im->doScaleImage(425, 160);
                $p['scale'] = 9;
                $r3 = $im->save($p);
                if ($r1 === false || $r2 === false || $r3 === false) {
                    // if one failed, delete them all so we can start over.
                    notice(t('Image resize failed.') . EOL);
                    $x = q("delete from photo where resource_id = '%s' and uid = %d and scale >= 7 ", dbesc($base_image['resource_id']), local_channel());
                    return;
                }
                $channel = App::get_channel();
                send_cover_photo_activity($channel, $base_image, $profile);
            } else {
                notice(t('Unable to process image') . EOL);
            }
        }
        goaway(z_root() . '/channel/' . $channel['channel_address']);
    }
    $hash = photo_new_resource();
    $smallest = 0;
    require_once 'include/attach.php';
    $res = attach_store(App::get_channel(), get_observer_hash(), '', array('album' => t('Cover Photos'), 'hash' => $hash));
    logger('attach_store: ' . print_r($res, true));
    if ($res && intval($res['data']['is_photo'])) {
        $i = q("select * from photo where resource_id = '%s' and uid = %d and scale = 0", dbesc($hash), intval(local_channel()));
        if (!$i) {
            notice(t('Image upload failed.') . EOL);
            return;
        }
        $os_storage = false;
        foreach ($i as $ii) {
            $smallest = intval($ii['scale']);
            $os_storage = intval($ii['os_storage']);
            $imagedata = $ii['data'];
            $filetype = $ii['type'];
        }
    }
    $imagedata = $os_storage ? @file_get_contents($imagedata) : $imagedata;
    $ph = photo_factory($imagedata, $filetype);
    if (!$ph->is_valid()) {
        notice(t('Unable to process image.') . EOL);
        return;
    }
    return cover_photo_crop_ui_head($a, $ph, $hash, $smallest);
}
示例#18
0
/**
 *
 * consume_feed - process atom feed and update anything/everything we might need to update
 *
 * $xml = the (atom) feed to consume - RSS isn't as fully supported but may work for simple feeds.
 *
 * $importer = the contact_record (joined to user_record) of the local user who owns this relationship.
 *             It is this person's stuff that is going to be updated.
 * $contact =  the person who is sending us stuff. If not set, we MAY be processing a "follow" activity
 *             from an external network and MAY create an appropriate contact record. Otherwise, we MUST 
 *             have a contact record.
 * $hub = should we find a hub declation in the feed, pass it back to our calling process, who might (or 
 *        might not) try and subscribe to it.
 * $datedir sorts in reverse order
 * $pass - by default ($pass = 0) we cannot guarantee that a parent item has been 
 *      imported prior to its children being seen in the stream unless we are certain
 *      of how the feed is arranged/ordered.
 * With $pass = 1, we only pull parent items out of the stream.
 * With $pass = 2, we only pull children (comments/likes).
 *
 * So running this twice, first with pass 1 and then with pass 2 will do the right
 * thing regardless of feed ordering. This won't be adequate in a fully-threaded
 * model where comments can have sub-threads. That would require some massive sorting
 * to get all the feed items into a mostly linear ordering, and might still require
 * recursion.  
 */
function consume_feed($xml, $importer, &$contact, &$hub, $datedir = 0, $pass = 0)
{
    require_once 'library/simplepie/simplepie.inc';
    if (!strlen($xml)) {
        logger('consume_feed: empty input');
        return;
    }
    $feed = new SimplePie();
    $feed->set_raw_data($xml);
    if ($datedir) {
        $feed->enable_order_by_date(true);
    } else {
        $feed->enable_order_by_date(false);
    }
    $feed->init();
    if ($feed->error()) {
        logger('consume_feed: Error parsing XML: ' . $feed->error());
    }
    $permalink = $feed->get_permalink();
    // Check at the feed level for updated contact name and/or photo
    $name_updated = '';
    $new_name = '';
    $photo_timestamp = '';
    $photo_url = '';
    $birthday = '';
    $hubs = $feed->get_links('hub');
    if (count($hubs)) {
        $hub = implode(',', $hubs);
    }
    $rawtags = $feed->get_feed_tags(NAMESPACE_DFRN, 'owner');
    if (!$rawtags) {
        $rawtags = $feed->get_feed_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'author');
    }
    if ($rawtags) {
        $elems = $rawtags[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_10];
        if ($elems['name'][0]['attribs'][NAMESPACE_DFRN]['updated']) {
            $name_updated = $elems['name'][0]['attribs'][NAMESPACE_DFRN]['updated'];
            $new_name = $elems['name'][0]['data'];
        }
        if (x($elems, 'link') && $elems['link'][0]['attribs']['']['rel'] === 'photo' && $elems['link'][0]['attribs'][NAMESPACE_DFRN]['updated']) {
            $photo_timestamp = datetime_convert('UTC', 'UTC', $elems['link'][0]['attribs'][NAMESPACE_DFRN]['updated']);
            $photo_url = $elems['link'][0]['attribs']['']['href'];
        }
        if (x($rawtags[0]['child'], NAMESPACE_DFRN) && x($rawtags[0]['child'][NAMESPACE_DFRN], 'birthday')) {
            $birthday = datetime_convert('UTC', 'UTC', $rawtags[0]['child'][NAMESPACE_DFRN]['birthday'][0]['data']);
        }
    }
    if (is_array($contact) && $photo_timestamp && strlen($photo_url) && $photo_timestamp > $contact['avatar-date']) {
        logger('consume_feed: Updating photo for ' . $contact['name']);
        require_once "Photo.php";
        $photo_failure = false;
        $have_photo = false;
        $r = q("SELECT `resource-id` FROM `photo` WHERE `contact-id` = %d AND `uid` = %d LIMIT 1", intval($contact['id']), intval($contact['uid']));
        if (count($r)) {
            $resource_id = $r[0]['resource-id'];
            $have_photo = true;
        } else {
            $resource_id = photo_new_resource();
        }
        $img_str = fetch_url($photo_url, true);
        $img = new Photo($img_str);
        if ($img->is_valid()) {
            if ($have_photo) {
                q("DELETE FROM `photo` WHERE `resource-id` = '%s' AND `contact-id` = %d AND `uid` = %d", dbesc($resource_id), intval($contact['id']), intval($contact['uid']));
            }
            $img->scaleImageSquare(175);
            $hash = $resource_id;
            $r = $img->store($contact['uid'], $contact['id'], $hash, basename($photo_url), 'Contact Photos', 4);
            $img->scaleImage(80);
            $r = $img->store($contact['uid'], $contact['id'], $hash, basename($photo_url), 'Contact Photos', 5);
            $img->scaleImage(48);
            $r = $img->store($contact['uid'], $contact['id'], $hash, basename($photo_url), 'Contact Photos', 6);
            $a = get_app();
            q("UPDATE `contact` SET `avatar-date` = '%s', `photo` = '%s', `thumb` = '%s', `micro` = '%s'  \n\t\t\t\tWHERE `uid` = %d AND `id` = %d LIMIT 1", dbesc(datetime_convert()), dbesc($a->get_baseurl() . '/photo/' . $hash . '-4.jpg'), dbesc($a->get_baseurl() . '/photo/' . $hash . '-5.jpg'), dbesc($a->get_baseurl() . '/photo/' . $hash . '-6.jpg'), intval($contact['uid']), intval($contact['id']));
        }
    }
    if (is_array($contact) && $name_updated && strlen($new_name) && $name_updated > $contact['name-date']) {
        $r = q("select * from contact where uid = %d and id = %d limit 1", intval($contact['uid']), intval($contact['id']));
        $x = q("UPDATE `contact` SET `name` = '%s', `name-date` = '%s' WHERE `uid` = %d AND `id` = %d LIMIT 1", dbesc(notags(trim($new_name))), dbesc(datetime_convert()), intval($contact['uid']), intval($contact['id']));
        // do our best to update the name on content items
        if (count($r)) {
            q("update item set `author-name` = '%s' where `author-name` = '%s' and `author-link` = '%s' and uid = %d", dbesc(notags(trim($new_name))), dbesc($r[0]['name']), dbesc($r[0]['url']), intval($contact['uid']));
        }
    }
    if (strlen($birthday)) {
        if (substr($birthday, 0, 4) != $contact['bdyear']) {
            logger('consume_feed: updating birthday: ' . $birthday);
            /**
             *
             * Add new birthday event for this person
             *
             * $bdtext is just a readable placeholder in case the event is shared
             * with others. We will replace it during presentation to our $importer
             * to contain a sparkle link and perhaps a photo. 
             *
             */
            $bdtext = t('Birthday:') . ' [url=' . $contact['url'] . ']' . $contact['name'] . '[/url]';
            $r = q("INSERT INTO `event` (`uid`,`cid`,`created`,`edited`,`start`,`finish`,`desc`,`type`)\n\t\t\t\tVALUES ( %d, %d, '%s', '%s', '%s', '%s', '%s', '%s' ) ", intval($contact['uid']), intval($contact['id']), dbesc(datetime_convert()), dbesc(datetime_convert()), dbesc(datetime_convert('UTC', 'UTC', $birthday)), dbesc(datetime_convert('UTC', 'UTC', $birthday . ' + 1 day ')), dbesc($bdtext), dbesc('birthday'));
            // update bdyear
            q("UPDATE `contact` SET `bdyear` = '%s' WHERE `uid` = %d AND `id` = %d LIMIT 1", dbesc(substr($birthday, 0, 4)), intval($contact['uid']), intval($contact['id']));
            // This function is called twice without reloading the contact
            // Make sure we only create one event. This is why &$contact
            // is a reference var in this function
            $contact['bdyear'] = substr($birthday, 0, 4);
        }
    }
    $community_page = 0;
    $rawtags = $feed->get_feed_tags(NAMESPACE_DFRN, 'community');
    if ($rawtags) {
        $community_page = intval($rawtags[0]['data']);
    }
    if (is_array($contact) && intval($contact['forum']) != $community_page) {
        q("update contact set forum = %d where id = %d limit 1", intval($community_page), intval($contact['id']));
        $contact['forum'] = (string) $community_page;
    }
    // process any deleted entries
    $del_entries = $feed->get_feed_tags(NAMESPACE_TOMB, 'deleted-entry');
    if (is_array($del_entries) && count($del_entries) && $pass != 2) {
        foreach ($del_entries as $dentry) {
            $deleted = false;
            if (isset($dentry['attribs']['']['ref'])) {
                $uri = $dentry['attribs']['']['ref'];
                $deleted = true;
                if (isset($dentry['attribs']['']['when'])) {
                    $when = $dentry['attribs']['']['when'];
                    $when = datetime_convert('UTC', 'UTC', $when, 'Y-m-d H:i:s');
                } else {
                    $when = datetime_convert('UTC', 'UTC', 'now', 'Y-m-d H:i:s');
                }
            }
            if ($deleted && is_array($contact)) {
                $r = q("SELECT `item`.*, `contact`.`self` FROM `item` left join `contact` on `item`.`contact-id` = `contact`.`id` \n\t\t\t\t\tWHERE `uri` = '%s' AND `item`.`uid` = %d AND `contact-id` = %d AND NOT `item`.`file` LIKE '%%[%%' LIMIT 1", dbesc($uri), intval($importer['uid']), intval($contact['id']));
                if (count($r)) {
                    $item = $r[0];
                    if (!$item['deleted']) {
                        logger('consume_feed: deleting item ' . $item['id'] . ' uri=' . $item['uri'], LOGGER_DEBUG);
                    }
                    if ($item['verb'] === ACTIVITY_TAG && $item['object-type'] === ACTIVITY_OBJ_TAGTERM) {
                        $xo = parse_xml_string($item['object'], false);
                        $xt = parse_xml_string($item['target'], false);
                        if ($xt->type === ACTIVITY_OBJ_NOTE) {
                            $i = q("select * from `item` where uri = '%s' and uid = %d limit 1", dbesc($xt->id), intval($importer['importer_uid']));
                            if (count($i)) {
                                // For tags, the owner cannot remove the tag on the author's copy of the post.
                                $owner_remove = $item['contact-id'] == $i[0]['contact-id'] ? true : false;
                                $author_remove = $item['origin'] && $item['self'] ? true : false;
                                $author_copy = $item['origin'] ? true : false;
                                if ($owner_remove && $author_copy) {
                                    continue;
                                }
                                if ($author_remove || $owner_remove) {
                                    $tags = explode(',', $i[0]['tag']);
                                    $newtags = array();
                                    if (count($tags)) {
                                        foreach ($tags as $tag) {
                                            if (trim($tag) !== trim($xo->body)) {
                                                $newtags[] = trim($tag);
                                            }
                                        }
                                    }
                                    q("update item set tag = '%s' where id = %d limit 1", dbesc(implode(',', $newtags)), intval($i[0]['id']));
                                }
                            }
                        }
                    }
                    if ($item['uri'] == $item['parent-uri']) {
                        $r = q("UPDATE `item` SET `deleted` = 1, `edited` = '%s', `changed` = '%s',\n\t\t\t\t\t\t\t`body` = '', `title` = ''\n\t\t\t\t\t\t\tWHERE `parent-uri` = '%s' AND `uid` = %d", dbesc($when), dbesc(datetime_convert()), dbesc($item['uri']), intval($importer['uid']));
                    } else {
                        $r = q("UPDATE `item` SET `deleted` = 1, `edited` = '%s', `changed` = '%s',\n\t\t\t\t\t\t\t`body` = '', `title` = '' \n\t\t\t\t\t\t\tWHERE `uri` = '%s' AND `uid` = %d LIMIT 1", dbesc($when), dbesc(datetime_convert()), dbesc($uri), intval($importer['uid']));
                        if ($item['last-child']) {
                            // ensure that last-child is set in case the comment that had it just got wiped.
                            q("UPDATE `item` SET `last-child` = 0, `changed` = '%s' WHERE `parent-uri` = '%s' AND `uid` = %d ", dbesc(datetime_convert()), dbesc($item['parent-uri']), intval($item['uid']));
                            // who is the last child now?
                            $r = q("SELECT `id` FROM `item` WHERE `parent-uri` = '%s' AND `type` != 'activity' AND `deleted` = 0 AND `moderated` = 0 AND `uid` = %d \n\t\t\t\t\t\t\t\tORDER BY `created` DESC LIMIT 1", dbesc($item['parent-uri']), intval($importer['uid']));
                            if (count($r)) {
                                q("UPDATE `item` SET `last-child` = 1 WHERE `id` = %d LIMIT 1", intval($r[0]['id']));
                            }
                        }
                    }
                }
            }
        }
    }
    // Now process the feed
    if ($feed->get_item_quantity()) {
        logger('consume_feed: feed item count = ' . $feed->get_item_quantity());
        // in inverse date order
        if ($datedir) {
            $items = array_reverse($feed->get_items());
        } else {
            $items = $feed->get_items();
        }
        foreach ($items as $item) {
            $is_reply = false;
            $item_id = $item->get_id();
            $rawthread = $item->get_item_tags(NAMESPACE_THREAD, 'in-reply-to');
            if (isset($rawthread[0]['attribs']['']['ref'])) {
                $is_reply = true;
                $parent_uri = $rawthread[0]['attribs']['']['ref'];
            }
            if ($is_reply && is_array($contact)) {
                if ($pass == 1) {
                    continue;
                }
                // Have we seen it? If not, import it.
                $item_id = $item->get_id();
                $datarray = get_atom_elements($feed, $item);
                if (!x($datarray, 'author-name') && $contact['network'] != NETWORK_DFRN) {
                    $datarray['author-name'] = $contact['name'];
                }
                if (!x($datarray, 'author-link') && $contact['network'] != NETWORK_DFRN) {
                    $datarray['author-link'] = $contact['url'];
                }
                if (!x($datarray, 'author-avatar') && $contact['network'] != NETWORK_DFRN) {
                    $datarray['author-avatar'] = $contact['thumb'];
                }
                if (!x($datarray, 'author-name') || !x($datarray, 'author-link')) {
                    logger('consume_feed: no author information! ' . print_r($datarray, true));
                    continue;
                }
                $r = q("SELECT `uid`, `last-child`, `edited`, `body` FROM `item` WHERE `uri` = '%s' AND `uid` = %d LIMIT 1", dbesc($item_id), intval($importer['uid']));
                // Update content if 'updated' changes
                if (count($r)) {
                    if (x($datarray, 'edited') !== false && datetime_convert('UTC', 'UTC', $datarray['edited']) !== $r[0]['edited']) {
                        $r = q("UPDATE `item` SET `title` = '%s', `body` = '%s', `tag` = '%s', `edited` = '%s' WHERE `uri` = '%s' AND `uid` = %d LIMIT 1", dbesc($datarray['title']), dbesc($datarray['body']), dbesc($datarray['tag']), dbesc(datetime_convert('UTC', 'UTC', $datarray['edited'])), dbesc($item_id), intval($importer['uid']));
                    }
                    // update last-child if it changes
                    $allow = $item->get_item_tags(NAMESPACE_DFRN, 'comment-allow');
                    if ($allow && $allow[0]['data'] != $r[0]['last-child']) {
                        $r = q("UPDATE `item` SET `last-child` = 0, `changed` = '%s' WHERE `parent-uri` = '%s' AND `uid` = %d", dbesc(datetime_convert()), dbesc($parent_uri), intval($importer['uid']));
                        $r = q("UPDATE `item` SET `last-child` = %d , `changed` = '%s'  WHERE `uri` = '%s' AND `uid` = %d LIMIT 1", intval($allow[0]['data']), dbesc(datetime_convert()), dbesc($item_id), intval($importer['uid']));
                    }
                    continue;
                }
                $force_parent = false;
                if ($contact['network'] === NETWORK_OSTATUS || stristr($contact['url'], 'twitter.com')) {
                    if ($contact['network'] === NETWORK_OSTATUS) {
                        $force_parent = true;
                    }
                    if (strlen($datarray['title'])) {
                        unset($datarray['title']);
                    }
                    $r = q("UPDATE `item` SET `last-child` = 0, `changed` = '%s' WHERE `parent-uri` = '%s' AND `uid` = %d", dbesc(datetime_convert()), dbesc($parent_uri), intval($importer['uid']));
                    $datarray['last-child'] = 1;
                }
                if ($contact['network'] === NETWORK_FEED || !strlen($contact['notify'])) {
                    // one way feed - no remote comment ability
                    $datarray['last-child'] = 0;
                }
                $datarray['parent-uri'] = $parent_uri;
                $datarray['uid'] = $importer['uid'];
                $datarray['contact-id'] = $contact['id'];
                if (activity_match($datarray['verb'], ACTIVITY_LIKE) || activity_match($datarray['verb'], ACTIVITY_DISLIKE)) {
                    $datarray['type'] = 'activity';
                    $datarray['gravity'] = GRAVITY_LIKE;
                    // only one like or dislike per person
                    $r = q("select id from item where uid = %d and `contact-id` = %d and verb ='%s' and deleted = 0 limit 1", intval($datarray['uid']), intval($datarray['contact-id']), dbesc($datarray['verb']));
                    if ($r && count($r)) {
                        continue;
                    }
                }
                if ($datarray['verb'] === ACTIVITY_TAG && $datarray['object-type'] === ACTIVITY_OBJ_TAGTERM) {
                    $xo = parse_xml_string($datarray['object'], false);
                    $xt = parse_xml_string($datarray['target'], false);
                    if ($xt->type == ACTIVITY_OBJ_NOTE) {
                        $r = q("select * from item where `uri` = '%s' AND `uid` = %d limit 1", dbesc($xt->id), intval($importer['importer_uid']));
                        if (!count($r)) {
                            continue;
                        }
                        // extract tag, if not duplicate, add to parent item
                        if ($xo->id && $xo->content) {
                            $newtag = '#[url=' . $xo->id . ']' . $xo->content . '[/url]';
                            if (!stristr($r[0]['tag'], $newtag)) {
                                q("UPDATE item SET tag = '%s' WHERE id = %d LIMIT 1", dbesc($r[0]['tag'] . (strlen($r[0]['tag']) ? ',' : '') . $newtag), intval($r[0]['id']));
                            }
                        }
                    }
                }
                $r = item_store($datarray, $force_parent);
                continue;
            } else {
                // Head post of a conversation. Have we seen it? If not, import it.
                $item_id = $item->get_id();
                $datarray = get_atom_elements($feed, $item);
                if (is_array($contact)) {
                    if (!x($datarray, 'author-name') && $contact['network'] != NETWORK_DFRN) {
                        $datarray['author-name'] = $contact['name'];
                    }
                    if (!x($datarray, 'author-link') && $contact['network'] != NETWORK_DFRN) {
                        $datarray['author-link'] = $contact['url'];
                    }
                    if (!x($datarray, 'author-avatar') && $contact['network'] != NETWORK_DFRN) {
                        $datarray['author-avatar'] = $contact['thumb'];
                    }
                }
                if (!x($datarray, 'author-name') || !x($datarray, 'author-link')) {
                    logger('consume_feed: no author information! ' . print_r($datarray, true));
                    continue;
                }
                // special handling for events
                if (x($datarray, 'object-type') && $datarray['object-type'] === ACTIVITY_OBJ_EVENT) {
                    $ev = bbtoevent($datarray['body']);
                    if (x($ev, 'desc') && x($ev, 'start')) {
                        $ev['uid'] = $importer['uid'];
                        $ev['uri'] = $item_id;
                        $ev['edited'] = $datarray['edited'];
                        $ev['private'] = $datarray['private'];
                        if (is_array($contact)) {
                            $ev['cid'] = $contact['id'];
                        }
                        $r = q("SELECT * FROM `event` WHERE `uri` = '%s' AND `uid` = %d LIMIT 1", dbesc($item_id), intval($importer['uid']));
                        if (count($r)) {
                            $ev['id'] = $r[0]['id'];
                        }
                        $xyz = event_store($ev);
                        continue;
                    }
                }
                $r = q("SELECT `uid`, `last-child`, `edited`, `body` FROM `item` WHERE `uri` = '%s' AND `uid` = %d LIMIT 1", dbesc($item_id), intval($importer['uid']));
                // Update content if 'updated' changes
                if (count($r)) {
                    if (x($datarray, 'edited') !== false && datetime_convert('UTC', 'UTC', $datarray['edited']) !== $r[0]['edited']) {
                        $r = q("UPDATE `item` SET `title` = '%s', `body` = '%s', `tag` = '%s', `edited` = '%s' WHERE `uri` = '%s' AND `uid` = %d LIMIT 1", dbesc($datarray['title']), dbesc($datarray['body']), dbesc($datarray['tag']), dbesc(datetime_convert('UTC', 'UTC', $datarray['edited'])), dbesc($item_id), intval($importer['uid']));
                    }
                    // update last-child if it changes
                    $allow = $item->get_item_tags(NAMESPACE_DFRN, 'comment-allow');
                    if ($allow && $allow[0]['data'] != $r[0]['last-child']) {
                        $r = q("UPDATE `item` SET `last-child` = %d , `changed` = '%s' WHERE `uri` = '%s' AND `uid` = %d LIMIT 1", intval($allow[0]['data']), dbesc(datetime_convert()), dbesc($item_id), intval($importer['uid']));
                    }
                    continue;
                }
                if (activity_match($datarray['verb'], ACTIVITY_FOLLOW)) {
                    logger('consume-feed: New follower');
                    new_follower($importer, $contact, $datarray, $item);
                    return;
                }
                if (activity_match($datarray['verb'], ACTIVITY_UNFOLLOW)) {
                    lose_follower($importer, $contact, $datarray, $item);
                    return;
                }
                if (activity_match($datarray['verb'], ACTIVITY_REQ_FRIEND)) {
                    logger('consume-feed: New friend request');
                    new_follower($importer, $contact, $datarray, $item, true);
                    return;
                }
                if (activity_match($datarray['verb'], ACTIVITY_UNFRIEND)) {
                    lose_sharer($importer, $contact, $datarray, $item);
                    return;
                }
                if (!is_array($contact)) {
                    return;
                }
                if ($contact['network'] === NETWORK_OSTATUS || stristr($contact['url'], 'twitter.com')) {
                    if (strlen($datarray['title'])) {
                        unset($datarray['title']);
                    }
                    $datarray['last-child'] = 1;
                }
                if ($contact['network'] === NETWORK_FEED || !strlen($contact['notify'])) {
                    // one way feed - no remote comment ability
                    $datarray['last-child'] = 0;
                }
                // This is my contact on another system, but it's really me.
                // Turn this into a wall post.
                if ($contact['remote_self']) {
                    $datarray['wall'] = 1;
                }
                $datarray['parent-uri'] = $item_id;
                $datarray['uid'] = $importer['uid'];
                $datarray['contact-id'] = $contact['id'];
                if (!link_compare($datarray['owner-link'], $contact['url'])) {
                    // The item owner info is not our contact. It's OK and is to be expected if this is a tgroup delivery,
                    // but otherwise there's a possible data mixup on the sender's system.
                    // the tgroup delivery code called from item_store will correct it if it's a forum,
                    // but we're going to unconditionally correct it here so that the post will always be owned by our contact.
                    logger('consume_feed: Correcting item owner.', LOGGER_DEBUG);
                    $datarray['owner-name'] = $contact['name'];
                    $datarray['owner-link'] = $contact['url'];
                    $datarray['owner-avatar'] = $contact['thumb'];
                }
                $r = item_store($datarray);
                continue;
            }
        }
    }
}
示例#19
0
function photos_post(&$a)
{
    logger('mod-photos: photos_post: begin', LOGGER_DEBUG);
    logger('mod_photos: REQUEST ' . print_r($_REQUEST, true), LOGGER_DATA);
    logger('mod_photos: FILES ' . print_r($_FILES, true), LOGGER_DATA);
    $can_post = false;
    $visitor = 0;
    $page_owner_uid = $a->data['user']['uid'];
    $community_page = $a->data['user']['page-flags'] == PAGE_COMMUNITY ? true : false;
    if (local_user() && local_user() == $page_owner_uid) {
        $can_post = true;
    } else {
        if ($community_page && remote_user()) {
            $r = q("SELECT `uid` FROM `contact` WHERE `blocked` = 0 AND `pending` = 0 AND `id` = %d AND `uid` = %d LIMIT 1", intval(remote_user()), intval($page_owner_uid));
            if (count($r)) {
                $can_post = true;
                $visitor = remote_user();
            }
        }
    }
    if (!$can_post) {
        notice(t('Permission denied.') . EOL);
        killme();
    }
    $r = q("SELECT `contact`.*, `user`.`nickname` FROM `contact` LEFT JOIN `user` ON `user`.`uid` = `contact`.`uid` \n\t\tWHERE `user`.`uid` = %d AND `self` = 1 LIMIT 1", intval($page_owner_uid));
    if (!count($r)) {
        notice(t('Contact information unavailable') . EOL);
        logger('photos_post: unable to locate contact record for page owner. uid=' . $page_owner_uid);
        killme();
    }
    $owner_record = $r[0];
    if ($a->argc > 3 && $a->argv[2] === 'album') {
        $album = hex2bin($a->argv[3]);
        if ($album === t('Profile Photos') || $album === 'Contact Photos' || $album === t('Contact Photos')) {
            goaway($a->get_baseurl() . '/' . $_SESSION['photo_return']);
            return;
            // NOTREACHED
        }
        $r = q("SELECT count(*) FROM `photo` WHERE `album` = '%s' AND `uid` = %d", dbesc($album), intval($page_owner_uid));
        if (!count($r)) {
            notice(t('Album not found.') . EOL);
            goaway($a->get_baseurl() . '/' . $_SESSION['photo_return']);
            return;
            // NOTREACHED
        }
        $newalbum = notags(trim($_POST['albumname']));
        if ($newalbum != $album) {
            q("UPDATE `photo` SET `album` = '%s' WHERE `album` = '%s' AND `uid` = %d", dbesc($newalbum), dbesc($album), intval($page_owner_uid));
            $newurl = str_replace(bin2hex($album), bin2hex($newalbum), $_SESSION['photo_return']);
            goaway($a->get_baseurl() . '/' . $newurl);
            return;
            // NOTREACHED
        }
        if ($_POST['dropalbum'] == t('Delete Album')) {
            $res = array();
            // get the list of photos we are about to delete
            if ($visitor) {
                $r = q("SELECT distinct(`resource-id`) as `rid` FROM `photo` WHERE `contact-id` = %d AND `uid` = %d AND `album` = '%s'", intval($visitor), intval($page_owner_uid), dbesc($album));
            } else {
                $r = q("SELECT distinct(`resource-id`) as `rid` FROM `photo` WHERE `uid` = %d AND `album` = '%s'", intval(local_user()), dbesc($album));
            }
            if (count($r)) {
                foreach ($r as $rr) {
                    $res[] = "'" . dbesc($rr['rid']) . "'";
                }
            } else {
                goaway($a->get_baseurl() . '/' . $_SESSION['photo_return']);
                return;
                // NOTREACHED
            }
            $str_res = implode(',', $res);
            // remove the associated photos
            q("DELETE FROM `photo` WHERE `resource-id` IN ( {$str_res} ) AND `uid` = %d", intval($page_owner_uid));
            // find and delete the corresponding item with all the comments and likes/dislikes
            $r = q("SELECT `parent-uri` FROM `item` WHERE `resource-id` IN ( {$str_res} ) AND `uid` = %d", intval($page_owner_uid));
            if (count($r)) {
                foreach ($r as $rr) {
                    q("UPDATE `item` SET `deleted` = 1, `changed` = '%s' WHERE `parent-uri` = '%s' AND `uid` = %d", dbesc(datetime_convert()), dbesc($rr['parent-uri']), intval($page_owner_uid));
                    $drop_id = intval($rr['id']);
                    // send the notification upstream/downstream as the case may be
                    if ($rr['visible']) {
                        proc_run('php', "include/notifier.php", "drop", "{$drop_id}");
                    }
                }
            }
        }
        goaway($a->get_baseurl() . '/photos/' . $a->data['user']['nickname']);
        return;
        // NOTREACHED
    }
    if ($a->argc > 2 && x($_POST, 'delete') && $_POST['delete'] == t('Delete Photo')) {
        // same as above but remove single photo
        if ($visitor) {
            $r = q("SELECT `id`, `resource-id` FROM `photo` WHERE `contact-id` = %d AND `uid` = %d AND `resource-id` = '%s' LIMIT 1", intval($visitor), intval($page_owner_uid), dbesc($a->argv[2]));
        } else {
            $r = q("SELECT `id`, `resource-id` FROM `photo` WHERE `uid` = %d AND `resource-id` = '%s' LIMIT 1", intval(local_user()), dbesc($a->argv[2]));
        }
        if (count($r)) {
            q("DELETE FROM `photo` WHERE `uid` = %d AND `resource-id` = '%s'", intval($page_owner_uid), dbesc($r[0]['resource-id']));
            $i = q("SELECT * FROM `item` WHERE `resource-id` = '%s' AND `uid` = %d LIMIT 1", dbesc($r[0]['resource-id']), intval($page_owner_uid));
            if (count($i)) {
                q("UPDATE `item` SET `deleted` = 1, `edited` = '%s', `changed` = '%s' WHERE `parent-uri` = '%s' AND `uid` = %d", dbesc(datetime_convert()), dbesc(datetime_convert()), dbesc($i[0]['uri']), intval($page_owner_uid));
                $url = $a->get_baseurl();
                $drop_id = intval($i[0]['id']);
                if ($i[0]['visible']) {
                    proc_run('php', "include/notifier.php", "drop", "{$drop_id}");
                }
            }
        }
        goaway($a->get_baseurl() . '/' . $_SESSION['photo_return']);
        return;
        // NOTREACHED
    }
    if ($a->argc > 2 && (x($_POST, 'desc') !== false || x($_POST, 'newtag') !== false) || x($_POST, 'albname') !== false) {
        $desc = x($_POST, 'desc') ? notags(trim($_POST['desc'])) : '';
        $rawtags = x($_POST, 'newtag') ? notags(trim($_POST['newtag'])) : '';
        $item_id = x($_POST, 'item_id') ? intval($_POST['item_id']) : 0;
        $albname = x($_POST, 'albname') ? notags(trim($_POST['albname'])) : '';
        $str_group_allow = perms2str($_POST['group_allow']);
        $str_contact_allow = perms2str($_POST['contact_allow']);
        $str_group_deny = perms2str($_POST['group_deny']);
        $str_contact_deny = perms2str($_POST['contact_deny']);
        $resource_id = $a->argv[2];
        if (!strlen($albname)) {
            $albname = datetime_convert('UTC', date_default_timezone_get(), 'now', 'Y');
        }
        if (x($_POST, 'rotate') !== false && intval($_POST['rotate']) == 1) {
            logger('rotate');
            $r = q("select * from photo where `resource-id` = '%s' and uid = %d and scale = 0 limit 1", dbesc($resource_id), intval($page_owner_uid));
            if (count($r)) {
                $ph = new Photo($r[0]['data']);
                if ($ph->is_valid()) {
                    $ph->rotate(270);
                    $width = $ph->getWidth();
                    $height = $ph->getHeight();
                    $x = q("update photo set data = '%s', height = %d, width = %d where `resource-id` = '%s' and uid = %d and scale = 0 limit 1", dbesc($ph->imageString()), intval($height), intval($width), dbesc($resource_id), intval($page_owner_uid));
                    if ($width > 640 || $height > 640) {
                        $ph->scaleImage(640);
                        $width = $ph->getWidth();
                        $height = $ph->getHeight();
                        $x = q("update photo set data = '%s', height = %d, width = %d where `resource-id` = '%s' and uid = %d and scale = 1 limit 1", dbesc($ph->imageString()), intval($height), intval($width), dbesc($resource_id), intval($page_owner_uid));
                    }
                    if ($width > 320 || $height > 320) {
                        $ph->scaleImage(320);
                        $width = $ph->getWidth();
                        $height = $ph->getHeight();
                        $x = q("update photo set data = '%s', height = %d, width = %d where `resource-id` = '%s' and uid = %d and scale = 2 limit 1", dbesc($ph->imageString()), intval($height), intval($width), dbesc($resource_id), intval($page_owner_uid));
                    }
                }
            }
        }
        $p = q("SELECT * FROM `photo` WHERE `resource-id` = '%s' AND `uid` = %d ORDER BY `scale` DESC", dbesc($resource_id), intval($page_owner_uid));
        if (count($p)) {
            $r = q("UPDATE `photo` SET `desc` = '%s', `album` = '%s', `allow_cid` = '%s', `allow_gid` = '%s', `deny_cid` = '%s', `deny_gid` = '%s' WHERE `resource-id` = '%s' AND `uid` = %d", dbesc($desc), dbesc($albname), dbesc($str_contact_allow), dbesc($str_group_allow), dbesc($str_contact_deny), dbesc($str_group_deny), dbesc($resource_id), intval($page_owner_uid));
        }
        /* Don't make the item visible if the only change was the album name */
        $visibility = 0;
        if ($p[0]['desc'] !== $desc || strlen($rawtags)) {
            $visibility = 1;
        }
        if (!$item_id) {
            // Create item container
            $title = '';
            $uri = item_new_uri($a->get_hostname(), $page_owner_uid);
            $arr = array();
            $arr['uid'] = $page_owner_uid;
            $arr['uri'] = $uri;
            $arr['parent-uri'] = $uri;
            $arr['type'] = 'photo';
            $arr['wall'] = 1;
            $arr['resource-id'] = $p[0]['resource-id'];
            $arr['contact-id'] = $owner_record['id'];
            $arr['owner-name'] = $owner_record['name'];
            $arr['owner-link'] = $owner_record['url'];
            $arr['owner-avatar'] = $owner_record['thumb'];
            $arr['author-name'] = $owner_record['name'];
            $arr['author-link'] = $owner_record['url'];
            $arr['author-avatar'] = $owner_record['thumb'];
            $arr['title'] = $title;
            $arr['allow_cid'] = $p[0]['allow_cid'];
            $arr['allow_gid'] = $p[0]['allow_gid'];
            $arr['deny_cid'] = $p[0]['deny_cid'];
            $arr['deny_gid'] = $p[0]['deny_gid'];
            $arr['last-child'] = 1;
            $arr['visible'] = $visibility;
            $arr['origin'] = 1;
            $arr['body'] = '[url=' . $a->get_baseurl() . '/photos/' . $a->data['user']['nickname'] . '/image/' . $p[0]['resource-id'] . ']' . '[img]' . $a->get_baseurl() . '/photo/' . $p[0]['resource-id'] . '-' . $p[0]['scale'] . '.jpg' . '[/img]' . '[/url]';
            $item_id = item_store($arr);
        }
        if ($item_id) {
            $r = q("SELECT * FROM `item` WHERE `id` = %d AND `uid` = %d LIMIT 1", intval($item_id), intval($page_owner_uid));
        }
        if (count($r)) {
            $old_tag = $r[0]['tag'];
            $old_inform = $r[0]['inform'];
        }
        if (strlen($rawtags)) {
            $str_tags = '';
            $inform = '';
            // if the new tag doesn't have a namespace specifier (@foo or #foo) give it a hashtag
            $x = substr($rawtags, 0, 1);
            if ($x !== '@' && $x !== '#') {
                $rawtags = '#' . $rawtags;
            }
            $taginfo = array();
            $tags = get_tags($rawtags);
            if (count($tags)) {
                foreach ($tags as $tag) {
                    if (isset($profile)) {
                        unset($profile);
                    }
                    if (strpos($tag, '@') === 0) {
                        $name = substr($tag, 1);
                        if (strpos($name, '@') || strpos($name, 'http://')) {
                            $newname = $name;
                            $links = @lrdd($name);
                            if (count($links)) {
                                foreach ($links as $link) {
                                    if ($link['@attributes']['rel'] === 'http://webfinger.net/rel/profile-page') {
                                        $profile = $link['@attributes']['href'];
                                    }
                                    if ($link['@attributes']['rel'] === 'salmon') {
                                        $salmon = '$url:' . str_replace(',', '%sc', $link['@attributes']['href']);
                                        if (strlen($inform)) {
                                            $inform .= ',';
                                        }
                                        $inform .= $salmon;
                                    }
                                }
                            }
                            $taginfo[] = array($newname, $profile, $salmon);
                        } else {
                            $newname = $name;
                            $alias = '';
                            $tagcid = 0;
                            if (strrpos($newname, '+')) {
                                $tagcid = intval(substr($newname, strrpos($newname, '+') + 1));
                            }
                            if ($tagcid) {
                                $r = q("SELECT * FROM `contact` WHERE `id` = %d AND `uid` = %d LIMIT 1", intval($tagcid), intval($profile_uid));
                            } elseif (strstr($name, '_') || strstr($name, ' ')) {
                                $newname = str_replace('_', ' ', $name);
                                $r = q("SELECT * FROM `contact` WHERE `name` = '%s' AND `uid` = %d LIMIT 1", dbesc($newname), intval($page_owner_uid));
                            } else {
                                $r = q("SELECT * FROM `contact` WHERE `attag` = '%s' OR `nick` = '%s' AND `uid` = %d ORDER BY `attag` DESC LIMIT 1", dbesc($name), dbesc($name), intval($page_owner_uid));
                            }
                            if (count($r)) {
                                $newname = $r[0]['name'];
                                $profile = $r[0]['url'];
                                $notify = 'cid:' . $r[0]['id'];
                                if (strlen($inform)) {
                                    $inform .= ',';
                                }
                                $inform .= $notify;
                            }
                        }
                        if ($profile) {
                            if (substr($notify, 0, 4) === 'cid:') {
                                $taginfo[] = array($newname, $profile, $notify, $r[0], '@[url=' . str_replace(',', '%2c', $profile) . ']' . $newname . '[/url]');
                            } else {
                                $taginfo[] = array($newname, $profile, $notify, null, $str_tags .= '@[url=' . $profile . ']' . $newname . '[/url]');
                            }
                            if (strlen($str_tags)) {
                                $str_tags .= ',';
                            }
                            $profile = str_replace(',', '%2c', $profile);
                            $str_tags .= '@[url=' . $profile . ']' . $newname . '[/url]';
                        }
                    }
                }
            }
            $newtag = $old_tag;
            if (strlen($newtag) && strlen($str_tags)) {
                $newtag .= ',';
            }
            $newtag .= $str_tags;
            $newinform = $old_inform;
            if (strlen($newinform) && strlen($inform)) {
                $newinform .= ',';
            }
            $newinform .= $inform;
            $r = q("UPDATE `item` SET `tag` = '%s', `inform` = '%s', `edited` = '%s', `changed` = '%s' WHERE `id` = %d AND `uid` = %d LIMIT 1", dbesc($newtag), dbesc($newinform), dbesc(datetime_convert()), dbesc(datetime_convert()), intval($item_id), intval($page_owner_uid));
            $best = 0;
            foreach ($p as $scales) {
                if (intval($scales['scale']) == 2) {
                    $best = 2;
                    break;
                }
                if (intval($scales['scale']) == 4) {
                    $best = 4;
                    break;
                }
            }
            if (count($taginfo)) {
                foreach ($taginfo as $tagged) {
                    $uri = item_new_uri($a->get_hostname(), $page_owner_uid);
                    $arr = array();
                    $arr['uid'] = $page_owner_uid;
                    $arr['uri'] = $uri;
                    $arr['parent-uri'] = $uri;
                    $arr['type'] = 'activity';
                    $arr['wall'] = 1;
                    $arr['contact-id'] = $owner_record['id'];
                    $arr['owner-name'] = $owner_record['name'];
                    $arr['owner-link'] = $owner_record['url'];
                    $arr['owner-avatar'] = $owner_record['thumb'];
                    $arr['author-name'] = $owner_record['name'];
                    $arr['author-link'] = $owner_record['url'];
                    $arr['author-avatar'] = $owner_record['thumb'];
                    $arr['title'] = '';
                    $arr['allow_cid'] = $p[0]['allow_cid'];
                    $arr['allow_gid'] = $p[0]['allow_gid'];
                    $arr['deny_cid'] = $p[0]['deny_cid'];
                    $arr['deny_gid'] = $p[0]['deny_gid'];
                    $arr['last-child'] = 1;
                    $arr['visible'] = 1;
                    $arr['verb'] = ACTIVITY_TAG;
                    $arr['object-type'] = ACTIVITY_OBJ_PERSON;
                    $arr['target-type'] = ACTIVITY_OBJ_PHOTO;
                    $arr['tag'] = $tagged[4];
                    $arr['inform'] = $tagged[2];
                    $arr['origin'] = 1;
                    $arr['body'] = '[url=' . $tagged[1] . ']' . $tagged[0] . '[/url]' . ' ' . t('was tagged in a') . ' ' . '[url=' . $a->get_baseurl() . '/photos/' . $owner_record['nickname'] . '/image/' . $p[0]['resource-id'] . ']' . t('photo') . '[/url]' . ' ' . t('by') . ' ' . '[url=' . $owner_record['url'] . ']' . $owner_record['name'] . '[/url]';
                    $arr['body'] .= "\n\n" . '[url=' . $a->get_baseurl() . '/photos/' . $owner_record['nickname'] . '/image/' . $p[0]['resource-id'] . ']' . '[img]' . $a->get_baseurl() . "/photo/" . $p[0]['resource-id'] . '-' . $best . '.jpg' . '[/img][/url]' . "\n";
                    $arr['object'] = '<object><type>' . ACTIVITY_OBJ_PERSON . '</type><title>' . $tagged[0] . '</title><id>' . $tagged[1] . '/' . $tagged[0] . '</id>';
                    $arr['object'] .= '<link>' . xmlify('<link rel="alternate" type="text/html" href="' . $tagged[1] . '" />' . "\n");
                    if ($tagged[3]) {
                        $arr['object'] .= xmlify('<link rel="photo" type="image/jpeg" href="' . $tagged[3]['photo'] . '" />' . "\n");
                    }
                    $arr['object'] .= '</link></object>' . "\n";
                    $arr['target'] = '<target><type>' . ACTIVITY_OBJ_PHOTO . '</type><title>' . $p[0]['desc'] . '</title><id>' . $a->get_baseurl() . '/photos/' . $owner_record['nickname'] . '/image/' . $p[0]['resource-id'] . '</id>';
                    $arr['target'] .= '<link>' . xmlify('<link rel="alternate" type="text/html" href="' . $a->get_baseurl() . '/photos/' . $owner_record['nickname'] . '/image/' . $p[0]['resource-id'] . '" />' . "\n" . '<link rel="preview" type="image/jpeg" href="' . $a->get_baseurl() . "/photo/" . $p[0]['resource-id'] . '-' . $best . '.jpg' . '" />') . '</link></target>';
                    $item_id = item_store($arr);
                    if ($item_id) {
                        q("UPDATE `item` SET `plink` = '%s' WHERE `uid` = %d AND `id` = %d LIMIT 1", dbesc($a->get_baseurl() . '/display/' . $owner_record['nickname'] . '/' . $item_id), intval($page_owner_uid), intval($item_id));
                        proc_run('php', "include/notifier.php", "tag", "{$item_id}");
                    }
                }
            }
        }
        goaway($a->get_baseurl() . '/' . $_SESSION['photo_return']);
        return;
        // NOTREACHED
    }
    /**
     * default post action - upload a photo
     */
    call_hooks('photo_post_init', $_POST);
    /**
     * Determine the album to use
     */
    $album = notags(trim($_REQUEST['album']));
    $newalbum = notags(trim($_REQUEST['newalbum']));
    logger('mod/photos.php: photos_post(): album= ' . $album . ' newalbum= ' . $newalbum, LOGGER_DEBUG);
    if (!strlen($album)) {
        if (strlen($newalbum)) {
            $album = $newalbum;
        } else {
            $album = datetime_convert('UTC', date_default_timezone_get(), 'now', 'Y');
        }
    }
    /**
     *
     * We create a wall item for every photo, but we don't want to
     * overwhelm the data stream with a hundred newly uploaded photos.
     * So we will make the first photo uploaded to this album in the last several hours
     * visible by default, the rest will become visible over time when and if
     * they acquire comments, likes, dislikes, and/or tags 
     *
     */
    $r = q("SELECT * FROM `photo` WHERE `album` = '%s' AND `uid` = %d AND `created` > UTC_TIMESTAMP() - INTERVAL 3 HOUR ", dbesc($album), intval($page_owner_uid));
    if (!count($r) || $album == t('Profile Photos')) {
        $visible = 1;
    } else {
        $visible = 0;
    }
    if (intval($_REQUEST['not_visible']) || $_REQUEST['not_visible'] === 'true') {
        $visible = 0;
    }
    $str_group_allow = perms2str(is_array($_REQUEST['group_allow']) ? $_REQUEST['group_allow'] : explode(',', $_REQUEST['group_allow']));
    $str_contact_allow = perms2str(is_array($_REQUEST['contact_allow']) ? $_REQUEST['contact_allow'] : explode(',', $_REQUEST['contact_allow']));
    $str_group_deny = perms2str(is_array($_REQUEST['group_deny']) ? $_REQUEST['group_deny'] : explode(',', $_REQUEST['group_deny']));
    $str_contact_deny = perms2str(is_array($_REQUEST['contact_deny']) ? $_REQUEST['contact_deny'] : explode(',', $_REQUEST['contact_deny']));
    $ret = array('src' => '', 'filename' => '', 'filesize' => 0);
    call_hooks('photo_post_file', $ret);
    if (x($ret, 'src') && x($ret, 'filesize')) {
        $src = $ret['src'];
        $filename = $ret['filename'];
        $filesize = $ret['filesize'];
    } else {
        $src = $_FILES['userfile']['tmp_name'];
        $filename = basename($_FILES['userfile']['name']);
        $filesize = intval($_FILES['userfile']['size']);
    }
    logger('photos: upload: received file: ' . $filename . ' as ' . $src . ' ' . $filesize . ' bytes', LOGGER_DEBUG);
    $maximagesize = get_config('system', 'maximagesize');
    if ($maximagesize && $filesize > $maximagesize) {
        notice(t('Image exceeds size limit of ') . $maximagesize . EOL);
        @unlink($src);
        $foo = 0;
        call_hooks('photo_post_end', $foo);
        return;
    }
    if (!$filesize) {
        notice(t('Image file is empty.') . EOL);
        @unlink($src);
        $foo = 0;
        call_hooks('photo_post_end', $foo);
        return;
    }
    logger('mod/photos.php: photos_post(): loading the contents of ' . $src, LOGGER_DEBUG);
    $imagedata = @file_get_contents($src);
    $ph = new Photo($imagedata);
    if (!$ph->is_valid()) {
        logger('mod/photos.php: photos_post(): unable to process image', LOGGER_DEBUG);
        notice(t('Unable to process image.') . EOL);
        @unlink($src);
        $foo = 0;
        call_hooks('photo_post_end', $foo);
        killme();
    }
    @unlink($src);
    $width = $ph->getWidth();
    $height = $ph->getHeight();
    $smallest = 0;
    $photo_hash = photo_new_resource();
    $r = $ph->store($page_owner_uid, $visitor, $photo_hash, $filename, $album, 0, 0, $str_contact_allow, $str_group_allow, $str_contact_deny, $str_group_deny);
    if (!$r) {
        logger('mod/photos.php: photos_post(): image store failed', LOGGER_DEBUG);
        notice(t('Image upload failed.') . EOL);
        killme();
    }
    if ($width > 640 || $height > 640) {
        $ph->scaleImage(640);
        $ph->store($page_owner_uid, $visitor, $photo_hash, $filename, $album, 1, 0, $str_contact_allow, $str_group_allow, $str_contact_deny, $str_group_deny);
        $smallest = 1;
    }
    if ($width > 320 || $height > 320) {
        $ph->scaleImage(320);
        $ph->store($page_owner_uid, $visitor, $photo_hash, $filename, $album, 2, 0, $str_contact_allow, $str_group_allow, $str_contact_deny, $str_group_deny);
        $smallest = 2;
    }
    $basename = basename($filename);
    $uri = item_new_uri($a->get_hostname(), $page_owner_uid);
    // Create item container
    $arr = array();
    $arr['uid'] = $page_owner_uid;
    $arr['uri'] = $uri;
    $arr['parent-uri'] = $uri;
    $arr['type'] = 'photo';
    $arr['wall'] = 1;
    $arr['resource-id'] = $photo_hash;
    $arr['contact-id'] = $owner_record['id'];
    $arr['owner-name'] = $owner_record['name'];
    $arr['owner-link'] = $owner_record['url'];
    $arr['owner-avatar'] = $owner_record['thumb'];
    $arr['author-name'] = $owner_record['name'];
    $arr['author-link'] = $owner_record['url'];
    $arr['author-avatar'] = $owner_record['thumb'];
    $arr['title'] = '';
    $arr['allow_cid'] = $str_contact_allow;
    $arr['allow_gid'] = $str_group_allow;
    $arr['deny_cid'] = $str_contact_deny;
    $arr['deny_gid'] = $str_group_deny;
    $arr['last-child'] = 1;
    $arr['visible'] = $visible;
    $arr['origin'] = 1;
    $arr['body'] = '[url=' . $a->get_baseurl() . '/photos/' . $owner_record['nickname'] . '/image/' . $photo_hash . ']' . '[img]' . $a->get_baseurl() . "/photo/{$photo_hash}-{$smallest}.jpg" . '[/img]' . '[/url]';
    $item_id = item_store($arr);
    if ($item_id) {
        q("UPDATE `item` SET `plink` = '%s' WHERE `uid` = %d AND `id` = %d LIMIT 1", dbesc($a->get_baseurl() . '/display/' . $owner_record['nickname'] . '/' . $item_id), intval($page_owner_uid), intval($item_id));
    }
    if ($visible) {
        proc_run('php', "include/notifier.php", 'wall-new', $item_id);
    }
    call_hooks('photo_post_end', intval($item_id));
    // addon uploaders should call "killme()" [e.g. exit] within the photo_post_end hook
    // if they do not wish to be redirected
    goaway($a->get_baseurl() . '/' . $_SESSION['photo_return']);
    // NOTREACHED
}
示例#20
0
function openclipatar_content(&$a)
{
    if (!local_channel()) {
        return;
    }
    $o = '';
    if (argc() == 3 && argv(1) == 'use') {
        $id = argv(2);
        $chan = App::get_channel();
        $x = z_fetch_url('https://openclipart.org/image/250px/svg_to_png/' . $id . '/' . $id . '.png', true);
        if ($x['success']) {
            $imagedata = $x['body'];
        }
        $ph = photo_factory($imagedata, 'image/png');
        if (!$ph->is_valid()) {
            return t('Unknown error. Please try again later.');
        }
        // create a unique resource_id
        $hash = photo_new_resource();
        $width = $ph->getWidth();
        $height = $ph->getHeight();
        // save an original or "scale 0" image
        $p = array('aid' => get_account_id(), 'uid' => local_channel(), 'resource_id' => $hash, 'filename' => $id . '.png', 'album' => t('Profile Photos'), 'imgscale' => 0);
        $r = $ph->save($p);
        if ($r) {
            if (($width > 1024 || $height > 1024) && !$errors) {
                $ph->scaleImage(1024);
            }
            $p['imgscale'] = 1;
            $r1 = $ph->save($p);
            if (($width > 640 || $height > 640) && !$errors) {
                $ph->scaleImage(640);
            }
            $p['imgscale'] = 2;
            $r2 = $ph->save($p);
            if (($width > 320 || $height > 320) && !$errors) {
                $ph->scaleImage(320);
            }
            $p['imgscale'] = 3;
            $r3 = $ph->save($p);
            // ensure squareness at first, subsequent scales keep ratio
            $ph->scaleImageSquare(175);
            $p['imgscale'] = 4;
            $r = $ph->save($p);
            if ($r === false) {
                $photo_failure = true;
            }
            $ph->scaleImage(80);
            $p['imgscale'] = 5;
            $r = $ph->save($p);
            if ($r === false) {
                $photo_failure = true;
            }
            $ph->scaleImage(48);
            $p['imgscale'] = 6;
            $r = $ph->save($p);
            if ($r === false) {
                $photo_failure = true;
            }
        }
        $is_default_profile = 1;
        if ($_REQUEST['profile']) {
            $r = q("select id, is_default from profile where id = %d and uid = %d limit 1", intval($_REQUEST['profile']), intval(local_channel()));
            if ($r && !intval($r[0]['is_default'])) {
                $is_default_profile = 0;
            }
        }
        if ($is_default_profile) {
            // unset any existing profile photos
            $r = q("UPDATE photo SET photo_usage = %d WHERE photo_usage = %d AND uid = %d", intval(PHOTO_NORMAL), intval(PHOTO_PROFILE), intval(local_channel()));
            // set all sizes of this one as profile photos
            $r = q("UPDATE photo SET photo_usage = %d WHERE uid = %d AND resource_id = '%s'", intval(PHOTO_PROFILE), intval(local_channel()), dbesc($hash));
            require_once 'include/photos.php';
            profile_photo_set_profile_perms(local_channel());
            //Reset default profile photo permissions to public
            // only the default needs reload since it uses canonical url -- despite the slightly ambiguous message, left it so as to re-use translations
            info(t('Shift-reload the page or clear browser cache if the new photo does not display immediately.') . EOL);
        } else {
            // not the default profile, set the path in the correct entry in the profile DB
            $r = q("update profile set photo = '%s', thumb = '%s' where id = %d and uid = %d", dbesc(z_root() . '/photo/' . $hash . '-4'), dbesc(z_root() . '/photo/' . $hash . '-5'), intval($_REQUEST['profile']), intval(local_channel()));
            info(t('Profile photo updated successfully.') . EOL);
        }
        // set a new photo_date on our xchan so that we can tell everybody to update their cached copy
        $r = q("UPDATE xchan set xchan_photo_date = '%s' where xchan_hash = '%s'", dbesc(datetime_convert()), dbesc($chan['xchan_hash']));
        // Similarly, tell the nav bar to bypass the cache and update the avater image.
        $_SESSION['reload_avatar'] = true;
        // tell everybody
        Zotlabs\Daemon\Master::Summon(array('Directory', local_channel()));
        $returnafter = get_config('openclipatar', 'returnafter');
        $returnafter_urls = array(0 => z_root() . '/profile/' . ($_REQUEST['profile'] ? $_REQUEST['profile'] . '/view' : $chan['channel_address']), 1 => z_root() . '/profiles/' . ($_REQUEST['profile'] ? $_REQUEST['profile'] : App::$profile_uid), 2 => z_root() . '/profiles');
        goaway($returnafter_urls[$returnafter]);
    } else {
        //invoked as module, we place in content pane the same as we would for the end of the profile photo page. Also handles json for endless scroll for either invokation.
        openclipatar_profile_photo_content_end($a, $o);
    }
    return $o;
}
示例#21
0
function wall_upload_post(&$a, $desktopmode = true)
{
    logger("wall upload: starting new upload", LOGGER_DEBUG);
    $r_json = x($_GET, 'response') && $_GET['response'] == 'json';
    if ($a->argc > 1) {
        if (!x($_FILES, 'media')) {
            $nick = $a->argv[1];
            $r = q("SELECT `user`.*, `contact`.`id` FROM `user` INNER JOIN `contact` on `user`.`uid` = `contact`.`uid`  WHERE `user`.`nickname` = '%s' AND `user`.`blocked` = 0 and `contact`.`self` = 1 LIMIT 1", dbesc($nick));
            if (!count($r)) {
                if ($r_json) {
                    echo json_encode(['error' => t('Invalid request.')]);
                    killme();
                }
                return;
            }
        } else {
            $user_info = api_get_user($a);
            $r = q("SELECT `user`.*, `contact`.`id` FROM `user` INNER JOIN `contact` on `user`.`uid` = `contact`.`uid`  WHERE `user`.`nickname` = '%s' AND `user`.`blocked` = 0 and `contact`.`self` = 1 LIMIT 1", dbesc($user_info['screen_name']));
        }
    } else {
        if ($r_json) {
            echo json_encode(['error' => t('Invalid request.')]);
            killme();
        }
        return;
    }
    $can_post = false;
    $visitor = 0;
    $page_owner_uid = $r[0]['uid'];
    $default_cid = $r[0]['id'];
    $page_owner_nick = $r[0]['nickname'];
    $community_page = $r[0]['page-flags'] == PAGE_COMMUNITY ? true : false;
    if (local_user() && local_user() == $page_owner_uid) {
        $can_post = true;
    } else {
        if ($community_page && remote_user()) {
            $cid = 0;
            if (is_array($_SESSION['remote'])) {
                foreach ($_SESSION['remote'] as $v) {
                    if ($v['uid'] == $page_owner_uid) {
                        $cid = $v['cid'];
                        break;
                    }
                }
            }
            if ($cid) {
                $r = q("SELECT `uid` FROM `contact` WHERE `blocked` = 0 AND `pending` = 0 AND `id` = %d AND `uid` = %d LIMIT 1", intval($cid), intval($page_owner_uid));
                if (count($r)) {
                    $can_post = true;
                    $visitor = $cid;
                }
            }
        }
    }
    if (!$can_post) {
        if ($r_json) {
            echo json_encode(['error' => t('Permission denied.')]);
            killme();
        }
        notice(t('Permission denied.') . EOL);
        killme();
    }
    if (!x($_FILES, 'userfile') && !x($_FILES, 'media')) {
        if ($r_json) {
            echo json_encode(['error' => t('Invalid request.')]);
            killme();
        }
        killme();
    }
    $src = "";
    if (x($_FILES, 'userfile')) {
        $src = $_FILES['userfile']['tmp_name'];
        $filename = basename($_FILES['userfile']['name']);
        $filesize = intval($_FILES['userfile']['size']);
        $filetype = $_FILES['userfile']['type'];
    } elseif (x($_FILES, 'media')) {
        if (is_array($_FILES['media']['tmp_name'])) {
            $src = $_FILES['media']['tmp_name'][0];
        } else {
            $src = $_FILES['media']['tmp_name'];
        }
        if (is_array($_FILES['media']['name'])) {
            $filename = basename($_FILES['media']['name'][0]);
        } else {
            $filename = basename($_FILES['media']['name']);
        }
        if (is_array($_FILES['media']['size'])) {
            $filesize = intval($_FILES['media']['size'][0]);
        } else {
            $filesize = intval($_FILES['media']['size']);
        }
        if (is_array($_FILES['media']['type'])) {
            $filetype = $_FILES['media']['type'][0];
        } else {
            $filetype = $_FILES['media']['type'];
        }
    }
    if ($src == "") {
        if ($r_json) {
            echo json_encode(['error' => t('Invalid request.')]);
            killme();
        }
        notice(t('Invalid request.') . EOL);
        killme();
    }
    // This is a special treatment for picture upload from Twidere
    if ($filename == "octet-stream" and $filetype != "") {
        $filename = $filetype;
        $filetype = "";
    }
    if ($filetype == "") {
        $filetype = guess_image_type($filename);
    }
    // If there is a temp name, then do a manual check
    // This is more reliable than the provided value
    $imagedata = getimagesize($src);
    if ($imagedata) {
        $filetype = $imagedata['mime'];
    }
    logger("File upload src: " . $src . " - filename: " . $filename . " - size: " . $filesize . " - type: " . $filetype, LOGGER_DEBUG);
    $maximagesize = get_config('system', 'maximagesize');
    if ($maximagesize && $filesize > $maximagesize) {
        $msg = sprintf(t('Image exceeds size limit of %s'), formatBytes($maximagesize));
        if ($r_json) {
            echo json_encode(['error' => $msg]);
        } else {
            echo $msg . EOL;
        }
        @unlink($src);
        killme();
    }
    $r = q("select sum(octet_length(data)) as total from photo where uid = %d and scale = 0 and album != 'Contact Photos' ", intval($page_owner_uid));
    $limit = service_class_fetch($page_owner_uid, 'photo_upload_limit');
    if ($limit !== false && $r[0]['total'] + strlen($imagedata) > $limit) {
        $msg = upgrade_message(true);
        if ($r_json) {
            echo json_encode(['error' => $msg]);
        } else {
            echo $msg . EOL;
        }
        @unlink($src);
        killme();
    }
    $imagedata = @file_get_contents($src);
    $ph = new Photo($imagedata, $filetype);
    if (!$ph->is_valid()) {
        $msg = t('Unable to process image.');
        if ($r_json) {
            echo json_encode(['error' => $msg]);
        } else {
            echo $msg . EOL;
        }
        @unlink($src);
        killme();
    }
    $ph->orient($src);
    @unlink($src);
    $max_length = get_config('system', 'max_image_length');
    if (!$max_length) {
        $max_length = MAX_IMAGE_LENGTH;
    }
    if ($max_length > 0) {
        $ph->scaleImage($max_length);
        logger("File upload: Scaling picture to new size " . $max_length, LOGGER_DEBUG);
    }
    $width = $ph->getWidth();
    $height = $ph->getHeight();
    $hash = photo_new_resource();
    $smallest = 0;
    $defperm = '<' . $default_cid . '>';
    $r = $ph->store($page_owner_uid, $visitor, $hash, $filename, t('Wall Photos'), 0, 0, $defperm);
    if (!$r) {
        $msg = t('Image upload failed.');
        if ($r_json) {
            echo json_encode(['error' => $msg]);
        } else {
            echo $msg . EOL;
        }
        killme();
    }
    if ($width > 640 || $height > 640) {
        $ph->scaleImage(640);
        $r = $ph->store($page_owner_uid, $visitor, $hash, $filename, t('Wall Photos'), 1, 0, $defperm);
        if ($r) {
            $smallest = 1;
        }
    }
    if ($width > 320 || $height > 320) {
        $ph->scaleImage(320);
        $r = $ph->store($page_owner_uid, $visitor, $hash, $filename, t('Wall Photos'), 2, 0, $defperm);
        if ($r and $smallest == 0) {
            $smallest = 2;
        }
    }
    $basename = basename($filename);
    if (!$desktopmode) {
        $r = q("SELECT `id`, `datasize`, `width`, `height`, `type` FROM `photo` WHERE `resource-id` = '%s' ORDER BY `width` DESC LIMIT 1", $hash);
        if (!$r) {
            if ($r_json) {
                echo json_encode(['error' => '']);
                killme();
            }
            return false;
        }
        $picture = array();
        $picture["id"] = $r[0]["id"];
        $picture["size"] = $r[0]["datasize"];
        $picture["width"] = $r[0]["width"];
        $picture["height"] = $r[0]["height"];
        $picture["type"] = $r[0]["type"];
        $picture["albumpage"] = $a->get_baseurl() . '/photos/' . $page_owner_nick . '/image/' . $hash;
        $picture["picture"] = $a->get_baseurl() . "/photo/{$hash}-0." . $ph->getExt();
        $picture["preview"] = $a->get_baseurl() . "/photo/{$hash}-{$smallest}." . $ph->getExt();
        if ($r_json) {
            echo json_encode(['picture' => $picture]);
            killme();
        }
        return $picture;
    }
    if ($r_json) {
        echo json_encode(['ok' => true]);
        killme();
    }
    /* mod Waitman Gobble NO WARRANTY */
    //if we get the signal then return the image url info in BBCODE, otherwise this outputs the info and bails (for the ajax image uploader on wall post)
    if ($_REQUEST['hush'] != 'yeah') {
        if (local_user() && (!feature_enabled(local_user(), 'richtext') || x($_REQUEST['nomce']))) {
            echo "\n\n" . '[url=' . $a->get_baseurl() . '/photos/' . $page_owner_nick . '/image/' . $hash . '][img]' . $a->get_baseurl() . "/photo/{$hash}-{$smallest}." . $ph->getExt() . "[/img][/url]\n\n";
        } else {
            echo '<br /><br /><a href="' . $a->get_baseurl() . '/photos/' . $page_owner_nick . '/image/' . $hash . '" ><img src="' . $a->get_baseurl() . "/photo/{$hash}-{$smallest}." . $ph->getExt() . "\" alt=\"{$basename}\" /></a><br /><br />";
        }
    } else {
        $m = '[url=' . $a->get_baseurl() . '/photos/' . $page_owner_nick . '/image/' . $hash . '][img]' . $a->get_baseurl() . "/photo/{$hash}-{$smallest}." . $ph->getExt() . "[/img][/url]";
        return $m;
    }
    /* mod Waitman Gobble NO WARRANTY */
    killme();
    // NOTREACHED
}
示例#22
0
function retriever_store_photo($item, &$resource)
{
    $hash = photo_new_resource();
    if (class_exists('Imagick')) {
        try {
            $image = new Imagick();
            $image->readImageBlob($resource['data']);
            $resource['width'] = $image->getImageWidth();
            $resource['height'] = $image->getImageHeight();
        } catch (Exception $e) {
            logger("ImageMagick couldn't process image " . $resource['id'] . " " . $resource['url'] . ' length ' . strlen($resource['data']) . ': ' . $e->getMessage(), LOGGER_DEBUG);
            return false;
        }
    }
    if (!array_key_exists('width', $resource)) {
        $image = @imagecreatefromstring($resource['data']);
        if ($image === false) {
            logger("Couldn't process image " . $resource['id'] . " " . $resource['url'], LOGGER_DEBUG);
            return false;
        }
        $resource['width'] = imagesx($image);
        $resource['height'] = imagesy($image);
        imagedestroy($image);
    }
    $url_components = parse_url($resource['url']);
    $filename = basename($url_components['path']);
    if (!strlen($filename)) {
        $filename = 'image';
    }
    $r = q("INSERT INTO `photo`\n                ( `uid`, `contact-id`, `guid`, `resource-id`, `created`, `edited`, `filename`, `type`, `album`, `height`, `width`, `datasize`, `data` )\n                VALUES ( %d, %d, '%s', '%s', '%s', '%s', '%s', '%s', '%s', %d, %d, %d, '%s' )", intval($item['item-uid']), intval($item['contact-id']), dbesc(get_guid()), dbesc($hash), dbesc(datetime_convert()), dbesc(datetime_convert()), dbesc($filename), dbesc($resource['type']), dbesc('Retrieved Images'), intval($resource['height']), intval($resource['width']), intval(strlen($resource['data'])), dbesc($resource['data']));
    return $hash;
}
function profile_photo_post(&$a)
{
    if (!local_channel()) {
        return;
    }
    check_form_security_token_redirectOnErr('/profile_photo', 'profile_photo');
    if (x($_POST, 'cropfinal') && $_POST['cropfinal'] == 1) {
        // unless proven otherwise
        $is_default_profile = 1;
        if ($_REQUEST['profile']) {
            $r = q("select id, profile_guid, is_default, gender from profile where id = %d and uid = %d limit 1", intval($_REQUEST['profile']), intval(local_channel()));
            if ($r) {
                $profile = $r[0];
                if (!intval($profile['is_default'])) {
                    $is_default_profile = 0;
                }
            }
        }
        // phase 2 - we have finished cropping
        if (argc() != 2) {
            notice(t('Image uploaded but image cropping failed.') . EOL);
            return;
        }
        $image_id = argv(1);
        if (substr($image_id, -2, 1) == '-') {
            $scale = substr($image_id, -1, 1);
            $image_id = substr($image_id, 0, -2);
        }
        $srcX = $_POST['xstart'];
        $srcY = $_POST['ystart'];
        $srcW = $_POST['xfinal'] - $srcX;
        $srcH = $_POST['yfinal'] - $srcY;
        $r = q("SELECT * FROM photo WHERE resource_id = '%s' AND uid = %d AND scale = %d LIMIT 1", dbesc($image_id), dbesc(local_channel()), intval($scale));
        if ($r) {
            $base_image = $r[0];
            $base_image['data'] = $r[0]['os_storage'] ? @file_get_contents($base_image['data']) : dbunescbin($base_image['data']);
            $im = photo_factory($base_image['data'], $base_image['type']);
            if ($im->is_valid()) {
                $im->cropImage(300, $srcX, $srcY, $srcW, $srcH);
                $aid = get_account_id();
                $p = array('aid' => $aid, 'uid' => local_channel(), 'resource_id' => $base_image['resource_id'], 'filename' => $base_image['filename'], 'album' => t('Profile Photos'));
                $p['scale'] = 4;
                $p['photo_usage'] = $is_default_profile ? PHOTO_PROFILE : PHOTO_NORMAL;
                $r1 = $im->save($p);
                $im->scaleImage(80);
                $p['scale'] = 5;
                $r2 = $im->save($p);
                $im->scaleImage(48);
                $p['scale'] = 6;
                $r3 = $im->save($p);
                if ($r1 === false || $r2 === false || $r3 === false) {
                    // if one failed, delete them all so we can start over.
                    notice(t('Image resize failed.') . EOL);
                    $x = q("delete from photo where resource_id = '%s' and uid = %d and scale >= 4 ", dbesc($base_image['resource_id']), local_channel());
                    return;
                }
                $channel = App::get_channel();
                // If setting for the default profile, unset the profile photo flag from any other photos I own
                if ($is_default_profile) {
                    $r = q("UPDATE photo SET photo_usage = %d WHERE photo_usage = %d\n\t\t\t\t\t\tAND resource_id != '%s' AND `uid` = %d", intval(PHOTO_NORMAL), intval(PHOTO_PROFILE), dbesc($base_image['resource_id']), intval(local_channel()));
                    send_profile_photo_activity($channel, $base_image, $profile);
                } else {
                    $r = q("update profile set photo = '%s', thumb = '%s' where id = %d and uid = %d", dbesc(z_root() . '/photo/' . $base_image['resource_id'] . '-4'), dbesc(z_root() . '/photo/' . $base_image['resource_id'] . '-5'), intval($_REQUEST['profile']), intval(local_channel()));
                }
                profiles_build_sync(local_channel());
                // We'll set the updated profile-photo timestamp even if it isn't the default profile,
                // so that browsers will do a cache update unconditionally
                $r = q("UPDATE xchan set xchan_photo_mimetype = '%s', xchan_photo_date = '%s' \n\t\t\t\t\twhere xchan_hash = '%s'", dbesc($im->getType()), dbesc(datetime_convert()), dbesc($channel['xchan_hash']));
                info(t('Shift-reload the page or clear browser cache if the new photo does not display immediately.') . EOL);
                // Update directory in background
                proc_run('php', "include/directory.php", $channel['channel_id']);
                // Now copy profile-permissions to pictures, to prevent privacyleaks by automatically created folder 'Profile Pictures'
                profile_photo_set_profile_perms($_REQUEST['profile']);
            } else {
                notice(t('Unable to process image') . EOL);
            }
        }
        goaway(z_root() . '/profiles');
        return;
        // NOTREACHED
    }
    $hash = photo_new_resource();
    $smallest = 0;
    require_once 'include/attach.php';
    $res = attach_store(App::get_channel(), get_observer_hash(), '', array('album' => t('Profile Photos'), 'hash' => $hash));
    logger('attach_store: ' . print_r($res, true));
    if ($res && intval($res['data']['is_photo'])) {
        $i = q("select * from photo where resource_id = '%s' and uid = %d order by scale", dbesc($hash), intval(local_channel()));
        if (!$i) {
            notice(t('Image upload failed.') . EOL);
            return;
        }
        $os_storage = false;
        foreach ($i as $ii) {
            if (intval($ii['scale']) < 2) {
                $smallest = intval($ii['scale']);
                $os_storage = intval($ii['os_storage']);
                $imagedata = $ii['data'];
                $filetype = $ii['type'];
            }
        }
    }
    $imagedata = $os_storage ? @file_get_contents($imagedata) : $imagedata;
    $ph = photo_factory($imagedata, $filetype);
    if (!$ph->is_valid()) {
        notice(t('Unable to process image.') . EOL);
        return;
    }
    return profile_photo_crop_ui_head($a, $ph, $hash, $smallest);
}
示例#24
0
/**
 * @brief
 *
 * @param array $channel
 * @param array $observer
 * @param array $args
 * @return array
 */
function photo_upload($channel, $observer, $args)
{
    $ret = array('success' => false);
    $channel_id = $channel['channel_id'];
    $account_id = $channel['channel_account_id'];
    if (!perm_is_allowed($channel_id, $observer['xchan_hash'], 'write_storage')) {
        $ret['message'] = t('Permission denied.');
        return $ret;
    }
    //	call_hooks('photo_upload_begin', $args);
    /*
     * Determine the album to use
     */
    $album = $args['album'];
    if (intval($args['visible']) || $args['visible'] === 'true') {
        $visible = 1;
    } else {
        $visible = 0;
    }
    // Set to default channel permissions. If the parent directory (album) has permissions set,
    // use those instead. If we have specific permissions supplied, they take precedence over
    // all other settings. 'allow_cid' being passed from an external source takes priority over channel settings.
    // ...messy... needs re-factoring once the photos/files integration stabilises
    $acl = new AccessList($channel);
    if (array_key_exists('directory', $args) && $args['directory']) {
        $acl->set($args['directory']);
    }
    if (array_key_exists('allow_cid', $args)) {
        $acl->set($args);
    }
    if (array_key_exists('group_allow', $args) || array_key_exists('contact_allow', $args) || array_key_exists('group_deny', $args) || array_key_exists('contact_deny', $args)) {
        $acl->set_from_array($args);
    }
    $ac = $acl->get();
    $os_storage = 0;
    if ($args['os_path'] && $args['getimagesize']) {
        $imagedata = @file_get_contents($args['os_path']);
        $filename = $args['filename'];
        $filesize = strlen($imagedata);
        // this is going to be deleted if it exists
        $src = '/tmp/deletemenow';
        $type = $args['getimagesize']['mime'];
        $os_storage = 1;
    } elseif ($args['data']) {
        // allow an import from a binary string representing the image.
        // This bypasses the upload step and max size limit checking
        $imagedata = $args['data'];
        $filename = $args['filename'];
        $filesize = strlen($imagedata);
        // this is going to be deleted if it exists
        $src = '/tmp/deletemenow';
        $type = $args['type'];
    } else {
        $f = array('src' => '', 'filename' => '', 'filesize' => 0, 'type' => '');
        //		call_hooks('photo_upload_file',$f);
        if (x($f, 'src') && x($f, 'filesize')) {
            $src = $f['src'];
            $filename = $f['filename'];
            $filesize = $f['filesize'];
            $type = $f['type'];
        } else {
            $src = $_FILES['userfile']['tmp_name'];
            $filename = basename($_FILES['userfile']['name']);
            $filesize = intval($_FILES['userfile']['size']);
            $type = $_FILES['userfile']['type'];
        }
        if (!$type) {
            $type = guess_image_type($filename);
        }
        logger('photo_upload: received file: ' . $filename . ' as ' . $src . ' (' . $type . ') ' . $filesize . ' bytes', LOGGER_DEBUG);
        $maximagesize = get_config('system', 'maximagesize');
        if ($maximagesize && $filesize > $maximagesize) {
            $ret['message'] = sprintf(t('Image exceeds website size limit of %lu bytes'), $maximagesize);
            @unlink($src);
            call_hooks('photo_upload_end', $ret);
            return $ret;
        }
        if (!$filesize) {
            $ret['message'] = t('Image file is empty.');
            @unlink($src);
            call_hooks('photo_post_end', $ret);
            return $ret;
        }
        logger('photo_upload: loading the contents of ' . $src, LOGGER_DEBUG);
        $imagedata = @file_get_contents($src);
    }
    $r = q("select sum(size) as total from photo where aid = %d and scale = 0 ", intval($account_id));
    $limit = service_class_fetch($channel_id, 'photo_upload_limit');
    if ($r && $limit !== false && $r[0]['total'] + strlen($imagedata) > $limit) {
        $ret['message'] = upgrade_message();
        @unlink($src);
        call_hooks('photo_post_end', $ret);
        return $ret;
    }
    $ph = photo_factory($imagedata, $type);
    if (!$ph->is_valid()) {
        $ret['message'] = t('Unable to process image');
        logger('photo_upload: unable to process image');
        @unlink($src);
        call_hooks('photo_upload_end', $ret);
        return $ret;
    }
    $exif = $ph->orient($args['os_path'] ? $args['os_path'] : $src);
    @unlink($src);
    $max_length = get_config('system', 'max_image_length');
    if (!$max_length) {
        $max_length = MAX_IMAGE_LENGTH;
    }
    if ($max_length > 0) {
        $ph->scaleImage($max_length);
    }
    $width = $ph->getWidth();
    $height = $ph->getHeight();
    $smallest = 0;
    $photo_hash = $args['resource_id'] ? $args['resource_id'] : photo_new_resource();
    $visitor = '';
    if ($channel['channel_hash'] !== $observer['xchan_hash']) {
        $visitor = $observer['xchan_hash'];
    }
    $errors = false;
    $p = array('aid' => $account_id, 'uid' => $channel_id, 'xchan' => $visitor, 'resource_id' => $photo_hash, 'filename' => $filename, 'album' => $album, 'scale' => 0, 'photo_usage' => PHOTO_NORMAL, 'allow_cid' => $ac['allow_cid'], 'allow_gid' => $ac['allow_gid'], 'deny_cid' => $ac['deny_cid'], 'deny_gid' => $ac['deny_gid'], 'os_storage' => $os_storage, 'os_path' => $args['os_path']);
    if ($args['created']) {
        $p['created'] = $args['created'];
    }
    if ($args['edited']) {
        $p['edited'] = $args['edited'];
    }
    if ($args['title']) {
        $p['title'] = $args['title'];
    }
    if ($args['description']) {
        $p['description'] = $args['description'];
    }
    $r1 = $ph->save($p);
    if (!$r1) {
        $errors = true;
    }
    unset($p['os_storage']);
    unset($p['os_path']);
    if (($width > 640 || $height > 640) && !$errors) {
        $ph->scaleImage(640);
        $p['scale'] = 1;
        $r2 = $ph->save($p);
        $smallest = 1;
        if (!$r2) {
            $errors = true;
        }
    }
    if (($width > 320 || $height > 320) && !$errors) {
        $ph->scaleImage(320);
        $p['scale'] = 2;
        $r3 = $ph->save($p);
        $smallest = 2;
        if (!$r3) {
            $errors = true;
        }
    }
    if ($errors) {
        q("delete from photo where resource_id = '%s' and uid = %d", dbesc($photo_hash), intval($channel_id));
        $ret['message'] = t('Photo storage failed.');
        logger('photo_upload: photo store failed.');
        call_hooks('photo_upload_end', $ret);
        return $ret;
    }
    // This will be the width and height of the smallest representation
    $width_x_height = $ph->getWidth() . 'x' . $ph->getHeight();
    // Create item container
    $item_hidden = $visible ? 0 : 1;
    $lat = $lon = null;
    if ($exif && $exif['GPS']) {
        if (feature_enabled($channel_id, 'photo_location')) {
            $lat = getGps($exif['GPS']['GPSLatitude'], $exif['GPS']['GPSLatitudeRef']);
            $lon = getGps($exif['GPS']['GPSLongitude'], $exif['GPS']['GPSLongitudeRef']);
        }
    }
    if ($args['item']) {
        foreach ($args['item'] as $i) {
            $item = get_item_elements($i);
            $force = false;
            if ($item['mid'] === $item['parent_mid']) {
                $item['body'] = '[zrl=' . z_root() . '/photos/' . $channel['channel_address'] . '/image/' . $photo_hash . ']' . $tag . z_root() . "/photo/{$photo_hash}-{$smallest}." . $ph->getExt() . '[/zmg]' . '[/zrl]';
                if ($item['author_xchan'] === $channel['channel_hash']) {
                    $item['sig'] = base64url_encode(rsa_sign($item['body'], $channel['channel_prvkey']));
                    $item['item_verified'] = 1;
                } else {
                    $item['sig'] = '';
                }
                $force = true;
            }
            $r = q("select id, edited from item where mid = '%s' and uid = %d limit 1", dbesc($item['mid']), intval($channel['channel_id']));
            if ($r) {
                if ($item['edited'] > $r[0]['edited'] || $force) {
                    $item['id'] = $r[0]['id'];
                    $item['uid'] = $channel['channel_id'];
                    item_store_update($item);
                    continue;
                }
            } else {
                $item['aid'] = $channel['channel_account_id'];
                $item['uid'] = $channel['channel_id'];
                $item_result = item_store($item);
            }
        }
    } else {
        $title = '';
        $mid = item_message_id();
        $arr = array();
        if ($lat && $lon) {
            $arr['coord'] = $lat . ' ' . $lon;
        }
        $arr['aid'] = $account_id;
        $arr['uid'] = $channel_id;
        $arr['mid'] = $mid;
        $arr['parent_mid'] = $mid;
        $arr['item_hidden'] = $item_hidden;
        $arr['resource_type'] = 'photo';
        $arr['resource_id'] = $photo_hash;
        $arr['owner_xchan'] = $channel['channel_hash'];
        $arr['author_xchan'] = $observer['xchan_hash'];
        $arr['title'] = $title;
        $arr['allow_cid'] = $ac['allow_cid'];
        $arr['allow_gid'] = $ac['allow_gid'];
        $arr['deny_cid'] = $ac['deny_cid'];
        $arr['deny_gid'] = $ac['deny_gid'];
        $arr['verb'] = ACTIVITY_POST;
        $arr['item_wall'] = 1;
        $arr['item_origin'] = 1;
        $arr['item_thread_top'] = 1;
        $arr['item_private'] = intval($acl->is_private());
        $arr['plink'] = z_root() . '/channel/' . $channel['channel_address'] . '/?f=&mid=' . $arr['mid'];
        // We should also put a width_x_height on large photos. Left as an exercise for
        // devs looking for simple stuff to fix.
        $larger = feature_enabled($channel['channel_id'], 'large_photos');
        if ($larger) {
            $tag = '[zmg]';
            if ($r2) {
                $smallest = 1;
            } else {
                $smallest = 0;
            }
        } else {
            if ($width_x_height) {
                $tag = '[zmg=' . $width_x_height . ']';
            } else {
                $tag = '[zmg]';
            }
        }
        $arr['body'] = '[zrl=' . z_root() . '/photos/' . $channel['channel_address'] . '/image/' . $photo_hash . ']' . $tag . z_root() . "/photo/{$photo_hash}-{$smallest}." . $ph->getExt() . '[/zmg]' . '[/zrl]';
        $result = item_store($arr);
        $item_id = $result['item_id'];
        if ($visible) {
            proc_run('php', "include/notifier.php", 'wall-new', $item_id);
        }
    }
    $ret['success'] = true;
    $ret['item'] = $arr;
    $ret['body'] = $arr['body'];
    $ret['resource_id'] = $photo_hash;
    $ret['photoitem_id'] = $item_id;
    call_hooks('photo_upload_end', $ret);
    return $ret;
}