Example #1
0
function drop_item($id, $interactive = true)
{
    $a = get_app();
    // locate item to be deleted
    $r = q("SELECT * FROM `item` WHERE `id` = %d LIMIT 1", intval($id));
    if (!count($r)) {
        if (!$interactive) {
            return 0;
        }
        notice(t('Item not found.') . EOL);
        goaway($a->get_baseurl() . '/' . $_SESSION['return_url']);
    }
    $item = $r[0];
    $owner = $item['uid'];
    $cid = 0;
    // check if logged in user is either the author or owner of this item
    if (is_array($_SESSION['remote'])) {
        foreach ($_SESSION['remote'] as $visitor) {
            if ($visitor['uid'] == $item['uid'] && $visitor['cid'] == $item['contact-id']) {
                $cid = $visitor['cid'];
                break;
            }
        }
    }
    if (local_user() == $item['uid'] || $cid || !$interactive) {
        // Check if we should do HTML-based delete confirmation
        if ($_REQUEST['confirm']) {
            // <form> can't take arguments in its "action" parameter
            // so add any arguments as hidden inputs
            $query = explode_querystring($a->query_string);
            $inputs = array();
            foreach ($query['args'] as $arg) {
                if (strpos($arg, 'confirm=') === false) {
                    $arg_parts = explode('=', $arg);
                    $inputs[] = array('name' => $arg_parts[0], 'value' => $arg_parts[1]);
                }
            }
            return replace_macros(get_markup_template('confirm.tpl'), array('$method' => 'get', '$message' => t('Do you really want to delete this item?'), '$extra_inputs' => $inputs, '$confirm' => t('Yes'), '$confirm_url' => $query['base'], '$confirm_name' => 'confirmed', '$cancel' => t('Cancel')));
        }
        // Now check how the user responded to the confirmation query
        if ($_REQUEST['canceled']) {
            goaway($a->get_baseurl() . '/' . $_SESSION['return_url']);
        }
        logger('delete item: ' . $item['id'], LOGGER_DEBUG);
        // delete the item
        $r = q("UPDATE `item` SET `deleted` = 1, `title` = '', `body` = '', `edited` = '%s', `changed` = '%s' WHERE `id` = %d", dbesc(datetime_convert()), dbesc(datetime_convert()), intval($item['id']));
        create_tags_from_item($item['id']);
        create_files_from_item($item['id']);
        delete_thread($item['id'], $item['parent-uri']);
        // clean up categories and tags so they don't end up as orphans
        $matches = false;
        $cnt = preg_match_all('/<(.*?)>/', $item['file'], $matches, PREG_SET_ORDER);
        if ($cnt) {
            foreach ($matches as $mtch) {
                file_tag_unsave_file($item['uid'], $item['id'], $mtch[1], true);
            }
        }
        $matches = false;
        $cnt = preg_match_all('/\\[(.*?)\\]/', $item['file'], $matches, PREG_SET_ORDER);
        if ($cnt) {
            foreach ($matches as $mtch) {
                file_tag_unsave_file($item['uid'], $item['id'], $mtch[1], false);
            }
        }
        // If item is a link to a photo resource, nuke all the associated photos
        // (visitors will not have photo resources)
        // This only applies to photos uploaded from the photos page. Photos inserted into a post do not
        // generate a resource-id and therefore aren't intimately linked to the item.
        if (strlen($item['resource-id'])) {
            q("DELETE FROM `photo` WHERE `resource-id` = '%s' AND `uid` = %d ", dbesc($item['resource-id']), intval($item['uid']));
            // ignore the result
        }
        // If item is a link to an event, nuke the event record.
        if (intval($item['event-id'])) {
            q("DELETE FROM `event` WHERE `id` = %d AND `uid` = %d", intval($item['event-id']), intval($item['uid']));
            // ignore the result
        }
        // If item has attachments, drop them
        foreach (explode(",", $item['attach']) as $attach) {
            preg_match("|attach/(\\d+)|", $attach, $matches);
            q("DELETE FROM `attach` WHERE `id` = %d AND `uid` = %d", intval($matches[1]), local_user());
            // ignore the result
        }
        // clean up item_id and sign meta-data tables
        /*
        // Old code - caused very long queries and warning entries in the mysql logfiles:
        
        $r = q("DELETE FROM item_id where iid in (select id from item where parent = %d and uid = %d)",
        	intval($item['id']),
        	intval($item['uid'])
        );
        
        $r = q("DELETE FROM sign where iid in (select id from item where parent = %d and uid = %d)",
        	intval($item['id']),
        	intval($item['uid'])
        );
        */
        // The new code splits the queries since the mysql optimizer really has bad problems with subqueries
        // Creating list of parents
        $r = q("select id from item where parent = %d and uid = %d", intval($item['id']), intval($item['uid']));
        $parentid = "";
        foreach ($r as $row) {
            if ($parentid != "") {
                $parentid .= ", ";
            }
            $parentid .= $row["id"];
        }
        // Now delete them
        if ($parentid != "") {
            $r = q("DELETE FROM item_id where iid in (%s)", dbesc($parentid));
            $r = q("DELETE FROM sign where iid in (%s)", dbesc($parentid));
        }
        // If it's the parent of a comment thread, kill all the kids
        if ($item['uri'] == $item['parent-uri']) {
            $r = q("UPDATE `item` SET `deleted` = 1, `edited` = '%s', `changed` = '%s', `body` = '' , `title` = ''\n\t\t\t\tWHERE `parent-uri` = '%s' AND `uid` = %d ", dbesc(datetime_convert()), dbesc(datetime_convert()), dbesc($item['parent-uri']), intval($item['uid']));
            create_tags_from_itemuri($item['parent-uri'], $item['uid']);
            create_files_from_itemuri($item['parent-uri'], $item['uid']);
            delete_thread_uri($item['parent-uri'], $item['uid']);
            // ignore the result
        } else {
            // ensure that last-child is set in case the comment that had it just got wiped.
            q("UPDATE `item` SET `last-child` = 0, `changed` = '%s' WHERE `parent-uri` = '%s' AND `uid` = %d ", dbesc(datetime_convert()), dbesc($item['parent-uri']), intval($item['uid']));
            // who is the last child now?
            $r = q("SELECT `id` FROM `item` WHERE `parent-uri` = '%s' AND `type` != 'activity' AND `deleted` = 0 AND `uid` = %d ORDER BY `edited` DESC LIMIT 1", dbesc($item['parent-uri']), intval($item['uid']));
            if (count($r)) {
                q("UPDATE `item` SET `last-child` = 1 WHERE `id` = %d", intval($r[0]['id']));
            }
            // Add a relayable_retraction signature for Diaspora.
            store_diaspora_retract_sig($item, $a->user, $a->get_baseurl());
        }
        $drop_id = intval($item['id']);
        // send the notification upstream/downstream as the case may be
        proc_run('php', "include/notifier.php", "drop", "{$drop_id}");
        if (!$interactive) {
            return $owner;
        }
        goaway($a->get_baseurl() . '/' . $_SESSION['return_url']);
        //NOTREACHED
    } else {
        if (!$interactive) {
            return 0;
        }
        notice(t('Permission denied.') . EOL);
        goaway($a->get_baseurl() . '/' . $_SESSION['return_url']);
        //NOTREACHED
    }
}
Example #2
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
}
Example #3
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);
    $phototypes = Photo::supportedTypes();
    $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()) {
            $cid = 0;
            if (is_array($_SESSION['remote'])) {
                foreach ($_SESSION['remote'] as $v) {
                    if ($v['uid'] == $page_owner_uid) {
                        $cid = $v['cid'];
                        break;
                    }
                }
            }
            if ($cid) {
                $r = q("SELECT `uid` FROM `contact` WHERE `blocked` = 0 AND `pending` = 0 AND `id` = %d AND `uid` = %d LIMIT 1", intval($cid), intval($page_owner_uid));
                if (count($r)) {
                    $can_post = true;
                    $visitor = $cid;
                }
            }
        }
    }
    if (!$can_post) {
        notice(t('Permission denied.') . EOL);
        killme();
    }
    $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
        }
        // Check if the user has responded to a delete confirmation query
        if ($_REQUEST['canceled']) {
            goaway($a->get_baseurl() . '/' . $_SESSION['photo_return']);
        }
        $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')) {
            // Check if we should do HTML-based delete confirmation
            if ($_REQUEST['confirm']) {
                $drop_url = $a->query_string;
                $extra_inputs = array(array('name' => 'albumname', 'value' => $_POST['albumname']));
                $a->page['content'] = replace_macros(get_markup_template('confirm.tpl'), array('$method' => 'post', '$message' => t('Do you really want to delete this photo album and all its photos?'), '$extra_inputs' => $extra_inputs, '$confirm' => t('Delete Album'), '$confirm_url' => $drop_url, '$confirm_name' => 'dropalbum', '$cancel' => t('Cancel')));
                $a->error = 1;
                // Set $a->error so the other module functions don't execute
                return;
            }
            $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));
                    create_tags_from_itemuri($rr['parent-uri'], $page_owner_uid);
                    delete_thread_uri($rr['parent-uri'], $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
    }
    // Check if the user has responded to a delete confirmation query for a single photo
    if ($a->argc > 2 && $_REQUEST['canceled']) {
        goaway($a->get_baseurl() . '/' . $_SESSION['photo_return']);
    }
    if ($a->argc > 2 && x($_POST, 'delete') && $_POST['delete'] == t('Delete Photo')) {
        // same as above but remove single photo
        // Check if we should do HTML-based delete confirmation
        if ($_REQUEST['confirm']) {
            $drop_url = $a->query_string;
            $a->page['content'] = replace_macros(get_markup_template('confirm.tpl'), array('$method' => 'post', '$message' => t('Do you really want to delete this photo?'), '$extra_inputs' => array(), '$confirm' => t('Delete Photo'), '$confirm_url' => $drop_url, '$confirm_name' => 'delete', '$cancel' => t('Cancel')));
            $a->error = 1;
            // Set $a->error so the other module functions don't execute
            return;
        }
        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));
                create_tags_from_itemuri($i[0]['uri'], $page_owner_uid);
                delete_thread_uri($i[0]['uri'], $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() . '/photos/' . $a->data['user']['nickname']);
        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 || intval($_POST['rotate']) == 2)) {
            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'], $r[0]['type']);
                if ($ph->is_valid()) {
                    $rotate_deg = intval($_POST['rotate']) == 1 ? 270 : 90;
                    $ph->rotate($rotate_deg);
                    $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", 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", 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", 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)) {
            $ext = $phototypes[$p[0]['type']];
            $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'] . '.' . $ext . '[/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));
                            } else {
                                $newname = str_replace('_', ' ', $name);
                                //select someone from this user's contacts by name
                                $r = q("SELECT * FROM `contact` WHERE `name` = '%s' AND `uid` = %d LIMIT 1", dbesc($newname), intval($page_owner_uid));
                                if (!$r) {
                                    //select someone by attag or nick and the name passed in
                                    $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));
                                }
                            }
                            /*							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]';
                        }
                    } elseif (strpos($tag, '#') === 0) {
                        $tagname = substr($tag, 1);
                        $str_tags .= '#[url=' . $a->get_baseurl() . "/search?tag=" . $tagname . ']' . $tagname . '[/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", dbesc($newtag), dbesc($newinform), dbesc(datetime_convert()), dbesc(datetime_convert()), intval($item_id), intval($page_owner_uid));
            create_tags_from_item($item_id);
            update_thread($item_id);
            $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'] = sprintf(t('%1$s was tagged in %2$s by %3$s'), '[url=' . $tagged[1] . ']' . $tagged[0] . '[/url]', '[url=' . $a->get_baseurl() . '/photos/' . $owner_record['nickname'] . '/image/' . $p[0]['resource-id'] . ']' . t('a photo') . '[/url]', '[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 . '.' . $ext . '[/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="' . $p[0]['type'] . '" 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="' . $p[0]['type'] . '" href="' . $a->get_baseurl() . "/photo/" . $p[0]['resource-id'] . '-' . $best . '.' . $ext . '" />') . '</link></target>';
                    $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/' . $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, 'type' => '');
    call_hooks('photo_post_file', $ret);
    if (x($ret, 'src') && x($ret, 'filesize')) {
        $src = $ret['src'];
        $filename = $ret['filename'];
        $filesize = $ret['filesize'];
        $type = $ret['type'];
    } else {
        $src = $_FILES['userfile']['tmp_name'];
        $filename = basename($_FILES['userfile']['name']);
        $filesize = intval($_FILES['userfile']['size']);
        $type = $_FILES['userfile']['type'];
    }
    if ($type == "") {
        $type = guess_image_type($filename);
    }
    logger('photos: upload: received file: ' . $filename . ' as ' . $src . ' (' . $type . ') ' . $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);
    $r = q("select sum(octet_length(data)) as total from photo where uid = %d and scale = 0 and album != 'Contact Photos' ", intval($a->data['user']['uid']));
    $limit = service_class_fetch($a->data['user']['uid'], 'photo_upload_limit');
    if ($limit !== false && $r[0]['total'] + strlen($imagedata) > $limit) {
        notice(upgrade_message() . EOL);
        @unlink($src);
        $foo = 0;
        call_hooks('photo_post_end', $foo);
        killme();
    }
    $ph = new Photo($imagedata, $type);
    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();
    }
    $ph->orient($src);
    @unlink($src);
    $max_length = get_config('system', 'max_image_length');
    if (!$max_length) {
        $max_length = MAX_IMAGE_LENGTH;
    }
    if ($max_length > 0) {
        $ph->scaleImage($max_length);
    }
    $width = $ph->getWidth();
    $height = $ph->getHeight();
    $smallest = 0;
    $photo_hash = 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}." . $ph->getExt() . '[/img]' . '[/url]';
    $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/' . $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
}
Example #4
0
function create_tags_from_itemuri($itemuri, $uid)
{
    $messages = q("SELECT `id` FROM `item` WHERE uri ='%s' AND uid=%d", dbesc($itemuri), intval($uid));
    if (count($messages)) {
        foreach ($messages as $message) {
            create_tags_from_item($message["id"]);
        }
    }
}
Example #5
0
function update_items()
{
    //$messages = q("SELECT `id` FROM `item` where tag !='' ORDER BY `created` DESC limit 10");
    $messages = q("SELECT `id` FROM `item` where tag !=''");
    foreach ($messages as $message) {
        create_tags_from_item($message["id"]);
    }
}