Пример #1
0
function subthread_content(&$a)
{
    if (!local_user() && !remote_user()) {
        return;
    }
    $activity = ACTIVITY_FOLLOW;
    $item_id = $a->argc > 1 ? notags(trim($a->argv[1])) : 0;
    $r = q("SELECT * FROM `item` WHERE `parent` = '%s' OR `parent-uri` = '%s' and parent = id LIMIT 1", dbesc($item_id), dbesc($item_id));
    if (!$item_id || !count($r)) {
        logger('subthread: no item ' . $item_id);
        return;
    }
    $item = $r[0];
    $owner_uid = $item['uid'];
    if (!can_write_wall($a, $owner_uid)) {
        return;
    }
    $remote_owner = null;
    if (!$item['wall']) {
        // The top level post may have been written by somebody on another system
        $r = q("SELECT * FROM `contact` WHERE `id` = %d AND `uid` = %d LIMIT 1", intval($item['contact-id']), intval($item['uid']));
        if (!count($r)) {
            return;
        }
        if (!$r[0]['self']) {
            $remote_owner = $r[0];
        }
    }
    // this represents the post owner on this system.
    $r = q("SELECT `contact`.*, `user`.`nickname` FROM `contact` LEFT JOIN `user` ON `contact`.`uid` = `user`.`uid`\n\t\tWHERE `contact`.`self` = 1 AND `contact`.`uid` = %d LIMIT 1", intval($owner_uid));
    if (count($r)) {
        $owner = $r[0];
    }
    if (!$owner) {
        logger('like: no owner');
        return;
    }
    if (!$remote_owner) {
        $remote_owner = $owner;
    }
    // This represents the person posting
    if (local_user() && local_user() == $owner_uid) {
        $contact = $owner;
    } else {
        $r = q("SELECT * FROM `contact` WHERE `id` = %d AND `uid` = %d LIMIT 1", intval($_SESSION['visitor_id']), intval($owner_uid));
        if (count($r)) {
            $contact = $r[0];
        }
    }
    if (!$contact) {
        return;
    }
    $uri = item_new_uri($a->get_hostname(), $owner_uid);
    $post_type = $item['resource-id'] ? t('photo') : t('status');
    $objtype = $item['resource-id'] ? ACTIVITY_OBJ_PHOTO : ACTIVITY_OBJ_NOTE;
    $link = xmlify('<link rel="alternate" type="text/html" href="' . $a->get_baseurl() . '/display/' . $owner['nickname'] . '/' . $item['id'] . '" />' . "\n");
    $body = $item['body'];
    $obj = <<<EOT

\t<object>
\t\t<type>{$objtype}</type>
\t\t<local>1</local>
\t\t<id>{$item['uri']}</id>
\t\t<link>{$link}</link>
\t\t<title></title>
\t\t<content>{$body}</content>
\t</object>
EOT;
    $bodyverb = t('%1$s is following %2$s\'s %3$s');
    if (!isset($bodyverb)) {
        return;
    }
    $arr = array();
    $arr['uri'] = $uri;
    $arr['uid'] = $owner_uid;
    $arr['contact-id'] = $contact['id'];
    $arr['type'] = 'activity';
    $arr['wall'] = $item['wall'];
    $arr['origin'] = 1;
    $arr['gravity'] = GRAVITY_LIKE;
    $arr['parent'] = $item['id'];
    $arr['parent-uri'] = $item['uri'];
    $arr['thr-parent'] = $item['uri'];
    $arr['owner-name'] = $remote_owner['name'];
    $arr['owner-link'] = $remote_owner['url'];
    $arr['owner-avatar'] = $remote_owner['thumb'];
    $arr['author-name'] = $contact['name'];
    $arr['author-link'] = $contact['url'];
    $arr['author-avatar'] = $contact['thumb'];
    $ulink = '[url=' . $contact['url'] . ']' . $contact['name'] . '[/url]';
    $alink = '[url=' . $item['author-link'] . ']' . $item['author-name'] . '[/url]';
    $plink = '[url=' . $a->get_baseurl() . '/display/' . $owner['nickname'] . '/' . $item['id'] . ']' . $post_type . '[/url]';
    $arr['body'] = sprintf($bodyverb, $ulink, $alink, $plink);
    $arr['verb'] = $activity;
    $arr['object-type'] = $objtype;
    $arr['object'] = $obj;
    $arr['allow_cid'] = $item['allow_cid'];
    $arr['allow_gid'] = $item['allow_gid'];
    $arr['deny_cid'] = $item['deny_cid'];
    $arr['deny_gid'] = $item['deny_gid'];
    $arr['visible'] = 1;
    $arr['unseen'] = 1;
    $arr['last-child'] = 0;
    $post_id = item_store($arr);
    if (!$item['visible']) {
        $r = q("UPDATE `item` SET `visible` = 1 WHERE `id` = %d AND `uid` = %d LIMIT 1", intval($item['id']), intval($owner_uid));
    }
    $arr['id'] = $post_id;
    call_hooks('post_local_end', $arr);
    killme();
}
Пример #2
0
function pumpio_dolike(&$a, $uid, $self, $post, $own_id, $threadcompletion = true)
{
    require_once 'include/items.php';
    // Searching for the liked post
    // Two queries for speed issues
    $r = q("SELECT * FROM `item` WHERE `uri` = '%s' AND `uid` = %d LIMIT 1", dbesc($post->object->id), intval($uid));
    if (count($r)) {
        $orig_post = $r[0];
    } else {
        $r = q("SELECT * FROM `item` WHERE `extid` = '%s' AND `uid` = %d LIMIT 1", dbesc($post->object->id), intval($uid));
        if (!count($r)) {
            return;
        } else {
            $orig_post = $r[0];
        }
    }
    // thread completion
    if ($threadcompletion) {
        pumpio_fetchallcomments($a, $uid, $post->object->id);
    }
    $contactid = 0;
    if (link_compare($post->actor->url, $own_id)) {
        $contactid = $self[0]['id'];
        $post->actor->displayName = $self[0]['name'];
        $post->actor->url = $self[0]['url'];
        $post->actor->image->url = $self[0]['photo'];
    } else {
        $r = q("SELECT * FROM `contact` WHERE `url` = '%s' AND `uid` = %d AND `blocked` = 0 AND `readonly` = 0 LIMIT 1", dbesc($post->actor->url), intval($uid));
        if (count($r)) {
            $contactid = $r[0]['id'];
        }
        if ($contactid == 0) {
            $contactid = $orig_post['contact-id'];
        }
    }
    $r = q("SELECT parent FROM `item` WHERE `verb` = '%s' AND `uid` = %d AND `contact-id` = %d AND `thr-parent` = '%s' LIMIT 1", dbesc(ACTIVITY_LIKE), intval($uid), intval($contactid), dbesc($orig_post['uri']));
    if (count($r)) {
        logger("pumpio_dolike: found existing like. User " . $own_id . " " . $uid . " Contact: " . $contactid . " Url " . $orig_post['uri']);
        return;
    }
    $likedata = array();
    $likedata['parent'] = $orig_post['id'];
    $likedata['verb'] = ACTIVITY_LIKE;
    $likedata['gravity'] = 3;
    $likedata['uid'] = $uid;
    $likedata['wall'] = 0;
    $likedata['uri'] = item_new_uri($a->get_baseurl(), $uid);
    $likedata['parent-uri'] = $orig_post["uri"];
    $likedata['contact-id'] = $contactid;
    $likedata['app'] = $post->generator->displayName;
    $likedata['author-name'] = $post->actor->displayName;
    $likedata['author-link'] = $post->actor->url;
    $likedata['author-avatar'] = $post->actor->image->url;
    $author = '[url=' . $likedata['author-link'] . ']' . $likedata['author-name'] . '[/url]';
    $objauthor = '[url=' . $orig_post['author-link'] . ']' . $orig_post['author-name'] . '[/url]';
    $post_type = t('status');
    $plink = '[url=' . $orig_post['plink'] . ']' . $post_type . '[/url]';
    $likedata['object-type'] = ACTIVITY_OBJ_NOTE;
    $likedata['body'] = sprintf(t('%1$s likes %2$s\'s %3$s'), $author, $objauthor, $plink);
    $likedata['object'] = '<object><type>' . ACTIVITY_OBJ_NOTE . '</type><local>1</local>' . '<id>' . $orig_post['uri'] . '</id><link>' . xmlify('<link rel="alternate" type="text/html" href="' . xmlify($orig_post['plink']) . '" />') . '</link><title>' . $orig_post['title'] . '</title><content>' . $orig_post['body'] . '</content></object>';
    $ret = item_store($likedata);
    logger("pumpio_dolike: " . $ret . " User " . $own_id . " " . $uid . " Contact: " . $contactid . " Url " . $orig_post['uri']);
}
Пример #3
0
function event_store($arr)
{
    require_once 'include/datetime.php';
    require_once 'include/items.php';
    require_once 'include/bbcode.php';
    $a = get_app();
    $arr['created'] = $arr['created'] ? $arr['created'] : datetime_convert();
    $arr['edited'] = $arr['edited'] ? $arr['edited'] : datetime_convert();
    $arr['type'] = $arr['type'] ? $arr['type'] : 'event';
    $arr['cid'] = intval($arr['cid']) ? intval($arr['cid']) : 0;
    $arr['uri'] = x($arr, 'uri') ? $arr['uri'] : item_new_uri($a->get_hostname(), $arr['uid']);
    $arr['private'] = x($arr, 'private') ? intval($arr['private']) : 0;
    if ($arr['cid']) {
        $c = q("SELECT * FROM `contact` WHERE `id` = %d AND `uid` = %d LIMIT 1", intval($arr['cid']), intval($arr['uid']));
    } else {
        $c = q("SELECT * FROM `contact` WHERE `self` = 1 AND `uid` = %d LIMIT 1", intval($arr['uid']));
    }
    if (count($c)) {
        $contact = $c[0];
    }
    // Existing event being modified
    if ($arr['id']) {
        // has the event actually changed?
        $r = q("SELECT * FROM `event` WHERE `id` = %d AND `uid` = %d LIMIT 1", intval($arr['id']), intval($arr['uid']));
        if (!count($r) || $r[0]['edited'] === $arr['edited']) {
            // Nothing has changed. Grab the item id to return.
            $r = q("SELECT * FROM `item` WHERE `event-id` = %d AND `uid` = %d LIMIT 1", intval($arr['id']), intval($arr['uid']));
            return count($r) ? $r[0]['id'] : 0;
        }
        // The event changed. Update it.
        $r = q("UPDATE `event` SET\n\t\t\t`edited` = '%s',\n\t\t\t`start` = '%s',\n\t\t\t`finish` = '%s',\n\t\t\t`desc` = '%s',\n\t\t\t`location` = '%s',\n\t\t\t`type` = '%s',\n\t\t\t`adjust` = %d,\n\t\t\t`nofinish` = %d,\n\t\t\t`allow_cid` = '%s',\n\t\t\t`allow_gid` = '%s',\n\t\t\t`deny_cid` = '%s',\n\t\t\t`deny_gid` = '%s'\n\t\t\tWHERE `id` = %d AND `uid` = %d LIMIT 1", dbesc($arr['edited']), dbesc($arr['start']), dbesc($arr['finish']), dbesc($arr['desc']), dbesc($arr['location']), dbesc($arr['type']), intval($arr['adjust']), intval($arr['nofinish']), dbesc($arr['allow_cid']), dbesc($arr['allow_gid']), dbesc($arr['deny_cid']), dbesc($arr['deny_gid']), intval($arr['id']), intval($arr['uid']));
        $r = q("SELECT * FROM `item` WHERE `event-id` = %d AND `uid` = %d LIMIT 1", intval($arr['id']), intval($arr['uid']));
        if (count($r)) {
            $object = '<object><type>' . xmlify(ACTIVITY_OBJ_EVENT) . '</type><title></title><id>' . xmlify($arr['uri']) . '</id>';
            $object .= '<content>' . xmlify(format_event_bbcode($arr)) . '</content>';
            $object .= '</object>' . "\n";
            q("UPDATE `item` SET `body` = '%s', `object` = '%s', `allow_cid` = '%s', `allow_gid` = '%s', `deny_cid` = '%s', `deny_gid` = '%s', `edited` = '%s', `private` = %d WHERE `id` = %d AND `uid` = %d LIMIT 1", dbesc(format_event_bbcode($arr)), dbesc($object), dbesc($arr['allow_cid']), dbesc($arr['allow_gid']), dbesc($arr['deny_cid']), dbesc($arr['deny_gid']), dbesc($arr['edited']), intval($arr['private']), intval($r[0]['id']), intval($arr['uid']));
            return $r[0]['id'];
        } else {
            return 0;
        }
    } else {
        // New event. Store it.
        $r = q("INSERT INTO `event` ( `uid`,`cid`,`uri`,`created`,`edited`,`start`,`finish`,`desc`,`location`,`type`,\n\t\t\t`adjust`,`nofinish`,`allow_cid`,`allow_gid`,`deny_cid`,`deny_gid`)\n\t\t\tVALUES ( %d, %d, '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', %d, %d, '%s', '%s', '%s', '%s' ) ", intval($arr['uid']), intval($arr['cid']), dbesc($arr['uri']), dbesc($arr['created']), dbesc($arr['edited']), dbesc($arr['start']), dbesc($arr['finish']), dbesc($arr['desc']), dbesc($arr['location']), dbesc($arr['type']), intval($arr['adjust']), intval($arr['nofinish']), dbesc($arr['allow_cid']), dbesc($arr['allow_gid']), dbesc($arr['deny_cid']), dbesc($arr['deny_gid']));
        $r = q("SELECT * FROM `event` WHERE `uri` = '%s' AND `uid` = %d LIMIT 1", dbesc($arr['uri']), intval($arr['uid']));
        if (count($r)) {
            $event = $r[0];
        }
        $item_arr = array();
        $item_arr['uid'] = $arr['uid'];
        $item_arr['contact-id'] = $arr['cid'];
        $item_arr['uri'] = $arr['uri'];
        $item_arr['parent-uri'] = $arr['uri'];
        $item_arr['type'] = 'activity';
        $item_arr['wall'] = $arr['cid'] ? 0 : 1;
        $item_arr['contact-id'] = $contact['id'];
        $item_arr['owner-name'] = $contact['name'];
        $item_arr['owner-link'] = $contact['url'];
        $item_arr['owner-avatar'] = $contact['thumb'];
        $item_arr['author-name'] = $contact['name'];
        $item_arr['author-link'] = $contact['url'];
        $item_arr['author-avatar'] = $contact['thumb'];
        $item_arr['title'] = '';
        $item_arr['allow_cid'] = $arr['allow_cid'];
        $item_arr['allow_gid'] = $arr['allow_gid'];
        $item_arr['deny_cid'] = $arr['deny_cid'];
        $item_arr['deny_gid'] = $arr['deny_gid'];
        $item_arr['private'] = $arr['private'];
        $item_arr['last-child'] = 1;
        $item_arr['visible'] = 1;
        $item_arr['verb'] = ACTIVITY_POST;
        $item_arr['object-type'] = ACTIVITY_OBJ_EVENT;
        $item_arr['origin'] = intval($arr['cid']) == 0 ? 1 : 0;
        $item_arr['body'] = format_event_bbcode($event);
        $item_arr['object'] = '<object><type>' . xmlify(ACTIVITY_OBJ_EVENT) . '</type><title></title><id>' . xmlify($uri) . '</id>';
        $item_arr['object'] .= '<content>' . xmlify(format_event_bbcode($event)) . '</content>';
        $item_arr['object'] .= '</object>' . "\n";
        $item_id = item_store($item_arr);
        $r = q("SELECT * FROM `user` WHERE `uid` = %d LIMIT 1", intval($arr['uid']));
        if (count($r)) {
            $plink = $a->get_baseurl() . '/display/' . $r[0]['nickname'] . '/' . $item_id;
        }
        if ($item_id) {
            q("UPDATE `item` SET `plink` = '%s', `event-id` = %d  WHERE `uid` = %d AND `id` = %d LIMIT 1", dbesc($plink), intval($event['id']), intval($arr['uid']), intval($item_id));
        }
        return $item_id;
    }
}
Пример #4
0
function profile_activity($changed, $value)
{
    $a = get_app();
    if (!local_user() || !is_array($changed) || !count($changed)) {
        return;
    }
    if ($a->user['hidewall'] || get_config('system', 'block_public')) {
        return;
    }
    if (!get_pconfig(local_user(), 'system', 'post_profilechange')) {
        return;
    }
    require_once 'include/items.php';
    $self = q("SELECT * FROM `contact` WHERE `self` = 1 AND `uid` = %d LIMIT 1", intval(local_user()));
    if (!count($self)) {
        return;
    }
    $arr = array();
    $arr['uri'] = $arr['parent-uri'] = item_new_uri($a->get_hostname(), local_user());
    $arr['uid'] = local_user();
    $arr['contact-id'] = $self[0]['id'];
    $arr['wall'] = 1;
    $arr['type'] = 'wall';
    $arr['gravity'] = 0;
    $arr['origin'] = 1;
    $arr['author-name'] = $arr['owner-name'] = $self[0]['name'];
    $arr['author-link'] = $arr['owner-link'] = $self[0]['url'];
    $arr['author-avatar'] = $arr['owner-avatar'] = $self[0]['thumb'];
    $arr['verb'] = ACTIVITY_UPDATE;
    $arr['object-type'] = ACTIVITY_OBJ_PROFILE;
    $A = '[url=' . $self[0]['url'] . ']' . $self[0]['name'] . '[/url]';
    $changes = '';
    $t = count($changed);
    $z = 0;
    foreach ($changed as $ch) {
        if (strlen($changes)) {
            if ($z == $t - 1) {
                $changes .= t(' and ');
            } else {
                $changes .= ', ';
            }
        }
        $z++;
        $changes .= $ch;
    }
    $prof = '[url=' . $self[0]['url'] . '?tab=profile' . ']' . t('public profile') . '[/url]';
    if ($t == 1 && strlen($value)) {
        $message = sprintf(t('%1$s changed %2$s to &ldquo;%3$s&rdquo;'), $A, $changes, $value);
        $message .= "\n\n" . sprintf(t(' - Visit %1$s\'s %2$s'), $A, $prof);
    } else {
        $message = sprintf(t('%1$s has an updated %2$s, changing %3$s.'), $A, $prof, $changes);
    }
    $arr['body'] = $message;
    $arr['object'] = '<object><type>' . ACTIVITY_OBJ_PROFILE . '</type><title>' . $self[0]['name'] . '</title>' . '<id>' . $self[0]['url'] . '/' . $self[0]['name'] . '</id>';
    $arr['object'] .= '<link>' . xmlify('<link rel="alternate" type="text/html" href="' . $self[0]['url'] . '?tab=profile' . '" />' . "\n");
    $arr['object'] .= xmlify('<link rel="photo" type="image/jpeg" href="' . $self[0]['thumb'] . '" />' . "\n");
    $arr['object'] .= '</link></object>' . "\n";
    $arr['last-child'] = 1;
    $arr['allow_cid'] = $a->user['allow_cid'];
    $arr['allow_gid'] = $a->user['allow_gid'];
    $arr['deny_cid'] = $a->user['deny_cid'];
    $arr['deny_gid'] = $a->user['deny_gid'];
    $i = item_store($arr);
    if ($i) {
        // give it a permanent link
        //q("update item set plink = '%s' where id = %d",
        //	dbesc($a->get_baseurl() . '/display/' . $a->user['nickname'] . '/' . $i),
        //	intval($i)
        //);
        proc_run('php', "include/notifier.php", "activity", "{$i}");
    }
}
Пример #5
0
function tagger_content(&$a)
{
    if (!local_user() && !remote_user()) {
        return;
    }
    $term = notags(trim($_GET['term']));
    // no commas allowed
    $term = str_replace(array(',', ' '), array('', '_'), $term);
    if (!$term) {
        return;
    }
    $item_id = $a->argc > 1 ? notags(trim($a->argv[1])) : 0;
    logger('tagger: tag ' . $term . ' item ' . $item_id);
    $r = q("SELECT * FROM `item` WHERE `id` = '%s' LIMIT 1", dbesc($item_id));
    if (!$item_id || !count($r)) {
        logger('tagger: no item ' . $item_id);
        return;
    }
    $item = $r[0];
    $owner_uid = $item['uid'];
    $r = q("select `nickname`,`blocktags` from user where uid = %d limit 1", intval($owner_uid));
    if (count($r)) {
        $owner_nick = $r[0]['nickname'];
        $blocktags = $r[0]['blocktags'];
    }
    if (local_user() != $owner_uid) {
        return;
    }
    if (remote_user()) {
        $r = q("select * from contact where id = %d AND `uid` = %d limit 1", intval(remote_user()), intval($item['uid']));
    } else {
        $r = q("select * from contact where self = 1 and uid = %d limit 1", intval(local_user()));
    }
    if (count($r)) {
        $contact = $r[0];
    } else {
        logger('tagger: no contact_id');
        return;
    }
    $uri = item_new_uri($a->get_hostname(), $owner_uid);
    $post_type = $item['resource-id'] ? t('photo') : t('status');
    $targettype = $item['resource-id'] ? ACTIVITY_OBJ_PHOTO : ACTIVITY_OBJ_NOTE;
    $link = xmlify('<link rel="alternate" type="text/html" href="' . $a->get_baseurl() . '/display/' . $owner['nickname'] . '/' . $item['id'] . '" />' . "\n");
    $body = $item['body'];
    $target = <<<EOT
\t<target>
\t\t<type>{$targettype}</type>
\t\t<local>1</local>
\t\t<id>{$item['uri']}</id>
\t\t<link>{$link}</link>
\t\t<title></title>
\t\t<content>{$body}</content>
\t</target>
EOT;
    $tagid = $a->get_baseurl() . '/search?search=' . $term;
    $objtype = ACTIVITY_OBJ_TAGTERM;
    $obj = <<<EOT
\t<object>
\t\t<type>{$objtype}</type>
\t\t<local>1</local>
\t\t<id>{$tagid}</id>
\t\t<link>{$tagid}</link>
\t\t<title>{$term}</title>
\t\t<content>{$term}</content>
\t</object>
EOT;
    $bodyverb = t('%1$s tagged %2$s\'s %3$s with %4$s');
    if (!isset($bodyverb)) {
        return;
    }
    $termlink = html_entity_decode('&#x2317;') . '[url=' . $a->get_baseurl() . '/search?search=' . urlencode($term) . ']' . $term . '[/url]';
    $arr = array();
    $arr['uri'] = $uri;
    $arr['uid'] = $owner_uid;
    $arr['contact-id'] = $contact['id'];
    $arr['type'] = 'activity';
    $arr['wall'] = $item['wall'];
    $arr['gravity'] = GRAVITY_COMMENT;
    $arr['parent'] = $item['id'];
    $arr['parent-uri'] = $item['uri'];
    $arr['owner-name'] = $item['author-name'];
    $arr['owner-link'] = $item['author-link'];
    $arr['owner-avatar'] = $item['author-avatar'];
    $arr['author-name'] = $contact['name'];
    $arr['author-link'] = $contact['url'];
    $arr['author-avatar'] = $contact['thumb'];
    $ulink = '[url=' . $contact['url'] . ']' . $contact['name'] . '[/url]';
    $alink = '[url=' . $item['author-link'] . ']' . $item['author-name'] . '[/url]';
    $plink = '[url=' . $item['plink'] . ']' . $post_type . '[/url]';
    $arr['body'] = sprintf($bodyverb, $ulink, $alink, $plink, $termlink);
    $arr['verb'] = ACTIVITY_TAG;
    $arr['target-type'] = $targettype;
    $arr['target'] = $target;
    $arr['object-type'] = $objtype;
    $arr['object'] = $obj;
    $arr['allow_cid'] = $item['allow_cid'];
    $arr['allow_gid'] = $item['allow_gid'];
    $arr['deny_cid'] = $item['deny_cid'];
    $arr['deny_gid'] = $item['deny_gid'];
    $arr['visible'] = 1;
    $arr['unseen'] = 1;
    $arr['last-child'] = 1;
    $arr['origin'] = 1;
    $post_id = item_store($arr);
    q("UPDATE `item` set plink = '%s' where id = %d limit 1", dbesc($a->get_baseurl() . '/display/' . $owner_nick . '/' . $post_id), intval($post_id));
    if (!$item['visible']) {
        $r = q("UPDATE `item` SET `visible` = 1 WHERE `id` = %d AND `uid` = %d LIMIT 1", intval($item['id']), intval($owner_uid));
    }
    if (!$blocktags && !stristr($item['tag'], ']' . $term . '[')) {
        q("update item set tag = '%s' where id = %d limit 1", dbesc($item['tag'] . (strlen($item['tag']) ? ',' : '') . '#[url=' . $a->get_baseurl() . '/search?search=' . $term . ']' . $term . '[/url]'), intval($item['id']));
    }
    // if the original post is on this site, update it.
    $r = q("select `tag`,`id`,`uid` from item where `origin` = 1 AND `uri` = '%s' LIMIT 1", dbesc($item['uri']));
    if (count($r)) {
        $x = q("SELECT `blocktags` FROM `user` WHERE `uid` = %d limit 1", intval($r[0]['uid']));
        if (count($x) && !$x[0]['blocktags'] && !stristr($r[0]['tag'], ']' . $term . '[')) {
            q("update item set tag = '%s' where id = %d limit 1", dbesc($r[0]['tag'] . (strlen($r[0]['tag']) ? ',' : '') . '#[url=' . $a->get_baseurl() . '/search?search=' . $term . ']' . $term . '[/url]'), intval($r[0]['id']));
        }
    }
    $arr['id'] = $post_id;
    call_hooks('post_local_end', $arr);
    proc_run('php', "include/notifier.php", "tag", "{$post_id}");
    killme();
    return;
    // NOTREACHED
}
Пример #6
0
function fbsync_createlike($a, $uid, $self_id, $self, $contacts, $like)
{
    $r = q("SELECT * FROM `item` WHERE `uri` = '%s' AND `uid` = %d LIMIT 1", dbesc("fb::" . $like->post_id), intval($uid));
    if (count($r)) {
        $orig_post = $r[0];
    } else {
        return;
    }
    // If we posted the like locally, it will be found with our url, not the FB url.
    $second_url = $like->user_id == $self_id ? $self[0]["url"] : $contacts[$like->user_id]->url;
    $r = q("SELECT * FROM `item` WHERE `parent-uri` = '%s' AND `uid` = %d AND `verb` = '%s'\n\t\tAND (`author-link` = '%s' OR `author-link` = '%s') LIMIT 1", dbesc($orig_post["uri"]), intval($uid), dbesc(ACTIVITY_LIKE), dbesc($contacts[$like->user_id]->url), dbesc($second_url));
    if (count($r)) {
        return;
    }
    $contact_id = fbsync_fetch_contact($uid, $contacts[$like->user_id], array(), false);
    if ($contact_id <= 0) {
        $contact_id = $self[0]["id"];
    }
    $likedata = array();
    $likedata['parent'] = $orig_post['id'];
    $likedata['verb'] = ACTIVITY_LIKE;
    $likedata['object-type'] = ACTIVITY_OBJ_NOTE;
    $likedate['network'] = dbesc(NETWORK_FACEBOOK);
    $likedata['gravity'] = 3;
    $likedata['uid'] = $uid;
    $likedata['wall'] = 0;
    $likedata['uri'] = item_new_uri($a->get_baseurl(), $uid);
    $likedata['parent-uri'] = $orig_post["uri"];
    $likedata['app'] = "Facebook";
    if ($like->user_id != $self_id) {
        $likedata['contact-id'] = $contact_id;
        $likedata['author-name'] = $contacts[$like->user_id]->name;
        $likedata['author-link'] = $contacts[$like->user_id]->url;
        $likedata['author-avatar'] = $contacts[$like->user_id]->pic_square;
    } else {
        $likedata['contact-id'] = $self[0]["id"];
        $likedata['author-name'] = $self[0]["name"];
        $likedata['author-link'] = $self[0]["url"];
        $likedata['author-avatar'] = $self[0]["photo"];
    }
    $author = '[url=' . $likedata['author-link'] . ']' . $likedata['author-name'] . '[/url]';
    $objauthor = '[url=' . $orig_post['author-link'] . ']' . $orig_post['author-name'] . '[/url]';
    $post_type = t('status');
    $plink = '[url=' . $orig_post['plink'] . ']' . $post_type . '[/url]';
    $likedata['object-type'] = ACTIVITY_OBJ_NOTE;
    $likedata['body'] = sprintf(t('%1$s likes %2$s\'s %3$s'), $author, $objauthor, $plink);
    $likedata['object'] = '<object><type>' . ACTIVITY_OBJ_NOTE . '</type><local>1</local>' . '<id>' . $orig_post['uri'] . '</id><link>' . xmlify('<link rel="alternate" type="text/html" href="' . xmlify($orig_post['plink']) . '" />') . '</link><title>' . $orig_post['title'] . '</title><content>' . $orig_post['body'] . '</content></object>';
    $r = q("SELECT * FROM `item` WHERE `parent-uri` = '%s' AND `author-link` = '%s' AND `verb` = '%s' AND `uid` = %d LIMIT 1", dbesc($likedata['parent-uri']), dbesc($likedata['author-link']), dbesc(ACTIVITY_LIKE), intval($uid));
    if (count($r)) {
        return;
    }
    $item = item_store($likedata);
    logger('fbsync_createlike: liked item ' . $item . '. User ' . $self[0]["nick"], LOGGER_DEBUG);
}
Пример #7
0
function item_post(&$a)
{
    if (!local_user() && !remote_user()) {
        return;
    }
    require_once 'include/security.php';
    $uid = local_user();
    if (x($_POST, 'dropitems')) {
        require_once 'include/items.php';
        $arr_drop = explode(',', $_POST['dropitems']);
        drop_items($arr_drop);
        $json = array('success' => 1);
        echo json_encode($json);
        killme();
    }
    call_hooks('post_local_start', $_POST);
    $api_source = x($_POST, 'api_source') && $_POST['api_source'] ? true : false;
    $return_path = x($_POST, 'return') ? $_POST['return'] : '';
    /**
     * Is this a reply to something?
     */
    $parent = x($_POST, 'parent') ? intval($_POST['parent']) : 0;
    $parent_uri = x($_POST, 'parent_uri') ? trim($_POST['parent_uri']) : '';
    $parent_item = null;
    $parent_contact = null;
    $thr_parent = '';
    $parid = 0;
    $r = false;
    $preview = x($_POST, 'preview') ? intval($_POST['preview']) : 0;
    if ($parent || $parent_uri) {
        if (!x($_POST, 'type')) {
            $_POST['type'] = 'net-comment';
        }
        if ($parent) {
            $r = q("SELECT * FROM `item` WHERE `id` = %d LIMIT 1", intval($parent));
        } elseif ($parent_uri && local_user()) {
            // This is coming from an API source, and we are logged in
            $r = q("SELECT * FROM `item` WHERE `uri` = '%s' AND `uid` = %d LIMIT 1", dbesc($parent_uri), intval(local_user()));
        }
        // if this isn't the real parent of the conversation, find it
        if ($r !== false && count($r)) {
            $parid = $r[0]['parent'];
            if ($r[0]['id'] != $r[0]['parent']) {
                $r = q("SELECT * FROM `item` WHERE `id` = `parent` AND `parent` = %d LIMIT 1", intval($parid));
            }
        }
        if ($r === false || !count($r)) {
            notice(t('Unable to locate original post.') . EOL);
            if (x($_POST, 'return')) {
                goaway($a->get_baseurl() . "/" . $return_path);
            }
            killme();
        }
        $parent_item = $r[0];
        $parent = $r[0]['id'];
        // multi-level threading - preserve the info but re-parent to our single level threading
        if ($parid && $parid != $parent) {
            $thr_parent = $parent_uri;
        }
        if ($parent_item['contact-id'] && $uid) {
            $r = q("SELECT * FROM `contact` WHERE `id` = %d AND `uid` = %d LIMIT 1", intval($parent_item['contact-id']), intval($uid));
            if (count($r)) {
                $parent_contact = $r[0];
            }
        }
    }
    if ($parent) {
        logger('mod_post: parent=' . $parent);
    }
    $profile_uid = x($_POST, 'profile_uid') ? intval($_POST['profile_uid']) : 0;
    $post_id = x($_POST['post_id']) ? intval($_POST['post_id']) : 0;
    $app = x($_POST['source']) ? strip_tags($_POST['source']) : '';
    if (!can_write_wall($a, $profile_uid)) {
        notice(t('Permission denied.') . EOL);
        if (x($_POST, 'return')) {
            goaway($a->get_baseurl() . "/" . $return_path);
        }
        killme();
    }
    // is this an edited post?
    $orig_post = null;
    if ($post_id) {
        $i = q("SELECT * FROM `item` WHERE `uid` = %d AND `id` = %d LIMIT 1", intval($profile_uid), intval($post_id));
        if (!count($i)) {
            killme();
        }
        $orig_post = $i[0];
    }
    $user = null;
    $r = q("SELECT * FROM `user` WHERE `uid` = %d LIMIT 1", intval($profile_uid));
    if (count($r)) {
        $user = $r[0];
    }
    if ($orig_post) {
        $str_group_allow = $orig_post['allow_gid'];
        $str_contact_allow = $orig_post['allow_cid'];
        $str_group_deny = $orig_post['deny_gid'];
        $str_contact_deny = $orig_post['deny_cid'];
        $title = $orig_post['title'];
        $location = $orig_post['location'];
        $coord = $orig_post['coord'];
        $verb = $orig_post['verb'];
        $emailcc = $orig_post['emailcc'];
        $app = $orig_post['app'];
        $body = escape_tags(trim($_POST['body']));
        $private = $orig_post['private'];
        $pubmail_enable = $orig_post['pubmail'];
    } else {
        $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']);
        $title = notags(trim($_POST['title']));
        $location = notags(trim($_POST['location']));
        $coord = notags(trim($_POST['coord']));
        $verb = notags(trim($_POST['verb']));
        $emailcc = notags(trim($_POST['emailcc']));
        $body = escape_tags(trim($_POST['body']));
        $private = strlen($str_group_allow) || strlen($str_contact_allow) || strlen($str_group_deny) || strlen($str_contact_deny) ? 1 : 0;
        if ($parent_item && ($parent_item['private'] || strlen($parent_item['allow_cid']) || strlen($parent_item['allow_gid']) || strlen($parent_item['deny_cid']) || strlen($parent_item['deny_gid']))) {
            $private = 1;
        }
        $pubmail_enable = x($_POST, 'pubmail_enable') && intval($_POST['pubmail_enable']) && !$private ? 1 : 0;
        // if using the API, we won't see pubmail_enable - figure out if it should be set
        if ($api_source && $profile_uid && $profile_uid == local_user() && !$private) {
            $mail_disabled = function_exists('imap_open') && !get_config('system', 'imap_disabled') ? 0 : 1;
            if (!$mail_disabled) {
                $r = q("SELECT * FROM `mailacct` WHERE `uid` = %d AND `server` != '' LIMIT 1", intval(local_user()));
                if (count($r) && intval($r[0]['pubmail'])) {
                    $pubmail_enabled = true;
                }
            }
        }
        if (!strlen($body)) {
            info(t('Empty post discarded.') . EOL);
            if (x($_POST, 'return')) {
                goaway($a->get_baseurl() . "/" . $return_path);
            }
            killme();
        }
    }
    if ($api_source && !array_key_exists('allow_cid', $_REQUEST) && !array_key_exists('allow_gid', $_REQUEST) && !array_key_exists('deny_cid', $_REQUEST) && !array_key_exists('deny_gid', $_REQUEST)) {
        $str_group_allow = $user['allow_gid'];
        $str_contact_allow = $user['allow_cid'];
        $str_group_deny = $user['deny_gid'];
        $str_contact_deny = $user['deny_cid'];
    }
    // get contact info for poster
    $author = null;
    $self = false;
    if ($_SESSION['uid'] && $_SESSION['uid'] == $profile_uid) {
        $self = true;
        $r = q("SELECT * FROM `contact` WHERE `uid` = %d AND `self` = 1 LIMIT 1", intval($_SESSION['uid']));
    } else {
        if (x($_SESSION, 'visitor_id') && intval($_SESSION['visitor_id'])) {
            $r = q("SELECT * FROM `contact` WHERE `id` = %d LIMIT 1", intval($_SESSION['visitor_id']));
        }
    }
    if (count($r)) {
        $author = $r[0];
        $contact_id = $author['id'];
    }
    // get contact info for owner
    if ($profile_uid == $_SESSION['uid']) {
        $contact_record = $author;
    } else {
        $r = q("SELECT * FROM `contact` WHERE `uid` = %d AND `self` = 1 LIMIT 1", intval($profile_uid));
        if (count($r)) {
            $contact_record = $r[0];
        }
    }
    $post_type = notags(trim($_POST['type']));
    if ($post_type === 'net-comment') {
        if ($parent_item !== null) {
            if ($parent_item['wall'] == 1) {
                $post_type = 'wall-comment';
            } else {
                $post_type = 'remote-comment';
            }
        }
    }
    /**
     *
     * When a photo was uploaded into the message using the (profile wall) ajax 
     * uploader, The permissions are initially set to disallow anybody but the
     * owner from seeing it. This is because the permissions may not yet have been
     * set for the post. If it's private, the photo permissions should be set
     * appropriately. But we didn't know the final permissions on the post until
     * now. So now we'll look for links of uploaded messages that are in the
     * post and set them to the same permissions as the post itself.
     *
     */
    $match = null;
    if (!$preview && preg_match_all("/\\[img\\](.*?)\\[\\/img\\]/", $body, $match)) {
        $images = $match[1];
        if (count($images)) {
            foreach ($images as $image) {
                if (!stristr($image, $a->get_baseurl() . '/photo/')) {
                    continue;
                }
                $image_uri = substr($image, strrpos($image, '/') + 1);
                $image_uri = substr($image_uri, 0, strpos($image_uri, '-'));
                if (!strlen($image_uri)) {
                    continue;
                }
                $srch = '<' . intval($profile_uid) . '>';
                $r = q("SELECT `id` FROM `photo` WHERE `allow_cid` = '%s' AND `allow_gid` = '' AND `deny_cid` = '' AND `deny_gid` = ''\n\t\t\t\t\tAND `resource-id` = '%s' AND `uid` = %d LIMIT 1", dbesc($srch), dbesc($image_uri), intval($profile_uid));
                if (!count($r)) {
                    continue;
                }
                $r = q("UPDATE `photo` SET `allow_cid` = '%s', `allow_gid` = '%s', `deny_cid` = '%s', `deny_gid` = '%s'\n\t\t\t\t\tWHERE `resource-id` = '%s' AND `uid` = %d AND `album` = '%s' ", dbesc($str_contact_allow), dbesc($str_group_allow), dbesc($str_contact_deny), dbesc($str_group_deny), dbesc($image_uri), intval($profile_uid), dbesc(t('Wall Photos')));
            }
        }
    }
    /**
     * Next link in any attachment references we find in the post.
     */
    $match = false;
    if (!$preview && preg_match_all("/\\[attachment\\](.*?)\\[\\/attachment\\]/", $body, $match)) {
        $attaches = $match[1];
        if (count($attaches)) {
            foreach ($attaches as $attach) {
                $r = q("SELECT * FROM `attach` WHERE `uid` = %d AND `id` = %d LIMIT 1", intval($profile_uid), intval($attach));
                if (count($r)) {
                    $r = q("UPDATE `attach` SET `allow_cid` = '%s', `allow_gid` = '%s', `deny_cid` = '%s', `deny_gid` = '%s'\n\t\t\t\t\t\tWHERE `uid` = %d AND `id` = %d LIMIT 1", dbesc($str_contact_allow), dbesc($str_group_allow), dbesc($str_contact_deny), dbesc($str_group_deny), intval($profile_uid), intval($attach));
                }
            }
        }
    }
    // embedded bookmark in post? set bookmark flag
    $bookmark = 0;
    if (preg_match_all("/\\[bookmark\\=([^\\]]*)\\](.*?)\\[\\/bookmark\\]/ism", $body, $match, PREG_SET_ORDER)) {
        $bookmark = 1;
    }
    $body = bb_translate_video($body);
    /**
     * Fold multi-line [code] sequences
     */
    $body = preg_replace('/\\[\\/code\\]\\s*\\[code\\]/ism', "\n", $body);
    /**
     * Look for any tags and linkify them
     */
    $str_tags = '';
    $inform = '';
    $tags = get_tags($body);
    /**
     * add a statusnet style reply tag if the original post was from there
     * and we are replying, and there isn't one already
     */
    if ($parent_contact && $parent_contact['network'] === NETWORK_OSTATUS && $parent_contact['nick'] && !in_array('@' . $parent_contact['nick'], $tags)) {
        $body = '@' . $parent_contact['nick'] . ' ' . $body;
        $tags[] = '@' . $parent_contact['nick'];
    }
    if (count($tags)) {
        foreach ($tags as $tag) {
            if (isset($profile)) {
                unset($profile);
            }
            if (strpos($tag, '#') === 0) {
                if (strpos($tag, '[url=')) {
                    continue;
                }
                $basetag = str_replace('_', ' ', substr($tag, 1));
                $body = str_replace($tag, '#[url=' . $a->get_baseurl() . '/search?search=' . rawurlencode($basetag) . ']' . $basetag . '[/url]', $body);
                $newtag = '#[url=' . $a->get_baseurl() . '/search?search=' . rawurlencode($basetag) . ']' . $basetag . '[/url]';
                if (!stristr($str_tags, $newtag)) {
                    if (strlen($str_tags)) {
                        $str_tags .= ',';
                    }
                    $str_tags .= $newtag;
                }
                continue;
            }
            if (strpos($tag, '@') === 0) {
                if (strpos($tag, '[url=')) {
                    continue;
                }
                $stat = false;
                $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') {
                                if (strlen($inform)) {
                                    $inform .= ',';
                                }
                                $inform .= 'url:' . str_replace(',', '%2c', $link['@attributes']['href']);
                            }
                        }
                    }
                } else {
                    $newname = $name;
                    $alias = '';
                    $tagcid = 0;
                    if (strrpos($newname, '+')) {
                        $tagcid = intval(substr($newname, strrpos($newname, '+') + 1));
                        if (strpos($name, ' ')) {
                            $name = substr($name, 0, strpos($name, ' '));
                        }
                    }
                    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($profile_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($profile_uid));
                    }
                    if (count($r)) {
                        $profile = $r[0]['url'];
                        if ($r[0]['network'] === 'stat') {
                            $newname = $r[0]['nick'];
                            $stat = true;
                            if ($r[0]['alias']) {
                                $alias = $r[0]['alias'];
                            }
                        } else {
                            $newname = $r[0]['name'];
                        }
                        if (strlen($inform)) {
                            $inform .= ',';
                        }
                        $inform .= 'cid:' . $r[0]['id'];
                    }
                }
                if ($profile) {
                    $body = str_replace('@' . $name, '@' . '[url=' . $profile . ']' . $newname . '[/url]', $body);
                    $profile = str_replace(',', '%2c', $profile);
                    $newtag = '@[url=' . $profile . ']' . $newname . '[/url]';
                    if (!stristr($str_tags, $newtag)) {
                        if (strlen($str_tags)) {
                            $str_tags .= ',';
                        }
                        $str_tags .= $newtag;
                    }
                    // Status.Net seems to require the numeric ID URL in a mention if the person isn't
                    // subscribed to you. But the nickname URL is OK if they are. Grrr. We'll tag both.
                    if (strlen($alias)) {
                        $newtag = '@[url=' . $alias . ']' . $newname . '[/url]';
                        if (!stristr($str_tags, $newtag)) {
                            if (strlen($str_tags)) {
                                $str_tags .= ',';
                            }
                            $str_tags .= $newtag;
                        }
                    }
                }
            }
        }
    }
    $attachments = '';
    $match = false;
    if (preg_match_all('/(\\[attachment\\]([0-9]+)\\[\\/attachment\\])/', $body, $match)) {
        foreach ($match[2] as $mtch) {
            $r = q("SELECT `id`,`filename`,`filesize`,`filetype` FROM `attach` WHERE `uid` = %d AND `id` = %d LIMIT 1", intval($profile_uid), intval($mtch));
            if (count($r)) {
                if (strlen($attachments)) {
                    $attachments .= ',';
                }
                $attachments .= '[attach]href="' . $a->get_baseurl() . '/attach/' . $r[0]['id'] . '" length="' . $r[0]['filesize'] . '" type="' . $r[0]['filetype'] . '" title="' . ($r[0]['filename'] ? $r[0]['filename'] : '') . '"[/attach]';
            }
            $body = str_replace($match[1], '', $body);
        }
    }
    $wall = 0;
    if ($post_type === 'wall' || $post_type === 'wall-comment') {
        $wall = 1;
    }
    if (!strlen($verb)) {
        $verb = ACTIVITY_POST;
    }
    $gravity = $parent ? 6 : 0;
    // even if the post arrived via API we are considering that it
    // originated on this site by default for determining relayability.
    $origin = x($_REQUEST, 'origin') ? intval($_REQUEST['origin']) : 1;
    $notify_type = $parent ? 'comment-new' : 'wall-new';
    $uri = item_new_uri($a->get_hostname(), $profile_uid);
    $datarray = array();
    $datarray['uid'] = $profile_uid;
    $datarray['type'] = $post_type;
    $datarray['wall'] = $wall;
    $datarray['gravity'] = $gravity;
    $datarray['contact-id'] = $contact_id;
    $datarray['owner-name'] = $contact_record['name'];
    $datarray['owner-link'] = $contact_record['url'];
    $datarray['owner-avatar'] = $contact_record['thumb'];
    $datarray['author-name'] = $author['name'];
    $datarray['author-link'] = $author['url'];
    $datarray['author-avatar'] = $author['thumb'];
    $datarray['created'] = datetime_convert();
    $datarray['edited'] = datetime_convert();
    $datarray['commented'] = datetime_convert();
    $datarray['received'] = datetime_convert();
    $datarray['changed'] = datetime_convert();
    $datarray['uri'] = $uri;
    $datarray['title'] = $title;
    $datarray['body'] = $body;
    $datarray['app'] = $app;
    $datarray['location'] = $location;
    $datarray['coord'] = $coord;
    $datarray['tag'] = $str_tags;
    $datarray['inform'] = $inform;
    $datarray['verb'] = $verb;
    $datarray['allow_cid'] = $str_contact_allow;
    $datarray['allow_gid'] = $str_group_allow;
    $datarray['deny_cid'] = $str_contact_deny;
    $datarray['deny_gid'] = $str_group_deny;
    $datarray['private'] = $private;
    $datarray['pubmail'] = $pubmail_enable;
    $datarray['attach'] = $attachments;
    $datarray['bookmark'] = intval($bookmark);
    $datarray['thr-parent'] = $thr_parent;
    $datarray['postopts'] = '';
    $datarray['origin'] = $origin;
    /**
     * These fields are for the convenience of plugins...
     * 'self' if true indicates the owner is posting on their own wall
     * If parent is 0 it is a top-level post.
     */
    $datarray['parent'] = $parent;
    $datarray['self'] = $self;
    //	$datarray['prvnets']       = $user['prvnets'];
    if ($orig_post) {
        $datarray['edit'] = true;
    } else {
        $datarray['guid'] = get_guid();
    }
    // preview mode - prepare the body for display and send it via json
    if ($preview) {
        require_once 'include/conversation.php';
        $o = conversation(&$a, array(array_merge($contact_record, $datarray)), 'search', false, true);
        echo json_encode(array('preview' => $o));
        killme();
    }
    call_hooks('post_local', $datarray);
    if ($orig_post) {
        $r = q("UPDATE `item` SET `body` = '%s', `edited` = '%s' WHERE `id` = %d AND `uid` = %d LIMIT 1", dbesc($body), dbesc(datetime_convert()), intval($post_id), intval($profile_uid));
        proc_run('php', "include/notifier.php", 'edit_post', "{$post_id}");
        if (x($_POST, 'return') && strlen($return_path)) {
            logger('return: ' . $return_path);
            goaway($a->get_baseurl() . "/" . $return_path);
        }
        killme();
    } else {
        $post_id = 0;
    }
    $r = q("INSERT INTO `item` (`guid`, `uid`,`type`,`wall`,`gravity`,`contact-id`,`owner-name`,`owner-link`,`owner-avatar`, \n\t\t`author-name`, `author-link`, `author-avatar`, `created`, `edited`, `commented`, `received`, `changed`, `uri`, `thr-parent`, `title`, `body`, `app`, `location`, `coord`, \n\t\t`tag`, `inform`, `verb`, `postopts`, `allow_cid`, `allow_gid`, `deny_cid`, `deny_gid`, `private`, `pubmail`, `attach`, `bookmark`,`origin` )\n\t\tVALUES( '%s', %d, '%s', %d, %d, %d, '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', %d, %d, '%s', %d, %d )", dbesc($datarray['guid']), intval($datarray['uid']), dbesc($datarray['type']), intval($datarray['wall']), intval($datarray['gravity']), intval($datarray['contact-id']), dbesc($datarray['owner-name']), dbesc($datarray['owner-link']), dbesc($datarray['owner-avatar']), dbesc($datarray['author-name']), dbesc($datarray['author-link']), dbesc($datarray['author-avatar']), dbesc($datarray['created']), dbesc($datarray['edited']), dbesc($datarray['commented']), dbesc($datarray['received']), dbesc($datarray['changed']), dbesc($datarray['uri']), dbesc($datarray['thr-parent']), dbesc($datarray['title']), dbesc($datarray['body']), dbesc($datarray['app']), dbesc($datarray['location']), dbesc($datarray['coord']), dbesc($datarray['tag']), dbesc($datarray['inform']), dbesc($datarray['verb']), dbesc($datarray['postopts']), dbesc($datarray['allow_cid']), dbesc($datarray['allow_gid']), dbesc($datarray['deny_cid']), dbesc($datarray['deny_gid']), intval($datarray['private']), intval($datarray['pubmail']), dbesc($datarray['attach']), intval($datarray['bookmark']), intval($datarray['origin']));
    $r = q("SELECT `id` FROM `item` WHERE `uri` = '%s' LIMIT 1", dbesc($datarray['uri']));
    if (count($r)) {
        $post_id = $r[0]['id'];
        logger('mod_item: saved item ' . $post_id);
        if ($parent) {
            // This item is the last leaf and gets the comment box, clear any ancestors
            $r = q("UPDATE `item` SET `last-child` = 0, `changed` = '%s' WHERE `parent` = %d ", dbesc(datetime_convert()), intval($parent));
            // Inherit ACL's from the parent item.
            $r = q("UPDATE `item` SET `allow_cid` = '%s', `allow_gid` = '%s', `deny_cid` = '%s', `deny_gid` = '%s', `private` = %d\n\t\t\t\tWHERE `id` = %d LIMIT 1", dbesc($parent_item['allow_cid']), dbesc($parent_item['allow_gid']), dbesc($parent_item['deny_cid']), dbesc($parent_item['deny_gid']), intval($parent_item['private']), intval($post_id));
            if ($contact_record != $author) {
                notification(array('type' => NOTIFY_COMMENT, 'notify_flags' => $user['notify-flags'], 'language' => $user['language'], 'to_name' => $user['username'], 'to_email' => $user['email'], 'item' => $datarray, 'link' => $a->get_baseurl() . '/display/' . $user['nickname'] . '/' . $post_id, 'source_name' => $datarray['author-name'], 'source_link' => $datarray['author-link'], 'source_photo' => $datarray['author-avatar'], 'verb' => ACTIVITY_POST, 'otype' => 'item'));
            }
            // We won't be able to sign Diaspora comments for authenticated visitors - we don't have their private key
            if ($self) {
                require_once 'include/bb2diaspora.php';
                $signed_body = html_entity_decode(bb2diaspora($datarray['body']));
                $myaddr = $a->user['nickname'] . '@' . substr($a->get_baseurl(), strpos($a->get_baseurl(), '://') + 3);
                if ($datarray['verb'] === ACTIVITY_LIKE) {
                    $signed_text = $datarray['guid'] . ';' . 'Post' . ';' . $parent_item['guid'] . ';' . 'true' . ';' . $myaddr;
                } else {
                    $signed_text = $datarray['guid'] . ';' . $parent_item['guid'] . ';' . $signed_body . ';' . $myaddr;
                }
                $authorsig = base64_encode(rsa_sign($signed_text, $a->user['prvkey'], 'sha256'));
                q("insert into sign (`iid`,`signed_text`,`signature`,`signer`) values (%d,'%s','%s','%s') ", intval($post_id), dbesc($signed_text), dbesc(base64_encode($authorsig)), dbesc($myaddr));
            }
        } else {
            $parent = $post_id;
            if ($contact_record != $author) {
                notification(array('type' => NOTIFY_WALL, 'notify_flags' => $user['notify-flags'], 'language' => $user['language'], 'to_name' => $user['username'], 'to_email' => $user['email'], 'item' => $datarray, 'link' => $a->get_baseurl() . '/display/' . $user['nickname'] . '/' . $post_id, 'source_name' => $datarray['author-name'], 'source_link' => $datarray['author-link'], 'source_photo' => $datarray['author-avatar'], 'verb' => ACTIVITY_POST, 'otype' => 'item'));
            }
        }
        // fallback so that parent always gets set to non-zero.
        if (!$parent) {
            $parent = $post_id;
        }
        $r = q("UPDATE `item` SET `parent` = %d, `parent-uri` = '%s', `plink` = '%s', `changed` = '%s', `last-child` = 1, `visible` = 1\n\t\t\tWHERE `id` = %d LIMIT 1", intval($parent), dbesc($parent == $post_id ? $uri : $parent_item['uri']), dbesc($a->get_baseurl() . '/display/' . $user['nickname'] . '/' . $post_id), dbesc(datetime_convert()), intval($post_id));
        // photo comments turn the corresponding item visible to the profile wall
        // This way we don't see every picture in your new photo album posted to your wall at once.
        // They will show up as people comment on them.
        if (!$parent_item['visible']) {
            $r = q("UPDATE `item` SET `visible` = 1 WHERE `id` = %d LIMIT 1", intval($parent_item['id']));
        }
    } else {
        logger('mod_item: unable to retrieve post that was just stored.');
        notify(t('System error. Post not saved.'));
        goaway($a->get_baseurl() . "/" . $return_path);
        // NOTREACHED
    }
    // update the commented timestamp on the parent
    q("UPDATE `item` set `commented` = '%s', `changed` = '%s' WHERE `id` = %d LIMIT 1", dbesc(datetime_convert()), dbesc(datetime_convert()), intval($parent));
    $datarray['id'] = $post_id;
    $datarray['plink'] = $a->get_baseurl() . '/display/' . $user['nickname'] . '/' . $post_id;
    call_hooks('post_local_end', $datarray);
    if (strlen($emailcc) && $profile_uid == local_user()) {
        $erecips = explode(',', $emailcc);
        if (count($erecips)) {
            foreach ($erecips as $recip) {
                $addr = trim($recip);
                if (!strlen($addr)) {
                    continue;
                }
                $disclaimer = '<hr />' . sprintf(t('This message was sent to you by %s, a member of the Friendica social network.'), $a->user['username']) . '<br />';
                $disclaimer .= sprintf(t('You may visit them online at %s'), $a->get_baseurl() . '/profile/' . $a->user['nickname']) . EOL;
                $disclaimer .= t('Please contact the sender by replying to this post if you do not wish to receive these messages.') . EOL;
                $subject = '[Friendica]' . ' ' . sprintf(t('%s posted an update.'), $a->user['username']);
                $headers = 'From: ' . $a->user['username'] . ' <' . $a->user['email'] . '>' . "\n";
                $headers .= 'MIME-Version: 1.0' . "\n";
                $headers .= 'Content-Type: text/html; charset=UTF-8' . "\n";
                $headers .= 'Content-Transfer-Encoding: 8bit' . "\n\n";
                $link = '<a href="' . $a->get_baseurl() . '/profile/' . $a->user['nickname'] . '"><img src="' . $author['thumb'] . '" alt="' . $a->user['username'] . '" /></a><br /><br />';
                $html = prepare_body($datarray);
                $message = '<html><body>' . $link . $html . $disclaimer . '</body></html>';
                @mail($addr, $subject, $message, $headers);
            }
        }
    }
    // This is a real juggling act on shared hosting services which kill your processes
    // e.g. dreamhost. We used to start delivery to our native delivery agents in the background
    // and then run our plugin delivery from the foreground. We're now doing plugin delivery first,
    // because as soon as you start loading up a bunch of remote delivey processes, *this* page is
    // likely to get killed off. If you end up looking at an /item URL and a blank page,
    // it's very likely the delivery got killed before all your friends could be notified.
    // Currently the only realistic fixes are to use a reliable server - which precludes shared hosting,
    // or cut back on plugins which do remote deliveries.
    proc_run('php', "include/notifier.php", $notify_type, "{$post_id}");
    logger('post_complete');
    // figure out how to return, depending on from whence we came
    if ($api_source) {
        return;
    }
    if ($return_path) {
        goaway($a->get_baseurl() . "/" . $return_path);
    }
    $json = array('success' => 1);
    if (x($_POST, 'jsreload') && strlen($_POST['jsreload'])) {
        $json['reload'] = $a->get_baseurl() . '/' . $_POST['jsreload'];
    }
    logger('post_json: ' . print_r($json, true), LOGGER_DEBUG);
    echo json_encode($json);
    killme();
    // NOTREACHED
}
Пример #8
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
}
Пример #9
0
function photos_post(&$a)
{
    if (!local_user()) {
        notice(t('Permission denied.') . EOL);
        killme();
    }
    $r = q("SELECT `contact`.*, `user`.`nickname` FROM `contact` LEFT JOIN `user` ON `user`.`uid` = 1  WHERE `self` = 1 LIMIT 1");
    $contact_record = $r[0];
    if ($a->argc > 2 && $a->argv[1] == 'album') {
        $album = hex2bin($a->argv[2]);
        if ($album == t('Profile Photos') || $album == t('Contact Photos')) {
            goaway($a->get_baseurl() . '/' . $_SESSION['photo_return']);
            return;
            // NOTREACHED
        }
        $r = q("SELECT count(*) FROM `photo` WHERE `album` = '%s' ", dbesc($album));
        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' ", dbesc($newalbum), dbesc($album));
            $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();
            $r = q("SELECT distinct(`resource-id`) as `rid` FROM `photo` WHERE `album` = '%s'", 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);
            q("DELETE FROM `photo` WHERE `resource-id` IN ( {$str_res} ) ");
            $r = q("SELECT `parent-uri` FROM `item` WHERE `resource-id` IN ( {$str_res} ) ");
            if (count($r)) {
                foreach ($r as $rr) {
                    q("UPDATE `item` SET `deleted` = 1, `changed` = '%s' WHERE `parent-uri` = '%s' ", dbesc(datetime_convert()), dbesc($rr['parent-uri']));
                    $drop_id = intval($rr['id']);
                    $php_path = strlen($a->config['php_path']) ? $a->config['php_path'] : 'php';
                    // send the notification upstream/downstream as the case may be
                    if ($rr['visible']) {
                        proc_close(proc_open("\"{$php_path}\" \"include/notifier.php\" \"drop\" \"{$drop_id}\" & ", array(), $foo));
                    }
                }
            }
        }
        goaway($a->get_baseurl() . '/photos/' . $a->data['user']['nickname']);
        return;
        // NOTREACHED
    }
    if ($a->argc > 1 && x($_POST, 'delete') && $_POST['delete'] == t('Delete Photo')) {
        $r = q("SELECT `id` FROM `photo` WHERE `resource-id` = '%s' LIMIT 1", dbesc($a->argv[1]));
        if (count($r)) {
            q("DELETE FROM `photo` WHERE `resource-id` = '%s'", dbesc($r[0]['resource-id']));
            $i = q("SELECT * FROM `item` WHERE `resource-id` = '%s' LIMIT 1", dbesc($r[0]['resource-id']));
            if (count($i)) {
                q("UPDATE `item` SET `deleted` = 1, `edited` = '%s', `changed` = '%s'  WHERE `parent-uri` = '%s' ", dbesc(datetime_convert()), dbesc(datetime_convert()), dbesc($i[0]['uri']));
                $drop_id = intval($i[0]['id']);
                $php_path = strlen($a->config['php_path']) ? $a->config['php_path'] : 'php';
                // send the notification upstream/downstream as the case may be
                if ($i[0]['visible']) {
                    proc_close(proc_open("\"{$php_path}\" \"include/notifier.php\" \"drop\" \"{$drop_id}\" & ", array(), $foo));
                }
            }
        }
        goaway($a->get_baseurl() . '/' . $_SESSION['photo_return']);
        return;
        // NOTREACHED
    }
    if ($a->argc > 1 && x($_POST, 'desc') !== false) {
        $desc = notags(trim($_POST['desc']));
        $tags = notags(trim($_POST['tags']));
        $item_id = intval($_POST['item_id']);
        $resource_id = $a->argv[1];
        $p = q("SELECT * FROM `photo` WHERE `resource-id` = '%s' ORDER BY `scale` DESC", dbesc($resource_id));
        if (count($r)) {
            $r = q("UPDATE `photo` SET `desc` = '%s' WHERE `resource-id` = '%s' ", dbesc($desc), dbesc($resource_id));
        }
        if (!$item_id) {
            $title = '';
            $basename = basename($filename);
            // Create item container
            $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]';
            $uri = item_new_uri($a->get_hostname(), get_uid());
            $r = q("INSERT INTO `item` (`type`, `wall`, `resource-id`, `contact-id`,\n\t\t\t\t`owner-name`,`owner-link`,`owner-avatar`, `created`,\n\t\t\t\t`edited`, `changed`, `uri`, `parent-uri`, `title`, `body`, `allow_cid`, `allow_gid`, `deny_cid`, `deny_gid`)\n\t\t\t\tVALUES( '%s', %d, '%s', %d, '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s' )", dbesc('photo'), intval(1), dbesc($p[0]['resource-id']), intval($contact_record['id']), dbesc($contact_record['name']), dbesc($contact_record['url']), dbesc($contact_record['thumb']), dbesc(datetime_convert()), dbesc(datetime_convert()), dbesc(datetime_convert()), dbesc($uri), dbesc($uri), dbesc($title), dbesc($body), dbesc($p[0]['allow_cid']), dbesc($p[0]['allow_gid']), dbesc($p[0]['deny_cid']), dbesc($p[0]['deny_gid']));
            if ($r) {
                $r = q("SELECT `id` FROM `item` WHERE `uri` = '%s' LIMIT 1", dbesc($uri));
                if (count($r)) {
                    $item_id = $r[0]['id'];
                }
                q("UPDATE `item` SET `parent` = %d, `last-child` = 1 WHERE `id` = %d LIMIT 1", intval($r[0]['id']), intval($r[0]['id']));
            }
        }
        $r = q("UPDATE `item` SET `tag` = '%s', `edited` = '%s', `changed` = '%s' WHERE `id` = %d LIMIT 1", dbesc($tags), dbesc(datetime_convert()), dbesc(datetime_convert()), intval($item_id));
        goaway($a->get_baseurl() . '/' . $_SESSION['photo_return']);
        return;
        // NOTREACHED
    }
    if (!x($_FILES, 'userfile')) {
        killme();
    }
    if ($_POST['partitionCount']) {
        $java_upload = true;
    } else {
        $java_upload = false;
    }
    $album = notags(trim($_POST['album']));
    $newalbum = notags(trim($_POST['newalbum']));
    if (!strlen($album)) {
        if (strlen($newalbum)) {
            $album = $newalbum;
        } else {
            $album = datetime_convert('UTC', date_default_timezone_get(), 'now', 'Y');
        }
    }
    $r = q("SELECT * FROM `photo` WHERE `album` = '%s' ", dbesc($album));
    if (!count($r) || $album == t('Profile Photos')) {
        $visible = 1;
    } else {
        $visibile = 0;
    }
    $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']);
    $src = $_FILES['userfile']['tmp_name'];
    $filename = basename($_FILES['userfile']['name']);
    $filesize = intval($_FILES['userfile']['size']);
    $imagedata = @file_get_contents($src);
    $ph = new Photo($imagedata);
    if (!($image = $ph->getImage())) {
        notice(t('Unable to process image.') . EOL);
        @unlink($src);
        killme();
    }
    @unlink($src);
    $width = $ph->getWidth();
    $height = $ph->getHeight();
    $smallest = 0;
    $photo_hash = hash('md5', uniqid(mt_rand(), true));
    $r = $ph->store(0, $photo_hash, $filename, $album, 0, 0, $str_contact_allow, $str_group_allow, $str_contact_deny, $str_group_deny);
    if (!$r) {
        notice(t('Image upload failed.') . EOL);
        killme();
    }
    if ($width > 640 || $height > 640) {
        $ph->scaleImage(640);
        $ph->store(0, $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(0, $photo_hash, $filename, $album, 2, 0, $str_contact_allow, $str_group_allow, $str_contact_deny, $str_group_deny);
        $smallest = 2;
    }
    $basename = basename($filename);
    // Create item container
    $body = '[url=' . $a->get_baseurl() . '/photos/' . $contact_record['nickname'] . '/image/' . $photo_hash . ']' . '[img]' . $a->get_baseurl() . "/photo/{$photo_hash}-{$smallest}.jpg" . '[/img]' . '[/url]';
    $uri = item_new_uri($a->get_hostname(), get_uid());
    $r = q("INSERT INTO `item` (`type`, `wall`, `resource-id`, `contact-id`,`owner-name`,`owner-link`,`owner-avatar`, `created`,\n\t\t`edited`, `changed`, `uri`, `parent-uri`, `title`, `body`, `allow_cid`, `allow_gid`, `deny_cid`, `deny_gid`, `visible`)\n\t\tVALUES( '%s', %d, '%s', %d, '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', %d )", dbesc('photo'), intval(1), dbesc($photo_hash), intval($contact_record['id']), dbesc($contact_record['name']), dbesc($contact_record['url']), dbesc($contact_record['thumb']), dbesc(datetime_convert()), dbesc(datetime_convert()), dbesc(datetime_convert()), dbesc($uri), dbesc($uri), dbesc($title), dbesc($body), dbesc($str_contact_allow), dbesc($str_group_allow), dbesc($str_contact_deny), dbesc($str_group_deny), intval($visible));
    if ($r) {
        $r = q("SELECT `id` FROM `item` WHERE `uri` = '%s' LIMIT 1", dbesc($uri));
        if (count($r)) {
            q("UPDATE `item` SET `parent` = %d, `last-child` = 1 WHERE `id` = %d LIMIT 1", intval($r[0]['id']), intval($r[0]['id']));
        }
    }
    if (!$java_upload) {
        goaway($a->get_baseurl() . '/' . $_SESSION['photo_return']);
        return;
        // NOTREACHED
    }
    killme();
    return;
    // NOTREACHED
}
Пример #10
0
function diaspora_request($importer, $xml)
{
    $a = get_app();
    $sender_handle = unxmlify($xml->sender_handle);
    $recipient_handle = unxmlify($xml->recipient_handle);
    if (!$sender_handle || !$recipient_handle) {
        return;
    }
    $contact = diaspora_get_contact_by_handle($importer['uid'], $sender_handle);
    if ($contact) {
        // perhaps we were already sharing with this person. Now they're sharing with us.
        // That makes us friends.
        if ($contact['rel'] == CONTACT_IS_FOLLOWER) {
            q("UPDATE `contact` SET `rel` = %d, `writable` = 1 WHERE `id` = %d AND `uid` = %d LIMIT 1", intval(CONTACT_IS_FRIEND), intval($contact['id']), intval($importer['uid']));
        }
        // send notification
        $r = q("SELECT `hide-friends` FROM `profile` WHERE `uid` = %d AND `is-default` = 1 LIMIT 1", intval($importer['uid']));
        if (count($r) && $r[0]['hide-friends'] == 0) {
            require_once 'include/items.php';
            $self = q("SELECT * FROM `contact` WHERE `self` = 1 AND `uid` = %d LIMIT 1", intval($importer['uid']));
            // they are not CONTACT_IS_FOLLOWER anymore but that's what we have in the array
            if (count($self) && $contact['rel'] == CONTACT_IS_FOLLOWER) {
                $arr = array();
                $arr['uri'] = $arr['parent-uri'] = item_new_uri($a->get_hostname(), $importer['uid']);
                $arr['uid'] = $importer['uid'];
                $arr['contact-id'] = $self[0]['id'];
                $arr['wall'] = 1;
                $arr['type'] = 'wall';
                $arr['gravity'] = 0;
                $arr['origin'] = 1;
                $arr['author-name'] = $arr['owner-name'] = $self[0]['name'];
                $arr['author-link'] = $arr['owner-link'] = $self[0]['url'];
                $arr['author-avatar'] = $arr['owner-avatar'] = $self[0]['thumb'];
                $arr['verb'] = ACTIVITY_FRIEND;
                $arr['object-type'] = ACTIVITY_OBJ_PERSON;
                $A = '[url=' . $self[0]['url'] . ']' . $self[0]['name'] . '[/url]';
                $B = '[url=' . $contact['url'] . ']' . $contact['name'] . '[/url]';
                $BPhoto = '[url=' . $contact['url'] . ']' . '[img]' . $contact['thumb'] . '[/img][/url]';
                $arr['body'] = sprintf(t('%1$s is now friends with %2$s'), $A, $B) . "\n\n\n" . $Bphoto;
                $arr['object'] = '<object><type>' . ACTIVITY_OBJ_PERSON . '</type><title>' . $contact['name'] . '</title>' . '<id>' . $contact['url'] . '/' . $contact['name'] . '</id>';
                $arr['object'] .= '<link>' . xmlify('<link rel="alternate" type="text/html" href="' . $contact['url'] . '" />' . "\n");
                $arr['object'] .= xmlify('<link rel="photo" type="image/jpeg" href="' . $contact['thumb'] . '" />' . "\n");
                $arr['object'] .= '</link></object>' . "\n";
                $arr['last-child'] = 1;
                $arr['allow_cid'] = $user[0]['allow_cid'];
                $arr['allow_gid'] = $user[0]['allow_gid'];
                $arr['deny_cid'] = $user[0]['deny_cid'];
                $arr['deny_gid'] = $user[0]['deny_gid'];
                $i = item_store($arr);
                if ($i) {
                    proc_run('php', "include/notifier.php", "activity", "{$i}");
                }
            }
        }
        return;
    }
    $ret = find_diaspora_person_by_handle($sender_handle);
    if (!count($ret) || $ret['network'] != NETWORK_DIASPORA) {
        logger('diaspora_request: Cannot resolve diaspora handle ' . $sender_handle . ' for ' . $recipient_handle);
        return;
    }
    $batch = $ret['batch'] ? $ret['batch'] : implode('/', array_slice(explode('/', $ret['url']), 0, 3)) . '/receive/public';
    $r = q("INSERT INTO `contact` (`uid`, `network`,`addr`,`created`,`url`,`nurl`,`batch`,`name`,`nick`,`photo`,`pubkey`,`notify`,`poll`,`blocked`,`priority`)\n\t\tVALUES ( %d, '%s', '%s', '%s', '%s','%s','%s','%s','%s','%s','%s','%s','%s',%d,%d) ", intval($importer['uid']), dbesc($ret['network']), dbesc($ret['addr']), datetime_convert(), dbesc($ret['url']), dbesc(normalise_link($ret['url'])), dbesc($batch), dbesc($ret['name']), dbesc($ret['nick']), dbesc($ret['photo']), dbesc($ret['pubkey']), dbesc($ret['notify']), dbesc($ret['poll']), 1, 2);
    // find the contact record we just created
    $contact_record = diaspora_get_contact_by_handle($importer['uid'], $sender_handle);
    $hash = random_string() . (string) time();
    // Generate a confirm_key
    if ($contact_record) {
        $ret = q("INSERT INTO `intro` ( `uid`, `contact-id`, `blocked`, `knowyou`, `note`, `hash`, `datetime` )\n\t\t\tVALUES ( %d, %d, %d, %d, '%s', '%s', '%s' )", intval($importer['uid']), intval($contact_record['id']), 0, 0, dbesc(t('Sharing notification from Diaspora network')), dbesc($hash), dbesc(datetime_convert()));
    }
    return;
}
Пример #11
0
function mood_init(&$a)
{
    if (!local_user()) {
        return;
    }
    $uid = local_user();
    $verb = notags(trim($_GET['verb']));
    if (!$verb) {
        return;
    }
    $verbs = get_mood_verbs();
    if (!in_array($verb, $verbs)) {
        return;
    }
    $activity = ACTIVITY_MOOD . '#' . urlencode($verb);
    $parent = x($_GET, 'parent') ? intval($_GET['parent']) : 0;
    logger('mood: verb ' . $verb, LOGGER_DEBUG);
    if ($parent) {
        $r = q("select uri, private, allow_cid, allow_gid, deny_cid, deny_gid\n\t\t\tfrom item where id = %d and parent = %d and uid = %d limit 1", intval($parent), intval($parent), intval($uid));
        if (count($r)) {
            $parent_uri = $r[0]['uri'];
            $private = $r[0]['private'];
            $allow_cid = $r[0]['allow_cid'];
            $allow_gid = $r[0]['allow_gid'];
            $deny_cid = $r[0]['deny_cid'];
            $deny_gid = $r[0]['deny_gid'];
        }
    } else {
        $private = 0;
        $allow_cid = $a->user['allow_cid'];
        $allow_gid = $a->user['allow_gid'];
        $deny_cid = $a->user['deny_cid'];
        $deny_gid = $a->user['deny_gid'];
    }
    $poster = $a->contact;
    $uri = item_new_uri($a->get_hostname(), $uid);
    $action = sprintf(t('%1$s is currently %2$s'), '[url=' . $poster['url'] . ']' . $poster['name'] . '[/url]', $verbs[$verb]);
    $arr = array();
    $arr['uid'] = $uid;
    $arr['uri'] = $uri;
    $arr['parent-uri'] = $parent_uri ? $parent_uri : $uri;
    $arr['type'] = 'activity';
    $arr['wall'] = 1;
    $arr['contact-id'] = $poster['id'];
    $arr['owner-name'] = $poster['name'];
    $arr['owner-link'] = $poster['url'];
    $arr['owner-avatar'] = $poster['thumb'];
    $arr['author-name'] = $poster['name'];
    $arr['author-link'] = $poster['url'];
    $arr['author-avatar'] = $poster['thumb'];
    $arr['title'] = '';
    $arr['allow_cid'] = $allow_cid;
    $arr['allow_gid'] = $allow_gid;
    $arr['deny_cid'] = $deny_cid;
    $arr['deny_gid'] = $deny_gid;
    $arr['last-child'] = 1;
    $arr['visible'] = 1;
    $arr['verb'] = $activity;
    $arr['private'] = $private;
    $arr['origin'] = 1;
    $arr['body'] = $action;
    $item_id = item_store($arr);
    if ($item_id) {
        q("UPDATE `item` SET `plink` = '%s' WHERE `uid` = %d AND `id` = %d", dbesc($a->get_baseurl() . '/display/' . $poster['nickname'] . '/' . $item_id), intval($uid), intval($item_id));
        proc_run('php', "include/notifier.php", "tag", "{$item_id}");
    }
    call_hooks('post_local_end', $arr);
    proc_run('php', "include/notifier.php", "like", "{$post_id}");
    return;
}
Пример #12
0
/**
 * @param App $a
 * @param array $user
 * @param array $self
 * @param string $fb_id
 * @param bool $wall
 * @param array $orig_post
 * @param object $likes
 */
