function filer_content(&$a) { if (!local_channel()) { killme(); } $term = unxmlify(trim($_GET['term'])); $item_id = $a->argc > 1 ? intval($a->argv[1]) : 0; logger('filer: tag ' . $term . ' item ' . $item_id); if ($item_id && strlen($term)) { // file item store_item_tag(local_channel(), $item_id, TERM_OBJ_POST, TERM_FILE, $term, ''); // protect the entire conversation from periodic expiration $r = q("select parent from item where id = %d and uid = %d limit 1", intval($item_id), intval(local_channel())); if ($r) { $x = q("update item set item_retained = 1 where id = %d and uid = %d", intval($r[0]['parent']), intval(local_channel())); } } else { $filetags = array(); $r = q("select distinct(term) from term where uid = %d and type = %d order by term asc", intval(local_channel()), intval(TERM_FILE)); if (count($r)) { foreach ($r as $rr) { $filetags[] = $rr['term']; } } $tpl = get_markup_template("filer_dialog.tpl"); $o = replace_macros($tpl, array('$field' => array('term', t("Save to Folder:"), '', '', $filetags, t('- select -')), '$submit' => t('Save'))); echo $o; } killme(); }
/** * @brief Called when we deliver things that might be tagged in ways that require delivery processing. * * Handles community tagging of posts and also look for mention tags and sets up * a second delivery chain if appropriate. * * @param int $uid * @param int $item_id */ function tag_deliver($uid, $item_id) { $mention = false; /* * Fetch stuff we need - a channel and an item */ $u = q("select * from channel left join xchan on channel_hash = xchan_hash where channel_id = %d limit 1", intval($uid)); if (!$u) { return; } $i = q("select * from item where id = %d and uid = %d limit 1", intval($item_id), intval($uid)); if (!$i) { return; } $i = fetch_post_tags($i); $item = $i[0]; if ($item['source_xchan'] && $item['item_flags'] & ITEM_UPLINK && $item['item_flags'] & ITEM_THREAD_TOP && $item['edited'] != $item['created']) { // this is an update (edit) to a post which was already processed by us and has a second delivery chain // Just start the second delivery chain to deliver the updated post proc_run('php', 'include/notifier.php', 'tgroup', $item['id']); return; } /* * Seems like a good place to plug in a poke notification. */ if (stristr($item['verb'], ACTIVITY_POKE)) { $poke_notify = true; if ($item['obj_type'] == "" || $item['obj_type'] !== ACTIVITY_OBJ_PERSON || !$item['object']) { $poke_notify = false; } $obj = json_decode_plus($item['object']); if ($obj) { if ($obj['id'] !== $u[0]['channel_hash']) { $poke_notify = false; } } if ($item['item_restrict'] & ITEM_DELETED) { $poke_notify = false; } $verb = urldecode(substr($item['verb'], strpos($item['verb'], '#') + 1)); if ($poke_notify) { require_once 'include/enotify.php'; notification(array('to_xchan' => $u[0]['channel_hash'], 'from_xchan' => $item['author_xchan'], 'type' => NOTIFY_POKE, 'item' => $item, 'link' => $i[0]['llink'], 'verb' => ACTIVITY_POKE, 'activity' => $verb, 'otype' => 'item')); } } /* * Do community tagging */ if ($item['obj_type'] === ACTIVITY_OBJ_TAGTERM) { // We received a community tag activity for a post. // See if we are the owner of the parent item and have given permission to tag our posts. // If so tag the parent post. logger('tag_deliver: community tag activity received'); if ($item['owner_xchan'] === $u[0]['channel_hash'] && !get_pconfig($u[0]['channel_id'], 'system', 'blocktags')) { logger('tag_deliver: community tag recipient: ' . $u[0]['channel_name']); $j_tgt = json_decode_plus($item['target']); if ($j_tgt && $j_tgt['id']) { $p = q("select * from item where mid = '%s' and uid = %d limit 1", dbesc($j_tgt['id']), intval($u[0]['channel_id'])); if ($p) { $j_obj = json_decode_plus($item['object']); logger('tag_deliver: tag object: ' . print_r($j_obj, true), LOGGER_DATA); if ($j_obj && $j_obj['id'] && $j_obj['title']) { if (is_array($j_obj['link'])) { $taglink = get_rel_link($j_obj['link'], 'alternate'); } store_item_tag($u[0]['channel_id'], $p[0]['id'], TERM_OBJ_POST, TERM_HASHTAG, $j_obj['title'], $j_obj['id']); $x = q("update item set edited = '%s', received = '%s', changed = '%s' where mid = '%s' and uid = %d", dbesc(datetime_convert()), dbesc(datetime_convert()), dbesc(datetime_convert()), dbesc($j_tgt['id']), intval($u[0]['channel_id'])); proc_run('php', 'include/notifier.php', 'edit_post', $p[0]['id']); } } } } else { logger('tag_deliver: tag permission denied for ' . $u[0]['channel_address']); } } /* * A "union" is a message which our channel has sourced from another channel. * This sets up a second delivery chain just like forum tags do. * Find out if this is a source-able post. */ $union = check_item_source($uid, $item); if ($union) { logger('check_item_source returns true'); } // This might be a followup (e.g. comment) by the original post author to a tagged forum // If so setup a second delivery chain if (!($item['item_flags'] & ITEM_THREAD_TOP)) { $x = q("select * from item where id = parent and parent = %d and uid = %d limit 1", intval($item['parent']), intval($uid)); if ($x && $x[0]['item_flags'] & ITEM_UPLINK) { start_delivery_chain($u[0], $item, $item_id, $x[0]); } } /* * Now we've got those out of the way. Let's see if this is a post that's tagged for re-delivery */ $terms = get_terms_oftype($item['term'], TERM_MENTION); if ($terms) { logger('tag_deliver: post mentions: ' . print_r($terms, true), LOGGER_DATA); } $link = normalise_link($u[0]['xchan_url']); if ($terms) { foreach ($terms as $term) { if (link_compare($term['url'], $link)) { $mention = true; break; } } } if ($mention) { logger('tag_deliver: mention found for ' . $u[0]['channel_name']); $r = q("update item set item_flags = ( item_flags | %d ) where id = %d", intval(ITEM_MENTIONSME), intval($item_id)); // At this point we've determined that the person receiving this post was mentioned in it or it is a union. // Now let's check if this mention was inside a reshare so we don't spam a forum // If it's private we may have to unobscure it momentarily so that we can parse it. $body = ''; if ($item['item_flags'] & ITEM_OBSCURED) { $key = get_config('system', 'prvkey'); if ($item['body']) { $body = crypto_unencapsulate(json_decode_plus($item['body']), $key); } } else { $body = $item['body']; } $body = preg_replace('/\\[share(.*?)\\[\\/share\\]/', '', $body); $tagged = false; $plustagged = false; $matches = array(); $pattern = '/@\\!?\\[zrl\\=' . preg_quote($term['url'], '/') . '\\]' . preg_quote($term['term'], '/') . '\\[\\/zrl\\]/'; if (preg_match($pattern, $body, $matches)) { $tagged = true; } $pattern = '/@\\!?\\[zrl\\=([^\\]]*?)\\]((?:.(?!\\[zrl\\=))*?)\\+\\[\\/zrl\\]/'; if (preg_match_all($pattern, $body, $matches, PREG_SET_ORDER)) { $max_forums = get_config('system', 'max_tagged_forums'); if (!$max_forums) { $max_forums = 2; } $matched_forums = 0; foreach ($matches as $match) { $matched_forums++; if ($term['url'] === $match[1] && $term['term'] === $match[2]) { if ($matched_forums <= $max_forums) { $plustagged = true; break; } logger('forum ' . $term['term'] . ' exceeded max_tagged_forums - ignoring'); } } } if (!($tagged || $plustagged)) { logger('tag_deliver: mention was in a reshare or exceeded max_tagged_forums - ignoring'); return; } $arr = array('channel_id' => $uid, 'item' => $item, 'body' => $body); call_hooks('tagged', $arr); /* * Kill two birds with one stone. As long as we're here, send a mention notification. */ require_once 'include/enotify.php'; notification(array('to_xchan' => $u[0]['channel_hash'], 'from_xchan' => $item['author_xchan'], 'type' => NOTIFY_TAGSELF, 'item' => $item, 'link' => $i[0]['llink'], 'verb' => ACTIVITY_TAG, 'otype' => 'item')); // Just a normal tag? if (!$plustagged) { logger('tag_deliver: not a plus tag', LOGGER_DEBUG); return; } // plustagged - keep going, next check permissions if (!perm_is_allowed($uid, $item['author_xchan'], 'tag_deliver')) { logger('tag_delivery denied for uid ' . $uid . ' and xchan ' . $item['author_xchan']); return; } } if (!$mention && !$union) { logger('tag_deliver: no mention and no union.'); return; } // tgroup delivery - setup a second delivery chain // prevent delivery looping - only proceed // if the message originated elsewhere and is a top-level post if ($item['item_flags'] & ITEM_WALL || $item['item_flags'] & ITEM_ORIGIN || !($item['item_flags'] & ITEM_THREAD_TOP) || $item['id'] != $item['parent']) { logger('tag_deliver: item was local or a comment. rejected.'); return; } logger('tag_deliver: creating second delivery chain.'); start_delivery_chain($u[0], $item, $item_id, null); }
function sync_apps($channel, $apps) { if ($channel && $apps) { foreach ($apps as $app) { $exists = false; $term = array_key_exists('term', $app) ? $app['term'] : null; $x = q("select * from app where app_id = '%s' and app_channel = %d limit 1", dbesc($app['app_id']), intval($channel['channel_id'])); if ($x) { $exists = $x[0]; } if (array_key_exists('app_deleted', $app) && $app['app_deleted'] && $app['app_id']) { q("delete from app where app_id = '%s' and app_channel = %d limit 1", dbesc($app['app_id']), intval($channel['channel_id'])); if ($exists) { q("delete from term where otype = %d and oid = %d", intval(TERM_OBJ_APP), intval($exists['id'])); } continue; } unset($app['id']); unset($app['app_channel']); unset($app['term']); if ($exists) { q("delete from term where otype = %d and oid = %d", intval(TERM_OBJ_APP), intval($exists['id'])); } if (!$app['app_created'] || $app['app_created'] === NULL_DATE) { $app['app_created'] = datetime_convert(); } if (!$app['app_edited'] || $app['app_edited'] === NULL_DATE) { $app['app_edited'] = datetime_convert(); } $app['app_channel'] = $channel['channel_id']; if ($app['app_photo']) { $x = import_xchan_photo($app['app_photo'], $channel['channel_hash'], true); $app['app_photo'] = $x[0]; } if ($exists && $term) { foreach ($term as $t) { if (array_key_exists('type', $t)) { $t['ttype'] = $t['type']; } store_item_tag($channel['channel_id'], $exists['id'], TERM_OBJ_APP, $t['ttype'], escape_tags($t['term']), escape_tags($t['url'])); } } if ($exists) { if ($exists['app_edited'] >= $app['app_edited']) { continue; } } $hash = $app['app_id']; if ($exists) { unset($app['app_id']); foreach ($app as $k => $v) { $r = q("UPDATE app SET `%s` = '%s' WHERE app_id = '%s' AND app_channel = %d", dbesc($k), dbesc($v), dbesc($hash), intval($channel['channel_id'])); } } else { dbesc_array($app); $r = dbq("INSERT INTO app (`" . implode("`, `", array_keys($app)) . "`) VALUES ('" . implode("', '", array_values($app)) . "')"); if ($term) { $x = q("select * from app where app_id = '%s' and app_channel = %d limit 1", dbesc($hash), intval($channel['channel_id'])); if ($x) { foreach ($term as $t) { if (array_key_exists('type', $t)) { $t['ttype'] = $t['type']; } store_item_tag($channel['channel_id'], $x[0]['id'], TERM_OBJ_APP, $t['ttype'], escape_tags($t['term']), escape_tags($t['url'])); } } } } } } }
function tagger_content(&$a) { if (!local_channel() && !remote_channel()) { return; } $observer_hash = get_observer_hash(); //strip html-tags $term = notags(trim($_GET['term'])); //check if empty if (!$term) { return; } $item_id = argc() > 1 ? notags(trim(argv(1))) : 0; logger('tagger: tag ' . $term . ' item ' . $item_id); $r = q("SELECT * FROM item left join xchan on xchan_hash = author_xchan WHERE id = '%s' and uid = %d LIMIT 1", dbesc($item_id), intval(local_channel())); if (!$item_id || !$r) { logger('tagger: no item ' . $item_id); return; } $item = $r[0]; $owner_uid = $item['uid']; switch ($item['resource_type']) { case 'photo': $targettype = ACTIVITY_OBJ_PHOTO; $post_type = t('photo'); break; case 'event': $targgettype = ACTIVITY_OBJ_EVENT; $post_type = t('event'); break; default: $targettype = ACTIVITY_OBJ_NOTE; $post_type = t('post'); if ($item['mid'] != $item['parent_mid']) { $post_type = t('comment'); } break; } $links = array(array('rel' => 'alternate', 'type' => 'text/html', 'href' => z_root() . '/display/' . $item['mid'])); $target = json_encode(array('type' => $targettype, 'id' => $item['mid'], 'link' => $links, 'title' => $item['title'], 'content' => $item['body'], 'created' => $item['created'], 'edited' => $item['edited'], 'author' => array('name' => $item['xchan_name'], 'address' => $item['xchan_addr'], 'guid' => $item['xchan_guid'], 'guid_sig' => $item['xchan_guid_sig'], 'link' => array(array('rel' => 'alternate', 'type' => 'text/html', 'href' => $item['xchan_url']), array('rel' => 'photo', 'type' => $item['xchan_photo_mimetype'], 'href' => $item['xchan_photo_m']))))); $link = xmlify('<link rel="alternate" type="text/html" href="' . $a->get_baseurl() . '/display/' . $owner['nickname'] . '/' . $item['id'] . '" />' . "\n"); $tagid = $a->get_baseurl() . '/search?tag=' . $term; $objtype = ACTIVITY_OBJ_TAGTERM; $obj = json_encode(array('type' => $objtype, 'id' => $tagid, 'link' => array(array('rel' => 'alternate', 'type' => 'text/html', 'href' => $tagid)), 'title' => $term, 'content' => $term)); $bodyverb = t('%1$s tagged %2$s\'s %3$s with %4$s'); // saving here for reference // also check out x22d5 and x2317 and x0d6b and x0db8 and x24d0 and xff20 !!! $termlink = html_entity_decode('⋕') . '[zrl=' . $a->get_baseurl() . '/search?tag=' . urlencode($term) . ']' . $term . '[/zrl]'; $channel = $a->get_channel(); $arr = array(); $arr['owner_xchan'] = $item['owner_xchan']; $arr['author_xchan'] = $channel['channel_hash']; $arr['item_flags'] = ITEM_ORIGIN; if ($item['item_flags'] & ITEM_WALL) { $arr['item_flags'] |= ITEM_WALL; } $ulink = '[zrl=' . $channel['xchan_url'] . ']' . $channel['channel_name'] . '[/zrl]'; $alink = '[zrl=' . $item['xchan_url'] . ']' . $item['xchan_name'] . '[/zrl]'; $plink = '[zrl=' . $item['plink'] . ']' . $post_type . '[/zrl]'; $arr['body'] = sprintf($bodyverb, $ulink, $alink, $plink, $termlink); $arr['verb'] = ACTIVITY_TAG; $arr['tgt_type'] = $targettype; $arr['target'] = $target; $arr['obj_type'] = $objtype; $arr['object'] = $obj; $arr['parent_mid'] = $item['mid']; store_item_tag($item['uid'], $item['id'], TERM_OBJ_POST, TERM_HASHTAG, $term, $tagid); $ret = post_activity_item($arr); if ($ret['success']) { proc_run('php', 'include/notifier.php', 'tag', $ret['activity']['id']); } killme(); }
public static function app_update($arr) { $darray = array(); $ret = array('success' => false); $darray['app_url'] = x($arr, 'url') ? $arr['url'] : ''; $darray['app_channel'] = x($arr, 'uid') ? $arr['uid'] : 0; $darray['app_id'] = x($arr, 'guid') ? $arr['guid'] : 0; if (!$darray['app_url'] || !$darray['app_channel'] || !$darray['app_id']) { return $ret; } if ($arr['photo'] && !strstr($arr['photo'], z_root())) { $x = import_xchan_photo($arr['photo'], get_observer_hash(), true); $arr['photo'] = $x[1]; } $darray['app_sig'] = x($arr, 'sig') ? $arr['sig'] : ''; $darray['app_author'] = x($arr, 'author') ? $arr['author'] : get_observer_hash(); $darray['app_name'] = x($arr, 'name') ? escape_tags($arr['name']) : t('Unknown'); $darray['app_desc'] = x($arr, 'desc') ? escape_tags($arr['desc']) : ''; $darray['app_photo'] = x($arr, 'photo') ? $arr['photo'] : z_root() . '/' . get_default_profile_photo(80); $darray['app_version'] = x($arr, 'version') ? escape_tags($arr['version']) : ''; $darray['app_addr'] = x($arr, 'addr') ? escape_tags($arr['addr']) : ''; $darray['app_price'] = x($arr, 'price') ? escape_tags($arr['price']) : ''; $darray['app_page'] = x($arr, 'page') ? escape_tags($arr['page']) : ''; $darray['app_requires'] = x($arr, 'requires') ? escape_tags($arr['requires']) : ''; $darray['app_system'] = x($arr, 'system') ? intval($arr['system']) : 0; $darray['app_deleted'] = x($arr, 'deleted') ? intval($arr['deleted']) : 0; $edited = datetime_convert(); $r = q("update app set app_sig = '%s', app_author = '%s', app_name = '%s', app_desc = '%s', app_url = '%s', app_photo = '%s', app_version = '%s', app_addr = '%s', app_price = '%s', app_page = '%s', app_requires = '%s', app_edited = '%s', app_system = %d, app_deleted = %d where app_id = '%s' and app_channel = %d", dbesc($darray['app_sig']), dbesc($darray['app_author']), dbesc($darray['app_name']), dbesc($darray['app_desc']), dbesc($darray['app_url']), dbesc($darray['app_photo']), dbesc($darray['app_version']), dbesc($darray['app_addr']), dbesc($darray['app_price']), dbesc($darray['app_page']), dbesc($darray['app_requires']), dbesc($edited), intval($darray['app_system']), intval($darray['app_deleted']), dbesc($darray['app_id']), intval($darray['app_channel'])); if ($r) { $ret['success'] = true; $ret['app_id'] = $darray['app_id']; } $x = q("select id from app where app_id = '%s' and app_channel = %d limit 1", dbesc($darray['app_id']), intval($darray['app_channel'])); if ($x) { q("delete from term where otype = %d and oid = %d", intval(TERM_OBJ_APP), intval($x[0]['id'])); if ($arr['categories']) { $y = explode(',', $arr['categories']); if ($y) { foreach ($y as $t) { $t = trim($t); if ($t) { store_item_tag($darray['app_channel'], $x[0]['id'], TERM_OBJ_APP, TERM_CATEGORY, escape_tags($t), escape_tags(z_root() . '/apps/?f=&cat=' . escape_tags($t))); } } } } } return $ret; }