/** * Set the mode we'll be displayed on */ private function set_mode($mode) { if ($this->get_mode() == $mode) { return; } $a = $this->get_app(); switch ($mode) { case 'network': case 'notes': $this->profile_owner = local_user(); $this->writable = true; break; case 'profile': $this->profile_owner = $a->profile['profile_uid']; $this->writable = can_write_wall($a, $this->profile_owner); break; case 'display': $this->profile_owner = $a->profile['uid']; $this->writable = can_write_wall($a, $this->profile_owner); break; default: logger('[ERROR] Conversation::set_mode : Unhandled mode (' . $mode . ').', LOGGER_DEBUG); return false; break; } $this->mode = $mode; }
function common_friends_visitor_widget($profile_uid) { $a = get_app(); if (local_user() == $profile_uid) { return; } $cid = $zcid = 0; if (can_write_wall($a, $profile_uid)) { $cid = remote_user(); } else { if (get_my_url()) { $r = q("select id from contact where nurl = '%s' and uid = %d limit 1", dbesc(normalise_link(get_my_url())), intval($profile_uid)); if (count($r)) { $cid = $r[0]['id']; } else { $r = q("select id from gcontact where nurl = '%s' limit 1", dbesc(normalise_link(get_my_url()))); if (count($r)) { $zcid = $r[0]['id']; } } } } if ($cid == 0 && $zcid == 0) { return; } require_once 'include/socgraph.php'; if ($cid) { $t = count_common_friends($profile_uid, $cid); } else { $t = count_common_friends_zcid($profile_uid, $zcid); } if (!$t) { return; } if ($cid) { $r = common_friends($profile_uid, $cid, 0, 5, true); } else { $r = common_friends_zcid($profile_uid, $zcid, 0, 5, true); } return replace_macros(get_markup_template('remote_friends_common.tpl'), array('$desc' => sprintf(tt("%d contact in common", "%d contacts in common", $t), $t), '$base' => $a->get_baseurl(), '$uid' => $profile_uid, '$cid' => $cid ? $cid : '0', '$linkmore' => $t > 5 ? 'true' : '', '$more' => t('show more'), '$items' => $r)); }
function conversation(&$a, $items, $mode, $update, $preview = false) { require_once 'bbcode.php'; $ssl_state = local_user() ? true : false; $profile_owner = 0; $page_writeable = false; $previewing = $preview ? ' preview ' : ''; if ($mode === 'network') { $profile_owner = local_user(); $page_writeable = true; } if ($mode === 'profile') { $profile_owner = $a->profile['profile_uid']; $page_writeable = can_write_wall($a, $profile_owner); } if ($mode === 'notes') { $profile_owner = local_user(); $page_writeable = true; } if ($mode === 'display') { $profile_owner = $a->profile['uid']; $page_writeable = can_write_wall($a, $profile_owner); } if ($mode === 'community') { $profile_owner = 0; $page_writeable = false; } if ($update) { $return_url = $_SESSION['return_url']; } else { $return_url = $_SESSION['return_url'] = $a->query_string; } load_contact_links(local_user()); $cb = array('items' => $items, 'mode' => $mode, 'update' => $update, 'preview' => $preview); call_hooks('conversation_start', $cb); $items = $cb['items']; $cmnt_tpl = get_markup_template('comment_item.tpl'); $tpl = 'wall_item.tpl'; $wallwall = 'wallwall_item.tpl'; $hide_comments_tpl = get_markup_template('hide_comments.tpl'); $alike = array(); $dlike = array(); // array with html for each thread (parent+comments) $threads = array(); $threadsid = -1; if ($items && count($items)) { if ($mode === 'network-new' || $mode === 'search' || $mode === 'community') { // "New Item View" on network page or search page results // - just loop through the items and format them minimally for display //$tpl = get_markup_template('search_item.tpl'); $tpl = 'search_item.tpl'; foreach ($items as $item) { $threadsid++; $comment = ''; $owner_url = ''; $owner_photo = ''; $owner_name = ''; $sparkle = ''; if ($mode === 'search' || $mode === 'community') { if ((activity_match($item['verb'], ACTIVITY_LIKE) || activity_match($item['verb'], ACTIVITY_DISLIKE)) && $item['id'] != $item['parent']) { continue; } $nickname = $item['nickname']; } else { $nickname = $a->user['nickname']; } // prevent private email from leaking. if ($item['network'] === NETWORK_MAIL && local_user() != $item['uid']) { continue; } $profile_name = strlen($item['author-name']) ? $item['author-name'] : $item['name']; if ($item['author-link'] && !$item['author-name']) { $profile_name = $item['author-link']; } $sp = false; $profile_link = best_link_url($item, $sp); if ($profile_link === 'mailbox') { $profile_link = ''; } if ($sp) { $sparkle = ' sparkle'; } else { $profile_link = zrl($profile_link); } $normalised = normalise_link(strlen($item['author-link']) ? $item['author-link'] : $item['url']); if ($normalised != 'mailbox' && x($a->contacts[$normalised])) { $profile_avatar = $a->contacts[$normalised]['thumb']; } else { $profile_avatar = strlen($item['author-avatar']) ? $item['author-avatar'] : $item['thumb']; } $locate = array('location' => $item['location'], 'coord' => $item['coord'], 'html' => ''); call_hooks('render_location', $locate); $location = strlen($locate['html']) ? $locate['html'] : render_location_google($locate); localize_item($item); if ($mode === 'network-new') { $dropping = true; } else { $dropping = false; } $drop = array('dropping' => $dropping, 'select' => t('Select'), 'delete' => t('Delete')); $star = false; $isstarred = "unstarred"; $lock = false; $likebuttons = false; $shareable = false; $body = prepare_body($item, true); //$tmp_item = replace_macros($tpl,array( $tmp_item = array('template' => $tpl, 'id' => $preview ? 'P0' : $item['item_id'], 'linktitle' => sprintf(t('View %s\'s profile @ %s'), $profile_name, strlen($item['author-link']) ? $item['author-link'] : $item['url']), 'profile_url' => $profile_link, 'item_photo_menu' => item_photo_menu($item), 'name' => template_escape($profile_name), 'sparkle' => $sparkle, 'lock' => $lock, 'thumb' => $profile_avatar, 'title' => template_escape($item['title']), 'body' => template_escape($body), 'text' => strip_tags(template_escape($body)), 'ago' => $item['app'] ? sprintf(t('%s from %s'), relative_date($item['created']), $item['app']) : relative_date($item['created']), 'location' => template_escape($location), 'indent' => '', 'owner_name' => template_escape($owner_name), 'owner_url' => $owner_url, 'owner_photo' => $owner_photo, 'plink' => get_plink($item), 'edpost' => false, 'isstarred' => $isstarred, 'star' => $star, 'drop' => $drop, 'vote' => $likebuttons, 'like' => '', 'dislike' => '', 'comment' => '', 'conv' => $preview ? '' : array('href' => $a->get_baseurl($ssl_state) . '/display/' . $nickname . '/' . $item['id'], 'title' => t('View in context')), 'previewing' => $previewing, 'wait' => t('Please wait')); $arr = array('item' => $item, 'output' => $tmp_item); call_hooks('display_item', $arr); $threads[$threadsid]['id'] = $item['item_id']; $threads[$threadsid]['items'] = array($arr['output']); } } else { // Normal View // Figure out how many comments each parent has // (Comments all have gravity of 6) // Store the result in the $comments array $comments = array(); foreach ($items as $item) { if (intval($item['gravity']) == 6 && $item['id'] != $item['parent']) { if (!x($comments, $item['parent'])) { $comments[$item['parent']] = 1; } else { $comments[$item['parent']] += 1; } } elseif (!x($comments, $item['parent'])) { $comments[$item['parent']] = 0; } // avoid notices later on } // map all the like/dislike activities for each parent item // Store these in the $alike and $dlike arrays foreach ($items as $item) { like_puller($a, $item, $alike, 'like'); like_puller($a, $item, $dlike, 'dislike'); } $comments_collapsed = false; $comments_seen = 0; $comment_lastcollapsed = false; $comment_firstcollapsed = false; $blowhard = 0; $blowhard_count = 0; foreach ($items as $item) { $comment = ''; $template = $tpl; $commentww = ''; $sparkle = ''; $owner_url = $owner_photo = $owner_name = ''; // We've already parsed out like/dislike for special treatment. We can ignore them now if ((activity_match($item['verb'], ACTIVITY_LIKE) || activity_match($item['verb'], ACTIVITY_DISLIKE)) && $item['id'] != $item['parent']) { continue; } $toplevelpost = $item['id'] == $item['parent'] ? true : false; $toplevelprivate = false; // Take care of author collapsing and comment collapsing // (author collapsing is currently disabled) // If a single author has more than 3 consecutive top-level posts, squash the remaining ones. // If there are more than two comments, squash all but the last 2. if ($toplevelpost) { $toplevelprivate = $toplevelpost && $item['private'] ? true : false; $item_writeable = $item['writable'] || $item['self'] ? true : false; $comments_seen = 0; $comments_collapsed = false; $comment_lastcollapsed = false; $comment_firstcollapsed = false; $threadsid++; $threads[$threadsid]['id'] = $item['item_id']; $threads[$threadsid]['private'] = $item['private']; $threads[$threadsid]['items'] = array(); } else { // prevent private email reply to public conversation from leaking. if ($item['network'] === NETWORK_MAIL && local_user() != $item['uid']) { continue; } $comments_seen++; $comment_lastcollapsed = false; $comment_firstcollapsed = false; } $override_comment_box = $page_writeable && $item_writeable ? true : false; $show_comment_box = $page_writeable && $item_writeable && $comments_seen == $comments[$item['parent']] ? true : false; if ($comments[$item['parent']] > 2 && $comments_seen <= $comments[$item['parent']] - 2 && $item['gravity'] == 6) { if (!$comments_collapsed) { $threads[$threadsid]['num_comments'] = sprintf(tt('%d comment', '%d comments', $comments[$item['parent']]), $comments[$item['parent']]); $threads[$threadsid]['hide_text'] = t('show more'); $comments_collapsed = true; $comment_firstcollapsed = true; } } if ($comments[$item['parent']] > 2 && $comments_seen == $comments[$item['parent']] - 1) { $comment_lastcollapsed = true; } $redirect_url = $a->get_baseurl($ssl_state) . '/redir/' . $item['cid']; $lock = $item['private'] || $item['uid'] == local_user() && (strlen($item['allow_cid']) || strlen($item['allow_gid']) || strlen($item['deny_cid']) || strlen($item['deny_gid'])) ? t('Private Message') : false; // Top-level wall post not written by the wall owner (wall-to-wall) // First figure out who owns it. $osparkle = ''; if ($toplevelpost && !$item['self'] && $mode !== 'profile') { if ($item['wall']) { // On the network page, I am the owner. On the display page it will be the profile owner. // This will have been stored in $a->page_contact by our calling page. // Put this person as the wall owner of the wall-to-wall notice. $owner_url = zrl($a->page_contact['url']); $owner_photo = $a->page_contact['thumb']; $owner_name = $a->page_contact['name']; $template = $wallwall; $commentww = 'ww'; } if (!$item['wall'] && $item['owner-link']) { $owner_linkmatch = $item['owner-link'] && link_compare($item['owner-link'], $item['author-link']); $alias_linkmatch = $item['alias'] && link_compare($item['alias'], $item['author-link']); $owner_namematch = $item['owner-name'] && $item['owner-name'] == $item['author-name']; if (!$owner_linkmatch && !$alias_linkmatch && !$owner_namematch) { // The author url doesn't match the owner (typically the contact) // and also doesn't match the contact alias. // The name match is a hack to catch several weird cases where URLs are // all over the park. It can be tricked, but this prevents you from // seeing "Bob Smith to Bob Smith via Wall-to-wall" and you know darn // well that it's the same Bob Smith. // But it could be somebody else with the same name. It just isn't highly likely. $owner_url = $item['owner-link']; $owner_photo = $item['owner-avatar']; $owner_name = $item['owner-name']; $template = $wallwall; $commentww = 'ww'; // If it is our contact, use a friendly redirect link if (link_compare($item['owner-link'], $item['url']) && $item['network'] === NETWORK_DFRN) { $owner_url = $redirect_url; $osparkle = ' sparkle'; } else { $owner_url = zrl($owner_url); } } } } $likebuttons = ''; $shareable = $profile_owner == local_user() && !$item['private'] ? true : false; //($mode != 'display') && if ($page_writeable) { if ($toplevelpost) { $likebuttons = array('like' => array(t("I like this (toggle)"), t("like")), 'dislike' => array(t("I don't like this (toggle)"), t("dislike"))); if ($shareable) { $likebuttons['share'] = array(t('Share this'), t('share')); } } $qc = $qcomment = null; if (in_array('qcomment', $a->plugins)) { $qc = local_user() ? get_pconfig(local_user(), 'qcomment', 'words') : null; $qcomment = $qc ? explode("\n", $qc) : null; } if ($show_comment_box || $show_comment_box == false && $override_comment_box == false && $item['last-child']) { $comment = replace_macros($cmnt_tpl, array('$return_path' => '', '$jsreload' => $mode === 'display' ? $_SESSION['return_url'] : '', '$type' => $mode === 'profile' ? 'wall-comment' : 'net-comment', '$id' => $item['item_id'], '$parent' => $item['parent'], '$qcomment' => $qcomment, '$profile_uid' => $profile_owner, '$mylink' => $a->contact['url'], '$mytitle' => t('This is you'), '$myphoto' => $a->contact['thumb'], '$comment' => t('Comment'), '$submit' => t('Submit'), '$edbold' => t('Bold'), '$editalic' => t('Italic'), '$eduline' => t('Underline'), '$edquote' => t('Quote'), '$edcode' => t('Code'), '$edimg' => t('Image'), '$edurl' => t('Link'), '$edvideo' => t('Video'), '$preview' => t('Preview'), '$ww' => $mode === 'network' ? $commentww : '')); } } if (local_user() && link_compare($a->contact['url'], $item['author-link'])) { $edpost = array($a->get_baseurl($ssl_state) . "/editpost/" . $item['id'], t("Edit")); } else { $edpost = false; } $drop = ''; $dropping = false; if (intval($item['contact-id']) && $item['contact-id'] == remote_user() || $item['uid'] == local_user()) { $dropping = true; } $drop = array('dropping' => $dropping, 'select' => t('Select'), 'delete' => t('Delete')); $star = false; $filer = false; $isstarred = "unstarred"; if ($profile_owner == local_user()) { if ($toplevelpost) { $isstarred = $item['starred'] ? "starred" : "unstarred"; $star = array('do' => t("add star"), 'undo' => t("remove star"), 'toggle' => t("toggle star status"), 'classdo' => $item['starred'] ? "hidden" : "", 'classundo' => $item['starred'] ? "" : "hidden", 'starred' => t('starred'), 'tagger' => t("add tag"), 'classtagger' => ""); } $filer = t("save to folder"); } $photo = $item['photo']; $thumb = $item['thumb']; // Post was remotely authored. $diff_author = link_compare($item['url'], $item['author-link']) ? false : true; $profile_name = strlen($item['author-name']) && $diff_author ? $item['author-name'] : $item['name']; if ($item['author-link'] && !$item['author-name']) { $profile_name = $item['author-link']; } $sp = false; $profile_link = best_link_url($item, $sp); if ($profile_link === 'mailbox') { $profile_link = ''; } if ($sp) { $sparkle = ' sparkle'; } else { $profile_link = zrl($profile_link); } $normalised = normalise_link(strlen($item['author-link']) ? $item['author-link'] : $item['url']); if ($normalised != 'mailbox' && x($a->contacts, $normalised)) { $profile_avatar = $a->contacts[$normalised]['thumb']; } else { $profile_avatar = strlen($item['author-avatar']) && $diff_author ? $item['author-avatar'] : $thumb; } $like = x($alike, $item['id']) ? format_like($alike[$item['id']], $alike[$item['id'] . '-l'], 'like', $item['id']) : ''; $dislike = x($dlike, $item['id']) ? format_like($dlike[$item['id']], $dlike[$item['id'] . '-l'], 'dislike', $item['id']) : ''; $locate = array('location' => $item['location'], 'coord' => $item['coord'], 'html' => ''); call_hooks('render_location', $locate); $location = strlen($locate['html']) ? $locate['html'] : render_location_google($locate); $indent = $toplevelpost ? '' : ' comment'; if (strcmp(datetime_convert('UTC', 'UTC', $item['created']), datetime_convert('UTC', 'UTC', 'now - 12 hours')) > 0) { $indent .= ' shiny'; } // localize_item($item); $tags = array(); foreach (explode(',', $item['tag']) as $tag) { $tag = trim($tag); if ($tag != "") { $tags[] = bbcode($tag); } } // Build the HTML $body = prepare_body($item, true); //$tmp_item = replace_macros($template, $tmp_item = array('comment_firstcollapsed' => $comment_firstcollapsed, 'comment_lastcollapsed' => $comment_lastcollapsed, 'template' => $template, 'type' => implode("", array_slice(explode("/", $item['verb']), -1)), 'tags' => $tags, 'body' => template_escape($body), 'text' => strip_tags(template_escape($body)), 'id' => $item['item_id'], 'linktitle' => sprintf(t('View %s\'s profile @ %s'), $profile_name, strlen($item['author-link']) ? $item['author-link'] : $item['url']), 'olinktitle' => sprintf(t('View %s\'s profile @ %s'), $profile_name, strlen($item['owner-link']) ? $item['owner-link'] : $item['url']), 'to' => t('to'), 'wall' => t('Wall-to-Wall'), 'vwall' => t('via Wall-To-Wall:'), 'profile_url' => $profile_link, 'item_photo_menu' => item_photo_menu($item), 'name' => template_escape($profile_name), 'thumb' => $profile_avatar, 'osparkle' => $osparkle, 'sparkle' => $sparkle, 'title' => template_escape($item['title']), 'ago' => $item['app'] ? sprintf(t('%s from %s'), relative_date($item['created']), $item['app']) : relative_date($item['created']), 'lock' => $lock, 'location' => template_escape($location), 'indent' => $indent, 'owner_url' => $owner_url, 'owner_photo' => $owner_photo, 'owner_name' => template_escape($owner_name), 'plink' => get_plink($item), 'edpost' => $edpost, 'isstarred' => $isstarred, 'star' => $star, 'filer' => $filer, 'drop' => $drop, 'vote' => $likebuttons, 'like' => $like, 'dislike' => $dislike, 'comment' => $comment, 'previewing' => $previewing, 'wait' => t('Please wait')); $arr = array('item' => $item, 'output' => $tmp_item); call_hooks('display_item', $arr); $threads[$threadsid]['items'][] = $arr['output']; } } } $page_template = get_markup_template("conversation.tpl"); $o = replace_macros($page_template, array('$baseurl' => $a->get_baseurl($ssl_state), '$mode' => $mode, '$user' => $a->user, '$threads' => $threads, '$dropping' => $dropping ? t('Delete Selected Items') : False)); return $o; }
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 }
/** * "Render" a conversation or list of items for HTML display. * There are two major forms of display: * - Sequential or unthreaded ("New Item View" or search results) * - conversation view * The $mode parameter decides between the various renderings and also * figures out how to determine page owner and other contextual items * that are based on unique features of the calling module. * */ function conversation(&$a, $items, $mode, $update, $preview = false) { require_once 'bbcode.php'; $profile_owner = 0; $page_writeable = false; if ($mode === 'network') { $profile_owner = local_user(); $page_writeable = true; } if ($mode === 'profile') { $profile_owner = $a->profile['profile_uid']; $page_writeable = can_write_wall($a, $profile_owner); } if ($mode === 'notes') { $profile_owner = local_user(); $page_writeable = true; } if ($mode === 'display') { $profile_owner = $a->profile['uid']; $page_writeable = can_write_wall($a, $profile_owner); } if ($mode === 'community') { $profile_owner = 0; $page_writeable = false; } if ($update) { $return_url = $_SESSION['return_url']; } else { $return_url = $_SESSION['return_url'] = $a->cmd; } load_contact_links(local_user()); $cmnt_tpl = get_markup_template('comment_item.tpl'); $tpl = get_markup_template('wall_item.tpl'); $wallwall = get_markup_template('wallwall_item.tpl'); $hide_comments_tpl = get_markup_template('hide_comments.tpl'); $alike = array(); $dlike = array(); // array with html for each thread (parent+comments) $threads = array(); $threadsid = -1; if (count($items)) { if ($mode === 'network-new' || $mode === 'search' || $mode === 'community') { // "New Item View" on network page or search page results // - just loop through the items and format them minimally for display $tpl = get_markup_template('search_item.tpl'); foreach ($items as $item) { $threadsid++; $comment = ''; $owner_url = ''; $owner_photo = ''; $owner_name = ''; $sparkle = ''; if ($mode === 'search' || $mode === 'community') { if ((activity_match($item['verb'], ACTIVITY_LIKE) || activity_match($item['verb'], ACTIVITY_DISLIKE)) && $item['id'] != $item['parent']) { continue; } $nickname = $item['nickname']; } else { $nickname = $a->user['nickname']; } $profile_name = strlen($item['author-name']) ? $item['author-name'] : $item['name']; if ($item['author-link'] && !$item['author-name']) { $profile_name = $item['author-link']; } $sp = false; $profile_link = best_link_url($item, $sp); if ($sp) { $sparkle = ' sparkle'; } if ($profile_link === 'mailbox') { $profile_link = ''; } $normalised = normalise_link(strlen($item['author-link']) ? $item['author-link'] : $item['url']); if ($normalised != 'mailbox' && x($a->contacts[$normalised])) { $profile_avatar = $a->contacts[$normalised]['thumb']; } else { $profile_avatar = strlen($item['author-avatar']) ? $item['author-avatar'] : $item['thumb']; } $location = $item['location'] ? '<a target="map" title="' . $item['location'] . '" href="http://maps.google.com/?q=' . urlencode($item['location']) . '">' . $item['location'] . '</a>' : ''; $coord = $item['coord'] ? '<a target="map" title="' . $item['coord'] . '" href="http://maps.google.com/?q=' . urlencode($item['coord']) . '">' . $item['coord'] . '</a>' : ''; if ($coord) { if ($location) { $location .= '<br /><span class="smalltext">(' . $coord . ')</span>'; } else { $location = '<span class="smalltext">' . $coord . '</span>'; } } localize_item($item); if ($mode === 'network-new') { $dropping = true; } else { $dropping = false; } $drop = array('dropping' => $dropping, 'select' => t('Select'), 'delete' => t('Delete')); $star = false; $isstarred = "unstarred"; $lock = false; $likebuttons = false; $shareable = false; $body = prepare_body($item, true); $tmp_item = replace_macros($tpl, array('$id' => $item['item_id'], '$linktitle' => sprintf(t('View %s\'s profile @ %s'), $profile_name, strlen($item['author-link']) ? $item['author-link'] : $item['url']), '$profile_url' => $profile_link, '$item_photo_menu' => item_photo_menu($item), '$name' => template_escape($profile_name), '$sparkle' => $sparkle, '$lock' => $lock, '$thumb' => $profile_avatar, '$title' => template_escape($item['title']), '$body' => template_escape($body), '$ago' => $item['app'] ? sprintf(t('%s from %s'), relative_date($item['created']), $item['app']) : relative_date($item['created']), '$lock' => $lock, '$location' => template_escape($location), '$indent' => '', '$owner_name' => template_escape($owner_name), '$owner_url' => $owner_url, '$owner_photo' => $owner_photo, '$plink' => get_plink($item), '$edpost' => false, '$isstarred' => $isstarred, '$star' => $star, '$drop' => $drop, '$vote' => $likebuttons, '$like' => '', '$dislike' => '', '$comment' => '', '$conv' => $preview ? '' : array('href' => $a->get_baseurl() . '/display/' . $nickname . '/' . $item['id'], 'title' => t('View in context')), '$wait' => t('Please wait'))); $arr = array('item' => $item, 'output' => $tmp_item); call_hooks('display_item', $arr); $threads[$threadsid]['id'] = $item['item_id']; $threads[$threadsid]['html'] .= $arr['output']; } } else { // Normal View // Figure out how many comments each parent has // (Comments all have gravity of 6) // Store the result in the $comments array $comments = array(); foreach ($items as $item) { if (intval($item['gravity']) == 6 && $item['id'] != $item['parent']) { if (!x($comments, $item['parent'])) { $comments[$item['parent']] = 1; } else { $comments[$item['parent']] += 1; } } } // map all the like/dislike activities for each parent item // Store these in the $alike and $dlike arrays foreach ($items as $item) { like_puller($a, $item, $alike, 'like'); like_puller($a, $item, $dlike, 'dislike'); } $comments_collapsed = false; $blowhard = 0; $blowhard_count = 0; foreach ($items as $item) { $comment = ''; $template = $tpl; $commentww = ''; $sparkle = ''; $owner_url = $owner_photo = $owner_name = ''; // We've already parsed out like/dislike for special treatment. We can ignore them now if ((activity_match($item['verb'], ACTIVITY_LIKE) || activity_match($item['verb'], ACTIVITY_DISLIKE)) && $item['id'] != $item['parent']) { continue; } $toplevelpost = $item['id'] == $item['parent'] ? true : false; $toplevelprivate = false; // Take care of author collapsing and comment collapsing // If a single author has more than 3 consecutive top-level posts, squash the remaining ones. // If there are more than two comments, squash all but the last 2. if ($toplevelpost) { $toplevelprivate = $toplevelpost && $item['private'] ? true : false; $item_writeable = $item['writable'] || $item['self'] ? true : false; /*if($blowhard == $item['cid'] && (! $item['self']) && ($mode != 'profile') && ($mode != 'notes')) { $blowhard_count ++; if($blowhard_count == 3) { $o .= '<div class="icollapse-wrapper fakelink" id="icollapse-wrapper-' . $item['parent'] . '" onclick="openClose(' . '\'icollapse-' . $item['parent'] . '\'); $(\'#icollapse-wrapper-' . $item['parent'] . '\').hide();" >' . t('See more posts like this') . '</div>' . '<div class="icollapse" id="icollapse-' . $item['parent'] . '" style="display: none;" >'; } } else { $blowhard = $item['cid']; if($blowhard_count >= 3) $o .= '</div>'; $blowhard_count = 0; }*/ $comments_seen = 0; $comments_collapsed = false; $threadsid++; $threads[$threadsid]['id'] = $item['item_id']; $threads[$threadsid]['html'] = ""; } else { // prevent private email from leaking into public conversation if (!$toplevelpost && !toplevelprivate && $item['private'] && $profile_owner != local_user()) { continue; } $comments_seen++; } $override_comment_box = $page_writeable && $item_writeable ? true : false; $show_comment_box = $page_writeable && $item_writeable && $comments_seen == $comments[$item['parent']] ? true : false; if ($comments[$item['parent']] > 2 && $comments_seen <= $comments[$item['parent']] - 2 && $item['gravity'] == 6) { if (!$comments_collapsed) { // IMPORTANT: the closing </div> in the hide_comments template // is supplied below in code. $threads[$threadsid]['html'] .= replace_macros($hide_comments_tpl, array('$id' => $item['parent'], '$num_comments' => sprintf(tt('%d comment', '%d comments', $comments[$item['parent']]), $comments[$item['parent']]), '$display' => 'none', '$hide_text' => t('show more'))); $comments_collapsed = true; } } if ($comments[$item['parent']] > 2 && $comments_seen == $comments[$item['parent']] - 1) { $threads[$threadsid]['html'] .= '</div>'; } $redirect_url = $a->get_baseurl() . '/redir/' . $item['cid']; $lock = $item['private'] || $item['uid'] == local_user() && (strlen($item['allow_cid']) || strlen($item['allow_gid']) || strlen($item['deny_cid']) || strlen($item['deny_gid'])) ? t('Private Message') : false; // Top-level wall post not written by the wall owner (wall-to-wall) // First figure out who owns it. $osparkle = ''; if ($toplevelpost && !$item['self'] && $mode !== 'profile') { if ($item['wall']) { // On the network page, I am the owner. On the display page it will be the profile owner. // This will have been stored in $a->page_contact by our calling page. // Put this person on the left of the wall-to-wall notice. $owner_url = $a->page_contact['url']; $owner_photo = $a->page_contact['thumb']; $owner_name = $a->page_contact['name']; $template = $wallwall; $commentww = 'ww'; } if (!$item['wall'] && strlen($item['owner-link']) && $item['owner-link'] != $item['author-link']) { // Could be anybody. $owner_url = $item['owner-link']; $owner_photo = $item['owner-avatar']; $owner_name = $item['owner-name']; $template = $wallwall; $commentww = 'ww'; // If it is our contact, use a friendly redirect link if (link_compare($item['owner-link'], $item['url']) && $item['network'] === 'dfrn') { $owner_url = $redirect_url; $osparkle = ' sparkle'; } } } $likebuttons = ''; $shareable = $profile_owner == local_user() && $mode != 'display' && !$item['private'] ? true : false; if ($page_writeable) { if ($toplevelpost) { $likebuttons = array('like' => array(t("I like this (toggle)"), t("like")), 'dislike' => array(t("I don't like this (toggle)"), t("dislike"))); if ($shareable) { $likebuttons['share'] = array(t('Share this'), t('share')); } } if ($show_comment_box || $show_comment_box == false && $override_comment_box == false && $item['last-child']) { $comment = replace_macros($cmnt_tpl, array('$return_path' => '', '$jsreload' => $mode === 'display' ? $_SESSION['return_url'] : '', '$type' => $mode === 'profile' ? 'wall-comment' : 'net-comment', '$id' => $item['item_id'], '$parent' => $item['parent'], '$profile_uid' => $profile_owner, '$mylink' => $a->contact['url'], '$mytitle' => t('This is you'), '$myphoto' => $a->contact['thumb'], '$comment' => t('Comment'), '$submit' => t('Submit'), '$preview' => t('Preview'), '$ww' => $mode === 'network' ? $commentww : '')); } } $edpost = $profile_owner == local_user() && $toplevelpost && intval($item['wall']) == 1 || $mode === 'notes' ? array($a->get_baseurl() . "/editpost/" . $item['id'], t("Edit")) : False; $drop = ''; $dropping = false; if (intval($item['contact-id']) && $item['contact-id'] == remote_user() || $item['uid'] == local_user()) { $dropping = true; } $drop = array('dropping' => $dropping, 'select' => t('Select'), 'delete' => t('Delete')); $star = false; $isstarred = "unstarred"; if ($profile_owner == local_user() && $toplevelpost) { $isstarred = $item['starred'] ? "starred" : "unstarred"; $star = array('do' => t("add star"), 'undo' => t("remove star"), 'toggle' => t("toggle star status"), 'classdo' => $item['starred'] ? "hidden" : "", 'classundo' => $item['starred'] ? "" : "hidden", 'starred' => t('starred'), 'tagger' => t("add tag"), 'classtagger' => ""); } $photo = $item['photo']; $thumb = $item['thumb']; // Post was remotely authored. $diff_author = link_compare($item['url'], $item['author-link']) ? false : true; $profile_name = strlen($item['author-name']) && $diff_author ? $item['author-name'] : $item['name']; if ($item['author-link'] && !$item['author-name']) { $profile_name = $item['author-link']; } $sp = false; $profile_link = best_link_url($item, $sp); if ($sp) { $sparkle = ' sparkle'; } if ($profile_link === 'mailbox') { $profile_link = ''; } $normalised = normalise_link(strlen($item['author-link']) ? $item['author-link'] : $item['url']); if ($normalised != 'mailbox' && x($a->contacts, $normalised)) { $profile_avatar = $a->contacts[$normalised]['thumb']; } else { $profile_avatar = strlen($item['author-avatar']) && $diff_author ? $item['author-avatar'] : $thumb; } $like = x($alike, $item['id']) ? format_like($alike[$item['id']], $alike[$item['id'] . '-l'], 'like', $item['id']) : ''; $dislike = x($dlike, $item['id']) ? format_like($dlike[$item['id']], $dlike[$item['id'] . '-l'], 'dislike', $item['id']) : ''; $location = $item['location'] ? '<a target="map" title="' . $item['location'] . '" href="http://maps.google.com/?q=' . urlencode($item['location']) . '">' . $item['location'] . '</a>' : ''; $coord = $item['coord'] ? '<a target="map" title="' . $item['coord'] . '" href="http://maps.google.com/?q=' . urlencode($item['coord']) . '">' . $item['coord'] . '</a>' : ''; if ($coord) { if ($location) { $location .= '<br /><span class="smalltext">(' . $coord . ')</span>'; } else { $location = '<span class="smalltext">' . $coord . '</span>'; } } $indent = $toplevelpost ? '' : ' comment'; if (strcmp(datetime_convert('UTC', 'UTC', $item['created']), datetime_convert('UTC', 'UTC', 'now - 12 hours')) > 0) { $indent .= ' shiny'; } // localize_item($item); $tags = array(); foreach (explode(',', $item['tag']) as $tag) { $tag = trim($tag); if ($tag != "") { $tags[] = bbcode($tag); } } // Build the HTML $body = prepare_body($item, true); $tmp_item = replace_macros($template, array('$type' => implode("", array_slice(split("/", $item['verb']), -1)), '$tags' => $tags, '$body' => template_escape($body), '$id' => $item['item_id'], '$linktitle' => sprintf(t('View %s\'s profile @ %s'), $profile_name, strlen($item['author-link']) ? $item['author-link'] : $item['url']), '$olinktitle' => sprintf(t('View %s\'s profile @ %s'), $profile_name, strlen($item['owner-link']) ? $item['owner-link'] : $item['url']), '$to' => t('to'), '$wall' => t('Wall-to-Wall'), '$vwall' => t('via Wall-To-Wall:'), '$profile_url' => $profile_link, '$item_photo_menu' => item_photo_menu($item), '$name' => template_escape($profile_name), '$thumb' => $profile_avatar, '$osparkle' => $osparkle, '$sparkle' => $sparkle, '$title' => template_escape($item['title']), '$ago' => $item['app'] ? sprintf(t('%s from %s'), relative_date($item['created']), $item['app']) : relative_date($item['created']), '$lock' => $lock, '$location' => template_escape($location), '$indent' => $indent, '$owner_url' => $owner_url, '$owner_photo' => $owner_photo, '$owner_name' => template_escape($owner_name), '$plink' => get_plink($item), '$edpost' => $edpost, '$isstarred' => $isstarred, '$star' => $star, '$drop' => $drop, '$vote' => $likebuttons, '$like' => $like, '$dislike' => $dislike, '$comment' => $comment, '$wait' => t('Please wait'))); $arr = array('item' => $item, 'output' => $tmp_item); call_hooks('display_item', $arr); $threads[$threadsid]['html'] .= $arr['output']; } } } $page_template = get_markup_template("conversation.tpl"); $o .= replace_macros($page_template, array('$threads' => $threads, '$dropping' => $dropping ? t('Delete Selected Items') : False)); return $o; }
function photos_content(&$a) { // URLs: // photos/name // photos/name/upload // photos/name/upload/xxxxx (xxxxx is album name) // photos/name/album/xxxxx // photos/name/album/xxxxx/edit // photos/name/image/xxxxx // photos/name/image/xxxxx/edit if (get_config('system', 'block_public') && !local_user() && !remote_user()) { notice(t('Public access denied.') . EOL); return; } require_once 'include/bbcode.php'; require_once 'include/security.php'; require_once 'include/conversation.php'; if (!x($a->data, 'user')) { notice(t('No photos selected') . EOL); return; } $_SESSION['photo_return'] = $a->cmd; // // Parse arguments // if ($a->argc > 3) { $datatype = $a->argv[2]; $datum = $a->argv[3]; } elseif ($a->argc > 2 && $a->argv[2] === 'upload') { $datatype = 'upload'; } else { $datatype = 'summary'; } if ($a->argc > 4) { $cmd = $a->argv[4]; } else { $cmd = 'view'; } // // Setup permissions structures // $can_post = false; $visitor = 0; $contact = null; $remote_contact = false; $owner_uid = $a->data['user']['uid']; $community_page = $a->data['user']['page-flags'] == PAGE_COMMUNITY ? true : false; if (local_user() && local_user() == $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($owner_uid)); if (count($r)) { $can_post = true; $contact = $r[0]; $remote_contact = true; $visitor = remote_user(); } } } // perhaps they're visiting - but not a community page, so they wouldn't have write access if (remote_user() && !$visitor) { $contact_id = $_SESSION['visitor_id']; $groups = init_groups_visitor($contact_id); $r = q("SELECT * FROM `contact` WHERE `blocked` = 0 AND `pending` = 0 AND `id` = %d AND `uid` = %d LIMIT 1", intval(remote_user()), intval($owner_uid)); if (count($r)) { $contact = $r[0]; $remote_contact = true; } } if (!$remote_contact) { if (local_user()) { $contact_id = $_SESSION['cid']; $contact = $a->contact; } } if ($a->data['user']['hidewall'] && local_user() != $owner_uid && !$remote_contact) { notice(t('Access to this item is restricted.') . EOL); return; } $sql_extra = permissions_sql($owner_uid, $remote_contact, $groups); $o = ""; // tabs $_is_owner = local_user() && local_user() == $owner_uid; $o .= profile_tabs($a, $_is_owner, $a->data['user']['nickname']); // // dispatch request // if ($datatype === 'upload') { if (!$can_post) { notice(t('Permission denied.')); return; } $selname = $datum ? hex2bin($datum) : ''; $albumselect = '<select id="photos-upload-album-select" name="album" size="4">'; $albumselect .= '<option value="" ' . (!$selname ? ' selected="selected" ' : '') . '> </option>'; if (count($a->data['albums'])) { foreach ($a->data['albums'] as $album) { if ($album['album'] === '' || $album['album'] === 'Contact Photos' || $album['album'] === t('Contact Photos')) { continue; } $selected = $selname === $album['album'] ? ' selected="selected" ' : ''; $albumselect .= '<option value="' . $album['album'] . '"' . $selected . '>' . $album['album'] . '</option>'; } } $celeb = $a->user['page-flags'] == PAGE_SOAPBOX || $a->user['page-flags'] == PAGE_COMMUNITY ? true : false; $albumselect .= '</select>'; $uploader = ''; $ret = array('post_url' => $a->get_baseurl() . '/photos/' . $a->data['user']['nickname'], 'addon_text' => $uploader, 'default_upload' => true); call_hooks('photo_upload_form', $ret); $default_upload = '<input type="file" name="userfile" /> <div class="photos-upload-submit-wrapper" > <input type="submit" name="submit" value="' . t('Submit') . '" id="photos-upload-submit" /> </div>'; $tpl = get_markup_template('photos_upload.tpl'); $o .= replace_macros($tpl, array('$pagename' => t('Upload Photos'), '$sessid' => session_id(), '$nickname' => $a->data['user']['nickname'], '$newalbum' => t('New album name: '), '$existalbumtext' => t('or existing album name: '), '$nosharetext' => t('Do not show a status post for this upload'), '$albumselect' => template_escape($albumselect), '$permissions' => t('Permissions'), '$aclselect' => $visitor ? '' : template_escape(populate_acl($a->user, $celeb)), '$uploader' => $ret['addon_text'], '$default' => $ret['default_upload'] ? $default_upload : '', '$uploadurl' => $ret['post_url'])); return $o; } if ($datatype === 'album') { $album = hex2bin($datum); $r = q("SELECT `resource-id`, max(`scale`) AS `scale` FROM `photo` WHERE `uid` = %d AND `album` = '%s' \n\t\t\tAND `scale` <= 4 {$sql_extra} GROUP BY `resource-id`", intval($owner_uid), dbesc($album)); if (count($r)) { $a->set_pager_total(count($r)); $a->set_pager_itemspage(20); } $r = q("SELECT `resource-id`, `id`, `filename`, max(`scale`) AS `scale`, `desc` FROM `photo` WHERE `uid` = %d AND `album` = '%s' \n\t\t\tAND `scale` <= 4 {$sql_extra} GROUP BY `resource-id` ORDER BY `created` DESC LIMIT %d , %d", intval($owner_uid), dbesc($album), intval($a->pager['start']), intval($a->pager['itemspage'])); $o .= '<h3>' . $album . '</h3>'; if ($cmd === 'edit') { if ($album !== t('Profile Photos') && $album !== 'Contact Photos' && $album !== t('Contact Photos')) { if ($can_post) { $edit_tpl = get_markup_template('album_edit.tpl'); $o .= replace_macros($edit_tpl, array('$nametext' => t('New album name: '), '$nickname' => $a->data['user']['nickname'], '$album' => template_escape($album), '$hexalbum' => bin2hex($album), '$submit' => t('Submit'), '$dropsubmit' => t('Delete Album'))); } } } else { if ($album !== t('Profile Photos') && $album !== 'Contact Photos' && $album !== t('Contact Photos')) { if ($can_post) { $o .= '<div id="album-edit-link"><a href="' . $a->get_baseurl() . '/photos/' . $a->data['user']['nickname'] . '/album/' . bin2hex($album) . '/edit' . '">' . t('Edit Album') . '</a></div>'; } } } if ($can_post) { $o .= '<div class="photos-upload-link" ><a href="' . $a->get_baseurl() . '/photos/' . $a->data['user']['nickname'] . '/upload/' . bin2hex($album) . '" >' . t('Upload New Photos') . '</a></div>'; } $tpl = get_markup_template('photo_album.tpl'); if (count($r)) { $twist = 'rotright'; } foreach ($r as $rr) { if ($twist == 'rotright') { $twist = 'rotleft'; } else { $twist = 'rotright'; } $o .= replace_macros($tpl, array('$id' => $rr['id'], '$twist' => ' ' . $twist . rand(2, 4), '$photolink' => $a->get_baseurl() . '/photos/' . $a->data['user']['nickname'] . '/image/' . $rr['resource-id'], '$phototitle' => t('View Photo'), '$imgsrc' => $a->get_baseurl() . '/photo/' . $rr['resource-id'] . '-' . $rr['scale'] . '.jpg', '$imgalt' => template_escape($rr['filename']), '$desc' => template_escape($rr['desc']))); } $o .= '<div id="photo-album-end"></div>'; $o .= paginate($a); return $o; } if ($datatype === 'image') { //$o = ''; // fetch image, item containing image, then comments $ph = q("SELECT * FROM `photo` WHERE `uid` = %d AND `resource-id` = '%s' \n\t\t\t{$sql_extra} ORDER BY `scale` ASC ", intval($owner_uid), dbesc($datum)); if (!count($ph)) { $ph = q("SELECT `id` FROM `photo` WHERE `uid` = %d AND `resource-id` = '%s' \n\t\t\t\tLIMIT 1", intval($owner_uid), dbesc($datum)); if (count($ph)) { notice(t('Permission denied. Access to this item may be restricted.')); } else { notice(t('Photo not available') . EOL); } return; } $prevlink = ''; $nextlink = ''; $prvnxt = q("SELECT `resource-id` FROM `photo` WHERE `album` = '%s' AND `uid` = %d AND `scale` = 0 \n\t\t\t{$sql_extra} ORDER BY `created` DESC ", dbesc($ph[0]['album']), intval($owner_uid)); if (count($prvnxt)) { for ($z = 0; $z < count($prvnxt); $z++) { if ($prvnxt[$z]['resource-id'] == $ph[0]['resource-id']) { $prv = $z - 1; $nxt = $z + 1; if ($prv < 0) { $prv = count($prvnxt) - 1; } if ($nxt >= count($prvnxt)) { $nxt = 0; } break; } } $edit_suffix = $cmd === 'edit' && $can_post ? '/edit' : ''; $prevlink = $a->get_baseurl() . '/photos/' . $a->data['user']['nickname'] . '/image/' . $prvnxt[$prv]['resource-id'] . $edit_suffix; $nextlink = $a->get_baseurl() . '/photos/' . $a->data['user']['nickname'] . '/image/' . $prvnxt[$nxt]['resource-id'] . $edit_suffix; } if (count($ph) == 1) { $hires = $lores = $ph[0]; } if (count($ph) > 1) { if ($ph[1]['scale'] == 2) { // original is 640 or less, we can display it directly $hires = $lores = $ph[0]; } else { $hires = $ph[0]; $lores = $ph[1]; } } $album_link = $a->get_baseurl() . '/photos/' . $a->data['user']['nickname'] . '/album/' . bin2hex($ph[0]['album']); $tools = Null; $lock = Null; if ($can_post && $ph[0]['uid'] == $owner_uid) { $tools = array('edit' => array($a->get_baseurl() . '/photos/' . $a->data['user']['nickname'] . '/image/' . $datum . ($cmd === 'edit' ? '' : '/edit'), $cmd === 'edit' ? t('View photo') : t('Edit photo')), 'profile' => array($a->get_baseurl() . '/profile_photo/use/' . $ph[0]['resource-id'], t('Use as profile photo'))); // lock $lock = $ph[0]['uid'] == local_user() && (strlen($ph[0]['allow_cid']) || strlen($ph[0]['allow_gid']) || strlen($ph[0]['deny_cid']) || strlen($ph[0]['deny_gid'])) ? t('Private Message') : Null; } if (!$cmd !== 'edit') { $a->page['htmlhead'] .= '<script> $(document).keydown(function(event) {' . "\n"; if ($prevlink) { $a->page['htmlhead'] .= 'if(event.ctrlKey && event.keyCode == 37) { event.preventDefault(); window.location.href = \'' . $prevlink . '\'; }' . "\n"; } if ($nextlink) { $a->page['htmlhead'] .= 'if(event.ctrlKey && event.keyCode == 39) { event.preventDefault(); window.location.href = \'' . $nextlink . '\'; }' . "\n"; } $a->page['htmlhead'] .= '});</script>'; } if ($prevlink) { $prevlink = array($prevlink, '<div class="icon prev"></div>'); } $photo = array('href' => $a->get_baseurl() . '/photo/' . $hires['resource-id'] . '-' . $hires['scale'] . '.jpg', 'title' => t('View Full Size'), 'src' => $a->get_baseurl() . '/photo/' . $lores['resource-id'] . '-' . $lores['scale'] . '.jpg' . '?f=&_u=' . datetime_convert('', '', '', 'ymdhis')); if ($nextlink) { $nextlink = array($nextlink, '<div class="icon next"></div>'); } // Do we have an item for this photo? $linked_items = q("SELECT * FROM `item` WHERE `resource-id` = '%s' {$sql_extra} LIMIT 1", dbesc($datum)); if (count($linked_items)) { $link_item = $linked_items[0]; $r = q("SELECT COUNT(*) AS `total`\n\t\t\t\tFROM `item` LEFT JOIN `contact` ON `contact`.`id` = `item`.`contact-id`\n\t\t\t\tWHERE `parent-uri` = '%s' AND `uri` != '%s' AND `item`.`deleted` = 0 and `item`.`moderated` = 0\n\t\t\t\tAND `contact`.`blocked` = 0 AND `contact`.`pending` = 0\n\t\t\t\tAND `item`.`uid` = %d \n\t\t\t\t{$sql_extra} ", dbesc($link_item['uri']), dbesc($link_item['uri']), intval($link_item['uid'])); if (count($r)) { $a->set_pager_total($r[0]['total']); } $r = q("SELECT `item`.*, `item`.`id` AS `item_id`, \n\t\t\t\t`contact`.`name`, `contact`.`photo`, `contact`.`url`, `contact`.`network`, \n\t\t\t\t`contact`.`rel`, `contact`.`thumb`, `contact`.`self`, \n\t\t\t\t`contact`.`id` AS `cid`, `contact`.`uid` AS `contact-uid`\n\t\t\t\tFROM `item` LEFT JOIN `contact` ON `contact`.`id` = `item`.`contact-id`\n\t\t\t\tWHERE `parent-uri` = '%s' AND `uri` != '%s' AND `item`.`deleted` = 0 and `item`.`moderated` = 0\n\t\t\t\tAND `contact`.`blocked` = 0 AND `contact`.`pending` = 0\n\t\t\t\tAND `item`.`uid` = %d\n\t\t\t\t{$sql_extra}\n\t\t\t\tORDER BY `parent` DESC, `id` ASC LIMIT %d ,%d ", dbesc($link_item['uri']), dbesc($link_item['uri']), intval($link_item['uid']), intval($a->pager['start']), intval($a->pager['itemspage'])); if (local_user() && local_user() == $link_item['uid']) { q("UPDATE `item` SET `unseen` = 0 WHERE `parent` = %d and `uid` = %d", intval($link_item['parent']), intval(local_user())); } } $tags = Null; if (count($linked_items) && strlen($link_item['tag'])) { $arr = explode(',', $link_item['tag']); // parse tags and add links $tag_str = ''; foreach ($arr as $t) { if (strlen($tag_str)) { $tag_str .= ', '; } $tag_str .= bbcode($t); } $tags = array(t('Tags: '), $tag_str); if ($cmd === 'edit') { $tags[] = $a->get_baseurl() . '/tagrm/' . $link_item['id']; $tags[] = t('[Remove any tag]'); } } $edit = Null; if ($cmd === 'edit' && $can_post) { $edit_tpl = get_markup_template('photo_edit.tpl'); $edit = replace_macros($edit_tpl, array('$id' => $ph[0]['id'], '$rotate' => t('Rotate CW'), '$album' => template_escape($ph[0]['album']), '$newalbum' => t('New album name'), '$nickname' => $a->data['user']['nickname'], '$resource_id' => $ph[0]['resource-id'], '$capt_label' => t('Caption'), '$caption' => template_escape($ph[0]['desc']), '$tag_label' => t('Add a Tag'), '$tags' => $link_item['tag'], '$permissions' => t('Permissions'), '$aclselect' => template_escape(populate_acl($ph[0])), '$help_tags' => t('Example: @bob, @Barbara_Jensen, @jim@example.com, #California, #camping'), '$item_id' => count($linked_items) ? $link_item['id'] : 0, '$submit' => t('Submit'), '$delete' => t('Delete Photo'))); } if (count($linked_items)) { $cmnt_tpl = get_markup_template('comment_item.tpl'); $tpl = get_markup_template('photo_item.tpl'); $return_url = $a->cmd; $like_tpl = get_markup_template('like_noshare.tpl'); $likebuttons = ''; if ($can_post || can_write_wall($a, $owner_uid)) { $likebuttons = replace_macros($like_tpl, array('$id' => $link_item['id'], '$likethis' => t("I like this (toggle)"), '$nolike' => t("I don't like this (toggle)"), '$share' => t('Share'), '$wait' => t('Please wait'))); } $comments = ''; if (!count($r)) { if ($can_post || can_write_wall($a, $owner_uid)) { if ($link_item['last-child']) { $comments .= replace_macros($cmnt_tpl, array('$return_path' => '', '$jsreload' => $return_url, '$type' => 'wall-comment', '$id' => $link_item['id'], '$parent' => $link_item['id'], '$profile_uid' => $owner_uid, '$mylink' => $contact['url'], '$mytitle' => t('This is you'), '$myphoto' => $contact['thumb'], '$comment' => t('Comment'), '$submit' => t('Submit'), '$preview' => t('Preview'), '$ww' => '')); } } } $alike = array(); $dlike = array(); $like = ''; $dislike = ''; // display comments if (count($r)) { foreach ($r as $item) { like_puller($a, $item, $alike, 'like'); like_puller($a, $item, $dlike, 'dislike'); } $like = isset($alike[$link_item['id']]) ? format_like($alike[$link_item['id']], $alike[$link_item['id'] . '-l'], 'like', $link_item['id']) : ''; $dislike = isset($dlike[$link_item['id']]) ? format_like($dlike[$link_item['id']], $dlike[$link_item['id'] . '-l'], 'dislike', $link_item['id']) : ''; if ($can_post || can_write_wall($a, $owner_uid)) { if ($link_item['last-child']) { $comments .= replace_macros($cmnt_tpl, array('$return_path' => '', '$jsreload' => $return_url, '$type' => 'wall-comment', '$id' => $link_item['id'], '$parent' => $link_item['id'], '$profile_uid' => $owner_uid, '$mylink' => $contact['url'], '$mytitle' => t('This is you'), '$myphoto' => $contact['thumb'], '$comment' => t('Comment'), '$submit' => t('Submit'), '$ww' => '')); } } foreach ($r as $item) { $comment = ''; $template = $tpl; $sparkle = ''; if ((activity_match($item['verb'], ACTIVITY_LIKE) || activity_match($item['verb'], ACTIVITY_DISLIKE)) && $item['id'] != $item['parent']) { continue; } $redirect_url = $a->get_baseurl() . '/redir/' . $item['cid']; if ($can_post || can_write_wall($a, $owner_uid)) { if ($item['last-child']) { $comments .= replace_macros($cmnt_tpl, array('$return_path' => '', '$jsreload' => $return_url, '$type' => 'wall-comment', '$id' => $item['item_id'], '$parent' => $item['parent'], '$profile_uid' => $owner_uid, '$mylink' => $contact['url'], '$mytitle' => t('This is you'), '$myphoto' => $contact['thumb'], '$comment' => t('Comment'), '$submit' => t('Submit'), '$ww' => '')); } } if (local_user() && $item['contact-uid'] == local_user() && $item['network'] == 'dfrn' && !$item['self']) { $profile_url = $redirect_url; $sparkle = ' sparkle'; } else { $profile_url = $item['url']; $sparkle = ''; } $diff_author = $item['url'] !== $item['author-link'] ? true : false; $profile_name = strlen($item['author-name']) && $diff_author ? $item['author-name'] : $item['name']; $profile_avatar = strlen($item['author-avatar']) && $diff_author ? $item['author-avatar'] : $item['thumb']; $profile_link = $profile_url; $drop = ''; if ($item['contact-id'] == remote_user() || $item['uid'] == local_user()) { $drop = replace_macros(get_markup_template('photo_drop.tpl'), array('$id' => $item['id'], '$delete' => t('Delete'))); } $comments .= replace_macros($template, array('$id' => $item['item_id'], '$profile_url' => $profile_link, '$name' => template_escape($profile_name), '$thumb' => $profile_avatar, '$sparkle' => $sparkle, '$title' => template_escape($item['title']), '$body' => template_escape(bbcode($item['body'])), '$ago' => relative_date($item['created']), '$indent' => $item['parent'] != $item['item_id'] ? ' comment' : '', '$drop' => $drop, '$comment' => $comment)); } } $paginate = paginate($a); } $photo_tpl = get_markup_template('photo_view.tpl'); $o .= replace_macros($photo_tpl, array('$id' => $ph[0]['id'], '$album' => array($album_link, template_escape($ph[0]['album'])), '$tools' => $tools, '$lock' => $lock, '$photo' => $photo, '$prevlink' => $prevlink, '$nextlink' => $nextlink, '$desc' => $ph[0]['desc'], '$tags' => template_escape($tags), '$edit' => $edit, '$likebuttons' => $likebuttons, '$like' => template_escape($like), '$dislike' => template_escape($dislike), '$comments' => $comments, '$paginate' => $paginate)); return $o; } // Default - show recent photos with upload link (if applicable) //$o = ''; $r = q("SELECT `resource-id`, max(`scale`) AS `scale` FROM `photo` WHERE `uid` = %d AND `album` != '%s' AND `album` != '%s' \n\t\t{$sql_extra} GROUP BY `resource-id`", intval($a->data['user']['uid']), dbesc('Contact Photos'), dbesc(t('Contact Photos'))); if (count($r)) { $a->set_pager_total(count($r)); $a->set_pager_itemspage(20); } $r = q("SELECT `resource-id`, `id`, `filename`, `album`, max(`scale`) AS `scale` FROM `photo`\n\t\tWHERE `uid` = %d AND `album` != '%s' AND `album` != '%s' \n\t\t{$sql_extra} GROUP BY `resource-id` ORDER BY `created` DESC LIMIT %d , %d", intval($a->data['user']['uid']), dbesc('Contact Photos'), dbesc(t('Contact Photos')), intval($a->pager['start']), intval($a->pager['itemspage'])); $photos = array(); if (count($r)) { $twist = 'rotright'; foreach ($r as $rr) { if ($twist == 'rotright') { $twist = 'rotleft'; } else { $twist = 'rotright'; } $photos[] = array('id' => $rr['id'], 'twist' => ' ' . $twist . rand(2, 4), 'link' => $a->get_baseurl() . '/photos/' . $a->data['user']['nickname'] . '/image/' . $rr['resource-id'], 'title' => t('View Photo'), 'src' => $a->get_baseurl() . '/photo/' . $rr['resource-id'] . '-' . ($rr['scale'] == 6 ? 4 : $rr['scale']) . '.jpg', 'alt' => template_escape($rr['filename']), 'album' => array('link' => $a->get_baseurl() . '/photos/' . $a->data['user']['nickname'] . '/album/' . bin2hex($rr['album']), 'name' => template_escape($rr['album']), 'alt' => t('View Album'))); } } $tpl = get_markup_template('photos_recent.tpl'); $o .= replace_macros($tpl, array('$title' => t('Recent Photos'), '$can_post' => $can_post, '$upload' => array(t('Upload New Photos'), $a->get_baseurl() . '/photos/' . $a->data['user']['nickname'] . '/upload'), '$photos' => $photos)); $o .= paginate($a); return $o; }
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 }
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 }
function photos_content(&$a) { // URLs: // photos/name // photos/name/upload // photos/name/upload/xxxxx (xxxxx is album name) // photos/name/album/xxxxx // photos/name/album/xxxxx/edit // photos/name/image/xxxxx // photos/name/image/xxxxx/edit if (get_config('system', 'block_public') && !local_user() && !remote_user()) { notice(t('Public access denied.') . EOL); return; } require_once 'include/bbcode.php'; require_once 'include/security.php'; require_once 'include/conversation.php'; if (!x($a->data, 'user')) { notice(t('No photos selected') . EOL); return; } $phototypes = Photo::supportedTypes(); $_SESSION['photo_return'] = $a->cmd; // // Parse arguments // if ($a->argc > 3) { $datatype = $a->argv[2]; $datum = $a->argv[3]; } elseif ($a->argc > 2 && $a->argv[2] === 'upload') { $datatype = 'upload'; } else { $datatype = 'summary'; } if ($a->argc > 4) { $cmd = $a->argv[4]; } else { $cmd = 'view'; } // // Setup permissions structures // $can_post = false; $visitor = 0; $contact = null; $remote_contact = false; $contact_id = 0; $owner_uid = $a->data['user']['uid']; $community_page = $a->data['user']['page-flags'] == PAGE_COMMUNITY ? true : false; if (local_user() && local_user() == $owner_uid) { $can_post = true; } else { if ($community_page && remote_user()) { if (is_array($_SESSION['remote'])) { foreach ($_SESSION['remote'] as $v) { if ($v['uid'] == $owner_uid) { $contact_id = $v['cid']; break; } } } if ($contact_id) { $r = q("SELECT `uid` FROM `contact` WHERE `blocked` = 0 AND `pending` = 0 AND `id` = %d AND `uid` = %d LIMIT 1", intval($contact_id), intval($owner_uid)); if (count($r)) { $can_post = true; $contact = $r[0]; $remote_contact = true; $visitor = $cid; } } } } // perhaps they're visiting - but not a community page, so they wouldn't have write access if (remote_user() && !$visitor) { $contact_id = 0; if (is_array($_SESSION['remote'])) { foreach ($_SESSION['remote'] as $v) { if ($v['uid'] == $owner_uid) { $contact_id = $v['cid']; break; } } } if ($contact_id) { $groups = init_groups_visitor($contact_id); $r = q("SELECT * FROM `contact` WHERE `blocked` = 0 AND `pending` = 0 AND `id` = %d AND `uid` = %d LIMIT 1", intval($contact_id), intval($owner_uid)); if (count($r)) { $contact = $r[0]; $remote_contact = true; } } } if (!$remote_contact) { if (local_user()) { $contact_id = $_SESSION['cid']; $contact = $a->contact; } } if ($a->data['user']['hidewall'] && local_user() != $owner_uid && !$remote_contact) { notice(t('Access to this item is restricted.') . EOL); return; } $sql_extra = permissions_sql($owner_uid, $remote_contact, $groups); $o = ""; // tabs $_is_owner = local_user() && local_user() == $owner_uid; $o .= profile_tabs($a, $_is_owner, $a->data['user']['nickname']); // // dispatch request // if ($datatype === 'upload') { if (!$can_post) { notice(t('Permission denied.')); return; } $selname = $datum ? hex2bin($datum) : ''; $albumselect = ''; $albumselect .= '<option value="" ' . (!$selname ? ' selected="selected" ' : '') . '> </option>'; if (count($a->data['albums'])) { foreach ($a->data['albums'] as $album) { if ($album['album'] === '' || $album['album'] === 'Contact Photos' || $album['album'] === t('Contact Photos')) { continue; } $selected = $selname === $album['album'] ? ' selected="selected" ' : ''; $albumselect .= '<option value="' . $album['album'] . '"' . $selected . '>' . $album['album'] . '</option>'; } } $celeb = $a->user['page-flags'] == PAGE_SOAPBOX || $a->user['page-flags'] == PAGE_COMMUNITY ? true : false; $uploader = ''; $ret = array('post_url' => $a->get_baseurl() . '/photos/' . $a->data['user']['nickname'], 'addon_text' => $uploader, 'default_upload' => true); call_hooks('photo_upload_form', $ret); $default_upload_box = replace_macros(get_markup_template('photos_default_uploader_box.tpl'), array()); $default_upload_submit = replace_macros(get_markup_template('photos_default_uploader_submit.tpl'), array('$submit' => t('Submit'))); $usage_message = ''; $limit = service_class_fetch($a->data['user']['uid'], 'photo_upload_limit'); if ($limit !== false) { $r = q("select sum(datasize) as total from photo where uid = %d and scale = 0 and album != 'Contact Photos' ", intval($a->data['user']['uid'])); $usage_message = sprintf(t("You have used %1\$.2f Mbytes of %2\$.2f Mbytes photo storage."), $r[0]['total'] / 1024000, $limit / 1024000); } // Private/public post links for the non-JS ACL form $private_post = 1; if ($_REQUEST['public']) { $private_post = 0; } $query_str = $a->query_string; if (strpos($query_str, 'public=1') !== false) { $query_str = str_replace(array('?public=1', '&public=1'), array('', ''), $query_str); } // I think $a->query_string may never have ? in it, but I could be wrong // It looks like it's from the index.php?q=[etc] rewrite that the web // server does, which converts any ? to &, e.g. suggest&ignore=61 for suggest?ignore=61 if (strpos($query_str, '?') === false) { $public_post_link = '?public=1'; } else { $public_post_link = '&public=1'; } $tpl = get_markup_template('photos_upload.tpl'); if ($a->theme['template_engine'] === 'internal') { $albumselect_e = template_escape($albumselect); $aclselect_e = $visitor ? '' : template_escape(populate_acl($a->user, $celeb)); } else { $albumselect_e = $albumselect; $aclselect_e = $visitor ? '' : populate_acl($a->user, $celeb); } $o .= replace_macros($tpl, array('$pagename' => t('Upload Photos'), '$sessid' => session_id(), '$usage' => $usage_message, '$nickname' => $a->data['user']['nickname'], '$newalbum' => t('New album name: '), '$existalbumtext' => t('or existing album name: '), '$nosharetext' => t('Do not show a status post for this upload'), '$albumselect' => $albumselect_e, '$permissions' => t('Permissions'), '$aclselect' => $aclselect_e, '$alt_uploader' => $ret['addon_text'], '$default_upload_box' => $ret['default_upload'] ? $default_upload_box : '', '$default_upload_submit' => $ret['default_upload'] ? $default_upload_submit : '', '$uploadurl' => $ret['post_url'], '$acl_data' => construct_acl_data($a, $a->user), '$group_perms' => t('Show to Groups'), '$contact_perms' => t('Show to Contacts'), '$private' => t('Private Photo'), '$public' => t('Public Photo'), '$is_private' => $private_post, '$return_path' => $query_str, '$public_link' => $public_post_link)); return $o; } if ($datatype === 'album') { $album = hex2bin($datum); $r = q("SELECT `resource-id`, max(`scale`) AS `scale` FROM `photo` WHERE `uid` = %d AND `album` = '%s' \n\t\t\tAND `scale` <= 4 {$sql_extra} GROUP BY `resource-id`", intval($owner_uid), dbesc($album)); if (count($r)) { $a->set_pager_total(count($r)); $a->set_pager_itemspage(20); } if ($_GET['order'] === 'posted') { $order = 'ASC'; } else { $order = 'DESC'; } $r = q("SELECT `resource-id`, `id`, `filename`, type, max(`scale`) AS `scale`, `desc` FROM `photo` WHERE `uid` = %d AND `album` = '%s' \n\t\t\tAND `scale` <= 4 {$sql_extra} GROUP BY `resource-id` ORDER BY `created` {$order} LIMIT %d , %d", intval($owner_uid), dbesc($album), intval($a->pager['start']), intval($a->pager['itemspage'])); $o .= '<h3 id="photo-album-title">' . $album . '</h3>'; if ($cmd === 'edit') { if ($album !== t('Profile Photos') && $album !== 'Contact Photos' && $album !== t('Contact Photos')) { if ($can_post) { $edit_tpl = get_markup_template('album_edit.tpl'); if ($a->theme['template_engine'] === 'internal') { $album_e = template_escape($album); } else { $album_e = $album; } $o .= replace_macros($edit_tpl, array('$nametext' => t('New album name: '), '$nickname' => $a->data['user']['nickname'], '$album' => $album_e, '$hexalbum' => bin2hex($album), '$submit' => t('Submit'), '$dropsubmit' => t('Delete Album'))); } } } else { if ($album !== t('Profile Photos') && $album !== 'Contact Photos' && $album !== t('Contact Photos')) { if ($can_post) { $o .= '<div id="album-edit-link"><a href="' . $a->get_baseurl() . '/photos/' . $a->data['user']['nickname'] . '/album/' . bin2hex($album) . '/edit' . '">' . t('Edit Album') . '</a></div>'; } } } if ($_GET['order'] === 'posted') { $o .= '<div class="photos-upload-link" ><a href="' . $a->get_baseurl() . '/photos/' . $a->data['user']['nickname'] . '/album/' . bin2hex($album) . '" >' . t('Show Newest First') . '</a></div>'; } else { $o .= '<div class="photos-upload-link" ><a href="' . $a->get_baseurl() . '/photos/' . $a->data['user']['nickname'] . '/album/' . bin2hex($album) . '?f=&order=posted" >' . t('Show Oldest First') . '</a></div>'; } if ($can_post) { $o .= '<div class="photos-upload-link" ><a href="' . $a->get_baseurl() . '/photos/' . $a->data['user']['nickname'] . '/upload/' . bin2hex($album) . '" >' . t('Upload New Photos') . '</a></div>'; } $tpl = get_markup_template('photo_album.tpl'); if (count($r)) { $twist = 'rotright'; } foreach ($r as $rr) { if ($twist == 'rotright') { $twist = 'rotleft'; } else { $twist = 'rotright'; } $ext = $phototypes[$rr['type']]; if ($a->theme['template_engine'] === 'internal') { $imgalt_e = template_escape($rr['filename']); $desc_e = template_escape($rr['desc']); } else { $imgalt_e = $rr['filename']; $desc_e = $rr['desc']; } $o .= replace_macros($tpl, array('$id' => $rr['id'], '$twist' => ' ' . $twist . rand(2, 4), '$photolink' => $a->get_baseurl() . '/photos/' . $a->data['user']['nickname'] . '/image/' . $rr['resource-id'] . ($_GET['order'] === 'posted' ? '?f=&order=posted' : ''), '$phototitle' => t('View Photo'), '$imgsrc' => $a->get_baseurl() . '/photo/' . $rr['resource-id'] . '-' . $rr['scale'] . '.' . $ext, '$imgalt' => $imgalt_e, '$desc' => $desc_e)); } $o .= '<div id="photo-album-end"></div>'; $o .= paginate($a); return $o; } if ($datatype === 'image') { //$o = ''; // fetch image, item containing image, then comments $ph = q("SELECT * FROM `photo` WHERE `uid` = %d AND `resource-id` = '%s' \n\t\t\t{$sql_extra} ORDER BY `scale` ASC ", intval($owner_uid), dbesc($datum)); if (!count($ph)) { $ph = q("SELECT `id` FROM `photo` WHERE `uid` = %d AND `resource-id` = '%s'\n\t\t\t\tLIMIT 1", intval($owner_uid), dbesc($datum)); if (count($ph)) { notice(t('Permission denied. Access to this item may be restricted.')); } else { notice(t('Photo not available') . EOL); } return; } $prevlink = ''; $nextlink = ''; if ($_GET['order'] === 'posted') { $order = 'ASC'; } else { $order = 'DESC'; } $prvnxt = q("SELECT `resource-id` FROM `photo` WHERE `album` = '%s' AND `uid` = %d AND `scale` = 0\n\t\t\t{$sql_extra} ORDER BY `created` {$order} ", dbesc($ph[0]['album']), intval($owner_uid)); if (count($prvnxt)) { for ($z = 0; $z < count($prvnxt); $z++) { if ($prvnxt[$z]['resource-id'] == $ph[0]['resource-id']) { $prv = $z - 1; $nxt = $z + 1; if ($prv < 0) { $prv = count($prvnxt) - 1; } if ($nxt >= count($prvnxt)) { $nxt = 0; } break; } } $edit_suffix = $cmd === 'edit' && $can_post ? '/edit' : ''; $prevlink = $a->get_baseurl() . '/photos/' . $a->data['user']['nickname'] . '/image/' . $prvnxt[$prv]['resource-id'] . $edit_suffix . ($_GET['order'] === 'posted' ? '?f=&order=posted' : ''); $nextlink = $a->get_baseurl() . '/photos/' . $a->data['user']['nickname'] . '/image/' . $prvnxt[$nxt]['resource-id'] . $edit_suffix . ($_GET['order'] === 'posted' ? '?f=&order=posted' : ''); } if (count($ph) == 1) { $hires = $lores = $ph[0]; } if (count($ph) > 1) { if ($ph[1]['scale'] == 2) { // original is 640 or less, we can display it directly $hires = $lores = $ph[0]; } else { $hires = $ph[0]; $lores = $ph[1]; } } $album_link = $a->get_baseurl() . '/photos/' . $a->data['user']['nickname'] . '/album/' . bin2hex($ph[0]['album']); $tools = Null; $lock = Null; if ($can_post && $ph[0]['uid'] == $owner_uid) { $tools = array('edit' => array($a->get_baseurl() . '/photos/' . $a->data['user']['nickname'] . '/image/' . $datum . ($cmd === 'edit' ? '' : '/edit'), $cmd === 'edit' ? t('View photo') : t('Edit photo')), 'profile' => array($a->get_baseurl() . '/profile_photo/use/' . $ph[0]['resource-id'], t('Use as profile photo'))); // lock $lock = $ph[0]['uid'] == local_user() && (strlen($ph[0]['allow_cid']) || strlen($ph[0]['allow_gid']) || strlen($ph[0]['deny_cid']) || strlen($ph[0]['deny_gid'])) ? t('Private Message') : Null; } if ($cmd === 'edit') { $tpl = get_markup_template('photo_edit_head.tpl'); $a->page['htmlhead'] .= replace_macros($tpl, array('$prevlink' => $prevlink, '$nextlink' => $nextlink)); } if ($prevlink) { $prevlink = array($prevlink, '<div class="icon prev"></div>'); } $photo = array('href' => $a->get_baseurl() . '/photo/' . $hires['resource-id'] . '-' . $hires['scale'] . '.' . $phototypes[$hires['type']], 'title' => t('View Full Size'), 'src' => $a->get_baseurl() . '/photo/' . $lores['resource-id'] . '-' . $lores['scale'] . '.' . $phototypes[$lores['type']] . '?f=&_u=' . datetime_convert('', '', '', 'ymdhis'), 'height' => $hires['height'], 'width' => $hires['width'], 'album' => $hires['album'], 'filename' => $hires['filename']); if ($nextlink) { $nextlink = array($nextlink, '<div class="icon next"></div>'); } // Do we have an item for this photo? // FIXME! - replace following code to display the conversation with our normal // conversation functions so that it works correctly and tracks changes // in the evolving conversation code. // The difference is that we won't be displaying the conversation head item // as a "post" but displaying instead the photo it is linked to $linked_items = q("SELECT * FROM `item` WHERE `resource-id` = '%s' {$sql_extra} LIMIT 1", dbesc($datum)); if (count($linked_items)) { $link_item = $linked_items[0]; $r = q("SELECT COUNT(*) AS `total`\n\t\t\t\tFROM `item` LEFT JOIN `contact` ON `contact`.`id` = `item`.`contact-id`\n\t\t\t\tWHERE `parent-uri` = '%s' AND `uri` != '%s' AND `item`.`deleted` = 0 and `item`.`moderated` = 0\n\t\t\t\tAND `contact`.`blocked` = 0 AND `contact`.`pending` = 0\n\t\t\t\tAND `item`.`uid` = %d\n\t\t\t\t{$sql_extra} ", dbesc($link_item['uri']), dbesc($link_item['uri']), intval($link_item['uid'])); if (count($r)) { $a->set_pager_total($r[0]['total']); } $r = q("SELECT `item`.*, `item`.`id` AS `item_id`,\n\t\t\t\t`contact`.`name`, `contact`.`photo`, `contact`.`url`, `contact`.`network`,\n\t\t\t\t`contact`.`rel`, `contact`.`thumb`, `contact`.`self`,\n\t\t\t\t`contact`.`id` AS `cid`, `contact`.`uid` AS `contact-uid`\n\t\t\t\tFROM `item` LEFT JOIN `contact` ON `contact`.`id` = `item`.`contact-id`\n\t\t\t\tWHERE `parent-uri` = '%s' AND `uri` != '%s' AND `item`.`deleted` = 0 and `item`.`moderated` = 0\n\t\t\t\tAND `contact`.`blocked` = 0 AND `contact`.`pending` = 0\n\t\t\t\tAND `item`.`uid` = %d\n\t\t\t\t{$sql_extra}\n\t\t\t\tORDER BY `parent` DESC, `id` ASC LIMIT %d ,%d ", dbesc($link_item['uri']), dbesc($link_item['uri']), intval($link_item['uid']), intval($a->pager['start']), intval($a->pager['itemspage'])); if (local_user() && local_user() == $link_item['uid']) { q("UPDATE `item` SET `unseen` = 0 WHERE `parent` = %d and `uid` = %d", intval($link_item['parent']), intval(local_user())); update_thread($link_item['parent']); } } $tags = Null; if (count($linked_items) && strlen($link_item['tag'])) { $arr = explode(',', $link_item['tag']); // parse tags and add links $tag_str = ''; foreach ($arr as $t) { if (strlen($tag_str)) { $tag_str .= ', '; } $tag_str .= bbcode($t); } $tags = array(t('Tags: '), $tag_str); if ($cmd === 'edit') { $tags[] = $a->get_baseurl() . '/tagrm/' . $link_item['id']; $tags[] = t('[Remove any tag]'); } } $edit = Null; if ($cmd === 'edit' && $can_post) { $edit_tpl = get_markup_template('photo_edit.tpl'); // Private/public post links for the non-JS ACL form $private_post = 1; if ($_REQUEST['public']) { $private_post = 0; } $query_str = $a->query_string; if (strpos($query_str, 'public=1') !== false) { $query_str = str_replace(array('?public=1', '&public=1'), array('', ''), $query_str); } // I think $a->query_string may never have ? in it, but I could be wrong // It looks like it's from the index.php?q=[etc] rewrite that the web // server does, which converts any ? to &, e.g. suggest&ignore=61 for suggest?ignore=61 if (strpos($query_str, '?') === false) { $public_post_link = '?public=1'; } else { $public_post_link = '&public=1'; } if ($a->theme['template_engine'] === 'internal') { $album_e = template_escape($ph[0]['album']); $caption_e = template_escape($ph[0]['desc']); $aclselect_e = template_escape(populate_acl($ph[0])); } else { $album_e = $ph[0]['album']; $caption_e = $ph[0]['desc']; $aclselect_e = populate_acl($ph[0]); } $edit = replace_macros($edit_tpl, array('$id' => $ph[0]['id'], '$rotatecw' => t('Rotate CW (right)'), '$rotateccw' => t('Rotate CCW (left)'), '$album' => $album_e, '$newalbum' => t('New album name'), '$nickname' => $a->data['user']['nickname'], '$resource_id' => $ph[0]['resource-id'], '$capt_label' => t('Caption'), '$caption' => $caption_e, '$tag_label' => t('Add a Tag'), '$tags' => $link_item['tag'], '$permissions' => t('Permissions'), '$aclselect' => $aclselect_e, '$help_tags' => t('Example: @bob, @Barbara_Jensen, @jim@example.com, #California, #camping'), '$item_id' => count($linked_items) ? $link_item['id'] : 0, '$submit' => t('Submit'), '$delete' => t('Delete Photo'), '$acl_data' => construct_acl_data($a, $ph[0]), '$group_perms' => t('Show to Groups'), '$contact_perms' => t('Show to Contacts'), '$private' => t('Private photo'), '$public' => t('Public photo'), '$is_private' => $private_post, '$return_path' => $query_str, '$public_link' => $public_post_link)); } if (count($linked_items)) { $cmnt_tpl = get_markup_template('comment_item.tpl'); $tpl = get_markup_template('photo_item.tpl'); $return_url = $a->cmd; $like_tpl = get_markup_template('like_noshare.tpl'); $likebuttons = ''; if ($can_post || can_write_wall($a, $owner_uid)) { $likebuttons = replace_macros($like_tpl, array('$id' => $link_item['id'], '$likethis' => t("I like this (toggle)"), '$nolike' => feature_enabled(local_user(), 'dislike') ? t("I don't like this (toggle)") : '', '$share' => t('Share'), '$wait' => t('Please wait'), '$return_path' => $a->query_string)); } $comments = ''; if (!count($r)) { if ($can_post || can_write_wall($a, $owner_uid)) { if ($link_item['last-child']) { $comments .= replace_macros($cmnt_tpl, array('$return_path' => '', '$jsreload' => $return_url, '$type' => 'wall-comment', '$id' => $link_item['id'], '$parent' => $link_item['id'], '$profile_uid' => $owner_uid, '$mylink' => $contact['url'], '$mytitle' => t('This is you'), '$myphoto' => $contact['thumb'], '$comment' => t('Comment'), '$submit' => t('Submit'), '$preview' => t('Preview'), '$sourceapp' => t($a->sourcename), '$ww' => '', '$rand_num' => random_digits(12))); } } } $alike = array(); $dlike = array(); $like = ''; $dislike = ''; // display comments if (count($r)) { foreach ($r as $item) { like_puller($a, $item, $alike, 'like'); like_puller($a, $item, $dlike, 'dislike'); } $like = isset($alike[$link_item['id']]) ? format_like($alike[$link_item['id']], $alike[$link_item['id'] . '-l'], 'like', $link_item['id']) : ''; $dislike = isset($dlike[$link_item['id']]) ? format_like($dlike[$link_item['id']], $dlike[$link_item['id'] . '-l'], 'dislike', $link_item['id']) : ''; if ($can_post || can_write_wall($a, $owner_uid)) { if ($link_item['last-child']) { $comments .= replace_macros($cmnt_tpl, array('$return_path' => '', '$jsreload' => $return_url, '$type' => 'wall-comment', '$id' => $link_item['id'], '$parent' => $link_item['id'], '$profile_uid' => $owner_uid, '$mylink' => $contact['url'], '$mytitle' => t('This is you'), '$myphoto' => $contact['thumb'], '$comment' => t('Comment'), '$submit' => t('Submit'), '$preview' => t('Preview'), '$sourceapp' => t($a->sourcename), '$ww' => '', '$rand_num' => random_digits(12))); } } foreach ($r as $item) { $comment = ''; $template = $tpl; $sparkle = ''; if ((activity_match($item['verb'], ACTIVITY_LIKE) || activity_match($item['verb'], ACTIVITY_DISLIKE)) && $item['id'] != $item['parent']) { continue; } $redirect_url = $a->get_baseurl() . '/redir/' . $item['cid']; if (local_user() && $item['contact-uid'] == local_user() && $item['network'] == 'dfrn' && !$item['self']) { $profile_url = $redirect_url; $sparkle = ' sparkle'; } else { $profile_url = $item['url']; $sparkle = ''; } $diff_author = $item['url'] !== $item['author-link'] ? true : false; $profile_name = strlen($item['author-name']) && $diff_author ? $item['author-name'] : $item['name']; $profile_avatar = strlen($item['author-avatar']) && $diff_author ? $item['author-avatar'] : $item['thumb']; $profile_link = $profile_url; $dropping = $item['contact-id'] == $contact_id || $item['uid'] == local_user(); $drop = array('dropping' => $dropping, 'pagedrop' => false, 'select' => t('Select'), 'delete' => t('Delete')); if ($a->theme['template_engine'] === 'internal') { $name_e = template_escape($profile_name); $title_e = template_escape($item['title']); $body_e = template_escape(bbcode($item['body'])); } else { $name_e = $profile_name; $title_e = $item['title']; $body_e = bbcode($item['body']); } $comments .= replace_macros($template, array('$id' => $item['item_id'], '$profile_url' => $profile_link, '$name' => $name_e, '$thumb' => $profile_avatar, '$sparkle' => $sparkle, '$title' => $title_e, '$body' => $body_e, '$ago' => relative_date($item['created']), '$indent' => $item['parent'] != $item['item_id'] ? ' comment' : '', '$drop' => $drop, '$comment' => $comment)); if ($can_post || can_write_wall($a, $owner_uid)) { if ($item['last-child']) { $comments .= replace_macros($cmnt_tpl, array('$return_path' => '', '$jsreload' => $return_url, '$type' => 'wall-comment', '$id' => $item['item_id'], '$parent' => $item['parent'], '$profile_uid' => $owner_uid, '$mylink' => $contact['url'], '$mytitle' => t('This is you'), '$myphoto' => $contact['thumb'], '$comment' => t('Comment'), '$submit' => t('Submit'), '$preview' => t('Preview'), '$sourceapp' => t($a->sourcename), '$ww' => '', '$rand_num' => random_digits(12))); } } } } $paginate = paginate($a); } $photo_tpl = get_markup_template('photo_view.tpl'); if ($a->theme['template_engine'] === 'internal') { $album_e = array($album_link, template_escape($ph[0]['album'])); $tags_e = template_escape($tags); $like_e = template_escape($like); $dislike_e = template_escape($dislike); } else { $album_e = array($album_link, $ph[0]['album']); $tags_e = $tags; $like_e = $like; $dislike_e = $dislike; } $o .= replace_macros($photo_tpl, array('$id' => $ph[0]['id'], '$album' => $album_e, '$tools' => $tools, '$lock' => $lock, '$photo' => $photo, '$prevlink' => $prevlink, '$nextlink' => $nextlink, '$desc' => $ph[0]['desc'], '$tags' => $tags_e, '$edit' => $edit, '$likebuttons' => $likebuttons, '$like' => $like_e, '$dislike' => $dikslike_e, '$comments' => $comments, '$paginate' => $paginate)); $a->page['htmlhead'] .= "\n" . '<meta name="twitter:card" content="photo" />' . "\n"; $a->page['htmlhead'] .= '<meta name="twitter:title" content="' . $photo["album"] . '" />' . "\n"; $a->page['htmlhead'] .= '<meta name="twitter:image" content="' . $photo["href"] . '" />' . "\n"; $a->page['htmlhead'] .= '<meta name="twitter:image:width" content="' . $photo["width"] . '" />' . "\n"; $a->page['htmlhead'] .= '<meta name="twitter:image:height" content="' . $photo["height"] . '" />' . "\n"; return $o; } // Default - show recent photos with upload link (if applicable) //$o = ''; $r = q("SELECT `resource-id`, max(`scale`) AS `scale` FROM `photo` WHERE `uid` = %d AND `album` != '%s' AND `album` != '%s' \n\t\t{$sql_extra} GROUP BY `resource-id`", intval($a->data['user']['uid']), dbesc('Contact Photos'), dbesc(t('Contact Photos'))); if (count($r)) { $a->set_pager_total(count($r)); $a->set_pager_itemspage(20); } $r = q("SELECT `resource-id`, `id`, `filename`, type, `album`, max(`scale`) AS `scale` FROM `photo`\n\t\tWHERE `uid` = %d AND `album` != '%s' AND `album` != '%s' \n\t\t{$sql_extra} GROUP BY `resource-id` ORDER BY `created` DESC LIMIT %d , %d", intval($a->data['user']['uid']), dbesc('Contact Photos'), dbesc(t('Contact Photos')), intval($a->pager['start']), intval($a->pager['itemspage'])); $photos = array(); if (count($r)) { $twist = 'rotright'; foreach ($r as $rr) { if ($twist == 'rotright') { $twist = 'rotleft'; } else { $twist = 'rotright'; } $ext = $phototypes[$rr['type']]; if ($a->theme['template_engine'] === 'internal') { $alt_e = template_escape($rr['filename']); $name_e = template_escape($rr['album']); } else { $alt_e = $rr['filename']; $name_e = $rr['album']; } $photos[] = array('id' => $rr['id'], 'twist' => ' ' . $twist . rand(2, 4), 'link' => $a->get_baseurl() . '/photos/' . $a->data['user']['nickname'] . '/image/' . $rr['resource-id'], 'title' => t('View Photo'), 'src' => $a->get_baseurl() . '/photo/' . $rr['resource-id'] . '-' . ($rr['scale'] == 6 ? 4 : $rr['scale']) . '.' . $ext, 'alt' => $alt_e, 'album' => array('link' => $a->get_baseurl() . '/photos/' . $a->data['user']['nickname'] . '/album/' . bin2hex($rr['album']), 'name' => $name_e, 'alt' => t('View Album'))); } } $tpl = get_markup_template('photos_recent.tpl'); $o .= replace_macros($tpl, array('$title' => t('Recent Photos'), '$can_post' => $can_post, '$upload' => array(t('Upload New Photos'), $a->get_baseurl() . '/photos/' . $a->data['user']['nickname'] . '/upload'), '$photos' => $photos)); $o .= paginate($a); return $o; }
function profile_content(&$a, $update = 0) { if (get_config('system', 'block_public') && !local_user() && !remote_user()) { return login(); } require_once "include/bbcode.php"; require_once 'include/security.php'; require_once 'include/conversation.php'; require_once 'include/acl_selectors.php'; $groups = array(); $tab = 'posts'; $o = ''; if ($update) { // Ensure we've got a profile owner if updating. $a->profile['profile_uid'] = $update; } else { if ($a->profile['profile_uid'] == local_user()) { nav_set_selected('home'); } } $contact = null; $remote_contact = false; if (remote_user()) { $contact_id = $_SESSION['visitor_id']; $groups = init_groups_visitor($contact_id); $r = q("SELECT * FROM `contact` WHERE `id` = %d AND `uid` = %d LIMIT 1", intval($contact_id), intval($a->profile['profile_uid'])); if (count($r)) { $contact = $r[0]; $remote_contact = true; } } if (!$remote_contact) { if (local_user()) { $contact_id = $_SESSION['cid']; $contact = $a->contact; } } $is_owner = local_user() && local_user() == $a->profile['profile_uid'] ? true : false; if ($a->profile['hidewall'] && !$is_owner && !$remote_contact) { notice(t('Access to this profile has been restricted.') . EOL); return; } if (!$update) { if (x($_GET, 'tab')) { $tab = notags(trim($_GET['tab'])); } $o .= profile_tabs($a, $is_owner, $a->profile['nickname']); if ($tab === 'profile') { require_once 'include/profile_advanced.php'; $o .= advanced_profile($a); call_hooks('profile_advanced', $o); return $o; } if (x($_SESSION, 'new_member') && $_SESSION['new_member'] && $is_owner) { $o .= '<a href="newmember">' . t('Tips for New Members') . '</a>' . EOL; } $commpage = $a->profile['page-flags'] == PAGE_COMMUNITY ? true : false; $commvisitor = $commpage && $remote_contact == true ? true : false; $celeb = $a->profile['page-flags'] == PAGE_SOAPBOX || $a->profile['page-flags'] == PAGE_COMMUNITY ? true : false; if (can_write_wall($a, $a->profile['profile_uid'])) { $x = array('is_owner' => $is_owner, 'allow_location' => ($is_owner || $commvisitor) && $a->profile['allow_location'] ? true : false, 'default_location' => $is_owner ? $a->user['default-location'] : '', 'nickname' => $a->profile['nickname'], 'lockstate' => is_array($a->user) && (strlen($a->user['allow_cid']) || strlen($a->user['allow_gid']) || strlen($a->user['deny_cid']) || strlen($a->user['deny_gid'])) ? 'lock' : 'unlock', 'acl' => $is_owner ? populate_acl($a->user, $celeb) : '', 'bang' => '', 'visitor' => $is_owner || $commvisitor ? 'block' : 'none', 'profile_uid' => $a->profile['profile_uid']); $o .= status_editor($a, $x); } } if ($is_owner) { $r = q("UPDATE `item` SET `unseen` = 0 \n\t\t\tWHERE `wall` = 1 AND `unseen` = 1 AND `uid` = %d", intval(local_user())); } /** * Get permissions SQL - if $remote_contact is true, our remote user has been pre-verified and we already have fetched his/her groups */ $sql_extra = permissions_sql($a->profile['profile_uid'], $remote_contact, $groups); $r = q("SELECT COUNT(*) AS `total`\n\t\tFROM `item` LEFT JOIN `contact` ON `contact`.`id` = `item`.`contact-id`\n\t\tWHERE `item`.`uid` = %d AND `item`.`visible` = 1 AND `item`.`deleted` = 0\n\t\tAND `contact`.`blocked` = 0 AND `contact`.`pending` = 0 \n\t\tAND `item`.`id` = `item`.`parent` AND `item`.`wall` = 1\n\t\t{$sql_extra} ", intval($a->profile['profile_uid'])); if (count($r)) { $a->set_pager_total($r[0]['total']); $a->set_pager_itemspage(40); } $r = q("SELECT `item`.`id` AS `item_id`, `contact`.`uid` AS `contact-uid`\n\t\tFROM `item` LEFT JOIN `contact` ON `contact`.`id` = `item`.`contact-id`\n\t\tWHERE `item`.`uid` = %d AND `item`.`visible` = 1 AND `item`.`deleted` = 0\n\t\tAND `contact`.`blocked` = 0 AND `contact`.`pending` = 0\n\t\tAND `item`.`id` = `item`.`parent` AND `item`.`wall` = 1\n\t\t{$sql_extra}\n\t\tORDER BY `item`.`created` DESC LIMIT %d ,%d ", intval($a->profile['profile_uid']), intval($a->pager['start']), intval($a->pager['itemspage'])); $parents_arr = array(); $parents_str = ''; if (count($r)) { foreach ($r as $rr) { $parents_arr[] = $rr['item_id']; } $parents_str = implode(', ', $parents_arr); $r = q("SELECT `item`.*, `item`.`id` AS `item_id`, \n\t\t\t`contact`.`name`, `contact`.`photo`, `contact`.`url`, `contact`.`network`, `contact`.`rel`, \n\t\t\t`contact`.`thumb`, `contact`.`self`, `contact`.`writable`, \n\t\t\t`contact`.`id` AS `cid`, `contact`.`uid` AS `contact-uid`\n\t\t\tFROM `item`, (SELECT `p`.`id`,`p`.`created` FROM `item` AS `p` WHERE `p`.`parent` = `p`.`id`) AS `parentitem`, `contact`\n\t\t\tWHERE `item`.`uid` = %d AND `item`.`visible` = 1 AND `item`.`deleted` = 0\n\t\t\tAND `contact`.`id` = `item`.`contact-id`\n\t\t\tAND `contact`.`blocked` = 0 AND `contact`.`pending` = 0\n\t\t\tAND `item`.`parent` = `parentitem`.`id` AND `item`.`parent` IN ( %s )\n\t\t\t{$sql_extra}\n\t\t\tORDER BY `parentitem`.`created` DESC, `gravity` ASC, `item`.`created` ASC ", intval($a->profile['profile_uid']), dbesc($parents_str)); } if ($is_owner && !$update) { $o .= get_birthdays(); $o .= get_events(); } if (!$update && $tab === 'posts') { // This is ugly, but we can't pass the profile_uid through the session to the ajax updater, // because browser prefetching might change it on us. We have to deliver it with the page. $o .= '<div id="live-profile"></div>' . "\r\n"; $o .= "<script> var profile_uid = " . $a->profile['profile_uid'] . "; var netargs = '/?f='; var profile_page = " . $a->pager['page'] . "; </script>\r\n"; } $o .= conversation($a, $r, 'profile', $update); if (!$update) { $o .= paginate($a); } return $o; }
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 }
function profile_content(&$a, $update = false) { require_once "include/bbcode.php"; require_once 'include/security.php'; $groups = array(); $tab = 'posts'; if (remote_user()) { $contact_id = $_SESSION['visitor_id']; $groups = init_groups_visitor($contact_id); $r = q("SELECT * FROM `contact` WHERE `id` = %d LIMIT 1", intval($contact_id)); if (count($r)) { $contact = $r[0]; } } else { if (local_user()) { $contact_id = $_SESSION['cid']; $contact = $a->contact; } } $a->profile['profile_uid'] = 1; if (!$update) { if (x($_GET, 'tab')) { $tab = notags(trim($_GET['tab'])); } $tpl = file_get_contents('view/profile_tabs.tpl'); $o .= replace_macros($tpl, array('$url' => $a->get_baseurl() . '/' . $a->cmd, '$phototab' => $a->get_baseurl() . '/photos/' . $a->profile['nickname'])); if ($tab == 'profile') { require_once 'view/profile_advanced.php'; return $o; } if (can_write_wall($a, 1)) { $tpl = file_get_contents('view/jot-header.tpl'); $a->page['htmlhead'] .= replace_macros($tpl, array('$baseurl' => $a->get_baseurl())); require_once 'view/acl_selectors.php'; $tpl = file_get_contents("view/jot.tpl"); if (is_array($a->user) && (strlen($a->user['allow_cid']) || strlen($a->user['allow_gid']) || strlen($a->user['deny_cid']) || strlen($a->user['deny_gid']))) { $lockstate = 'lock'; } else { $lockstate = 'unlock'; } $o .= replace_macros($tpl, array('$baseurl' => $a->get_baseurl(), '$defloc' => $_SESSION['uid'] == 1 ? $a->user['default-location'] : '', '$return_path' => $a->cmd, '$visitor' => $_SESSION['uid'] == 1 ? 'block' : 'none', '$lockstate' => $lockstate, '$acl' => $_SESSION['uid'] == 1 ? populate_acl($a->user) : '', '$profile_uid' => 1)); } if ($tab == 'posts' && !$a->pager['start']) { $o .= '<div id="live-profile"></div>' . "\r\n"; } } // default permissions - anonymous user $sql_extra = " AND `allow_cid` = '' AND `allow_gid` = '' AND `deny_cid` = '' AND `deny_gid` = '' "; // Profile owner - everything is visible if (local_user()) { $sql_extra = ''; // Oh - while we're here... reset the Unseen messages $r = q("UPDATE `item` SET `unseen` = 0 WHERE `type` != 'remote' AND `unseen` = 1 "); } elseif (remote_user()) { $gs = '<<>>'; // should be impossible to match if (count($groups)) { foreach ($groups as $g) { $gs .= '|<' . intval($g) . '>'; } } $sql_extra = sprintf(" AND ( `allow_cid` = '' OR `allow_cid` REGEXP '<%d>' ) \n\t\t\t AND ( `deny_cid` = '' OR NOT `deny_cid` REGEXP '<%d>' ) \n\t\t\t AND ( `allow_gid` = '' OR `allow_gid` REGEXP '%s' )\n\t\t\t AND ( `deny_gid` = '' OR NOT `deny_gid` REGEXP '%s') ", intval($_SESSION['visitor_id']), intval($_SESSION['visitor_id']), dbesc($gs), dbesc($gs)); } $r = q("SELECT COUNT(*) AS `total`\n\t\tFROM `item` LEFT JOIN `contact` ON `contact`.`id` = `item`.`contact-id`\n\t\tWHERE `item`.`visible` = 1 AND `item`.`deleted` = 0\n\t\tAND `contact`.`blocked` = 0 AND `contact`.`pending` = 0\n\t\tAND `item`.`parent` IN ( SELECT `parent` FROM `item` WHERE `id` = `parent` AND `type` != 'remote') \n\t\t{$sql_extra} "); if (count($r)) { $a->set_pager_total($r[0]['total']); } $r = q("SELECT `item`.*, `item`.`id` AS `item_id`, \n\t\t`contact`.`name`, `contact`.`photo`, `contact`.`url`, \n\t\t`contact`.`thumb`, `contact`.`dfrn-id`, `contact`.`self`, \n\t\t`contact`.`id` AS `cid`\n\t\tFROM `item` LEFT JOIN `contact` ON `contact`.`id` = `item`.`contact-id`\n\t\tWHERE `item`.`visible` = 1 AND `item`.`deleted` = 0\n\t\tAND `contact`.`blocked` = 0 AND `contact`.`pending` = 0\n\t\tAND `item`.`parent` IN ( SELECT `parent` FROM `item` WHERE `id` = `parent` AND `type` != 'remote') \n\t\t{$sql_extra}\n\t\tORDER BY `parent` DESC, `id` ASC LIMIT %d ,%d ", intval($a->pager['start']), intval($a->pager['itemspage'])); $cmnt_tpl = file_get_contents('view/comment_item.tpl'); $tpl = file_get_contents('view/wall_item.tpl'); if ($update) { $return_url = $_SESSION['return_url']; } else { $return_url = $_SESSION['return_url'] = $a->cmd; } if (count($r)) { foreach ($r as $item) { $comment = ''; $template = $tpl; $redirect_url = $a->get_baseurl() . '/redir/' . $item['cid']; if (can_write_wall($a, 1)) { if ($item['last-child']) { $comment = replace_macros($cmnt_tpl, array('$return_path' => $_SESSION['return_url'], '$type' => 'wall-comment', '$id' => $item['item_id'], '$parent' => $item['parent'], '$profile_uid' => 1, '$mylink' => $contact['url'], '$mytitle' => t('Me'), '$myphoto' => $contact['thumb'], '$ww' => '')); } } $profile_url = $item['url']; // This is my profile but I'm not the author of this post/comment. If it's somebody that's a fan or mutual friend, // I can go directly to their profile as an authenticated guest. if (local_user() && ($item['rel'] == DIRECTION_IN || $item['rel'] == DIRECTION_BOTH) && !$item['self']) { $profile_url = $redirect_url; } // We received this post via a remote feed. It's either a wall-to-wall or a remote comment. The author is // known to us and is reflected in the contact-id for this item. We can use the contact url or redirect rather than // use the link in the feed. This is different than on the network page where we may not know the author. $profile_name = strlen($item['author-name']) ? $item['author-name'] : $item['name']; $profile_avatar = strlen($item['author-avatar']) ? $item['author-avatar'] : $item['thumb']; $profile_link = $profile_url; $drop = ''; if ($item['contact-id'] == $_SESSION['visitor_id'] || $_SESSION['uid']) { $drop = replace_macros(file_get_contents('view/wall_item_drop.tpl'), array('$id' => $item['id'])); } $o .= replace_macros($template, array('$id' => $item['item_id'], '$profile_url' => $profile_link, '$name' => $profile_name, '$thumb' => $profile_avatar, '$title' => $item['title'], '$body' => bbcode($item['body']), '$ago' => relative_date($item['created']), '$location' => $item['location'] ? '<a target="map" href="http://maps.google.com/?q=' . urlencode($item['location']) . '">' . $item['location'] . '</a>' : '', '$indent' => $item['parent'] != $item['item_id'] ? ' comment' : '', '$drop' => $drop, '$comment' => $comment)); } } if ($update) { return $o; } $o .= paginate($a); return $o; }
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 }
function photos_content(&$a) { // URLs: // photos/name // photos/name/upload // photos/name/album/xxxxx // photos/name/album/xxxxx/edit // photos/name/image/xxxxx // photos/name/image/xxxxx/edit if (!x($a->data, 'user')) { notice(t('No photos selected') . EOL); return; } $_SESSION['photo_return'] = $a->cmd; // // Parse arguments // if ($a->argc > 3) { $datatype = $a->argv[2]; $datum = $a->argv[3]; } elseif ($a->argc > 2 && $a->argv[2] == 'upload') { $datatype = 'upload'; } else { $datatype = 'summary'; } if ($a->argc > 4) { $cmd = $a->argv[4]; } else { $cmd = 'view'; } // // Setup permissions structures // $owner_uid = $a->data['user']['uid']; if (remote_user()) { $contact_id = $_SESSION['visitor_id']; $groups = init_groups_visitor($contact_id); } // default permissions - anonymous user $sql_extra = " AND `allow_cid` = '' AND `allow_gid` = '' AND `deny_cid` = '' AND `deny_gid` = '' "; // Profile owner - everything is visible if (local_user() && $_SESSION['uid'] == $owner_uid) { $sql_extra = ''; } elseif (remote_user()) { // authenticated visitor - here lie dragons $gs = '<<>>'; // should be impossible to match if (count($groups)) { foreach ($groups as $g) { $gs .= '|<' . intval($g) . '>'; } } $sql_extra = sprintf(" AND ( `allow_cid` = '' OR `allow_cid` REGEXP '<%d>' ) \n\t\t\t AND ( `deny_cid` = '' OR NOT `deny_cid` REGEXP '<%d>' ) \n\t\t\t AND ( `allow_gid` = '' OR `allow_gid` REGEXP '%s' )\n\t\t\t AND ( `deny_gid` = '' OR NOT `deny_gid` REGEXP '%s') ", intval($_SESSION['visitor_id']), intval($_SESSION['visitor_id']), dbesc($gs), dbesc($gs)); } // // dispatch request // if ($datatype == 'upload') { if (!(local_user() && $_SESSION['uid'] == $a->data['user']['uid'])) { notice(t('Permission denied.')); return; } $albumselect = '<select id="photos-upload-album-select" name="album" size="4">'; $albumselect .= '<option value="" selected="selected" > </option>'; if (count($a->data['albums'])) { foreach ($a->data['albums'] as $album) { if ($album['album'] == '' || $album['album'] == t('Contact Photos')) { continue; } $albumselect .= '<option value="' . $album['album'] . '">' . $album['album'] . '</option>'; } } $albumselect .= '</select>'; $tpl = file_get_contents('view/photos_upload.tpl'); $o .= replace_macros($tpl, array('$pagename' => t('Upload Photos'), '$sessid' => session_id(), '$newalbum' => t('New album name: '), '$existalbumtext' => t('or existing album name: '), '$filestext' => t('Select files to upload: '), '$albumselect' => $albumselect, '$permissions' => t('Permissions'), '$aclselect' => populate_acl($a->user), '$archive' => $a->get_baseurl() . '/jumploader_z.jar', '$nojava' => t('Use the following controls only if the Java uploader (above) fails to launch.'), '$uploadurl' => $a->get_baseurl() . '/photos', '$submit' => t('Submit'))); return $o; } if ($datatype == 'album') { $album = hex2bin($datum); $r = q("SELECT `resource-id`, max(`scale`) AS `scale` FROM `photo` WHERE `album` = '%s' \n\t\t\t{$sql_extra} GROUP BY `resource-id`", dbesc($album)); if (count($r)) { $a->set_pager_total(count($r)); } $r = q("SELECT `resource-id`, max(`scale`) AS `scale` FROM `photo` WHERE `album` = '%s' \n\t\t\t{$sql_extra} GROUP BY `resource-id` ORDER BY `created` DESC LIMIT %d , %d", dbesc($album), intval($a->pager['start']), intval($a->pager['itemspage'])); $o .= '<h3>' . $album . '</h3>'; if ($cmd == 'edit') { if ($album != t('Profile Photos') && $album != t('Contact Photos')) { if (local_user() && $_SESSION['uid'] == $a->data['user']['uid']) { $edit_tpl = file_get_contents('view/album_edit.tpl'); $o .= replace_macros($edit_tpl, array('$nametext' => t('New album name: '), '$album' => $album, '$hexalbum' => bin2hex($album), '$submit' => t('Submit'), '$dropsubmit' => t('Delete Album'))); } } } else { if ($album != t('Profile Photos') && $album != t('Contact Photos')) { if (local_user() && $_SESSION['uid'] == $a->data['user']['uid']) { $o .= '<div id="album-edit-link"><a href="' . $a->get_baseurl() . '/photos/' . $a->data['user']['nickname'] . '/album/' . bin2hex($album) . '/edit' . '">' . t('Edit Album') . '</a></div>'; } } } $tpl = file_get_contents('view/photo_album.tpl'); if (count($r)) { foreach ($r as $rr) { $o .= replace_macros($tpl, array('$id' => $rr['id'], '$photolink' => $a->get_baseurl() . '/photos/' . $a->data['user']['nickname'] . '/image/' . $rr['resource-id'], '$phototitle' => t('View Photo'), '$imgsrc' => $a->get_baseurl() . '/photo/' . $rr['resource-id'] . '-' . $rr['scale'] . '.jpg', '$imgalt' => $rr['filename'])); } } $o .= '<div id="photo-album-end"></div>'; return $o; } if ($datatype == 'image') { require_once 'security.php'; require_once 'bbcode.php'; // fetch image, item containing image, then comments $ph = q("SELECT * FROM `photo` WHERE `resource-id` = '%s' \n\t\t\t{$sql_extra} ORDER BY `scale` ASC ", dbesc($datum)); if (!count($ph)) { notice(t('Photo not available') . EOL); return; } if (count($ph) == 1) { $hires = $lores = $ph[0]; } if (count($ph) > 1) { if ($ph[1]['scale'] == 2) { // original is 640 or less, we can display it directly $hires = $lores = $ph[0]; } else { $hires = $ph[0]; $lores = $ph[1]; } } $o .= '<h3>' . '<a href="' . $a->get_baseurl() . '/photos/' . $a->data['user']['nickname'] . '/album/' . bin2hex($ph[0]['album']) . '">' . $ph[0]['album'] . '</a></h3>'; if (local_user()) { $o .= '<div id="photo-edit-link-wrap" ><a id="photo-edit-link" href="' . $a->get_baseurl() . '/photos/' . $a->data['user']['nickname'] . '/image/' . $datum . '/edit' . '">' . t('Edit photo') . '</a></div>'; } $o .= '<a href="' . $a->get_baseurl() . '/photo/' . $hires['resource-id'] . '-' . $hires['scale'] . '.jpg" title="' . t('View Full Size') . '" ><img src="' . $a->get_baseurl() . '/photo/' . $lores['resource-id'] . '-' . $lores['scale'] . '.jpg' . '" /></a>'; // Do we have an item for this photo? $i1 = q("SELECT * FROM `item` WHERE `resource-id` = '%s' {$sql_extra} LIMIT 1", dbesc($datum)); if (count($i1)) { $r = q("SELECT COUNT(*) AS `total`\n\t\t\t\tFROM `item` LEFT JOIN `contact` ON `contact`.`id` = `item`.`contact-id`\n\t\t\t\tWHERE `parent-uri` = '%s' AND `uri` != '%s' AND `item`.`deleted` = 0\n\t\t\t\tAND NOT `item`.`type` IN ( 'remote', 'net-comment') \n\t\t\t\tAND `contact`.`blocked` = 0 AND `contact`.`pending` = 0 \n\t\t\t\t{$sql_extra} ", dbesc($i1[0]['uri']), dbesc($i1[0]['uri'])); if (count($r)) { $a->set_pager_total($r[0]['total']); } $r = q("SELECT `item`.*, `item`.`id` AS `item_id`, \n\t\t\t\t`contact`.`name`, `contact`.`photo`, `contact`.`url`, \n\t\t\t\t`contact`.`thumb`, `contact`.`dfrn-id`, `contact`.`self`, \n\t\t\t\t`contact`.`id` AS `cid`\n\t\t\t\tFROM `item` LEFT JOIN `contact` ON `contact`.`id` = `item`.`contact-id`\n\t\t\t\tWHERE `parent-uri` = '%s' AND `uri` != '%s' AND `item`.`deleted` = 0\n\t\t\t\tAND NOT `item`.`type` IN ( 'remote', 'net-comment') \n\t\t\t\tAND `contact`.`blocked` = 0 AND `contact`.`pending` = 0\n\t\t\t\t{$sql_extra}\n\t\t\t\tORDER BY `parent` DESC, `id` ASC LIMIT %d ,%d ", dbesc($i1[0]['uri']), dbesc($i1[0]['uri']), intval($a->pager['start']), intval($a->pager['itemspage'])); } $o .= '<div id="photo-caption" >' . $ph[0]['desc'] . '</div>'; if (count($i1) && strlen($i1[0]['tag'])) { // parse tags and add links $o .= '<div id="in-this-photo-text">' . t('In this photo: ') . '</div>'; $o .= '<div id="in-this-photo">' . $i1[0]['tag'] . '</div>'; } if ($cmd == 'edit') { $edit_tpl = file_get_contents('view/photo_edit.tpl'); $o .= replace_macros($edit_tpl, array('$id' => $ph[0]['id'], '$resource_id' => $ph[0]['resource-id'], '$capt_label' => t('Caption'), '$caption' => $ph[0]['desc'], '$tag_label' => t('Tags'), '$tags' => $i1[0]['tag'], '$item_id' => count($i1) ? $i1[0]['id'] : 0, '$submit' => t('Submit'), '$delete' => t('Delete Photo'))); } if (count($i1)) { // pull out how many people like the photo $cmnt_tpl = file_get_contents('view/comment_item.tpl'); $tpl = file_get_contents('view/photo_item.tpl'); $return_url = $a->cmd; if (can_write_wall($a, $a->data['user']['uid'])) { if ($i1[0]['last-child']) { $o .= replace_macros($cmnt_tpl, array('$return_path' => $return_url, '$type' => 'wall-comment', '$id' => $i1[0]['id'], '$parent' => $i1[0]['id'], '$profile_uid' => $a->data['user']['uid'], '$ww' => '')); } } // display comments if (count($r)) { foreach ($r as $item) { $comment = ''; $template = $tpl; $redirect_url = $a->get_baseurl() . '/redir/' . $item['cid']; if (can_write_wall($a, $a->data['user']['uid'])) { if ($item['last-child']) { $comment = replace_macros($cmnt_tpl, array('$return_path' => $return_url, '$type' => 'wall-comment', '$id' => $item['item_id'], '$parent' => $item['parent'], '$profile_uid' => $a->data['user']['uid'], '$ww' => '')); } } $profile_url = $item['url']; if (local_user() && ($item['rel'] == DIRECTION_IN || $item['rel'] == DIRECTION_BOTH) && !$item['self']) { $profile_url = $redirect_url; } $profile_name = strlen($item['author-name']) ? $item['author-name'] : $item['name']; $profile_avatar = strlen($item['author-avatar']) ? $item['author-avatar'] : $item['thumb']; $profile_link = $profile_url; $drop = ''; if ($item['contact-id'] == $_SESSION['visitor_id'] || local_user()) { $drop = replace_macros(file_get_contents('view/wall_item_drop.tpl'), array('$id' => $item['id'])); } $o .= replace_macros($template, array('$id' => $item['item_id'], '$profile_url' => $profile_link, '$name' => $profile_name, '$thumb' => $profile_avatar, '$title' => $item['title'], '$body' => bbcode($item['body']), '$ago' => relative_date($item['created']), '$indent' => $item['parent'] != $item['item_id'] ? ' comment' : '', '$drop' => $drop, '$comment' => $comment)); } } $o .= paginate($a); } return $o; } // Default - show recent photos with upload link (if applicable) $r = q("SELECT `resource-id`, max(`scale`) AS `scale` FROM `photo` WHERE `album` != '%s' \n\t\t{$sql_extra} GROUP BY `resource-id`", dbesc(t('Contact Photos'))); if (count($r)) { $a->set_pager_total(count($r)); } $r = q("SELECT `resource-id`, `album`, max(`scale`) AS `scale` FROM `photo` WHERE `album` != '%s' \n\t\t{$sql_extra} GROUP BY `resource-id` ORDER BY `created` DESC LIMIT %d , %d", dbesc(t('Contact Photos')), intval($a->pager['start']), intval($a->pager['itemspage'])); $o .= '<h3>' . t('Recent Photos') . '</h3>'; if (local_user()) { $o .= '<div id="photo-top-links"><a id="photo-top-upload-link" href="' . $a->get_baseurl() . '/photos/' . $a->data['user']['nickname'] . '/upload' . '">' . t('Upload New Photos') . '</a></div>'; } $tpl = file_get_contents('view/photo_top.tpl'); if (count($r)) { foreach ($r as $rr) { $o .= replace_macros($tpl, array('$id' => $rr['id'], '$photolink' => $a->get_baseurl() . '/photos/' . $a->data['user']['nickname'] . '/image/' . $rr['resource-id'], '$phototitle' => t('View Photo'), '$imgsrc' => $a->get_baseurl() . '/photo/' . $rr['resource-id'] . '-' . $rr['scale'] . '.jpg', '$albumlink' => $a->get_baseurl . '/photos/' . $a->data['user']['nickname'] . '/album/' . bin2hex($rr['album']), '$albumname' => $rr['album'], '$albumalt' => t('View Album'), '$imgalt' => $rr['filename'])); } $o .= '<div id="photo-top-end"></div>'; } return $o; }
function profile_content(&$a, $update = 0) { $category = $datequery = $datequery2 = ''; if ($a->argc > 2) { for ($x = 2; $x < $a->argc; $x++) { if (is_a_date_arg($a->argv[$x])) { if ($datequery) { $datequery2 = escape_tags($a->argv[$x]); } else { $datequery = escape_tags($a->argv[$x]); } } else { $category = $a->argv[$x]; } } } if (!x($category)) { $category = x($_GET, 'category') ? $_GET['category'] : ''; } if (get_config('system', 'block_public') && !local_user() && !remote_user()) { return login(); } require_once "include/bbcode.php"; require_once 'include/security.php'; require_once 'include/conversation.php'; require_once 'include/acl_selectors.php'; require_once 'include/items.php'; $groups = array(); $tab = 'posts'; $o = ''; if ($update) { // Ensure we've got a profile owner if updating. $a->profile['profile_uid'] = $update; } else { if ($a->profile['profile_uid'] == local_user()) { nav_set_selected('home'); } } $contact = null; $remote_contact = false; $contact_id = 0; if (is_array($_SESSION['remote'])) { foreach ($_SESSION['remote'] as $v) { if ($v['uid'] == $a->profile['profile_uid']) { $contact_id = $v['cid']; break; } } } if ($contact_id) { $groups = init_groups_visitor($contact_id); $r = q("SELECT * FROM `contact` WHERE `id` = %d AND `uid` = %d LIMIT 1", intval($contact_id), intval($a->profile['profile_uid'])); if (count($r)) { $contact = $r[0]; $remote_contact = true; } } if (!$remote_contact) { if (local_user()) { $contact_id = $_SESSION['cid']; $contact = $a->contact; } } $is_owner = local_user() && local_user() == $a->profile['profile_uid'] ? true : false; if ($a->profile['hidewall'] && !$is_owner && !$remote_contact) { notice(t('Access to this profile has been restricted.') . EOL); return; } if (!$update) { if (x($_GET, 'tab')) { $tab = notags(trim($_GET['tab'])); } $o .= profile_tabs($a, $is_owner, $a->profile['nickname']); if ($tab === 'profile') { $o .= advanced_profile($a); call_hooks('profile_advanced', $o); return $o; } $o .= common_friends_visitor_widget($a->profile['profile_uid']); if (x($_SESSION, 'new_member') && $_SESSION['new_member'] && $is_owner) { $o .= '<a href="newmember" id="newmember-tips" style="font-size: 1.2em;"><b>' . t('Tips for New Members') . '</b></a>' . EOL; } $commpage = $a->profile['page-flags'] == PAGE_COMMUNITY ? true : false; $commvisitor = $commpage && $remote_contact == true ? true : false; $a->page['aside'] .= posted_date_widget($a->get_baseurl(true) . '/profile/' . $a->profile['nickname'], $a->profile['profile_uid'], true); $a->page['aside'] .= categories_widget($a->get_baseurl(true) . '/profile/' . $a->profile['nickname'], x($category) ? xmlify($category) : ''); if (can_write_wall($a, $a->profile['profile_uid'])) { $x = array('is_owner' => $is_owner, 'allow_location' => ($is_owner || $commvisitor) && $a->profile['allow_location'] ? true : false, 'default_location' => $is_owner ? $a->user['default-location'] : '', 'nickname' => $a->profile['nickname'], 'lockstate' => is_array($a->user) && (strlen($a->user['allow_cid']) || strlen($a->user['allow_gid']) || strlen($a->user['deny_cid']) || strlen($a->user['deny_gid'])) ? 'lock' : 'unlock', 'acl' => $is_owner ? populate_acl($a->user, true) : '', 'bang' => '', 'visitor' => $is_owner || $commvisitor ? 'block' : 'none', 'profile_uid' => $a->profile['profile_uid'], 'acl_data' => $is_owner ? construct_acl_data($a, $a->user) : ''); $o .= status_editor($a, $x); } } /** * Get permissions SQL - if $remote_contact is true, our remote user has been pre-verified and we already have fetched his/her groups */ $sql_extra = item_permissions_sql($a->profile['profile_uid'], $remote_contact, $groups); if ($update) { $r = q("SELECT distinct(parent) AS `item_id`, `item`.`network` AS `item_network`,\n\t\t\t`contact`.`uid` AS `contact-uid`\n\t\t\tFROM `item` INNER JOIN `contact` ON `contact`.`id` = `item`.`contact-id`\n\t\t\tAND `contact`.`blocked` = 0 AND `contact`.`pending` = 0\n\t\t\tWHERE `item`.`uid` = %d AND `item`.`visible` = 1 AND\n\t\t\t(`item`.`deleted` = 0 OR item.verb = '" . ACTIVITY_LIKE . "' OR item.verb = '" . ACTIVITY_DISLIKE . "')\n\t\t\tand `item`.`moderated` = 0 and `item`.`unseen` = 1\n\t\t\tAND `item`.`wall` = 1\n\t\t\t{$sql_extra}\n\t\t\tORDER BY `item`.`created` DESC", intval($a->profile['profile_uid'])); } else { $sql_post_table = ""; if (x($category)) { $sql_post_table = sprintf("INNER JOIN (SELECT `oid` FROM `term` WHERE `term` = '%s' AND `otype` = %d AND `type` = %d AND `uid` = %d ORDER BY `tid` DESC) AS `term` ON `item`.`id` = `term`.`oid` ", dbesc(protect_sprintf($category)), intval(TERM_OBJ_POST), intval(TERM_CATEGORY), intval($a->profile['profile_uid'])); //$sql_extra .= protect_sprintf(file_tag_file_query('item',$category,'category')); } if ($datequery) { $sql_extra2 .= protect_sprintf(sprintf(" AND `thread`.`created` <= '%s' ", dbesc(datetime_convert(date_default_timezone_get(), '', $datequery)))); } if ($datequery2) { $sql_extra2 .= protect_sprintf(sprintf(" AND `thread`.`created` >= '%s' ", dbesc(datetime_convert(date_default_timezone_get(), '', $datequery2)))); } if (get_config('system', 'old_pager')) { $r = q("SELECT COUNT(*) AS `total`\n\t\t\t FROM `thread` INNER JOIN `item` ON `item`.`id` = `thread`.`iid`\n\t\t\t {$sql_post_table} INNER JOIN `contact` ON `contact`.`id` = `thread`.`contact-id`\n\t\t\t AND `contact`.`blocked` = 0 AND `contact`.`pending` = 0\n\t\t\t WHERE `thread`.`uid` = %d AND `thread`.`visible` = 1 AND `thread`.`deleted` = 0\n\t\t\t and `thread`.`moderated` = 0\n\t\t\t AND `thread`.`wall` = 1\n\t\t\t {$sql_extra} {$sql_extra2} ", intval($a->profile['profile_uid'])); if (count($r)) { $a->set_pager_total($r[0]['total']); } } // check if we serve a mobile device and get the user settings // accordingly if ($a->is_mobile) { $itemspage_network = get_pconfig(local_user(), 'system', 'itemspage_mobile_network'); $itemspage_network = intval($itemspage_network) ? $itemspage_network : 20; } else { $itemspage_network = get_pconfig(local_user(), 'system', 'itemspage_network'); $itemspage_network = intval($itemspage_network) ? $itemspage_network : 40; } // now that we have the user settings, see if the theme forces // a maximum item number which is lower then the user choice if ($a->force_max_items > 0 && $a->force_max_items < $itemspage_network) { $itemspage_network = $a->force_max_items; } $a->set_pager_itemspage($itemspage_network); $pager_sql = sprintf(" LIMIT %d, %d ", intval($a->pager['start']), intval($a->pager['itemspage'])); $r = q("SELECT `thread`.`iid` AS `item_id`, `thread`.`network` AS `item_network`,\n\t\t\t`thread`.`uid` AS `contact-uid`\n\t\t\tFROM `thread` INNER JOIN `item` ON `item`.`id` = `thread`.`iid`\n\t\t\t{$sql_post_table} INNER JOIN `contact` ON `contact`.`id` = `thread`.`contact-id`\n\t\t\tAND `contact`.`blocked` = 0 AND `contact`.`pending` = 0\n\t\t\tWHERE `thread`.`uid` = %d AND `thread`.`visible` = 1 AND `thread`.`deleted` = 0\n\t\t\tand `thread`.`moderated` = 0\n\t\t\tAND `thread`.`wall` = 1\n\t\t\t{$sql_extra} {$sql_extra2}\n\t\t\tORDER BY `thread`.`created` DESC {$pager_sql} ", intval($a->profile['profile_uid'])); } $parents_arr = array(); $parents_str = ''; if (count($r)) { foreach ($r as $rr) { $parents_arr[] = $rr['item_id']; } $parents_str = implode(', ', $parents_arr); $items = q("SELECT `item`.*, `item`.`id` AS `item_id`, `item`.`network` AS `item_network`,\n\t\t\t`contact`.`name`, `contact`.`photo`, `contact`.`url`, `contact`.`alias`, `contact`.`network`, `contact`.`rel`,\n\t\t\t`contact`.`thumb`, `contact`.`self`, `contact`.`writable`,\n\t\t\t`contact`.`id` AS `cid`, `contact`.`uid` AS `contact-uid`\n\t\t\tFROM `item`, `contact`\n\t\t\tWHERE `item`.`uid` = %d AND `item`.`visible` = 1 AND `item`.`deleted` = 0\n\t\t\tand `item`.`moderated` = 0\n\t\t\tAND `contact`.`id` = `item`.`contact-id`\n\t\t\tAND `contact`.`blocked` = 0 AND `contact`.`pending` = 0\n\t\t\tAND `item`.`parent` IN ( %s )\n\t\t\t{$sql_extra} ", intval($a->profile['profile_uid']), dbesc($parents_str)); $items = conv_sort($items, 'created'); } else { $items = array(); } if ($is_owner && !$update && !get_config('theme', 'hide_eventlist')) { $o .= get_birthdays(); $o .= get_events(); } if ($is_owner) { $r = q("UPDATE `item` SET `unseen` = 0\n\t\t\tWHERE `wall` = 1 AND `unseen` = 1 AND `uid` = %d", intval(local_user())); } $o .= conversation($a, $items, 'profile', $update); if (!$update) { if (!get_config('system', 'old_pager')) { $o .= alt_pager($a, count($items)); } else { $o .= paginate($a); } } return $o; }
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(); }
function conversation(&$a, $items, $mode, $update, $preview = false) { require_once 'include/bbcode.php'; require_once 'mod/proxy.php'; $ssl_state = local_user() ? true : false; $profile_owner = 0; $page_writeable = false; $live_update_div = ''; $arr_blocked = null; if (local_user()) { $str_blocked = get_pconfig(local_user(), 'system', 'blocked'); if ($str_blocked) { $arr_blocked = explode(',', $str_blocked); for ($x = 0; $x < count($arr_blocked); $x++) { $arr_blocked[$x] = trim($arr_blocked[$x]); } } } $previewing = $preview ? ' preview ' : ''; if ($mode === 'network') { $profile_owner = local_user(); $page_writeable = true; if (!$update) { // The special div is needed for liveUpdate to kick in for this page. // We only launch liveUpdate if you aren't filtering in some incompatible // way and also you aren't writing a comment (discovered in javascript). $live_update_div = '<div id="live-network"></div>' . "\r\n" . "<script> var profile_uid = " . $_SESSION['uid'] . "; var netargs = '" . substr($a->cmd, 8) . '?f=' . (x($_GET, 'cid') ? '&cid=' . $_GET['cid'] : '') . (x($_GET, 'search') ? '&search=' . $_GET['search'] : '') . (x($_GET, 'star') ? '&star=' . $_GET['star'] : '') . (x($_GET, 'order') ? '&order=' . $_GET['order'] : '') . (x($_GET, 'bmark') ? '&bmark=' . $_GET['bmark'] : '') . (x($_GET, 'liked') ? '&liked=' . $_GET['liked'] : '') . (x($_GET, 'conv') ? '&conv=' . $_GET['conv'] : '') . (x($_GET, 'spam') ? '&spam=' . $_GET['spam'] : '') . (x($_GET, 'nets') ? '&nets=' . $_GET['nets'] : '') . (x($_GET, 'cmin') ? '&cmin=' . $_GET['cmin'] : '') . (x($_GET, 'cmax') ? '&cmax=' . $_GET['cmax'] : '') . (x($_GET, 'file') ? '&file=' . $_GET['file'] : '') . "'; var profile_page = " . $a->pager['page'] . "; </script>\r\n"; } } else { if ($mode === 'profile') { $profile_owner = $a->profile['profile_uid']; $page_writeable = can_write_wall($a, $profile_owner); if (!$update) { $tab = notags(trim($_GET['tab'])); $tab = $tab ? $tab : 'posts'; if ($tab === 'posts') { // This is ugly, but we can't pass the profile_uid through the session to the ajax updater, // because browser prefetching might change it on us. We have to deliver it with the page. $live_update_div = '<div id="live-profile"></div>' . "\r\n" . "<script> var profile_uid = " . $a->profile['profile_uid'] . "; var netargs = '?f='; var profile_page = " . $a->pager['page'] . "; </script>\r\n"; } } } else { if ($mode === 'notes') { $profile_owner = local_user(); $page_writeable = true; if (!$update) { $live_update_div = '<div id="live-notes"></div>' . "\r\n" . "<script> var profile_uid = " . local_user() . "; var netargs = '/?f='; var profile_page = " . $a->pager['page'] . "; </script>\r\n"; } } else { if ($mode === 'display') { $profile_owner = $a->profile['uid']; $page_writeable = can_write_wall($a, $profile_owner); if (!$update) { $live_update_div = '<div id="live-display"></div>' . "\r\n" . "<script> var profile_uid = " . $_SESSION['uid'] . ";" . " var profile_page = 1; </script>"; } } else { if ($mode === 'community') { $profile_owner = 0; $page_writeable = false; if (!$update) { $live_update_div = '<div id="live-community"></div>' . "\r\n" . "<script> var profile_uid = -1; var netargs = '/?f='; var profile_page = " . $a->pager['page'] . "; </script>\r\n"; } } else { if ($mode === 'search') { $live_update_div = '<div id="live-search"></div>' . "\r\n"; } } } } } } $page_dropping = local_user() && local_user() == $profile_owner ? true : false; if ($update) { $return_url = $_SESSION['return_url']; } else { $return_url = $_SESSION['return_url'] = $a->query_string; } load_contact_links(local_user()); $cb = array('items' => $items, 'mode' => $mode, 'update' => $update, 'preview' => $preview); call_hooks('conversation_start', $cb); $items = $cb['items']; $cmnt_tpl = get_markup_template('comment_item.tpl'); $hide_comments_tpl = get_markup_template('hide_comments.tpl'); $alike = array(); $dlike = array(); // array with html for each thread (parent+comments) $threads = array(); $threadsid = -1; $page_template = get_markup_template("conversation.tpl"); if ($items && count($items)) { if ($mode === 'network-new' || $mode === 'search' || $mode === 'community') { // "New Item View" on network page or search page results // - just loop through the items and format them minimally for display // $tpl = get_markup_template('search_item.tpl'); $tpl = 'search_item.tpl'; foreach ($items as $item) { if ($arr_blocked) { $blocked = false; foreach ($arr_blocked as $b) { if ($b && link_compare($item['author-link'], $b)) { $blocked = true; break; } } if ($blocked) { continue; } } $threadsid++; $comment = ''; $owner_url = ''; $owner_photo = ''; $owner_name = ''; $sparkle = ''; if ($mode === 'search' || $mode === 'community') { if ((activity_match($item['verb'], ACTIVITY_LIKE) || activity_match($item['verb'], ACTIVITY_DISLIKE)) && $item['id'] != $item['parent']) { continue; } $nickname = $item['nickname']; } else { $nickname = $a->user['nickname']; } // prevent private email from leaking. if ($item['network'] === NETWORK_MAIL && local_user() != $item['uid']) { continue; } $profile_name = strlen($item['author-name']) ? $item['author-name'] : $item['name']; if ($item['author-link'] && !$item['author-name']) { $profile_name = $item['author-link']; } $tags = array(); $hashtags = array(); $mentions = array(); $taglist = q("SELECT `type`, `term`, `url` FROM `term` WHERE `otype` = %d AND `oid` = %d AND `type` IN (%d, %d) ORDER BY `tid`", intval(TERM_OBJ_POST), intval($item['id']), intval(TERM_HASHTAG), intval(TERM_MENTION)); foreach ($taglist as $tag) { if ($tag["url"] == "") { $tag["url"] = $searchpath . strtolower($tag["term"]); } if ($tag["type"] == TERM_HASHTAG) { $hashtags[] = "#<a href=\"" . $tag["url"] . "\" target=\"_blank\">" . $tag["term"] . "</a>"; $prefix = "#"; } elseif ($tag["type"] == TERM_MENTION) { $mentions[] = "@<a href=\"" . $tag["url"] . "\" target=\"_blank\">" . $tag["term"] . "</a>"; $prefix = "@"; } $tags[] = $prefix . "<a href=\"" . $tag["url"] . "\" target=\"_blank\">" . $tag["term"] . "</a>"; } /*foreach(explode(',',$item['tag']) as $tag){ $tag = trim($tag); if ($tag!="") { $t = bbcode($tag); $tags[] = $t; if($t[0] == '#') $hashtags[] = $t; elseif($t[0] == '@') $mentions[] = $t; } }*/ $sp = false; $profile_link = best_link_url($item, $sp); if ($profile_link === 'mailbox') { $profile_link = ''; } if ($sp) { $sparkle = ' sparkle'; } else { $profile_link = zrl($profile_link); } $normalised = normalise_link(strlen($item['author-link']) ? $item['author-link'] : $item['url']); if ($normalised != 'mailbox' && x($a->contacts[$normalised])) { $profile_avatar = $a->contacts[$normalised]['thumb']; } else { $profile_avatar = strlen($item['author-avatar']) ? $a->get_cached_avatar_image($item['author-avatar']) : $item['thumb']; } $locate = array('location' => $item['location'], 'coord' => $item['coord'], 'html' => ''); call_hooks('render_location', $locate); $location = strlen($locate['html']) ? $locate['html'] : render_location_google($locate); localize_item($item); if ($mode === 'network-new') { $dropping = true; } else { $dropping = false; } $drop = array('dropping' => $dropping, 'pagedrop' => $page_dropping, 'select' => t('Select'), 'delete' => t('Delete')); $star = false; $isstarred = "unstarred"; $lock = false; $likebuttons = false; $shareable = false; $body = prepare_body($item, true, $preview); list($categories, $folders) = get_cats_and_terms($item); if ($a->theme['template_engine'] === 'internal') { $profile_name_e = template_escape($profile_name); $item['title_e'] = template_escape($item['title']); $body_e = template_escape($body); $tags_e = template_escape($tags); $hashtags_e = template_escape($hashtags); $mentions_e = template_escape($mentions); $location_e = template_escape($location); $owner_name_e = template_escape($owner_name); } else { $profile_name_e = $profile_name; $item['title_e'] = $item['title']; $body_e = $body; $tags_e = $tags; $hashtags_e = $hashtags; $mentions_e = $mentions; $location_e = $location; $owner_name_e = $owner_name; } $tmp_item = array('template' => $tpl, 'id' => $preview ? 'P0' : $item['item_id'], 'network' => $item['item_network'], 'linktitle' => sprintf(t('View %s\'s profile @ %s'), $profile_name, strlen($item['author-link']) ? $item['author-link'] : $item['url']), 'profile_url' => $profile_link, 'item_photo_menu' => item_photo_menu($item), 'name' => $profile_name_e, 'sparkle' => $sparkle, 'lock' => $lock, 'thumb' => proxy_url($profile_avatar), 'title' => $item['title_e'], 'body' => $body_e, 'tags' => $tags_e, 'hashtags' => $hashtags_e, 'mentions' => $mentions_e, 'txt_cats' => t('Categories:'), 'txt_folders' => t('Filed under:'), 'has_cats' => count($categories) ? 'true' : '', 'has_folders' => count($folders) ? 'true' : '', 'categories' => $categories, 'folders' => $folders, 'text' => strip_tags($body_e), 'localtime' => datetime_convert('UTC', date_default_timezone_get(), $item['created'], 'r'), 'ago' => $item['app'] ? sprintf(t('%s from %s'), relative_date($item['created']), $item['app']) : relative_date($item['created']), 'location' => $location_e, 'indent' => '', 'owner_name' => $owner_name_e, 'owner_url' => $owner_url, 'owner_photo' => proxy_url($owner_photo), 'plink' => get_plink($item), 'edpost' => false, 'isstarred' => $isstarred, 'star' => $star, 'drop' => $drop, 'vote' => $likebuttons, 'like' => '', 'dislike' => '', 'comment' => '', 'conv' => $preview ? '' : array('href' => $a->get_baseurl($ssl_state) . '/display/' . $item['guid'], 'title' => t('View in context')), 'previewing' => $previewing, 'wait' => t('Please wait'), 'thread_level' => 1); $arr = array('item' => $item, 'output' => $tmp_item); call_hooks('display_item', $arr); $threads[$threadsid]['id'] = $item['item_id']; $threads[$threadsid]['network'] = $item['item_network']; $threads[$threadsid]['items'] = array($arr['output']); } } else { // Normal View $page_template = get_markup_template("threaded_conversation.tpl"); require_once 'object/Conversation.php'; require_once 'object/Item.php'; $conv = new Conversation($mode, $preview); // get all the topmost parents // this shouldn't be needed, as we should have only them in our array // But for now, this array respects the old style, just in case $threads = array(); foreach ($items as $item) { if ($arr_blocked) { $blocked = false; foreach ($arr_blocked as $b) { if ($b && link_compare($item['author-link'], $b)) { $blocked = true; break; } } if ($blocked) { continue; } } // Can we put this after the visibility check? like_puller($a, $item, $alike, 'like'); like_puller($a, $item, $dlike, 'dislike'); // Only add what is visible if ($item['network'] === NETWORK_MAIL && local_user() != $item['uid']) { continue; } if (!visible_activity($item)) { continue; } call_hooks('display_item', $arr); $item['pagedrop'] = $page_dropping; if ($item['id'] == $item['parent']) { $item_object = new Item($item); $conv->add_thread($item_object); } } $threads = $conv->get_template_data($alike, $dlike); if (!$threads) { logger('[ERROR] conversation : Failed to get template data.', LOGGER_DEBUG); $threads = array(); } } } $o = replace_macros($page_template, array('$baseurl' => $a->get_baseurl($ssl_state), '$return_path' => $a->query_string, '$live_update' => $live_update_div, '$remove' => t('remove'), '$mode' => $mode, '$user' => $a->user, '$threads' => $threads, '$dropping' => $page_dropping && feature_enabled(local_user(), 'multi_delete') ? t('Delete Selected Items') : False)); return $o; }
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 }