function fb_consume_like(&$a, &$user, &$self, $fb_id, $wall, &$orig_post, &$likes)
{
    $top_item = $orig_post['id'];
    $uid = IntVal($user[0]['uid']);
    if (!$orig_post) {
        return;
    }
    // If we posted the like locally, it will be found with our url, not the FB url.
    $second_url = $likes->id == $fb_id ? $self[0]['url'] : 'http://facebook.com/profile.php?id=' . $likes->id;
    $r = q("SELECT * FROM `item` WHERE `parent-uri` = '%s' AND `uid` = %d AND `verb` = '%s'\n    \tAND ( `author-link` = '%s' OR `author-link` = '%s' ) LIMIT 1", dbesc($orig_post['uri']), intval($uid), dbesc(ACTIVITY_LIKE), dbesc('http://facebook.com/profile.php?id=' . $likes->id), dbesc($second_url));
    if (count($r)) {
        return;
    }
    $likedata = array();
    $likedata['parent'] = $top_item;
    $likedata['verb'] = ACTIVITY_LIKE;
    $likedata['gravity'] = 3;
    $likedata['uid'] = $uid;
    $likedata['wall'] = $wall ? 1 : 0;
    $likedata['uri'] = item_new_uri($a->get_baseurl(), $uid);
    $likedata['parent-uri'] = $orig_post['uri'];
    if ($likes->id == $fb_id) {
        $likedata['contact-id'] = $self[0]['id'];
    } else {
        $r = q("SELECT * FROM `contact` WHERE `notify` = '%s' AND `uid` = %d AND `blocked` = 0 AND `readonly` = 0 LIMIT 1", dbesc($likes->id), intval($uid));
        if (count($r)) {
            $likedata['contact-id'] = $r[0]['id'];
        }
    }
    if (!x($likedata, 'contact-id')) {
        $likedata['contact-id'] = $orig_post['contact-id'];
    }
    $likedata['app'] = 'facebook';
    $likedata['verb'] = ACTIVITY_LIKE;
    $likedata['author-name'] = $likes->name;
    $likedata['author-link'] = 'http://facebook.com/profile.php?id=' . $likes->id;
    $likedata['author-avatar'] = 'https://graph.facebook.com/' . $likes->id . '/picture';
    $author = '[url=' . $likedata['author-link'] . ']' . $likedata['author-name'] . '[/url]';
    $objauthor = '[url=' . $orig_post['author-link'] . ']' . $orig_post['author-name'] . '[/url]';
    $post_type = t('status');
    $plink = '[url=' . $orig_post['plink'] . ']' . $post_type . '[/url]';
    $likedata['object-type'] = ACTIVITY_OBJ_NOTE;
    $likedata['body'] = sprintf(t('%1$s likes %2$s\'s %3$s'), $author, $objauthor, $plink);
    $likedata['object'] = '<object><type>' . ACTIVITY_OBJ_NOTE . '</type><local>1</local>' . '<id>' . $orig_post['uri'] . '</id><link>' . xmlify('<link rel="alternate" type="text/html" href="' . xmlify($orig_post['plink']) . '" />') . '</link><title>' . $orig_post['title'] . '</title><content>' . $orig_post['body'] . '</content></object>';
    item_store($likedata);
}
Пример #13
0
function item_post(&$a)
{
    if (!local_user() && !remote_user()) {
        return;
    }
    require_once 'include/security.php';
    $uid = $_SESSION['uid'];
    $parent = x($_POST, 'parent') ? intval($_POST['parent']) : 0;
    $parent_item = null;
    if ($parent) {
        $r = q("SELECT * FROM `item` WHERE `id` = %d LIMIT 1", intval($parent));
        if (!count($r)) {
            notice(t('Unable to locate original post.') . EOL);
            goaway($a->get_baseurl() . "/" . $_POST['return']);
        }
        $parent_item = $r[0];
    }
    $profile_uid = x($_POST, 'profile_uid') ? intval($_POST['profile_uid']) : 0;
    if (!can_write_wall($a, $profile_uid)) {
        notice(t('Permission denied.') . EOL);
        return;
    }
    $user = null;
    $r = q("SELECT * FROM `user` WHERE `uid` = %d LIMIT 1", intval($profile_uid));
    if (count($r)) {
        $user = $r[0];
    }
    $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']);
    $title = notags(trim($_POST['title']));
    $body = escape_tags(trim($_POST['body']));
    $location = notags(trim($_POST['location']));
    $verb = notags(trim($_POST['verb']));
    if (!strlen($body)) {
        notice(t('Empty post discarded.') . EOL);
        goaway($a->get_baseurl() . "/" . $_POST['return']);
    }
    // get contact info for poster
    $author = null;
    if ($_SESSION['uid'] && $_SESSION['uid'] == $profile_uid) {
        $r = q("SELECT * FROM `contact` WHERE `self` = 1 LIMIT 1", intval($_SESSION['uid']));
    } else {
        if (x($_SESSION, 'visitor_id') && intval($_SESSION['visitor_id'])) {
            $r = q("SELECT * FROM `contact` WHERE `id` = %d LIMIT 1", intval($_SESSION['visitor_id']));
        }
    }
    if (count($r)) {
        $author = $r[0];
        $contact_id = $author['id'];
    }
    // get contact info for owner
    if ($profile_uid == $_SESSION['uid']) {
        $contact_record = $author;
    } else {
        $r = q("SELECT * FROM `contact` WHERE `self` = 1 LIMIT 1", intval($profile_uid));
        if (count($r)) {
            $contact_record = $r[0];
        }
    }
    $post_type = notags(trim($_POST['type']));
    if ($post_type == 'net-comment') {
        if ($parent_item !== null) {
            if ($parent_item['type'] == 'remote') {
                $post_type = 'remote-comment';
            } else {
                $post_type = 'wall-comment';
            }
        }
    }
    $wall = 0;
    if ($post_type == 'wall' || $post_type == 'wall-comment') {
        $wall = 1;
    }
    if (!strlen($verb)) {
        $verb = ACTIVITY_POST;
    }
    $gravity = $parent ? 6 : 0;
    $notify_type = $parent ? 'comment-new' : 'wall-new';
    $uri = item_new_uri($a->get_hostname(), $profile_uid);
    $r = q("INSERT INTO `item` (`type`,`wall`,`gravity`,`contact-id`,`owner-name`,`owner-link`,`owner-avatar`, \n\t\t`author-name`, `author-link`, `author-avatar`, `created`,\n\t\t`edited`, `changed`, `uri`, `title`, `body`, `location`, `verb`, `allow_cid`, `allow_gid`, `deny_cid`, `deny_gid`)\n\t\tVALUES( '%s', %d, %d, %d, '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s' )", dbesc($post_type), intval($wall), intval($gravity), intval($contact_id), dbesc($contact_record['name']), dbesc($contact_record['url']), dbesc($contact_record['thumb']), dbesc($author['name']), dbesc($author['url']), dbesc($author['thumb']), dbesc(datetime_convert()), dbesc(datetime_convert()), dbesc(datetime_convert()), dbesc($uri), dbesc($title), dbesc($body), dbesc($location), dbesc($verb), dbesc($str_contact_allow), dbesc($str_group_allow), dbesc($str_contact_deny), dbesc($str_group_deny));
    $r = q("SELECT `id` FROM `item` WHERE `uri` = '%s' LIMIT 1", dbesc($uri));
    if (count($r)) {
        $post_id = $r[0]['id'];
        if ($parent) {
            // This item is the last leaf and gets the comment box, clear any ancestors
            $r = q("UPDATE `item` SET `last-child` = 0, `changed` = '%s'  WHERE `parent` = %d ", dbesc(datetime_convert()), intval($parent));
            // Inherit ACL's from the parent item.
            // TODO merge with subsequent UPDATE operation and save a db write
            $r = q("UPDATE `item` SET `allow_cid` = '%s', `allow_gid` = '%s', `deny_cid` = '%s', `deny_gid` = '%s'\n\t\t\t\tWHERE `id` = %d LIMIT 1", dbesc($parent_item['allow_cid']), dbesc($parent_item['allow_gid']), dbesc($parent_item['deny_cid']), dbesc($parent_item['deny_gid']), intval($post_id));
            if ($user['notify-flags'] & NOTIFY_COMMENT && $contact_record != $author) {
                require_once 'bbcode.php';
                $from = $author['name'];
                $tpl = file_get_contents('view/cmnt_received_eml.tpl');
                $email_tpl = replace_macros($tpl, array('$sitename' => $a->config['sitename'], '$siteurl' => $a->get_baseurl(), '$username' => $user['username'], '$email' => $user['email'], '$from' => $from, '$body' => strip_tags(bbcode($body))));
                $res = mail($user['email'], $from . t(" commented on your item at ") . $a->config['sitename'], $email_tpl, t("From: Administrator@") . $a->get_hostname());
            }
        } else {
            $parent = $post_id;
            if ($user['notify-flags'] & NOTIFY_WALL && $contact_record != $author) {
                require_once 'bbcode.php';
                $from = $author['name'];
                $tpl = file_get_contents('view/wall_received_eml.tpl');
                $email_tpl = replace_macros($tpl, array('$sitename' => $a->config['sitename'], '$siteurl' => $a->get_baseurl(), '$username' => $user['username'], '$email' => $user['email'], '$from' => $from, '$body' => strip_tags(bbcode($body))));
                $res = mail($user['email'], $from . t(" posted on your profile wall at ") . $a->config['sitename'], $email_tpl, t("From: Administrator@") . $a->get_hostname());
            }
        }
        $r = q("UPDATE `item` SET `parent` = %d, `parent-uri` = '%s', `changed` = '%s', `last-child` = 1, `visible` = 1\n\t\t\tWHERE `id` = %d LIMIT 1", intval($parent), dbesc($parent == $post_id ? $uri : $parent_item['uri']), dbesc(datetime_convert()), intval($post_id));
        // photo comments turn the corresponding item visible to the profile wall
        if (!$parent_item['visible']) {
            $r = q("UPDATE `item` SET `visible` = 1 WHERE `id` = %d LIMIT 1", intval($parent_item['id']));
        }
    }
    $php_path = strlen($a->config['php_path']) ? $a->config['php_path'] : 'php';
    proc_close(proc_open("\"{$php_path}\" \"include/notifier.php\" \"{$notify_type}\" \"{$post_id}\" &", array(), $foo));
    goaway($a->get_baseurl() . "/" . $_POST['return']);
    return;
    // NOTREACHED
}
Пример #14
0
function item_post(&$a)
{
    if (!local_user() && !remote_user() && !x($_REQUEST, 'commenter')) {
        return;
    }
    require_once 'include/security.php';
    $uid = local_user();
    if (x($_REQUEST, 'dropitems')) {
        $arr_drop = explode(',', $_REQUEST['dropitems']);
        drop_items($arr_drop);
        $json = array('success' => 1);
        echo json_encode($json);
        killme();
    }
    call_hooks('post_local_start', $_REQUEST);
    //	logger('postinput ' . file_get_contents('php://input'));
    logger('postvars ' . print_r($_REQUEST, true), LOGGER_DATA);
    $api_source = x($_REQUEST, 'api_source') && $_REQUEST['api_source'] ? true : false;
    $message_id = x($_REQUEST, 'message_id') && $api_source ? strip_tags($_REQUEST['message_id']) : '';
    $return_path = x($_REQUEST, 'return') ? $_REQUEST['return'] : '';
    $preview = x($_REQUEST, 'preview') ? intval($_REQUEST['preview']) : 0;
    // Check for doubly-submitted posts, and reject duplicates
    // Note that we have to ignore previews, otherwise nothing will post
    // after it's been previewed
    if (!$preview && x($_REQUEST['post_id_random'])) {
        if (x($_SESSION['post-random']) && $_SESSION['post-random'] == $_REQUEST['post_id_random']) {
            logger("item post: duplicate post", LOGGER_DEBUG);
            item_post_return($a->get_baseurl(), $api_source, $return_path);
        } else {
            $_SESSION['post-random'] = $_REQUEST['post_id_random'];
        }
    }
    /**
     * Is this a reply to something?
     */
    $parent = x($_REQUEST, 'parent') ? intval($_REQUEST['parent']) : 0;
    $parent_uri = x($_REQUEST, 'parent_uri') ? trim($_REQUEST['parent_uri']) : '';
    $parent_item = null;
    $parent_contact = null;
    $thr_parent = '';
    $parid = 0;
    $r = false;
    $objecttype = null;
    if ($parent || $parent_uri) {
        $objecttype = ACTIVITY_OBJ_COMMENT;
        if (!x($_REQUEST, 'type')) {
            $_REQUEST['type'] = 'net-comment';
        }
        if ($parent) {
            $r = q("SELECT * FROM `item` WHERE `id` = %d LIMIT 1", intval($parent));
        } elseif ($parent_uri && local_user()) {
            // This is coming from an API source, and we are logged in
            $r = q("SELECT * FROM `item` WHERE `uri` = '%s' AND `uid` = %d LIMIT 1", dbesc($parent_uri), intval(local_user()));
        }
        // if this isn't the real parent of the conversation, find it
        if ($r !== false && count($r)) {
            $parid = $r[0]['parent'];
            $parent_uri = $r[0]['uri'];
            if ($r[0]['id'] != $r[0]['parent']) {
                $r = q("SELECT * FROM `item` WHERE `id` = `parent` AND `parent` = %d LIMIT 1", intval($parid));
            }
        }
        if ($r === false || !count($r)) {
            notice(t('Unable to locate original post.') . EOL);
            if (x($_REQUEST, 'return')) {
                goaway($a->get_baseurl() . "/" . $return_path);
            }
            killme();
        }
        $parent_item = $r[0];
        $parent = $r[0]['id'];
        // multi-level threading - preserve the info but re-parent to our single level threading
        //if(($parid) && ($parid != $parent))
        $thr_parent = $parent_uri;
        if ($parent_item['contact-id'] && $uid) {
            $r = q("SELECT * FROM `contact` WHERE `id` = %d AND `uid` = %d LIMIT 1", intval($parent_item['contact-id']), intval($uid));
            if (count($r)) {
                $parent_contact = $r[0];
                // If the contact id doesn't fit with the contact, then set the contact to null
                $thrparent = q("SELECT `author-link`, `network` FROM `item` WHERE `uri` = '%s' LIMIT 1", dbesc($thr_parent));
                if (count($thrparent) and $thrparent[0]["network"] === NETWORK_OSTATUS and normalise_link($parent_contact["url"]) != normalise_link($thrparent[0]["author-link"])) {
                    $parent_contact = null;
                    require_once "include/Scrape.php";
                    $probed_contact = probe_url($thrparent[0]["author-link"]);
                    if ($probed_contact["network"] != NETWORK_FEED) {
                        $parent_contact = $probed_contact;
                        $parent_contact["nurl"] = normalise_link($probed_contact["url"]);
                        $parent_contact["thumb"] = $probed_contact["photo"];
                        $parent_contact["micro"] = $probed_contact["photo"];
                    }
                    logger('parent contact: ' . print_r($parent_contact, true), LOGGER_DEBUG);
                } else {
                    logger('no contact found: ' . print_r($thrparent, true), LOGGER_DEBUG);
                }
            }
        }
    }
    if ($parent) {
        logger('mod_item: item_post parent=' . $parent);
    }
    $profile_uid = x($_REQUEST, 'profile_uid') ? intval($_REQUEST['profile_uid']) : 0;
    $post_id = x($_REQUEST, 'post_id') ? intval($_REQUEST['post_id']) : 0;
    $app = x($_REQUEST, 'source') ? strip_tags($_REQUEST['source']) : '';
    $extid = x($_REQUEST, 'extid') ? strip_tags($_REQUEST['extid']) : '';
    $allow_moderated = false;
    // here is where we are going to check for permission to post a moderated comment.
    // First check that the parent exists and it is a wall item.
    if (x($_REQUEST, 'commenter') && (!$parent || !$parent_item['wall'])) {
        notice(t('Permission denied.') . EOL);
        if (x($_REQUEST, 'return')) {
            goaway($a->get_baseurl() . "/" . $return_path);
        }
        killme();
    }
    // Now check that it is a page_type of PAGE_BLOG, and that valid personal details
    // have been provided, and run any anti-spam plugins
    // TODO
    if (!can_write_wall($a, $profile_uid) && !$allow_moderated) {
        notice(t('Permission denied.') . EOL);
        if (x($_REQUEST, 'return')) {
            goaway($a->get_baseurl() . "/" . $return_path);
        }
        killme();
    }
    // is this an edited post?
    $orig_post = null;
    if ($post_id) {
        $i = q("SELECT * FROM `item` WHERE `uid` = %d AND `id` = %d LIMIT 1", intval($profile_uid), intval($post_id));
        if (!count($i)) {
            killme();
        }
        $orig_post = $i[0];
    }
    $user = null;
    $r = q("SELECT * FROM `user` WHERE `uid` = %d LIMIT 1", intval($profile_uid));
    if (count($r)) {
        $user = $r[0];
    }
    if ($orig_post) {
        $str_group_allow = $orig_post['allow_gid'];
        $str_contact_allow = $orig_post['allow_cid'];
        $str_group_deny = $orig_post['deny_gid'];
        $str_contact_deny = $orig_post['deny_cid'];
        $location = $orig_post['location'];
        $coord = $orig_post['coord'];
        $verb = $orig_post['verb'];
        $objecttype = $orig_post['object-type'];
        $emailcc = $orig_post['emailcc'];
        $app = $orig_post['app'];
        $categories = $orig_post['file'];
        $title = notags(trim($_REQUEST['title']));
        $body = escape_tags(trim($_REQUEST['body']));
        $private = $orig_post['private'];
        $pubmail_enable = $orig_post['pubmail'];
        $network = $orig_post['network'];
        $guid = $orig_post['guid'];
        $extid = $orig_post['extid'];
    } else {
        // if coming from the API and no privacy settings are set,
        // use the user default permissions - as they won't have
        // been supplied via a form.
        if ($api_source && !array_key_exists('contact_allow', $_REQUEST) && !array_key_exists('group_allow', $_REQUEST) && !array_key_exists('contact_deny', $_REQUEST) && !array_key_exists('group_deny', $_REQUEST)) {
            $str_group_allow = $user['allow_gid'];
            $str_contact_allow = $user['allow_cid'];
            $str_group_deny = $user['deny_gid'];
            $str_contact_deny = $user['deny_cid'];
        } else {
            // use the posted permissions
            $str_group_allow = perms2str($_REQUEST['group_allow']);
            $str_contact_allow = perms2str($_REQUEST['contact_allow']);
            $str_group_deny = perms2str($_REQUEST['group_deny']);
            $str_contact_deny = perms2str($_REQUEST['contact_deny']);
        }
        $title = notags(trim($_REQUEST['title']));
        $location = notags(trim($_REQUEST['location']));
        $coord = notags(trim($_REQUEST['coord']));
        $verb = notags(trim($_REQUEST['verb']));
        $emailcc = notags(trim($_REQUEST['emailcc']));
        $body = escape_tags(trim($_REQUEST['body']));
        $network = notags(trim($_REQUEST['network']));
        $guid = get_guid(32);
        $naked_body = preg_replace('/\\[(.+?)\\]/', '', $body);
        if (version_compare(PHP_VERSION, '5.3.0', '>=')) {
            $l = new Text_LanguageDetect();
            //$lng = $l->detectConfidence($naked_body);
            //$postopts = (($lng['language']) ? 'lang=' . $lng['language'] . ';' . $lng['confidence'] : '');
            $lng = $l->detect($naked_body, 3);
            if (sizeof($lng) > 0) {
                $postopts = "";
                foreach ($lng as $language => $score) {
                    if ($postopts == "") {
                        $postopts = "lang=";
                    } else {
                        $postopts .= ":";
                    }
                    $postopts .= $language . ";" . $score;
                }
            }
            logger('mod_item: detect language' . print_r($lng, true) . $naked_body, LOGGER_DATA);
        } else {
            $postopts = '';
        }
        $private = strlen($str_group_allow) || strlen($str_contact_allow) || strlen($str_group_deny) || strlen($str_contact_deny) ? 1 : 0;
        if ($user['hidewall']) {
            $private = 2;
        }
        // If this is a comment, set the permissions from the parent.
        if ($parent_item) {
            $private = 0;
            // for non native networks use the network of the original post as network of the item
            if ($parent_item['network'] != NETWORK_DIASPORA and $parent_item['network'] != NETWORK_OSTATUS and $network == "") {
                $network = $parent_item['network'];
            }
            if ($parent_item['private'] || strlen($parent_item['allow_cid']) || strlen($parent_item['allow_gid']) || strlen($parent_item['deny_cid']) || strlen($parent_item['deny_gid'])) {
                $private = $parent_item['private'] ? $parent_item['private'] : 1;
            }
            $str_contact_allow = $parent_item['allow_cid'];
            $str_group_allow = $parent_item['allow_gid'];
            $str_contact_deny = $parent_item['deny_cid'];
            $str_group_deny = $parent_item['deny_gid'];
        }
        $pubmail_enable = x($_REQUEST, 'pubmail_enable') && intval($_REQUEST['pubmail_enable']) && !$private ? 1 : 0;
        // if using the API, we won't see pubmail_enable - figure out if it should be set
        if ($api_source && $profile_uid && $profile_uid == local_user() && !$private) {
            $mail_disabled = function_exists('imap_open') && !get_config('system', 'imap_disabled') ? 0 : 1;
            if (!$mail_disabled) {
                $r = q("SELECT * FROM `mailacct` WHERE `uid` = %d AND `server` != '' LIMIT 1", intval(local_user()));
                if (count($r) && intval($r[0]['pubmail'])) {
                    $pubmail_enabled = true;
                }
            }
        }
        if (!strlen($body)) {
            if ($preview) {
                killme();
            }
            info(t('Empty post discarded.') . EOL);
            if (x($_REQUEST, 'return')) {
                goaway($a->get_baseurl() . "/" . $return_path);
            }
            killme();
        }
    }
    if (strlen($categories)) {
        // get the "fileas" tags for this post
        $filedas = file_tag_file_to_list($categories, 'file');
    }
    // save old and new categories, so we can determine what needs to be deleted from pconfig
    $categories_old = $categories;
    $categories = file_tag_list_to_file(trim($_REQUEST['category']), 'category');
    $categories_new = $categories;
    if (strlen($filedas)) {
        // append the fileas stuff to the new categories list
        $categories .= file_tag_list_to_file($filedas, 'file');
    }
    // Work around doubled linefeeds in Tinymce 3.5b2
    // First figure out if it's a status post that would've been
    // created using tinymce. Otherwise leave it alone.
    /*	$plaintext = (local_user() ? intval(get_pconfig(local_user(),'system','plaintext')) || !feature_enabled($profile_uid,'richtext') : 0);
    	if((! $parent) && (! $api_source) && (! $plaintext)) {
    		$body = fix_mce_lf($body);
    	}*/
    $plaintext = local_user() ? !feature_enabled($profile_uid, 'richtext') : 0;
    if (!$parent && !$api_source && !$plaintext) {
        $body = fix_mce_lf($body);
    }
    // get contact info for poster
    $author = null;
    $self = false;
    $contact_id = 0;
    if (local_user() && local_user() == $profile_uid) {
        $self = true;
        $r = q("SELECT * FROM `contact` WHERE `uid` = %d AND `self` = 1 LIMIT 1", intval($_SESSION['uid']));
    } elseif (remote_user()) {
        if (is_array($_SESSION['remote'])) {
            foreach ($_SESSION['remote'] as $v) {
                if ($v['uid'] == $profile_uid) {
                    $contact_id = $v['cid'];
                    break;
                }
            }
        }
        if ($contact_id) {
            $r = q("SELECT * FROM `contact` WHERE `id` = %d LIMIT 1", intval($contact_id));
        }
    }
    if (count($r)) {
        $author = $r[0];
        $contact_id = $author['id'];
    }
    // get contact info for owner
    if ($profile_uid == local_user()) {
        $contact_record = $author;
    } else {
        $r = q("SELECT * FROM `contact` WHERE `uid` = %d AND `self` = 1 LIMIT 1", intval($profile_uid));
        if (count($r)) {
            $contact_record = $r[0];
        }
    }
    $post_type = notags(trim($_REQUEST['type']));
    if ($post_type === 'net-comment') {
        if ($parent_item !== null) {
            if ($parent_item['wall'] == 1) {
                $post_type = 'wall-comment';
            } else {
                $post_type = 'remote-comment';
            }
        }
    }
    /**
     *
     * When a photo was uploaded into the message using the (profile wall) ajax
     * uploader, The permissions are initially set to disallow anybody but the
     * owner from seeing it. This is because the permissions may not yet have been
     * set for the post. If it's private, the photo permissions should be set
     * appropriately. But we didn't know the final permissions on the post until
     * now. So now we'll look for links of uploaded messages that are in the
     * post and set them to the same permissions as the post itself.
     *
     */
    $match = null;
    if (!$preview && preg_match_all("/\\[img([\\=0-9x]*?)\\](.*?)\\[\\/img\\]/", $body, $match)) {
        $images = $match[2];
        if (count($images)) {
            $objecttype = ACTIVITY_OBJ_IMAGE;
            foreach ($images as $image) {
                if (!stristr($image, $a->get_baseurl() . '/photo/')) {
                    continue;
                }
                $image_uri = substr($image, strrpos($image, '/') + 1);
                $image_uri = substr($image_uri, 0, strpos($image_uri, '-'));
                if (!strlen($image_uri)) {
                    continue;
                }
                $srch = '<' . intval($contact_id) . '>';
                $r = q("SELECT `id` FROM `photo` WHERE `allow_cid` = '%s' AND `allow_gid` = '' AND `deny_cid` = '' AND `deny_gid` = ''\n\t\t\t\t\tAND `resource-id` = '%s' AND `uid` = %d LIMIT 1", dbesc($srch), dbesc($image_uri), intval($profile_uid));
                if (!count($r)) {
                    continue;
                }
                $r = q("UPDATE `photo` SET `allow_cid` = '%s', `allow_gid` = '%s', `deny_cid` = '%s', `deny_gid` = '%s'\n\t\t\t\t\tWHERE `resource-id` = '%s' AND `uid` = %d AND `album` = '%s' ", dbesc($str_contact_allow), dbesc($str_group_allow), dbesc($str_contact_deny), dbesc($str_group_deny), dbesc($image_uri), intval($profile_uid), dbesc(t('Wall Photos')));
            }
        }
    }
    /**
     * Next link in any attachment references we find in the post.
     */
    $match = false;
    if (!$preview && preg_match_all("/\\[attachment\\](.*?)\\[\\/attachment\\]/", $body, $match)) {
        $attaches = $match[1];
        if (count($attaches)) {
            foreach ($attaches as $attach) {
                $r = q("SELECT * FROM `attach` WHERE `uid` = %d AND `id` = %d LIMIT 1", intval($profile_uid), intval($attach));
                if (count($r)) {
                    $r = q("UPDATE `attach` SET `allow_cid` = '%s', `allow_gid` = '%s', `deny_cid` = '%s', `deny_gid` = '%s'\n\t\t\t\t\t\tWHERE `uid` = %d AND `id` = %d", dbesc($str_contact_allow), dbesc($str_group_allow), dbesc($str_contact_deny), dbesc($str_group_deny), intval($profile_uid), intval($attach));
                }
            }
        }
    }
    // embedded bookmark in post? set bookmark flag
    $bookmark = 0;
    if (preg_match_all("/\\[bookmark\\=([^\\]]*)\\](.*?)\\[\\/bookmark\\]/ism", $body, $match, PREG_SET_ORDER)) {
        $objecttype = ACTIVITY_OBJ_BOOKMARK;
        $bookmark = 1;
    }
    $body = bb_translate_video($body);
    /**
     * Fold multi-line [code] sequences
     */
    $body = preg_replace('/\\[\\/code\\]\\s*\\[code\\]/ism', "\n", $body);
    $body = scale_external_images($body, false);
    // Setting the object type if not defined before
    if (!$objecttype) {
        $objecttype = ACTIVITY_OBJ_NOTE;
        // Default value
        require_once "include/plaintext.php";
        $objectdata = get_attached_data($body);
        if ($post["type"] == "link") {
            $objecttype = ACTIVITY_OBJ_BOOKMARK;
        } elseif ($post["type"] == "video") {
            $objecttype = ACTIVITY_OBJ_VIDEO;
        } elseif ($post["type"] == "photo") {
            $objecttype = ACTIVITY_OBJ_IMAGE;
        }
    }
    /**
     * Look for any tags and linkify them
     */
    $str_tags = '';
    $inform = '';
    $tags = get_tags($body);
    /**
     * add a statusnet style reply tag if the original post was from there
     * and we are replying, and there isn't one already
     */
    if ($parent_contact && $parent_contact['network'] === NETWORK_OSTATUS && $parent_contact['nick'] && !in_array('@' . $parent_contact['nick'], $tags)) {
        $body = '@' . $parent_contact['nick'] . ' ' . $body;
        $tags[] = '@' . $parent_contact['nick'];
    }
    $tagged = array();
    $private_forum = false;
    if (count($tags)) {
        foreach ($tags as $tag) {
            if (strpos($tag, '#') === 0) {
                continue;
            }
            // If we already tagged 'Robert Johnson', don't try and tag 'Robert'.
            // Robert Johnson should be first in the $tags array
            $fullnametagged = false;
            for ($x = 0; $x < count($tagged); $x++) {
                if (stristr($tagged[$x], $tag . ' ')) {
                    $fullnametagged = true;
                    break;
                }
            }
            if ($fullnametagged) {
                continue;
            }
            $success = handle_tag($a, $body, $inform, $str_tags, local_user() ? local_user() : $profile_uid, $tag, $network);
            if ($success['replaced']) {
                $tagged[] = $tag;
            }
            if (is_array($success['contact']) && intval($success['contact']['prv'])) {
                $private_forum = true;
                $private_id = $success['contact']['id'];
            }
        }
    }
    if ($private_forum && !$parent && !$private) {
        // we tagged a private forum in a top level post and the message was public.
        // Restrict it.
        $private = 1;
        $str_contact_allow = '<' . $private_id . '>';
    }
    $attachments = '';
    $match = false;
    if (preg_match_all('/(\\[attachment\\]([0-9]+)\\[\\/attachment\\])/', $body, $match)) {
        foreach ($match[2] as $mtch) {
            $r = q("SELECT `id`,`filename`,`filesize`,`filetype` FROM `attach` WHERE `uid` = %d AND `id` = %d LIMIT 1", intval($profile_uid), intval($mtch));
            if (count($r)) {
                if (strlen($attachments)) {
                    $attachments .= ',';
                }
                $attachments .= '[attach]href="' . $a->get_baseurl() . '/attach/' . $r[0]['id'] . '" length="' . $r[0]['filesize'] . '" type="' . $r[0]['filetype'] . '" title="' . ($r[0]['filename'] ? $r[0]['filename'] : '') . '"[/attach]';
            }
            $body = str_replace($match[1], '', $body);
        }
    }
    $wall = 0;
    if ($post_type === 'wall' || $post_type === 'wall-comment') {
        $wall = 1;
    }
    if (!strlen($verb)) {
        $verb = ACTIVITY_POST;
    }
    if ($network == "") {
        $network = NETWORK_DFRN;
    }
    $gravity = $parent ? 6 : 0;
    // even if the post arrived via API we are considering that it
    // originated on this site by default for determining relayability.
    $origin = x($_REQUEST, 'origin') ? intval($_REQUEST['origin']) : 1;
    $notify_type = $parent ? 'comment-new' : 'wall-new';
    $uri = $message_id ? $message_id : item_new_uri($a->get_hostname(), $profile_uid);
    // Fallback so that we alway have a thr-parent
    if (!$thr_parent) {
        $thr_parent = $uri;
    }
    $datarray = array();
    $datarray['uid'] = $profile_uid;
    $datarray['type'] = $post_type;
    $datarray['wall'] = $wall;
    $datarray['gravity'] = $gravity;
    $datarray['network'] = $network;
    $datarray['contact-id'] = $contact_id;
    $datarray['owner-name'] = $contact_record['name'];
    $datarray['owner-link'] = $contact_record['url'];
    $datarray['owner-avatar'] = $contact_record['thumb'];
    $datarray['author-name'] = $author['name'];
    $datarray['author-link'] = $author['url'];
    $datarray['author-avatar'] = $author['thumb'];
    $datarray['created'] = datetime_convert();
    $datarray['edited'] = datetime_convert();
    $datarray['commented'] = datetime_convert();
    $datarray['received'] = datetime_convert();
    $datarray['changed'] = datetime_convert();
    $datarray['extid'] = $extid;
    $datarray['guid'] = $guid;
    $datarray['uri'] = $uri;
    $datarray['title'] = $title;
    $datarray['body'] = $body;
    $datarray['app'] = $app;
    $datarray['location'] = $location;
    $datarray['coord'] = $coord;
    $datarray['tag'] = $str_tags;
    $datarray['file'] = $categories;
    $datarray['inform'] = $inform;
    $datarray['verb'] = $verb;
    $datarray['object-type'] = $objecttype;
    $datarray['allow_cid'] = $str_contact_allow;
    $datarray['allow_gid'] = $str_group_allow;
    $datarray['deny_cid'] = $str_contact_deny;
    $datarray['deny_gid'] = $str_group_deny;
    $datarray['private'] = $private;
    $datarray['pubmail'] = $pubmail_enable;
    $datarray['attach'] = $attachments;
    $datarray['bookmark'] = intval($bookmark);
    $datarray['thr-parent'] = $thr_parent;
    $datarray['postopts'] = $postopts;
    $datarray['origin'] = $origin;
    $datarray['moderated'] = $allow_moderated;
    /**
     * These fields are for the convenience of plugins...
     * 'self' if true indicates the owner is posting on their own wall
     * If parent is 0 it is a top-level post.
     */
    $datarray['parent'] = $parent;
    $datarray['self'] = $self;
    //	$datarray['prvnets']       = $user['prvnets'];
    if ($orig_post) {
        $datarray['edit'] = true;
    }
    // Search for hashtags
    item_body_set_hashtags($datarray);
    // preview mode - prepare the body for display and send it via json
    if ($preview) {
        require_once 'include/conversation.php';
        $o = conversation($a, array(array_merge($contact_record, $datarray)), 'search', false, true);
        logger('preview: ' . $o);
        echo json_encode(array('preview' => $o));
        killme();
    }
    call_hooks('post_local', $datarray);
    if (x($datarray, 'cancel')) {
        logger('mod_item: post cancelled by plugin.');
        if ($return_path) {
            goaway($a->get_baseurl() . "/" . $return_path);
        }
        $json = array('cancel' => 1);
        if (x($_REQUEST, 'jsreload') && strlen($_REQUEST['jsreload'])) {
            $json['reload'] = $a->get_baseurl() . '/' . $_REQUEST['jsreload'];
        }
        echo json_encode($json);
        killme();
    }
    // Fill the cache field
    put_item_in_cache($datarray);
    if ($orig_post) {
        $r = q("UPDATE `item` SET `title` = '%s', `body` = '%s', `tag` = '%s', `attach` = '%s', `file` = '%s', `rendered-html` = '%s', `rendered-hash` = '%s', `edited` = '%s', `changed` = '%s' WHERE `id` = %d AND `uid` = %d", dbesc($datarray['title']), dbesc($datarray['body']), dbesc($datarray['tag']), dbesc($datarray['attach']), dbesc($datarray['file']), dbesc($datarray['rendered-html']), dbesc($datarray['rendered-hash']), dbesc(datetime_convert()), dbesc(datetime_convert()), intval($post_id), intval($profile_uid));
        create_tags_from_item($post_id);
        create_files_from_item($post_id);
        update_thread($post_id);
        // update filetags in pconfig
        file_tag_update_pconfig($uid, $categories_old, $categories_new, 'category');
        proc_run('php', "include/notifier.php", 'edit_post', "{$post_id}");
        if (x($_REQUEST, 'return') && strlen($return_path)) {
            logger('return: ' . $return_path);
            goaway($a->get_baseurl() . "/" . $return_path);
        }
        killme();
    } else {
        $post_id = 0;
    }
    $r = q("INSERT INTO `item` (`guid`, `extid`, `uid`,`type`,`wall`,`gravity`, `network`, `contact-id`,`owner-name`,`owner-link`,`owner-avatar`, `author-name`, `author-link`, `author-avatar`,\n\t\t`created`, `edited`, `commented`, `received`, `changed`, `uri`, `thr-parent`, `title`, `body`, `app`, `location`, `coord`, `tag`, `inform`, `verb`, `object-type`, `postopts`,\n\t\t`allow_cid`, `allow_gid`, `deny_cid`, `deny_gid`, `private`, `pubmail`, `attach`, `bookmark`,`origin`, `moderated`, `file`, `rendered-html`, `rendered-hash`)\n\t\tVALUES( '%s', '%s', %d, '%s', %d, %d, '%s', %d, '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', %d, %d, '%s', %d, %d, %d, '%s', '%s', '%s')", dbesc($datarray['guid']), dbesc($datarray['extid']), intval($datarray['uid']), dbesc($datarray['type']), intval($datarray['wall']), intval($datarray['gravity']), dbesc($datarray['network']), intval($datarray['contact-id']), dbesc($datarray['owner-name']), dbesc($datarray['owner-link']), dbesc($datarray['owner-avatar']), dbesc($datarray['author-name']), dbesc($datarray['author-link']), dbesc($datarray['author-avatar']), dbesc($datarray['created']), dbesc($datarray['edited']), dbesc($datarray['commented']), dbesc($datarray['received']), dbesc($datarray['changed']), dbesc($datarray['uri']), dbesc($datarray['thr-parent']), dbesc($datarray['title']), dbesc($datarray['body']), dbesc($datarray['app']), dbesc($datarray['location']), dbesc($datarray['coord']), dbesc($datarray['tag']), dbesc($datarray['inform']), dbesc($datarray['verb']), dbesc($datarray['object-type']), dbesc($datarray['postopts']), dbesc($datarray['allow_cid']), dbesc($datarray['allow_gid']), dbesc($datarray['deny_cid']), dbesc($datarray['deny_gid']), intval($datarray['private']), intval($datarray['pubmail']), dbesc($datarray['attach']), intval($datarray['bookmark']), intval($datarray['origin']), intval($datarray['moderated']), dbesc($datarray['file']), dbesc($datarray['rendered-html']), dbesc($datarray['rendered-hash']));
    $r = q("SELECT `id` FROM `item` WHERE `uri` = '%s' LIMIT 1", dbesc($datarray['uri']));
    if (!count($r)) {
        logger('mod_item: unable to retrieve post that was just stored.');
        notice(t('System error. Post not saved.') . EOL);
        goaway($a->get_baseurl() . "/" . $return_path);
        // NOTREACHED
    }
    $post_id = $r[0]['id'];
    logger('mod_item: saved item ' . $post_id);
    $datarray["id"] = $post_id;
    $datarray["plink"] = $a->get_baseurl() . '/display/' . urlencode($datarray["guid"]);
    // update filetags in pconfig
    file_tag_update_pconfig($uid, $categories_old, $categories_new, 'category');
    if ($parent) {
        // This item is the last leaf and gets the comment box, clear any ancestors
        $r = q("UPDATE `item` SET `last-child` = 0, `changed` = '%s' WHERE `parent` = %d ", dbesc(datetime_convert()), intval($parent));
        update_thread($parent, true);
        // Inherit ACLs from the parent item.
        $r = q("UPDATE `item` SET `allow_cid` = '%s', `allow_gid` = '%s', `deny_cid` = '%s', `deny_gid` = '%s', `private` = %d\n\t\t\tWHERE `id` = %d", dbesc($parent_item['allow_cid']), dbesc($parent_item['allow_gid']), dbesc($parent_item['deny_cid']), dbesc($parent_item['deny_gid']), intval($parent_item['private']), intval($post_id));
        if ($contact_record != $author) {
            notification(array('type' => NOTIFY_COMMENT, 'notify_flags' => $user['notify-flags'], 'language' => $user['language'], 'to_name' => $user['username'], 'to_email' => $user['email'], 'uid' => $user['uid'], 'item' => $datarray, 'link' => $a->get_baseurl() . '/display/' . urlencode($datarray['guid']), 'source_name' => $datarray['author-name'], 'source_link' => $datarray['author-link'], 'source_photo' => $datarray['author-avatar'], 'verb' => ACTIVITY_POST, 'otype' => 'item', 'parent' => $parent, 'parent_uri' => $parent_item['uri']));
        }
        // Store the comment signature information in case we need to relay to Diaspora
        store_diaspora_comment_sig($datarray, $author, $self ? $a->user['prvkey'] : false, $parent_item, $post_id);
    } else {
        $parent = $post_id;
        if ($contact_record != $author) {
            notification(array('type' => NOTIFY_WALL, 'notify_flags' => $user['notify-flags'], 'language' => $user['language'], 'to_name' => $user['username'], 'to_email' => $user['email'], 'uid' => $user['uid'], 'item' => $datarray, 'link' => $a->get_baseurl() . '/display/' . urlencode($datarray['guid']), 'source_name' => $datarray['author-name'], 'source_link' => $datarray['author-link'], 'source_photo' => $datarray['author-avatar'], 'verb' => ACTIVITY_POST, 'otype' => 'item'));
        }
    }
    // fallback so that parent always gets set to non-zero.
    if (!$parent) {
        $parent = $post_id;
    }
    $r = q("UPDATE `item` SET `parent` = %d, `parent-uri` = '%s', `plink` = '%s', `changed` = '%s', `last-child` = 1, `visible` = 1\n\t\tWHERE `id` = %d", intval($parent), dbesc($parent == $post_id ? $uri : $parent_item['uri']), dbesc($a->get_baseurl() . '/display/' . urlencode($datarray['guid'])), dbesc(datetime_convert()), intval($post_id));
    // photo comments turn the corresponding item visible to the profile wall
    // This way we don't see every picture in your new photo album posted to your wall at once.
    // They will show up as people comment on them.
    if (!$parent_item['visible']) {
        $r = q("UPDATE `item` SET `visible` = 1 WHERE `id` = %d", intval($parent_item['id']));
        update_thread($parent_item['id']);
    }
    // update the commented timestamp on the parent
    q("UPDATE `item` set `commented` = '%s', `changed` = '%s' WHERE `id` = %d", dbesc(datetime_convert()), dbesc(datetime_convert()), intval($parent));
    if ($post_id != $parent) {
        update_thread($parent);
    }
    call_hooks('post_local_end', $datarray);
    if (strlen($emailcc) && $profile_uid == local_user()) {
        $erecips = explode(',', $emailcc);
        if (count($erecips)) {
            foreach ($erecips as $recip) {
                $addr = trim($recip);
                if (!strlen($addr)) {
                    continue;
                }
                $disclaimer = '<hr />' . sprintf(t('This message was sent to you by %s, a member of the Friendica social network.'), $a->user['username']) . '<br />';
                $disclaimer .= sprintf(t('You may visit them online at %s'), $a->get_baseurl() . '/profile/' . $a->user['nickname']) . EOL;
                $disclaimer .= t('Please contact the sender by replying to this post if you do not wish to receive these messages.') . EOL;
                if (!$datarray['title'] == '') {
                    $subject = email_header_encode($datarray['title'], 'UTF-8');
                } else {
                    $subject = email_header_encode('[Friendica]' . ' ' . sprintf(t('%s posted an update.'), $a->user['username']), 'UTF-8');
                }
                $link = '<a href="' . $a->get_baseurl() . '/profile/' . $a->user['nickname'] . '"><img src="' . $author['thumb'] . '" alt="' . $a->user['username'] . '" /></a><br /><br />';
                $html = prepare_body($datarray);
                $message = '<html><body>' . $link . $html . $disclaimer . '</body></html>';
                include_once 'include/html2plain.php';
                $params = array('fromName' => $a->user['username'], 'fromEmail' => $a->user['email'], 'toEmail' => $addr, 'replyTo' => $a->user['email'], 'messageSubject' => $subject, 'htmlVersion' => $message, 'textVersion' => html2plain($html . $disclaimer));
                Emailer::send($params);
            }
        }
    }
    create_tags_from_item($post_id);
    create_files_from_item($post_id);
    if ($post_id == $parent) {
        add_thread($post_id);
    }
    // This is a real juggling act on shared hosting services which kill your processes
    // e.g. dreamhost. We used to start delivery to our native delivery agents in the background
    // and then run our plugin delivery from the foreground. We're now doing plugin delivery first,
    // because as soon as you start loading up a bunch of remote delivey processes, *this* page is
    // likely to get killed off. If you end up looking at an /item URL and a blank page,
    // it's very likely the delivery got killed before all your friends could be notified.
    // Currently the only realistic fixes are to use a reliable server - which precludes shared hosting,
    // or cut back on plugins which do remote deliveries.
    proc_run('php', "include/notifier.php", $notify_type, "{$post_id}");
    logger('post_complete');
    item_post_return($a->get_baseurl(), $api_source, $return_path);
    // NOTREACHED
}
Пример #15
0
function dfrn_confirm_post(&$a, $handsfree = null)
{
    if (is_array($handsfree)) {
        /**
         * We were called directly from dfrn_request due to automatic friend acceptance.
         * Any $_POST parameters we may require are supplied in the $handsfree array.
         *
         */
        $node = $handsfree['node'];
        $a->interactive = false;
        // notice() becomes a no-op since nobody is there to see it
    } else {
        if ($a->argc > 1) {
            $node = $a->argv[1];
        }
    }
    /**
     *
     * Main entry point. Scenario 1. Our user received a friend request notification (perhaps
     * from another site) and clicked 'Approve'.
     * $POST['source_url'] is not set. If it is, it indicates Scenario 2.
     *
     * We may also have been called directly from dfrn_request ($handsfree != null) due to
     * this being a page type which supports automatic friend acceptance. That is also Scenario 1
     * since we are operating on behalf of our registered user to approve a friendship.
     *
     */
    if (!x($_POST, 'source_url')) {
        $uid = is_array($handsfree) ? $handsfree['uid'] : local_user();
        if (!$uid) {
            notice(t('Permission denied.') . EOL);
            return;
        }
        $user = q("SELECT * FROM `user` WHERE `uid` = %d LIMIT 1", intval($uid));
        if (!$user) {
            notice(t('Profile not found.') . EOL);
            return;
        }
        // These data elements may come from either the friend request notification form or $handsfree array.
        if (is_array($handsfree)) {
            logger('Confirm in handsfree mode');
            $dfrn_id = $handsfree['dfrn_id'];
            $intro_id = $handsfree['intro_id'];
            $duplex = $handsfree['duplex'];
            $hidden = array_key_exists('hidden', $handsfree) ? intval($handsfree['hidden']) : 0;
            $activity = array_key_exists('activity', $handsfree) ? intval($handsfree['activity']) : 0;
        } else {
            $dfrn_id = x($_POST, 'dfrn_id') ? notags(trim($_POST['dfrn_id'])) : "";
            $intro_id = x($_POST, 'intro_id') ? intval($_POST['intro_id']) : 0;
            $duplex = x($_POST, 'duplex') ? intval($_POST['duplex']) : 0;
            $cid = x($_POST, 'contact_id') ? intval($_POST['contact_id']) : 0;
            $hidden = x($_POST, 'hidden') ? intval($_POST['hidden']) : 0;
            $activity = x($_POST, 'activity') ? intval($_POST['activity']) : 0;
        }
        /**
         *
         * Ensure that dfrn_id has precedence when we go to find the contact record.
         * We only want to search based on contact id if there is no dfrn_id,
         * e.g. for OStatus network followers.
         *
         */
        if (strlen($dfrn_id)) {
            $cid = 0;
        }
        logger('Confirming request for dfrn_id (issued) ' . $dfrn_id);
        if ($cid) {
            logger('Confirming follower with contact_id: ' . $cid);
        }
        /**
         *
         * The other person will have been issued an ID when they first requested friendship.
         * Locate their record. At this time, their record will have both pending and blocked set to 1.
         * There won't be any dfrn_id if this is a network follower, so use the contact_id instead.
         *
         */
        $r = q("SELECT * FROM `contact` WHERE ( ( `issued-id` != '' AND `issued-id` = '%s' ) OR ( `id` = %d AND `id` != 0 ) ) AND `uid` = %d AND `duplex` = 0 LIMIT 1", dbesc($dfrn_id), intval($cid), intval($uid));
        if (!count($r)) {
            logger('Contact not found in DB.');
            notice(t('Contact not found.') . EOL);
            notice(t('This may occasionally happen if contact was requested by both persons and it has already been approved.') . EOL);
            return;
        }
        $contact = $r[0];
        $contact_id = $contact['id'];
        $relation = $contact['rel'];
        $site_pubkey = $contact['site-pubkey'];
        $dfrn_confirm = $contact['confirm'];
        $aes_allow = $contact['aes_allow'];
        $network = strlen($contact['issued-id']) ? NETWORK_DFRN : NETWORK_OSTATUS;
        if ($contact['network']) {
            $network = $contact['network'];
        }
        if ($network === NETWORK_DFRN) {
            /**
             *
             * Generate a key pair for all further communications with this person.
             * We have a keypair for every contact, and a site key for unknown people.
             * This provides a means to carry on relationships with other people if
             * any single key is compromised. It is a robust key. We're much more
             * worried about key leakage than anybody cracking it.
             *
             */
            require_once 'include/crypto.php';
            $res = new_keypair(4096);
            $private_key = $res['prvkey'];
            $public_key = $res['pubkey'];
            // Save the private key. Send them the public key.
            $r = q("UPDATE `contact` SET `prvkey` = '%s' WHERE `id` = %d AND `uid` = %d", dbesc($private_key), intval($contact_id), intval($uid));
            $params = array();
            /**
             *
             * Per the DFRN protocol, we will verify both ends by encrypting the dfrn_id with our
             * site private key (person on the other end can decrypt it with our site public key).
             * Then encrypt our profile URL with the other person's site public key. They can decrypt
             * it with their site private key. If the decryption on the other end fails for either
             * item, it indicates tampering or key failure on at least one site and we will not be
             * able to provide a secure communication pathway.
             *
             * If other site is willing to accept full encryption, (aes_allow is 1 AND we have php5.3
             * or later) then we encrypt the personal public key we send them using AES-256-CBC and a
             * random key which is encrypted with their site public key.
             *
             */
            $src_aes_key = random_string();
            $result = '';
            openssl_private_encrypt($dfrn_id, $result, $user[0]['prvkey']);
            $params['dfrn_id'] = bin2hex($result);
            $params['public_key'] = $public_key;
            $my_url = $a->get_baseurl() . '/profile/' . $user[0]['nickname'];
            openssl_public_encrypt($my_url, $params['source_url'], $site_pubkey);
            $params['source_url'] = bin2hex($params['source_url']);
            if ($aes_allow && function_exists('openssl_encrypt')) {
                openssl_public_encrypt($src_aes_key, $params['aes_key'], $site_pubkey);
                $params['aes_key'] = bin2hex($params['aes_key']);
                $params['public_key'] = bin2hex(openssl_encrypt($public_key, 'AES-256-CBC', $src_aes_key));
            }
            $params['dfrn_version'] = DFRN_PROTOCOL_VERSION;
            if ($duplex == 1) {
                $params['duplex'] = 1;
            }
            if ($user[0]['page-flags'] == PAGE_COMMUNITY) {
                $params['page'] = 1;
            }
            if ($user[0]['page-flags'] == PAGE_PRVGROUP) {
                $params['page'] = 2;
            }
            logger('Confirm: posting data to ' . $dfrn_confirm . ': ' . print_r($params, true), LOGGER_DATA);
            /**
             *
             * POST all this stuff to the other site.
             * Temporarily raise the network timeout to 120 seconds because the default 60
             * doesn't always give the other side quite enough time to decrypt everything.
             *
             */
            $a->config['system']['curl_timeout'] = 120;
            $res = post_url($dfrn_confirm, $params);
            logger(' Confirm: received data: ' . $res, LOGGER_DATA);
            // Now figure out what they responded. Try to be robust if the remote site is
            // having difficulty and throwing up errors of some kind.
            $leading_junk = substr($res, 0, strpos($res, '<?xml'));
            $res = substr($res, strpos($res, '<?xml'));
            if (!strlen($res)) {
                // No XML at all, this exchange is messed up really bad.
                // We shouldn't proceed, because the xml parser might choke,
                // and $status is going to be zero, which indicates success.
                // We can hardly call this a success.
                notice(t('Response from remote site was not understood.') . EOL);
                return;
            }
            if (strlen($leading_junk) && get_config('system', 'debugging')) {
                // This might be more common. Mixed error text and some XML.
                // If we're configured for debugging, show the text. Proceed in either case.
                notice(t('Unexpected response from remote site: ') . EOL . $leading_junk . EOL);
            }
            if (stristr($res, "<status") === false) {
                // wrong xml! stop here!
                notice(t('Unexpected response from remote site: ') . EOL . htmlspecialchars($res) . EOL);
                return;
            }
            $xml = parse_xml_string($res);
            $status = (int) $xml->status;
            $message = unxmlify($xml->message);
            // human readable text of what may have gone wrong.
            switch ($status) {
                case 0:
                    info(t("Confirmation completed successfully.") . EOL);
                    if (strlen($message)) {
                        notice(t('Remote site reported: ') . $message . EOL);
                    }
                    break;
                case 1:
                    // birthday paradox - generate new dfrn-id and fall through.
                    $new_dfrn_id = random_string();
                    $r = q("UPDATE contact SET `issued-id` = '%s' WHERE `id` = %d AND `uid` = %d", dbesc($new_dfrn_id), intval($contact_id), intval($uid));
                case 2:
                    notice(t("Temporary failure. Please wait and try again.") . EOL);
                    if (strlen($message)) {
                        notice(t('Remote site reported: ') . $message . EOL);
                    }
                    break;
                case 3:
                    notice(t("Introduction failed or was revoked.") . EOL);
                    if (strlen($message)) {
                        notice(t('Remote site reported: ') . $message . EOL);
                    }
                    break;
            }
            if ($status == 0 && $intro_id) {
                // Success. Delete the notification.
                $r = q("DELETE FROM `intro` WHERE `id` = %d AND `uid` = %d", intval($intro_id), intval($uid));
            }
            if ($status != 0) {
                return;
            }
        }
        /*
         *
         * We have now established a relationship with the other site.
         * Let's make our own personal copy of their profile photo so we don't have
         * to always load it from their site.
         *
         * We will also update the contact record with the nature and scope of the relationship.
         *
         */
        require_once 'include/Photo.php';
        $photos = import_profile_photo($contact['photo'], $uid, $contact_id);
        logger('dfrn_confirm: confirm - imported photos');
        if ($network === NETWORK_DFRN) {
            $new_relation = CONTACT_IS_FOLLOWER;
            if ($relation == CONTACT_IS_SHARING || $duplex) {
                $new_relation = CONTACT_IS_FRIEND;
            }
            if ($relation == CONTACT_IS_SHARING && $duplex) {
                $duplex = 0;
            }
            $r = q("UPDATE `contact` SET\n\t\t\t\t`photo` = '%s',\n\t\t\t\t`thumb` = '%s',\n\t\t\t\t`micro` = '%s',\n\t\t\t\t`rel` = %d,\n\t\t\t\t`name-date` = '%s',\n\t\t\t\t`uri-date` = '%s',\n\t\t\t\t`avatar-date` = '%s',\n\t\t\t\t`blocked` = 0,\n\t\t\t\t`pending` = 0,\n\t\t\t\t`duplex` = %d,\n\t\t\t\t`hidden` = %d,\n\t\t\t\t`network` = '%s' WHERE `id` = %d\n\t\t\t", dbesc($photos[0]), dbesc($photos[1]), dbesc($photos[2]), intval($new_relation), dbesc(datetime_convert()), dbesc(datetime_convert()), dbesc(datetime_convert()), intval($duplex), intval($hidden), dbesc(NETWORK_DFRN), intval($contact_id));
        } else {
            // $network !== NETWORK_DFRN
            $network = $contact['network'] ? $contact['network'] : NETWORK_OSTATUS;
            $notify = $contact['notify'] ? $contact['notify'] : '';
            $poll = $contact['poll'] ? $contact['poll'] : '';
            if (!$contact['notify'] || !$contact['poll']) {
                $arr = lrdd($contact['url']);
                if (count($arr)) {
                    foreach ($arr as $link) {
                        if ($link['@attributes']['rel'] === 'salmon') {
                            $notify = $link['@attributes']['href'];
                        }
                        if ($link['@attributes']['rel'] === NAMESPACE_FEED) {
                            $poll = $link['@attributes']['href'];
                        }
                    }
                }
            }
            $new_relation = $contact['rel'];
            $writable = $contact['writable'];
            if ($network === NETWORK_DIASPORA) {
                if ($duplex) {
                    $new_relation = CONTACT_IS_FRIEND;
                } else {
                    $new_relation = CONTACT_IS_FOLLOWER;
                }
                if ($new_relation != CONTACT_IS_FOLLOWER) {
                    $writable = 1;
                }
            }
            $r = q("DELETE FROM `intro` WHERE `id` = %d AND `uid` = %d", intval($intro_id), intval($uid));
            $r = q("UPDATE `contact` SET `photo` = '%s',\n\t\t\t\t`thumb` = '%s',\n\t\t\t\t`micro` = '%s',\n\t\t\t\t`name-date` = '%s',\n\t\t\t\t`uri-date` = '%s',\n\t\t\t\t`avatar-date` = '%s',\n\t\t\t\t`notify` = '%s',\n\t\t\t\t`poll` = '%s',\n\t\t\t\t`blocked` = 0,\n\t\t\t\t`pending` = 0,\n\t\t\t\t`network` = '%s',\n\t\t\t\t`writable` = %d,\n\t\t\t\t`hidden` = %d,\n\t\t\t\t`rel` = %d\n\t\t\t\tWHERE `id` = %d\n\t\t\t", dbesc($photos[0]), dbesc($photos[1]), dbesc($photos[2]), dbesc(datetime_convert()), dbesc(datetime_convert()), dbesc(datetime_convert()), dbesc($notify), dbesc($poll), dbesc($network), intval($writable), intval($hidden), intval($new_relation), intval($contact_id));
        }
        if ($r === false) {
            notice(t('Unable to set contact photo.') . EOL);
        }
        // reload contact info
        $r = q("SELECT * FROM `contact` WHERE `id` = %d LIMIT 1", intval($contact_id));
        if (count($r)) {
            $contact = $r[0];
        } else {
            $contact = null;
        }
        if (isset($new_relation) && $new_relation == CONTACT_IS_FRIEND) {
            if ($contact && $contact['network'] === NETWORK_DIASPORA) {
                require_once 'include/diaspora.php';
                $ret = diaspora_share($user[0], $r[0]);
                logger('mod_follow: diaspora_share returns: ' . $ret);
            }
            // Send a new friend post if we are allowed to...
            $r = q("SELECT `hide-friends` FROM `profile` WHERE `uid` = %d AND `is-default` = 1 LIMIT 1", intval($uid));
            if (count($r) && $r[0]['hide-friends'] == 0 && $activity && !$hidden) {
                require_once 'include/items.php';
                $self = q("SELECT * FROM `contact` WHERE `self` = 1 AND `uid` = %d LIMIT 1", intval($uid));
                if (count($self)) {
                    $arr = array();
                    $arr['uri'] = $arr['parent-uri'] = item_new_uri($a->get_hostname(), $uid);
                    $arr['uid'] = $uid;
                    $arr['contact-id'] = $self[0]['id'];
                    $arr['wall'] = 1;
                    $arr['type'] = 'wall';
                    $arr['gravity'] = 0;
                    $arr['origin'] = 1;
                    $arr['author-name'] = $arr['owner-name'] = $self[0]['name'];
                    $arr['author-link'] = $arr['owner-link'] = $self[0]['url'];
                    $arr['author-avatar'] = $arr['owner-avatar'] = $self[0]['thumb'];
                    $A = '[url=' . $self[0]['url'] . ']' . $self[0]['name'] . '[/url]';
                    $APhoto = '[url=' . $self[0]['url'] . ']' . '[img]' . $self[0]['thumb'] . '[/img][/url]';
                    $B = '[url=' . $contact['url'] . ']' . $contact['name'] . '[/url]';
                    $BPhoto = '[url=' . $contact['url'] . ']' . '[img]' . $contact['thumb'] . '[/img][/url]';
                    $arr['verb'] = ACTIVITY_FRIEND;
                    $arr['object-type'] = ACTIVITY_OBJ_PERSON;
                    $arr['body'] = sprintf(t('%1$s is now friends with %2$s'), $A, $B) . "\n\n\n" . $BPhoto;
                    $arr['object'] = '<object><type>' . ACTIVITY_OBJ_PERSON . '</type><title>' . $contact['name'] . '</title>' . '<id>' . $contact['url'] . '/' . $contact['name'] . '</id>';
                    $arr['object'] .= '<link>' . xmlify('<link rel="alternate" type="text/html" href="' . $contact['url'] . '" />' . "\n");
                    $arr['object'] .= xmlify('<link rel="photo" type="image/jpeg" href="' . $contact['thumb'] . '" />' . "\n");
                    $arr['object'] .= '</link></object>' . "\n";
                    $arr['last-child'] = 1;
                    $arr['allow_cid'] = $user[0]['allow_cid'];
                    $arr['allow_gid'] = $user[0]['allow_gid'];
                    $arr['deny_cid'] = $user[0]['deny_cid'];
                    $arr['deny_gid'] = $user[0]['deny_gid'];
                    $i = item_store($arr);
                    if ($i) {
                        proc_run('php', "include/notifier.php", "activity", "{$i}");
                    }
                }
            }
        }
        $g = q("select def_gid from user where uid = %d limit 1", intval($uid));
        if ($contact && $g && intval($g[0]['def_gid'])) {
            require_once 'include/group.php';
            group_add_member($uid, '', $contact['id'], $g[0]['def_gid']);
        }
        // Let's send our user to the contact editor in case they want to
        // do anything special with this new friend.
        if ($handsfree === null) {
            goaway($a->get_baseurl() . '/contacts/' . intval($contact_id));
        } else {
            return;
        }
        //NOTREACHED
    }
    /**
     *
     *
     * End of Scenario 1. [Local confirmation of remote friend request].
     *
     * Begin Scenario 2. This is the remote response to the above scenario.
     * This will take place on the site that originally initiated the friend request.
     * In the section above where the confirming party makes a POST and
     * retrieves xml status information, they are communicating with the following code.
     *
     */
    if (x($_POST, 'source_url')) {
        // We are processing an external confirmation to an introduction created by our user.
        $public_key = x($_POST, 'public_key') ? $_POST['public_key'] : '';
        $dfrn_id = x($_POST, 'dfrn_id') ? hex2bin($_POST['dfrn_id']) : '';
        $source_url = x($_POST, 'source_url') ? hex2bin($_POST['source_url']) : '';
        $aes_key = x($_POST, 'aes_key') ? $_POST['aes_key'] : '';
        $duplex = x($_POST, 'duplex') ? intval($_POST['duplex']) : 0;
        $page = x($_POST, 'page') ? intval($_POST['page']) : 0;
        $version_id = x($_POST, 'dfrn_version') ? (double) $_POST['dfrn_version'] : 2.0;
        $forum = $page == 1 ? 1 : 0;
        $prv = $page == 2 ? 1 : 0;
        logger('dfrn_confirm: requestee contacted: ' . $node);
        logger('dfrn_confirm: request: POST=' . print_r($_POST, true), LOGGER_DATA);
        // If $aes_key is set, both of these items require unpacking from the hex transport encoding.
        if (x($aes_key)) {
            $aes_key = hex2bin($aes_key);
            $public_key = hex2bin($public_key);
        }
        // Find our user's account
        $r = q("SELECT * FROM `user` WHERE `nickname` = '%s' LIMIT 1", dbesc($node));
        if (!count($r)) {
            $message = sprintf(t('No user record found for \'%s\' '), $node);
            xml_status(3, $message);
            // failure
            // NOTREACHED
        }
        $my_prvkey = $r[0]['prvkey'];
        $local_uid = $r[0]['uid'];
        if (!strstr($my_prvkey, 'PRIVATE KEY')) {
            $message = t('Our site encryption key is apparently messed up.');
            xml_status(3, $message);
        }
        // verify everything
        $decrypted_source_url = "";
        openssl_private_decrypt($source_url, $decrypted_source_url, $my_prvkey);
        if (!strlen($decrypted_source_url)) {
            $message = t('Empty site URL was provided or URL could not be decrypted by us.');
            xml_status(3, $message);
            // NOTREACHED
        }
        $ret = q("SELECT * FROM `contact` WHERE `url` = '%s' AND `uid` = %d LIMIT 1", dbesc($decrypted_source_url), intval($local_uid));
        if (!count($ret)) {
            if (strstr($decrypted_source_url, 'http:')) {
                $newurl = str_replace('http:', 'https:', $decrypted_source_url);
            } else {
                $newurl = str_replace('https:', 'http:', $decrypted_source_url);
            }
            $ret = q("SELECT * FROM `contact` WHERE `url` = '%s' AND `uid` = %d LIMIT 1", dbesc($newurl), intval($local_uid));
            if (!count($ret)) {
                // this is either a bogus confirmation (?) or we deleted the original introduction.
                $message = t('Contact record was not found for you on our site.');
                xml_status(3, $message);
                return;
                // NOTREACHED
            }
        }
        $relation = $ret[0]['rel'];
        // Decrypt all this stuff we just received
        $foreign_pubkey = $ret[0]['site-pubkey'];
        $dfrn_record = $ret[0]['id'];
        if (!$foreign_pubkey) {
            $message = sprintf(t('Site public key not available in contact record for URL %s.'), $newurl);
            xml_status(3, $message);
        }
        $decrypted_dfrn_id = "";
        openssl_public_decrypt($dfrn_id, $decrypted_dfrn_id, $foreign_pubkey);
        if (strlen($aes_key)) {
            $decrypted_aes_key = "";
            openssl_private_decrypt($aes_key, $decrypted_aes_key, $my_prvkey);
            $dfrn_pubkey = openssl_decrypt($public_key, 'AES-256-CBC', $decrypted_aes_key);
        } else {
            $dfrn_pubkey = $public_key;
        }
        $r = q("SELECT * FROM `contact` WHERE `dfrn-id` = '%s' LIMIT 1", dbesc($decrypted_dfrn_id));
        if (count($r)) {
            $message = t('The ID provided by your system is a duplicate on our system. It should work if you try again.');
            xml_status(1, $message);
            // Birthday paradox - duplicate dfrn-id
            // NOTREACHED
        }
        $r = q("UPDATE `contact` SET `dfrn-id` = '%s', `pubkey` = '%s' WHERE `id` = %d", dbesc($decrypted_dfrn_id), dbesc($dfrn_pubkey), intval($dfrn_record));
        if (!count($r)) {
            $message = t('Unable to set your contact credentials on our system.');
            xml_status(3, $message);
        }
        // It's possible that the other person also requested friendship.
        // If it is a duplex relationship, ditch the issued-id if one exists.
        if ($duplex) {
            $r = q("UPDATE `contact` SET `issued-id` = '' WHERE `id` = %d", intval($dfrn_record));
        }
        // We're good but now we have to scrape the profile photo and send notifications.
        $r = q("SELECT `photo` FROM `contact` WHERE `id` = %d LIMIT 1", intval($dfrn_record));
        if (count($r)) {
            $photo = $r[0]['photo'];
        } else {
            $photo = $a->get_baseurl() . '/images/person-175.jpg';
        }
        require_once "include/Photo.php";
        $photos = import_profile_photo($photo, $local_uid, $dfrn_record);
        logger('dfrn_confirm: request - photos imported');
        $new_relation = CONTACT_IS_SHARING;
        if ($relation == CONTACT_IS_FOLLOWER || $duplex) {
            $new_relation = CONTACT_IS_FRIEND;
        }
        if ($relation == CONTACT_IS_FOLLOWER && $duplex) {
            $duplex = 0;
        }
        $r = q("UPDATE `contact` SET\n\t\t\t`photo` = '%s',\n\t\t\t`thumb` = '%s',\n\t\t\t`micro` = '%s',\n\t\t\t`rel` = %d,\n\t\t\t`name-date` = '%s',\n\t\t\t`uri-date` = '%s',\n\t\t\t`avatar-date` = '%s',\n\t\t\t`blocked` = 0,\n\t\t\t`pending` = 0,\n\t\t\t`duplex` = %d,\n\t\t\t`forum` = %d,\n\t\t\t`prv` = %d,\n\t\t\t`network` = '%s' WHERE `id` = %d\n\t\t", dbesc($photos[0]), dbesc($photos[1]), dbesc($photos[2]), intval($new_relation), dbesc(datetime_convert()), dbesc(datetime_convert()), dbesc(datetime_convert()), intval($duplex), intval($forum), intval($prv), dbesc(NETWORK_DFRN), intval($dfrn_record));
        if ($r === false) {
            // indicates schema is messed up or total db failure
            $message = t('Unable to update your contact profile details on our system');
            xml_status(3, $message);
        }
        // Otherwise everything seems to have worked and we are almost done. Yay!
        // Send an email notification
        logger('dfrn_confirm: request: info updated');
        $r = q("SELECT `contact`.*, `user`.* FROM `contact` LEFT JOIN `user` ON `contact`.`uid` = `user`.`uid`\n\t\t\tWHERE `contact`.`id` = %d LIMIT 1", intval($dfrn_record));
        if (count($r)) {
            $combined = $r[0];
        }
        if (count($r) && $r[0]['notify-flags'] & NOTIFY_CONFIRM) {
            $mutual = $new_relation == CONTACT_IS_FRIEND;
            notification(array('type' => NOTIFY_CONFIRM, 'notify_flags' => $r[0]['notify-flags'], 'language' => $r[0]['language'], 'to_name' => $r[0]['username'], 'to_email' => $r[0]['email'], 'uid' => $r[0]['uid'], 'link' => $a->get_baseurl() . '/contacts/' . $dfrn_record, 'source_name' => strlen(stripslashes($r[0]['name'])) ? stripslashes($r[0]['name']) : t('[Name Withheld]'), 'source_link' => $r[0]['url'], 'source_photo' => $r[0]['photo'], 'verb' => $mutual ? ACTIVITY_FRIEND : ACTIVITY_FOLLOW, 'otype' => 'intro'));
        }
        // Send a new friend post if we are allowed to...
        if ($page && intval(get_pconfig($local_uid, 'system', 'post_joingroup'))) {
            $r = q("SELECT `hide-friends` FROM `profile` WHERE `uid` = %d AND `is-default` = 1 LIMIT 1", intval($local_uid));
            if (count($r) && $r[0]['hide-friends'] == 0) {
                require_once 'include/items.php';
                $self = q("SELECT * FROM `contact` WHERE `self` = 1 AND `uid` = %d LIMIT 1", intval($local_uid));
                if (count($self)) {
                    $arr = array();
                    $arr['uri'] = $arr['parent-uri'] = item_new_uri($a->get_hostname(), $local_uid);
                    $arr['uid'] = $local_uid;
                    $arr['contact-id'] = $self[0]['id'];
                    $arr['wall'] = 1;
                    $arr['type'] = 'wall';
                    $arr['gravity'] = 0;
                    $arr['origin'] = 1;
                    $arr['author-name'] = $arr['owner-name'] = $self[0]['name'];
                    $arr['author-link'] = $arr['owner-link'] = $self[0]['url'];
                    $arr['author-avatar'] = $arr['owner-avatar'] = $self[0]['thumb'];
                    $A = '[url=' . $self[0]['url'] . ']' . $self[0]['name'] . '[/url]';
                    $APhoto = '[url=' . $self[0]['url'] . ']' . '[img]' . $self[0]['thumb'] . '[/img][/url]';
                    $B = '[url=' . $combined['url'] . ']' . $combined['name'] . '[/url]';
                    $BPhoto = '[url=' . $combined['url'] . ']' . '[img]' . $combined['thumb'] . '[/img][/url]';
                    $arr['verb'] = ACTIVITY_JOIN;
                    $arr['object-type'] = ACTIVITY_OBJ_GROUP;
                    $arr['body'] = sprintf(t('%1$s has joined %2$s'), $A, $B) . "\n\n\n" . $BPhoto;
                    $arr['object'] = '<object><type>' . ACTIVITY_OBJ_GROUP . '</type><title>' . $combined['name'] . '</title>' . '<id>' . $combined['url'] . '/' . $combined['name'] . '</id>';
                    $arr['object'] .= '<link>' . xmlify('<link rel="alternate" type="text/html" href="' . $combined['url'] . '" />' . "\n");
                    $arr['object'] .= xmlify('<link rel="photo" type="image/jpeg" href="' . $combined['thumb'] . '" />' . "\n");
                    $arr['object'] .= '</link></object>' . "\n";
                    $arr['last-child'] = 1;
                    $arr['allow_cid'] = $user[0]['allow_cid'];
                    $arr['allow_gid'] = $user[0]['allow_gid'];
                    $arr['deny_cid'] = $user[0]['deny_cid'];
                    $arr['deny_gid'] = $user[0]['deny_gid'];
                    $i = item_store($arr);
                    if ($i) {
                        proc_run('php', "include/notifier.php", "activity", "{$i}");
                    }
                }
            }
        }
        xml_status(0);
        // Success
        return;
        // NOTREACHED
        ////////////////////// End of this scenario ///////////////////////////////////////////////
    }
    // somebody arrived here by mistake or they are fishing. Send them to the homepage.
    goaway(z_root());
    // NOTREACHED
}
Пример #16
0
function item_is_remote_self($contact, &$datarray)
{
    $a = get_app();
    if (!$contact['remote_self']) {
        return false;
    }
    // Prevent the forwarding of posts that are forwarded
    if ($datarray["extid"] == NETWORK_DFRN) {
        return false;
    }
    // Prevent to forward already forwarded posts
    if ($datarray["app"] == $a->get_hostname()) {
        return false;
    }
    // Only forward posts
    if ($datarray["verb"] != ACTIVITY_POST) {
        return false;
    }
    if ($contact['network'] != NETWORK_FEED and $datarray['private']) {
        return false;
    }
    $datarray2 = $datarray;
    logger('remote-self start - Contact ' . $contact['url'] . ' - ' . $contact['remote_self'] . ' Item ' . print_r($datarray, true), LOGGER_DEBUG);
    if ($contact['remote_self'] == 2) {
        $r = q("SELECT `id`,`url`,`name`,`thumb` FROM `contact` WHERE `uid` = %d AND `self`", intval($contact['uid']));
        if (count($r)) {
            $datarray['contact-id'] = $r[0]["id"];
            $datarray['owner-name'] = $r[0]["name"];
            $datarray['owner-link'] = $r[0]["url"];
            $datarray['owner-avatar'] = $r[0]["thumb"];
            $datarray['author-name'] = $datarray['owner-name'];
            $datarray['author-link'] = $datarray['owner-link'];
            $datarray['author-avatar'] = $datarray['owner-avatar'];
        }
        if ($contact['network'] != NETWORK_FEED) {
            $datarray["guid"] = get_guid(32);
            unset($datarray["plink"]);
            $datarray["uri"] = item_new_uri($a->get_hostname(), $contact['uid'], $datarray["guid"]);
            $datarray["parent-uri"] = $datarray["uri"];
            $datarray["extid"] = $contact['network'];
            $urlpart = parse_url($datarray2['author-link']);
            $datarray["app"] = $urlpart["host"];
        } else {
            $datarray['private'] = 0;
        }
    }
    if ($contact['network'] != NETWORK_FEED) {
        // Store the original post
        $r = item_store($datarray2, false, false);
        logger('remote-self post original item - Contact ' . $contact['url'] . ' return ' . $r . ' Item ' . print_r($datarray2, true), LOGGER_DEBUG);
    } else {
        $datarray["app"] = "Feed";
    }
    return true;
}
Пример #17
0
function like_content(&$a)
{
    if (!local_user() && !remote_user()) {
        return;
    }
    $verb = notags(trim($_GET['verb']));
    if (!$verb) {
        $verb = 'like';
    }
    switch ($verb) {
        case 'like':
        case 'unlike':
            $activity = ACTIVITY_LIKE;
            break;
        case 'dislike':
        case 'undislike':
            $activity = ACTIVITY_DISLIKE;
            break;
        default:
            return;
            break;
    }
    $item_id = $a->argc > 1 ? notags(trim($a->argv[1])) : 0;
    logger('like: verb ' . $verb . ' item ' . $item_id);
    $r = q("SELECT * FROM `item` WHERE ( `id` = '%s' OR `uri` = '%s') AND `id` = `parent` LIMIT 1", dbesc($item_id), dbesc($item_id));
    if (!$item_id || !count($r)) {
        logger('like: no item ' . $item_id);
        return;
    }
    $item = $r[0];
    $owner_uid = $item['uid'];
    if (!can_write_wall($a, $owner_uid)) {
        return;
    }
    $remote_owner = null;
    if (!$item['wall']) {
        // The top level post may have been written by somebody on another system
        $r = q("SELECT * FROM `contact` WHERE `id` = %d AND `uid` = %d LIMIT 1", intval($item['contact-id']), intval($item['uid']));
        if (!count($r)) {
            return;
        }
        if (!$r[0]['self']) {
            $remote_owner = $r[0];
        }
    }
    // this represents the post owner on this system.
    $r = q("SELECT `contact`.*, `user`.`nickname` FROM `contact` LEFT JOIN `user` ON `contact`.`uid` = `user`.`uid`\n\t\tWHERE `contact`.`self` = 1 AND `contact`.`uid` = %d LIMIT 1", intval($owner_uid));
    if (count($r)) {
        $owner = $r[0];
    }
    if (!$owner) {
        logger('like: no owner');
        return;
    }
    if (!$remote_owner) {
        $remote_owner = $owner;
    }
    // This represents the person posting
    if (local_user() && local_user() == $owner_uid) {
        $contact = $owner;
    } else {
        $r = q("SELECT * FROM `contact` WHERE `id` = %d AND `uid` = %d LIMIT 1", intval($_SESSION['visitor_id']), intval($owner_uid));
        if (count($r)) {
            $contact = $r[0];
        }
    }
    if (!$contact) {
        return;
    }
    $r = q("SELECT `id` FROM `item` WHERE `verb` = '%s' AND `deleted` = 0 \n\t\tAND `contact-id` = %d AND ( `parent` = '%s' OR `parent-uri` = '%s') LIMIT 1", dbesc($activity), intval($contact['id']), dbesc($item_id), dbesc($item_id));
    if (count($r)) {
        // Already voted, undo it
        $r = q("UPDATE `item` SET `deleted` = 1, `changed` = '%s' WHERE `id` = %d LIMIT 1", dbesc(datetime_convert()), intval($r[0]['id']));
        proc_run('php', "include/notifier.php", "like", "{$post_id}");
        return;
    }
    $uri = item_new_uri($a->get_hostname(), $owner_uid);
    $post_type = $item['resource-id'] ? t('photo') : t('status');
    $objtype = $item['resource-id'] ? ACTIVITY_OBJ_PHOTO : ACTIVITY_OBJ_NOTE;
    $link = xmlify('<link rel="alternate" type="text/html" href="' . $a->get_baseurl() . '/display/' . $owner['nickname'] . '/' . $item['id'] . '" />' . "\n");
    $body = $item['body'];
    $obj = <<<EOT

\t<object>
\t\t<type>{$objtype}</type>
\t\t<local>1</local>
\t\t<id>{$item['uri']}</id>
\t\t<link>{$link}</link>
\t\t<title></title>
\t\t<content>{$body}</content>
\t</object>
EOT;
    if ($verb === 'like') {
        $bodyverb = t('%1$s likes %2$s\'s %3$s');
    }
    if ($verb === 'dislike') {
        $bodyverb = t('%1$s doesn\'t like %2$s\'s %3$s');
    }
    if (!isset($bodyverb)) {
        return;
    }
    $arr = array();
    $arr['uri'] = $uri;
    $arr['uid'] = $owner_uid;
    $arr['contact-id'] = $contact['id'];
    $arr['type'] = 'activity';
    $arr['wall'] = $item['wall'];
    $arr['origin'] = 1;
    $arr['gravity'] = GRAVITY_LIKE;
    $arr['parent'] = $item['id'];
    $arr['parent-uri'] = $item['uri'];
    $arr['owner-name'] = $remote_owner['name'];
    $arr['owner-link'] = $remote_owner['url'];
    $arr['owner-avatar'] = $remote_owner['thumb'];
    $arr['author-name'] = $contact['name'];
    $arr['author-link'] = $contact['url'];
    $arr['author-avatar'] = $contact['thumb'];
    $ulink = '[url=' . $contact['url'] . ']' . $contact['name'] . '[/url]';
    $alink = '[url=' . $item['author-link'] . ']' . $item['author-name'] . '[/url]';
    $plink = '[url=' . $a->get_baseurl() . '/display/' . $owner['nickname'] . '/' . $item['id'] . ']' . $post_type . '[/url]';
    $arr['body'] = sprintf($bodyverb, $ulink, $alink, $plink);
    $arr['verb'] = $activity;
    $arr['object-type'] = $objtype;
    $arr['object'] = $obj;
    $arr['allow_cid'] = $item['allow_cid'];
    $arr['allow_gid'] = $item['allow_gid'];
    $arr['deny_cid'] = $item['deny_cid'];
    $arr['deny_gid'] = $item['deny_gid'];
    $arr['visible'] = 1;
    $arr['unseen'] = 1;
    $arr['last-child'] = 0;
    $post_id = item_store($arr);
    if (!$item['visible']) {
        $r = q("UPDATE `item` SET `visible` = 1 WHERE `id` = %d AND `uid` = %d LIMIT 1", intval($item['id']), intval($owner_uid));
    }
    $arr['id'] = $post_id;
    call_hooks('post_local_end', $arr);
    proc_run('php', "include/notifier.php", "like", "{$post_id}");
    killme();
    //	return; // NOTREACHED
}
Пример #18
0
function like_content(&$a)
{
    if (!local_user() && !remote_user()) {
        return;
    }
    $verb = notags(trim($_GET['verb']));
    if (!$verb) {
        $verb = 'like';
    }
    switch ($verb) {
        case 'like':
        case 'unlike':
            $activity = ACTIVITY_LIKE;
            break;
        case 'dislike':
        case 'undislike':
            $activity = ACTIVITY_DISLIKE;
            break;
        case 'attendyes':
        case 'unattendyes':
            $activity = ACTIVITY_ATTEND;
            break;
        case 'attendno':
        case 'unattendno':
            $activity = ACTIVITY_ATTENDNO;
            break;
        case 'attendmaybe':
        case 'unattendmaybe':
            $activity = ACTIVITY_ATTENDMAYBE;
            break;
        default:
            return;
            break;
    }
    $item_id = $a->argc > 1 ? notags(trim($a->argv[1])) : 0;
    logger('like: verb ' . $verb . ' item ' . $item_id);
    $r = q("SELECT * FROM `item` WHERE `id` = '%s' OR `uri` = '%s' LIMIT 1", dbesc($item_id), dbesc($item_id));
    if (!$item_id || !count($r)) {
        logger('like: no item ' . $item_id);
        return;
    }
    $item = $r[0];
    $owner_uid = $item['uid'];
    if (!can_write_wall($a, $owner_uid)) {
        return;
    }
    $remote_owner = null;
    if (!$item['wall']) {
        // The top level post may have been written by somebody on another system
        $r = q("SELECT * FROM `contact` WHERE `id` = %d AND `uid` = %d LIMIT 1", intval($item['contact-id']), intval($item['uid']));
        if (!count($r)) {
            return;
        }
        if (!$r[0]['self']) {
            $remote_owner = $r[0];
        }
    }
    // this represents the post owner on this system.
    $r = q("SELECT `contact`.*, `user`.`nickname` FROM `contact` LEFT JOIN `user` ON `contact`.`uid` = `user`.`uid`\n\t\tWHERE `contact`.`self` = 1 AND `contact`.`uid` = %d LIMIT 1", intval($owner_uid));
    if (count($r)) {
        $owner = $r[0];
    }
    if (!$owner) {
        logger('like: no owner');
        return;
    }
    if (!$remote_owner) {
        $remote_owner = $owner;
    }
    // This represents the person posting
    if (local_user() && local_user() == $owner_uid) {
        $contact = $owner;
    } else {
        $r = q("SELECT * FROM `contact` WHERE `id` = %d AND `uid` = %d LIMIT 1", intval($_SESSION['visitor_id']), intval($owner_uid));
        if (count($r)) {
            $contact = $r[0];
        }
    }
    if (!$contact) {
        return;
    }
    // See if we've been passed a return path to redirect to
    $return_path = x($_REQUEST, 'return') ? $_REQUEST['return'] : '';
    $verbs = " '" . dbesc($activity) . "' ";
    // event participation are essentially radio toggles. If you make a subsequent choice,
    // we need to eradicate your first choice.
    if ($activity === ACTIVITY_ATTEND || $activity === ACTIVITY_ATTENDNO || $activity === ACTIVITY_ATTENDMAYBE) {
        $verbs = " '" . dbesc(ACTIVITY_ATTEND) . "','" . dbesc(ACTIVITY_ATTENDNO) . "','" . dbesc(ACTIVITY_ATTENDMAYBE) . "' ";
    }
    $r = q("SELECT `id`, `guid` FROM `item` WHERE `verb` IN ( {$verbs} ) AND `deleted` = 0\n\t\tAND `contact-id` = %d AND `uid` = %d\n\t\tAND (`parent` = '%s' OR `parent-uri` = '%s' OR `thr-parent` = '%s') LIMIT 1", intval($contact['id']), intval($owner_uid), dbesc($item_id), dbesc($item_id), dbesc($item['uri']));
    if (count($r)) {
        $like_item = $r[0];
        // Already voted, undo it
        $r = q("UPDATE `item` SET `deleted` = 1, `unseen` = 1, `changed` = '%s' WHERE `id` = %d", dbesc(datetime_convert()), intval($like_item['id']));
        // Clean up the Diaspora signatures for this like
        // Go ahead and do it even if Diaspora support is disabled. We still want to clean up
        // if it had been enabled in the past
        $r = q("DELETE FROM `sign` WHERE `iid` = %d", intval($like_item['id']));
        // Save the author information for the unlike in case we need to relay to Diaspora
        store_diaspora_like_retract_sig($activity, $item, $like_item, $contact);
        //		proc_run('php',"include/notifier.php","like","$post_id"); // $post_id isn't defined here!
        $like_item_id = $like_item['id'];
        proc_run('php', "include/notifier.php", "like", "{$like_item_id}");
        like_content_return($a->get_baseurl(), $return_path);
        return;
        // NOTREACHED
    }
    $uri = item_new_uri($a->get_hostname(), $owner_uid);
    $post_type = $item['resource-id'] ? t('photo') : t('status');
    if ($item['obj_type'] === ACTIVITY_OBJ_EVENT) {
        $post_type = t('event');
    }
    $objtype = $item['resource-id'] ? ACTIVITY_OBJ_PHOTO : ACTIVITY_OBJ_NOTE;
    $link = xmlify('<link rel="alternate" type="text/html" href="' . $a->get_baseurl() . '/display/' . $owner['nickname'] . '/' . $item['id'] . '" />' . "\n");
    $body = $item['body'];
    $obj = <<<EOT

\t<object>
\t\t<type>{$objtype}</type>
\t\t<local>1</local>
\t\t<id>{$item['uri']}</id>
\t\t<link>{$link}</link>
\t\t<title></title>
\t\t<content>{$body}</content>
\t</object>
EOT;
    if ($verb === 'like') {
        $bodyverb = t('%1$s likes %2$s\'s %3$s');
    }
    if ($verb === 'dislike') {
        $bodyverb = t('%1$s doesn\'t like %2$s\'s %3$s');
    }
    if ($verb === 'attendyes') {
        $bodyverb = t('%1$s is attending %2$s\'s %3$s');
    }
    if ($verb === 'attendno') {
        $bodyverb = t('%1$s is not attending %2$s\'s %3$s');
    }
    if ($verb === 'attendmaybe') {
        $bodyverb = t('%1$s may attend %2$s\'s %3$s');
    }
    if (!isset($bodyverb)) {
        return;
    }
    $arr = array();
    $arr['uri'] = $uri;
    $arr['uid'] = $owner_uid;
    $arr['contact-id'] = $contact['id'];
    $arr['type'] = 'activity';
    $arr['wall'] = $item['wall'];
    $arr['origin'] = 1;
    $arr['gravity'] = GRAVITY_LIKE;
    $arr['parent'] = $item['id'];
    $arr['parent-uri'] = $item['uri'];
    $arr['thr-parent'] = $item['uri'];
    $arr['owner-name'] = $remote_owner['name'];
    $arr['owner-link'] = $remote_owner['url'];
    $arr['owner-avatar'] = $remote_owner['thumb'];
    $arr['author-name'] = $contact['name'];
    $arr['author-link'] = $contact['url'];
    $arr['author-avatar'] = $contact['thumb'];
    $ulink = '[url=' . $contact['url'] . ']' . $contact['name'] . '[/url]';
    $alink = '[url=' . $item['author-link'] . ']' . $item['author-name'] . '[/url]';
    $plink = '[url=' . $a->get_baseurl() . '/display/' . $owner['nickname'] . '/' . $item['id'] . ']' . $post_type . '[/url]';
    $arr['body'] = sprintf($bodyverb, $ulink, $alink, $plink);
    $arr['verb'] = $activity;
    $arr['object-type'] = $objtype;
    $arr['object'] = $obj;
    $arr['allow_cid'] = $item['allow_cid'];
    $arr['allow_gid'] = $item['allow_gid'];
    $arr['deny_cid'] = $item['deny_cid'];
    $arr['deny_gid'] = $item['deny_gid'];
    $arr['visible'] = 1;
    $arr['unseen'] = 1;
    $arr['last-child'] = 0;
    $post_id = item_store($arr);
    if (!$item['visible']) {
        $r = q("UPDATE `item` SET `visible` = 1 WHERE `id` = %d AND `uid` = %d", intval($item['id']), intval($owner_uid));
    }
    // Save the author information for the like in case we need to relay to Diaspora
    store_diaspora_like_sig($activity, $post_type, $contact, $post_id);
    $arr['id'] = $post_id;
    call_hooks('post_local_end', $arr);
    proc_run('php', "include/notifier.php", "like", "{$post_id}");
    like_content_return($a->get_baseurl(), $return_path);
    killme();
    // NOTREACHED
    //	return; // NOTREACHED
}
Пример #19
0
function poke_init(&$a)
{
    if (!local_user()) {
        return;
    }
    $uid = local_user();
    $verb = notags(trim($_GET['verb']));
    if (!$verb) {
        return;
    }
    $verbs = get_poke_verbs();
    if (!array_key_exists($verb, $verbs)) {
        return;
    }
    $activity = ACTIVITY_POKE . '#' . urlencode($verbs[$verb][0]);
    $contact_id = intval($_GET['cid']);
    if (!$contact_id) {
        return;
    }
    $parent = x($_GET, 'parent') ? intval($_GET['parent']) : 0;
    logger('poke: verb ' . $verb . ' contact ' . $contact_id, LOGGER_DEBUG);
    $r = q("SELECT * FROM `contact` WHERE `id` = %d and  `uid` = %d LIMIT 1", intval($contact_id), intval($uid));
    if (!count($r)) {
        logger('poke: no contact ' . $contact_id);
        return;
    }
    $target = $r[0];
    if ($parent) {
        $r = q("select uri, private, allow_cid, allow_gid, deny_cid, deny_gid \n\t\t\tfrom item where id = %d and parent = %d and uid = %d limit 1", intval($parent), intval($parent), intval($uid));
        if (count($r)) {
            $parent_uri = $r[0]['uri'];
            $private = $r[0]['private'];
            $allow_cid = $r[0]['allow_cid'];
            $allow_gid = $r[0]['allow_gid'];
            $deny_cid = $r[0]['deny_cid'];
            $deny_gid = $r[0]['deny_gid'];
        }
    } else {
        $private = x($_GET, 'private') ? intval($_GET['private']) : 0;
        $allow_cid = $private ? '<' . $target['id'] . '>' : $a->user['allow_cid'];
        $allow_gid = $private ? '' : $a->user['allow_gid'];
        $deny_cid = $private ? '' : $a->user['deny_cid'];
        $deny_gid = $private ? '' : $a->user['deny_gid'];
    }
    $poster = $a->contact;
    $uri = item_new_uri($a->get_hostname(), $uid);
    $arr = array();
    $arr['uid'] = $uid;
    $arr['uri'] = $uri;
    $arr['parent-uri'] = $parent_uri ? $parent_uri : $uri;
    $arr['type'] = 'activity';
    $arr['wall'] = 1;
    $arr['contact-id'] = $poster['id'];
    $arr['owner-name'] = $poster['name'];
    $arr['owner-link'] = $poster['url'];
    $arr['owner-avatar'] = $poster['thumb'];
    $arr['author-name'] = $poster['name'];
    $arr['author-link'] = $poster['url'];
    $arr['author-avatar'] = $poster['thumb'];
    $arr['title'] = '';
    $arr['allow_cid'] = $allow_cid;
    $arr['allow_gid'] = $allow_gid;
    $arr['deny_cid'] = $deny_cid;
    $arr['deny_gid'] = $deny_gid;
    $arr['last-child'] = 1;
    $arr['visible'] = 1;
    $arr['verb'] = $activity;
    $arr['private'] = $private;
    $arr['object-type'] = ACTIVITY_OBJ_PERSON;
    $arr['origin'] = 1;
    $arr['body'] = '[url=' . $poster['url'] . ']' . $poster['name'] . '[/url]' . ' ' . t($verbs[$verb][0]) . ' ' . '[url=' . $target['url'] . ']' . $target['name'] . '[/url]';
    $arr['object'] = '<object><type>' . ACTIVITY_OBJ_PERSON . '</type><title>' . $target['name'] . '</title><id>' . $a->get_baseurl() . '/contact/' . $target['id'] . '</id>';
    $arr['object'] .= '<link>' . xmlify('<link rel="alternate" type="text/html" href="' . $target['url'] . '" />' . "\n");
    $arr['object'] .= xmlify('<link rel="photo" type="image/jpeg" href="' . $target['photo'] . '" />' . "\n");
    $arr['object'] .= '</link></object>' . "\n";
    $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/' . $poster['nickname'] . '/' . $item_id), intval($uid), intval($item_id));
        proc_run('php', "include/notifier.php", "tag", "{$item_id}");
    }
    call_hooks('post_local_end', $arr);
    proc_run('php', "include/notifier.php", "like", "{$post_id}");
    return;
}
Пример #20
0
function diaspora_request($importer, $xml)
{
    $a = get_app();
    $sender_handle = unxmlify($xml->sender_handle);
    $recipient_handle = unxmlify($xml->recipient_handle);
    if (!$sender_handle || !$recipient_handle) {
        return;
    }
    $contact = diaspora_get_contact_by_handle($importer['uid'], $sender_handle);
    if ($contact) {
        // perhaps we were already sharing with this person. Now they're sharing with us.
        // That makes us friends.
        if ($contact['rel'] == CONTACT_IS_FOLLOWER && !in_array($importer['page-flags'], array(PAGE_COMMUNITY, PAGE_SOAPBOX))) {
            q("UPDATE `contact` SET `rel` = %d, `writable` = 1 WHERE `id` = %d AND `uid` = %d", intval(CONTACT_IS_FRIEND), intval($contact['id']), intval($importer['uid']));
        }
        // send notification
        $r = q("SELECT `hide-friends` FROM `profile` WHERE `uid` = %d AND `is-default` = 1 LIMIT 1", intval($importer['uid']));
        if (count($r) && !$r[0]['hide-friends'] && !$contact['hidden'] && intval(get_pconfig($importer['uid'], 'system', 'post_newfriend'))) {
            require_once 'include/items.php';
            $self = q("SELECT * FROM `contact` WHERE `self` = 1 AND `uid` = %d LIMIT 1", intval($importer['uid']));
            // they are not CONTACT_IS_FOLLOWER anymore but that's what we have in the array
            if (count($self) && $contact['rel'] == CONTACT_IS_FOLLOWER) {
                $arr = array();
                $arr['uri'] = $arr['parent-uri'] = item_new_uri($a->get_hostname(), $importer['uid']);
                $arr['uid'] = $importer['uid'];
                $arr['contact-id'] = $self[0]['id'];
                $arr['wall'] = 1;
                $arr['type'] = 'wall';
                $arr['gravity'] = 0;
                $arr['origin'] = 1;
                $arr['author-name'] = $arr['owner-name'] = $self[0]['name'];
                $arr['author-link'] = $arr['owner-link'] = $self[0]['url'];
                $arr['author-avatar'] = $arr['owner-avatar'] = $self[0]['thumb'];
                $arr['verb'] = ACTIVITY_FRIEND;
                $arr['object-type'] = ACTIVITY_OBJ_PERSON;
                $A = '[url=' . $self[0]['url'] . ']' . $self[0]['name'] . '[/url]';
                $B = '[url=' . $contact['url'] . ']' . $contact['name'] . '[/url]';
                $BPhoto = '[url=' . $contact['url'] . ']' . '[img]' . $contact['thumb'] . '[/img][/url]';
                $arr['body'] = sprintf(t('%1$s is now friends with %2$s'), $A, $B) . "\n\n\n" . $Bphoto;
                $arr['object'] = '<object><type>' . ACTIVITY_OBJ_PERSON . '</type><title>' . $contact['name'] . '</title>' . '<id>' . $contact['url'] . '/' . $contact['name'] . '</id>';
                $arr['object'] .= '<link>' . xmlify('<link rel="alternate" type="text/html" href="' . $contact['url'] . '" />' . "\n");
                $arr['object'] .= xmlify('<link rel="photo" type="image/jpeg" href="' . $contact['thumb'] . '" />' . "\n");
                $arr['object'] .= '</link></object>' . "\n";
                $arr['last-child'] = 1;
                $arr['allow_cid'] = $user[0]['allow_cid'];
                $arr['allow_gid'] = $user[0]['allow_gid'];
                $arr['deny_cid'] = $user[0]['deny_cid'];
                $arr['deny_gid'] = $user[0]['deny_gid'];
                $i = item_store($arr);
                if ($i) {
                    proc_run('php', "include/notifier.php", "activity", "{$i}");
                }
            }
        }
        return;
    }
    $ret = find_diaspora_person_by_handle($sender_handle);
    if (!count($ret) || $ret['network'] != NETWORK_DIASPORA) {
        logger('diaspora_request: Cannot resolve diaspora handle ' . $sender_handle . ' for ' . $recipient_handle);
        return;
    }
    $batch = $ret['batch'] ? $ret['batch'] : implode('/', array_slice(explode('/', $ret['url']), 0, 3)) . '/receive/public';
    $r = q("INSERT INTO `contact` (`uid`, `network`,`addr`,`created`,`url`,`nurl`,`batch`,`name`,`nick`,`photo`,`pubkey`,`notify`,`poll`,`blocked`,`priority`)\n\t\tVALUES ( %d, '%s', '%s', '%s', '%s','%s','%s','%s','%s','%s','%s','%s','%s',%d,%d) ", intval($importer['uid']), dbesc($ret['network']), dbesc($ret['addr']), datetime_convert(), dbesc($ret['url']), dbesc(normalise_link($ret['url'])), dbesc($batch), dbesc($ret['name']), dbesc($ret['nick']), dbesc($ret['photo']), dbesc($ret['pubkey']), dbesc($ret['notify']), dbesc($ret['poll']), 1, 2);
    // find the contact record we just created
    $contact_record = diaspora_get_contact_by_handle($importer['uid'], $sender_handle);
    if (!$contact_record) {
        logger('diaspora_request: unable to locate newly created contact record.');
        return;
    }
    $g = q("select def_gid from user where uid = %d limit 1", intval($importer['uid']));
    if ($g && intval($g[0]['def_gid'])) {
        require_once 'include/group.php';
        group_add_member($importer['uid'], '', $contact_record['id'], $g[0]['def_gid']);
    }
    if ($importer['page-flags'] == PAGE_NORMAL) {
        $hash = random_string() . (string) time();
        // Generate a confirm_key
        $ret = q("INSERT INTO `intro` ( `uid`, `contact-id`, `blocked`, `knowyou`, `note`, `hash`, `datetime` )\n\t\t\tVALUES ( %d, %d, %d, %d, '%s', '%s', '%s' )", intval($importer['uid']), intval($contact_record['id']), 0, 0, dbesc(t('Sharing notification from Diaspora network')), dbesc($hash), dbesc(datetime_convert()));
    } else {
        // automatic friend approval
        require_once 'include/Photo.php';
        $photos = import_profile_photo($contact_record['photo'], $importer['uid'], $contact_record['id']);
        // technically they are sharing with us (CONTACT_IS_SHARING),
        // but if our page-type is PAGE_COMMUNITY or PAGE_SOAPBOX
        // we are going to change the relationship and make them a follower.
        if ($importer['page-flags'] == PAGE_FREELOVE) {
            $new_relation = CONTACT_IS_FRIEND;
        } else {
            $new_relation = CONTACT_IS_FOLLOWER;
        }
        $r = q("UPDATE `contact` SET\n\t\t\t`photo` = '%s',\n\t\t\t`thumb` = '%s',\n\t\t\t`micro` = '%s',\n\t\t\t`rel` = %d,\n\t\t\t`name-date` = '%s',\n\t\t\t`uri-date` = '%s',\n\t\t\t`avatar-date` = '%s',\n\t\t\t`blocked` = 0,\n\t\t\t`pending` = 0,\n\t\t\t`writable` = 1\n\t\t\tWHERE `id` = %d\n\t\t\t", dbesc($photos[0]), dbesc($photos[1]), dbesc($photos[2]), intval($new_relation), dbesc(datetime_convert()), dbesc(datetime_convert()), dbesc(datetime_convert()), intval($contact_record['id']));
        $u = q("select * from user where uid = %d limit 1", intval($importer['uid']));
        if ($u) {
            $ret = diaspora_share($u[0], $contact_record);
        }
    }
    return;
}
Пример #21
0
function like_content(&$a)
{
    if (!local_user() && !remote_user()) {
        return;
    }
    $verb = notags(trim($_GET['verb']));
    if (!$verb) {
        $verb = 'like';
    }
    switch ($verb) {
        case 'like':
        case 'unlike':
            $activity = ACTIVITY_LIKE;
            break;
        case 'dislike':
        case 'undislike':
            $activity = ACTIVITY_DISLIKE;
            break;
        default:
            return;
            break;
    }
    $item_id = $a->argc > 1 ? notags(trim($a->argv[1])) : 0;
    logger('like: verb ' . $verb . ' item ' . $item_id);
    $r = q("SELECT * FROM `item` WHERE ( `id` = '%s' OR `uri` = '%s') AND `id` = `parent` LIMIT 1", dbesc($item_id), dbesc($item_id));
    if (!$item_id || !count($r)) {
        logger('like: no item ' . $item_id);
        return;
    }
    $item = $r[0];
    $owner_uid = $item['uid'];
    if (!can_write_wall($a, $owner_uid)) {
        return;
    }
    $remote_owner = null;
    if (!$item['wall']) {
        // The top level post may have been written by somebody on another system
        $r = q("SELECT * FROM `contact` WHERE `id` = %d AND `uid` = %d LIMIT 1", intval($item['contact-id']), intval($item['uid']));
        if (!count($r)) {
            return;
        }
        if (!$r[0]['self']) {
            $remote_owner = $r[0];
        }
    }
    // this represents the post owner on this system.
    $r = q("SELECT `contact`.*, `user`.`nickname` FROM `contact` LEFT JOIN `user` ON `contact`.`uid` = `user`.`uid`\n\t\tWHERE `contact`.`self` = 1 AND `contact`.`uid` = %d LIMIT 1", intval($owner_uid));
    if (count($r)) {
        $owner = $r[0];
    }
    if (!$owner) {
        logger('like: no owner');
        return;
    }
    if (!$remote_owner) {
        $remote_owner = $owner;
    }
    // This represents the person posting
    if (local_user() && local_user() == $owner_uid) {
        $contact = $owner;
    } else {
        $r = q("SELECT * FROM `contact` WHERE `id` = %d AND `uid` = %d LIMIT 1", intval($_SESSION['visitor_id']), intval($owner_uid));
        if (count($r)) {
            $contact = $r[0];
        }
    }
    if (!$contact) {
        return;
    }
    $r = q("SELECT * FROM `item` WHERE `verb` = '%s' AND `deleted` = 0 \n\t\tAND `contact-id` = %d AND ( `parent` = '%s' OR `parent-uri` = '%s') LIMIT 1", dbesc($activity), intval($contact['id']), dbesc($item_id), dbesc($item_id));
    if (count($r)) {
        $like_item = $r[0];
        // Already voted, undo it
        $r = q("UPDATE `item` SET `deleted` = 1, `changed` = '%s' WHERE `id` = %d LIMIT 1", dbesc(datetime_convert()), intval($like_item['id']));
        // Clean up the `sign` table
        $r = q("DELETE FROM `sign` WHERE `iid` = %d", intval($like_item['id']));
        // Save the author information for the unlike in case we need to relay to Diaspora
        // Note that we can only create a signature for a user of the local server. We don't have
        // a key for remote users. That is ok, because if a remote user is "unlike"ing a post, it
        // means we are the relay, and for relayable_retractions, Diaspora
        // only checks the parent_author_signature if it doesn't have to relay further
        //
        // If $item['resource-id'] exists, it means the item is a photo. Diaspora doesn't support
        // likes on photos, so don't bother.
        if ($activity === ACTIVITY_LIKE && !$item['resource-id']) {
            $signed_text = $like_item['guid'] . ';' . 'Like';
            if ($contact['network'] === NETWORK_DIASPORA) {
                $diaspora_handle = $contact['addr'];
            } else {
                // Only works for NETWORK_DFRN
                $contact_baseurl_start = strpos($contact['url'], '://') + 3;
                $contact_baseurl_length = strpos($contact['url'], '/profile') - $contact_baseurl_start;
                $contact_baseurl = substr($contact['url'], $contact_baseurl_start, $contact_baseurl_length);
                $diaspora_handle = $contact['nick'] . '@' . $contact_baseurl;
                // Get contact's private key if he's a user of the local Friendica server
                $r = q("SELECT `contact`.`uid` FROM `contact` WHERE `url` = '%s' AND `self` = 1 LIMIT 1", dbesc($contact['url']));
                if ($r) {
                    $contact_uid = $r['uid'];
                    $r = q("SELECT prvkey FROM user WHERE uid = %d LIMIT 1", intval($contact_uid));
                    if ($r) {
                        $authorsig = base64_encode(rsa_sign($signed_text, $r['prvkey'], 'sha256'));
                    }
                }
            }
            if (!isset($authorsig)) {
                $authorsig = '';
            }
            q("insert into sign (`retract_iid`,`signed_text`,`signature`,`signer`) values (%d,'%s','%s','%s') ", intval($like_item['id']), dbesc($signed_text), dbesc($authorsig), dbesc($diaspora_handle));
        }
        //		proc_run('php',"include/notifier.php","like","$post_id"); // $post_id isn't defined here!
        $like_item_id = $like_item['id'];
        proc_run('php', "include/notifier.php", "like", "{$like_item_id}");
        return;
    }
    $uri = item_new_uri($a->get_hostname(), $owner_uid);
    $post_type = $item['resource-id'] ? t('photo') : t('status');
    $objtype = $item['resource-id'] ? ACTIVITY_OBJ_PHOTO : ACTIVITY_OBJ_NOTE;
    $link = xmlify('<link rel="alternate" type="text/html" href="' . $a->get_baseurl() . '/display/' . $owner['nickname'] . '/' . $item['id'] . '" />' . "\n");
    $body = $item['body'];
    $obj = <<<EOT

\t<object>
\t\t<type>{$objtype}</type>
\t\t<local>1</local>
\t\t<id>{$item['uri']}</id>
\t\t<link>{$link}</link>
\t\t<title></title>
\t\t<content>{$body}</content>
\t</object>
EOT;
    if ($verb === 'like') {
        $bodyverb = t('%1$s likes %2$s\'s %3$s');
    }
    if ($verb === 'dislike') {
        $bodyverb = t('%1$s doesn\'t like %2$s\'s %3$s');
    }
    if (!isset($bodyverb)) {
        return;
    }
    $arr = array();
    $arr['uri'] = $uri;
    $arr['uid'] = $owner_uid;
    $arr['contact-id'] = $contact['id'];
    $arr['type'] = 'activity';
    $arr['wall'] = $item['wall'];
    $arr['origin'] = 1;
    $arr['gravity'] = GRAVITY_LIKE;
    $arr['parent'] = $item['id'];
    $arr['parent-uri'] = $item['uri'];
    $arr['owner-name'] = $remote_owner['name'];
    $arr['owner-link'] = $remote_owner['url'];
    $arr['owner-avatar'] = $remote_owner['thumb'];
    $arr['author-name'] = $contact['name'];
    $arr['author-link'] = $contact['url'];
    $arr['author-avatar'] = $contact['thumb'];
    $ulink = '[url=' . $contact['url'] . ']' . $contact['name'] . '[/url]';
    $alink = '[url=' . $item['author-link'] . ']' . $item['author-name'] . '[/url]';
    $plink = '[url=' . $a->get_baseurl() . '/display/' . $owner['nickname'] . '/' . $item['id'] . ']' . $post_type . '[/url]';
    $arr['body'] = sprintf($bodyverb, $ulink, $alink, $plink);
    $arr['verb'] = $activity;
    $arr['object-type'] = $objtype;
    $arr['object'] = $obj;
    $arr['allow_cid'] = $item['allow_cid'];
    $arr['allow_gid'] = $item['allow_gid'];
    $arr['deny_cid'] = $item['deny_cid'];
    $arr['deny_gid'] = $item['deny_gid'];
    $arr['visible'] = 1;
    $arr['unseen'] = 1;
    $arr['last-child'] = 0;
    $post_id = item_store($arr);
    if (!$item['visible']) {
        $r = q("UPDATE `item` SET `visible` = 1 WHERE `id` = %d AND `uid` = %d LIMIT 1", intval($item['id']), intval($owner_uid));
    }
    // Save the author information for the like in case we need to relay to Diaspora
    // Note that we can only create a signature for a user of the local server. We don't have
    // a key for remote users. That is ok, because if a remote user is "unlike"ing a post, it
    // means we are the relay, and for relayable_retractions, Diaspora
    // only checks the parent_author_signature if it doesn't have to relay further
    if ($activity === ACTIVITY_LIKE && $post_type === t('status')) {
        if ($contact['network'] === NETWORK_DIASPORA) {
            $diaspora_handle = $contact['addr'];
        } else {
            // Only works for NETWORK_DFRN
            $contact_baseurl_start = strpos($contact['url'], '://') + 3;
            $contact_baseurl_length = strpos($contact['url'], '/profile') - $contact_baseurl_start;
            $contact_baseurl = substr($contact['url'], $contact_baseurl_start, $contact_baseurl_length);
            $diaspora_handle = $contact['nick'] . '@' . $contact_baseurl;
            // Get contact's private key if he's a user of the local Friendica server
            $r = q("SELECT `contact`.`uid` FROM `contact` WHERE `url` = '%s' AND `self` = 1 LIMIT 1", dbesc($contact['url']));
            if ($r) {
                $contact_uid = $r['uid'];
                $r = q("SELECT prvkey FROM user WHERE uid = %d LIMIT 1", intval($contact_uid));
                if ($r) {
                    $contact_uprvkey = $r['prvkey'];
                }
            }
        }
        $r = q("SELECT guid, parent FROM `item` WHERE id = %d LIMIT 1", intval($post_id));
        if ($r) {
            $p = q("SELECT guid FROM `item` WHERE id = %d AND parent = %d LIMIT 1", intval($r[0]['parent']), intval($r[0]['parent']));
            if ($p) {
                $signed_text = $r[0]['guid'] . ';Post;' . $p[0]['guid'] . ';true;' . $diaspora_handle;
                if (isset($contact_uprvkey)) {
                    $authorsig = base64_encode(rsa_sign($signed_text, $contact_uprvkey, 'sha256'));
                } else {
                    $authorsig = '';
                }
                q("insert into sign (`iid`,`signed_text`,`signature`,`signer`) values (%d,'%s','%s','%s') ", intval($post_id), dbesc($signed_text), dbesc($authorsig), dbesc($diaspora_handle));
            }
        }
    }
    $arr['id'] = $post_id;
    call_hooks('post_local_end', $arr);
    proc_run('php', "include/notifier.php", "like", "{$post_id}");
    killme();
    //	return; // NOTREACHED
}