function get_atom_elements($item) { $res = array(); $author = $item->get_author(); $res['author-name'] = unxmlify($author->get_name()); $res['author-link'] = unxmlify($author->get_link()); $res['author-avatar'] = unxmlify($author->get_avatar()); $res['uri'] = unxmlify($item->get_id()); $res['title'] = unxmlify($item->get_title()); $res['body'] = unxmlify($item->get_content()); $maxlen = get_max_import_size(); if ($maxlen && strlen($res['body']) > $maxlen) { $res['body'] = substr($res['body'], 0, $maxlen); } $allow = $item->get_item_tags(NAMESPACE_DFRN, 'comment-allow'); if ($allow && $allow[0]['data'] == 1) { $res['last-child'] = 1; } else { $res['last-child'] = 0; } $rawcreated = $item->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'published'); if ($rawcreated) { $res['created'] = unxmlify($rawcreated[0]['data']); } $rawedited = $item->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'updated'); if ($rawedited) { $res['edited'] = unxmlify($rawcreated[0]['data']); } $rawowner = $item->get_item_tags(NAMESPACE_DFRN, 'owner'); if ($rawowner[0]['child'][NAMESPACE_DFRN]['name'][0]['data']) { $res['owner-name'] = unxmlify($rawowner[0]['child'][NAMESPACE_DFRN]['name'][0]['data']); } if ($rawowner[0]['child'][NAMESPACE_DFRN]['uri'][0]['data']) { $res['owner-link'] = unxmlify($rawowner[0]['child'][NAMESPACE_DFRN]['uri'][0]['data']); } if ($rawowner[0]['child'][NAMESPACE_DFRN]['avatar'][0]['data']) { $res['owner-avatar'] = unxmlify($rawowner[0]['child'][NAMESPACE_DFRN]['avatar'][0]['data']); } return $res; }
function get_item_elements($x) { $arr = array(); $arr['body'] = $x['body'] ? htmlspecialchars($x['body'], ENT_COMPAT, 'UTF-8', false) : ''; $key = get_config('system', 'pubkey'); $maxlen = get_max_import_size(); if ($maxlen && mb_strlen($arr['body']) > $maxlen) { $arr['body'] = mb_substr($arr['body'], 0, $maxlen, 'UTF-8'); logger('get_item_elements: message length exceeds max_import_size: truncated'); } $arr['created'] = datetime_convert('UTC', 'UTC', $x['created']); $arr['edited'] = datetime_convert('UTC', 'UTC', $x['edited']); if ($arr['created'] > datetime_convert()) { $arr['created'] = datetime_convert(); } if ($arr['edited'] > datetime_convert()) { $arr['edited'] = datetime_convert(); } $arr['expires'] = x($x, 'expires') && $x['expires'] ? datetime_convert('UTC', 'UTC', $x['expires']) : NULL_DATE; $arr['commented'] = x($x, 'commented') && $x['commented'] ? datetime_convert('UTC', 'UTC', $x['commented']) : $arr['created']; $arr['comments_closed'] = x($x, 'comments_closed') && $x['comments_closed'] ? datetime_convert('UTC', 'UTC', $x['comments_closed']) : NULL_DATE; $arr['title'] = $x['title'] ? htmlspecialchars($x['title'], ENT_COMPAT, 'UTF-8', false) : ''; if (mb_strlen($arr['title']) > 255) { $arr['title'] = mb_substr($arr['title'], 0, 255); } $arr['app'] = $x['app'] ? htmlspecialchars($x['app'], ENT_COMPAT, 'UTF-8', false) : ''; $arr['route'] = $x['route'] ? htmlspecialchars($x['route'], ENT_COMPAT, 'UTF-8', false) : ''; $arr['mid'] = $x['message_id'] ? htmlspecialchars($x['message_id'], ENT_COMPAT, 'UTF-8', false) : ''; $arr['parent_mid'] = $x['message_top'] ? htmlspecialchars($x['message_top'], ENT_COMPAT, 'UTF-8', false) : ''; $arr['thr_parent'] = $x['message_parent'] ? htmlspecialchars($x['message_parent'], ENT_COMPAT, 'UTF-8', false) : ''; $arr['plink'] = $x['permalink'] ? htmlspecialchars($x['permalink'], ENT_COMPAT, 'UTF-8', false) : ''; $arr['location'] = $x['location'] ? htmlspecialchars($x['location'], ENT_COMPAT, 'UTF-8', false) : ''; $arr['coord'] = $x['longlat'] ? htmlspecialchars($x['longlat'], ENT_COMPAT, 'UTF-8', false) : ''; $arr['verb'] = $x['verb'] ? htmlspecialchars($x['verb'], ENT_COMPAT, 'UTF-8', false) : ''; $arr['mimetype'] = $x['mimetype'] ? htmlspecialchars($x['mimetype'], ENT_COMPAT, 'UTF-8', false) : ''; $arr['obj_type'] = $x['object_type'] ? htmlspecialchars($x['object_type'], ENT_COMPAT, 'UTF-8', false) : ''; $arr['tgt_type'] = $x['target_type'] ? htmlspecialchars($x['target_type'], ENT_COMPAT, 'UTF-8', false) : ''; $arr['public_policy'] = $x['public_scope'] ? htmlspecialchars($x['public_scope'], ENT_COMPAT, 'UTF-8', false) : ''; if ($arr['public_policy'] === 'public') { $arr['public_policy'] = ''; } $arr['comment_policy'] = $x['comment_scope'] ? htmlspecialchars($x['comment_scope'], ENT_COMPAT, 'UTF-8', false) : 'contacts'; $arr['sig'] = $x['signature'] ? htmlspecialchars($x['signature'], ENT_COMPAT, 'UTF-8', false) : ''; $arr['diaspora_meta'] = $x['diaspora_signature'] ? json_encode(crypto_encapsulate($x['diaspora_signature'], $key)) : ''; $arr['object'] = activity_sanitise($x['object']); $arr['target'] = activity_sanitise($x['target']); $arr['attach'] = activity_sanitise($x['attach']); $arr['term'] = decode_tags($x['tags']); $arr['item_private'] = array_key_exists('flags', $x) && is_array($x['flags']) && in_array('private', $x['flags']) ? 1 : 0; $arr['item_flags'] = 0; if (array_key_exists('flags', $x) && in_array('consensus', $x['flags'])) { $arr['item_flags'] |= ITEM_CONSENSUS; } if (array_key_exists('flags', $x) && in_array('deleted', $x['flags'])) { $arr['item_restrict'] |= ITEM_DELETED; } if (array_key_exists('flags', $x) && in_array('hidden', $x['flags'])) { $arr['item_restrict'] |= ITEM_HIDDEN; } // Here's the deal - the site might be down or whatever but if there's a new person you've never // seen before sending stuff to your stream, we MUST be able to look them up and import their data from their // hub and verify that they are legit - or else we're going to toss the post. We only need to do this // once, and after that your hub knows them. Sure some info is in the post, but it's only a transit identifier // and not enough info to be able to look you up from your hash - which is the only thing stored with the post. if (($xchan_hash = import_author_xchan($x['author'])) !== false) { $arr['author_xchan'] = $xchan_hash; } else { return array(); } // save a potentially expensive lookup if author == owner if ($arr['author_xchan'] === make_xchan_hash($x['owner']['guid'], $x['owner']['guid_sig'])) { $arr['owner_xchan'] = $arr['author_xchan']; } else { if (($xchan_hash = import_author_xchan($x['owner'])) !== false) { $arr['owner_xchan'] = $xchan_hash; } else { return array(); } } if ($arr['sig']) { $r = q("select xchan_pubkey from xchan where xchan_hash = '%s' limit 1", dbesc($arr['author_xchan'])); if ($r && rsa_verify($x['body'], base64url_decode($arr['sig']), $r[0]['xchan_pubkey'])) { $arr['item_flags'] |= ITEM_VERIFIED; } else { logger('get_item_elements: message verification failed.'); } } // if it's a private post, encrypt it in the DB. // We have to do that here because we need to cleanse the input and prevent bad stuff from getting in, // and we need plaintext to do that. if (intval($arr['item_private'])) { $arr['item_flags'] = $arr['item_flags'] | ITEM_OBSCURED; if ($arr['title']) { $arr['title'] = json_encode(crypto_encapsulate($arr['title'], $key)); } if ($arr['body']) { $arr['body'] = json_encode(crypto_encapsulate($arr['body'], $key)); } } if (array_key_exists('revision', $x)) { // extended export encoding $arr['revision'] = $x['revision']; $arr['allow_cid'] = $x['allow_cid']; $arr['allow_gid'] = $x['allow_gid']; $arr['deny_cid'] = $x['deny_cid']; $arr['deny_gid'] = $x['deny_gid']; $arr['layout_mid'] = $x['layout_mid']; $arr['postopts'] = $x['postopts']; $arr['resource_id'] = $x['resource_id']; $arr['resource_type'] = $x['resource_type']; $arr['item_restrict'] = $x['item_restrict']; $arr['item_flags'] = $x['item_flags']; $arr['attach'] = $x['attach']; } return $arr; }
function get_atom_elements($item) { require_once 'library/HTMLPurifier.auto.php'; require_once 'include/html2bbcode.php'; $res = array(); $raw_author = $item->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'author'); if ($raw_author) { if ($raw_author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['link'][0]['attribs']['']['rel'] == 'photo') { $res['author-avatar'] = unxmlify($raw_author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['link'][0]['attribs']['']['href']); } } $author = $item->get_author(); $res['author-name'] = unxmlify($author->get_name()); $res['author-link'] = unxmlify($author->get_link()); if (!$res['author-avatar']) { $res['author-avatar'] = unxmlify($author->get_avatar()); } $res['uri'] = unxmlify($item->get_id()); $res['title'] = unxmlify($item->get_title()); $res['body'] = unxmlify($item->get_content()); $maxlen = get_max_import_size(); if ($maxlen && strlen($res['body']) > $maxlen) { $res['body'] = substr($res['body'], 0, $maxlen); } // It isn't certain at this point whether our content is plaintext or html and we'd be foolish to trust // the content type. Our own network only emits text normally, though it might have been converted to // html if we used a pubsubhubbub transport. But if we see even one html open tag in our text, we will // have to assume it is all html and needs to be purified. // It doesn't matter all that much security wise - because before this content is used anywhere, we are // going to escape any tags we find regardless, but this lets us import a limited subset of html from // the wild, by sanitising it and converting supported tags to bbcode before we rip out any remaining // html. if (strpos($res['body'], '<')) { $res['body'] = preg_replace('#<object[^>]+>.+?' . 'http://www.youtube.com/((?:v|cp)/[A-Za-z0-9\\-_=]+).+?</object>#s', '[youtube]$1[/youtube]', $res['body']); $config = HTMLPurifier_Config::createDefault(); $config->set('Core.DefinitionCache', null); // we shouldn't need a whitelist, because the bbcode converter // will strip out any unsupported tags. // $config->set('HTML.Allowed', 'p,b,a[href],i'); $purifier = new HTMLPurifier($config); $res['body'] = $purifier->purify($res['body']); } $res['body'] = html2bbcode($res['body']); $allow = $item->get_item_tags(NAMESPACE_DFRN, 'comment-allow'); if ($allow && $allow[0]['data'] == 1) { $res['last-child'] = 1; } else { $res['last-child'] = 0; } $rawcreated = $item->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'published'); if ($rawcreated) { $res['created'] = unxmlify($rawcreated[0]['data']); } $rawlocation = $item->get_item_tags(NAMESPACE_DFRN, 'location'); if ($rawlocation) { $res['location'] = unxmlify($rawlocation[0]['data']); } $rawedited = $item->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'updated'); if ($rawedited) { $res['edited'] = unxmlify($rawcreated[0]['data']); } $rawowner = $item->get_item_tags(NAMESPACE_DFRN, 'owner'); if ($rawowner[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data']) { $res['owner-name'] = unxmlify($rawowner[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data']); } elseif ($rawowner[0]['child'][NAMESPACE_DFRN]['name'][0]['data']) { $res['owner-name'] = unxmlify($rawowner[0]['child'][NAMESPACE_DFRN]['name'][0]['data']); } if ($rawowner[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['uri'][0]['data']) { $res['owner-link'] = unxmlify($rawowner[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['uri'][0]['data']); } elseif ($rawowner[0]['child'][NAMESPACE_DFRN]['uri'][0]['data']) { $res['owner-link'] = unxmlify($rawowner[0]['child'][NAMESPACE_DFRN]['uri'][0]['data']); } if ($rawowner[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['link'][0]['attribs']['']['rel'] == 'photo') { $res['owner-avatar'] = unxmlify($rawowner[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['link'][0]['attribs']['']['href']); } elseif ($rawowner[0]['child'][NAMESPACE_DFRN]['avatar'][0]['data']) { $res['owner-avatar'] = unxmlify($rawowner[0]['child'][NAMESPACE_DFRN]['avatar'][0]['data']); } $rawverb = $item->get_item_tags(NAMESPACE_ACTIVITY, 'verb'); // select between supported verbs if ($rawverb) { $res['verb'] = unxmlify($rawverb[0]['data']); } $rawobj = $item->get_item_tags(NAMESPACE_ACTIVITY, 'object'); if ($rawobj) { $res['object-type'] = $rawobj[0]['object-type'][0]['data']; $res['object'] = $rawobj[0]; } return $res; }
function get_item_elements($x, $allow_code = false) { $arr = array(); if ($allow_code) { $arr['body'] = $x['body']; } else { $arr['body'] = $x['body'] ? htmlspecialchars($x['body'], ENT_COMPAT, 'UTF-8', false) : ''; } $key = get_config('system', 'pubkey'); $maxlen = get_max_import_size(); if ($maxlen && mb_strlen($arr['body']) > $maxlen) { $arr['body'] = mb_substr($arr['body'], 0, $maxlen, 'UTF-8'); logger('get_item_elements: message length exceeds max_import_size: truncated'); } $arr['created'] = datetime_convert('UTC', 'UTC', $x['created']); $arr['edited'] = datetime_convert('UTC', 'UTC', $x['edited']); if ($arr['created'] > datetime_convert()) { $arr['created'] = datetime_convert(); } if ($arr['edited'] > datetime_convert()) { $arr['edited'] = datetime_convert(); } $arr['expires'] = x($x, 'expires') && $x['expires'] ? datetime_convert('UTC', 'UTC', $x['expires']) : NULL_DATE; $arr['commented'] = x($x, 'commented') && $x['commented'] ? datetime_convert('UTC', 'UTC', $x['commented']) : $arr['created']; $arr['comments_closed'] = x($x, 'comments_closed') && $x['comments_closed'] ? datetime_convert('UTC', 'UTC', $x['comments_closed']) : NULL_DATE; $arr['title'] = $x['title'] ? htmlspecialchars($x['title'], ENT_COMPAT, 'UTF-8', false) : ''; if (mb_strlen($arr['title']) > 255) { $arr['title'] = mb_substr($arr['title'], 0, 255); } $arr['app'] = $x['app'] ? htmlspecialchars($x['app'], ENT_COMPAT, 'UTF-8', false) : ''; $arr['route'] = $x['route'] ? htmlspecialchars($x['route'], ENT_COMPAT, 'UTF-8', false) : ''; $arr['mid'] = $x['message_id'] ? htmlspecialchars($x['message_id'], ENT_COMPAT, 'UTF-8', false) : ''; $arr['parent_mid'] = $x['message_top'] ? htmlspecialchars($x['message_top'], ENT_COMPAT, 'UTF-8', false) : ''; $arr['thr_parent'] = $x['message_parent'] ? htmlspecialchars($x['message_parent'], ENT_COMPAT, 'UTF-8', false) : ''; $arr['plink'] = $x['permalink'] ? htmlspecialchars($x['permalink'], ENT_COMPAT, 'UTF-8', false) : ''; $arr['location'] = $x['location'] ? htmlspecialchars($x['location'], ENT_COMPAT, 'UTF-8', false) : ''; $arr['coord'] = $x['longlat'] ? htmlspecialchars($x['longlat'], ENT_COMPAT, 'UTF-8', false) : ''; $arr['verb'] = $x['verb'] ? htmlspecialchars($x['verb'], ENT_COMPAT, 'UTF-8', false) : ''; $arr['mimetype'] = $x['mimetype'] ? htmlspecialchars($x['mimetype'], ENT_COMPAT, 'UTF-8', false) : ''; $arr['obj_type'] = $x['object_type'] ? htmlspecialchars($x['object_type'], ENT_COMPAT, 'UTF-8', false) : ''; $arr['tgt_type'] = $x['target_type'] ? htmlspecialchars($x['target_type'], ENT_COMPAT, 'UTF-8', false) : ''; $arr['public_policy'] = $x['public_scope'] ? htmlspecialchars($x['public_scope'], ENT_COMPAT, 'UTF-8', false) : ''; if ($arr['public_policy'] === 'public') { $arr['public_policy'] = ''; } $arr['comment_policy'] = $x['comment_scope'] ? htmlspecialchars($x['comment_scope'], ENT_COMPAT, 'UTF-8', false) : 'contacts'; $arr['sig'] = $x['signature'] ? htmlspecialchars($x['signature'], ENT_COMPAT, 'UTF-8', false) : ''; if (array_key_exists('diaspora_signature', $x) && is_array($x['diaspora_signature'])) { $x['diaspora_signature'] = json_encode($x['diaspora_signature']); } $arr['diaspora_meta'] = $x['diaspora_signature'] ? $x['diaspora_signature'] : ''; $arr['object'] = activity_sanitise($x['object']); $arr['target'] = activity_sanitise($x['target']); $arr['attach'] = activity_sanitise($x['attach']); $arr['term'] = decode_tags($x['tags']); $arr['item_private'] = array_key_exists('flags', $x) && is_array($x['flags']) && in_array('private', $x['flags']) ? 1 : 0; $arr['item_flags'] = 0; if (array_key_exists('flags', $x) && in_array('consensus', $x['flags'])) { $arr['item_consensus'] = 1; } if (array_key_exists('flags', $x) && in_array('deleted', $x['flags'])) { $arr['item_deleted'] = 1; } if (array_key_exists('flags', $x) && in_array('hidden', $x['flags'])) { $arr['item_hidden'] = 1; } // Here's the deal - the site might be down or whatever but if there's a new person you've never // seen before sending stuff to your stream, we MUST be able to look them up and import their data from their // hub and verify that they are legit - or else we're going to toss the post. We only need to do this // once, and after that your hub knows them. Sure some info is in the post, but it's only a transit identifier // and not enough info to be able to look you up from your hash - which is the only thing stored with the post. if (($xchan_hash = import_author_xchan($x['author'])) !== false) { $arr['author_xchan'] = $xchan_hash; } else { return array(); } // save a potentially expensive lookup if author == owner if ($arr['author_xchan'] === make_xchan_hash($x['owner']['guid'], $x['owner']['guid_sig'])) { $arr['owner_xchan'] = $arr['author_xchan']; } else { if (($xchan_hash = import_author_xchan($x['owner'])) !== false) { $arr['owner_xchan'] = $xchan_hash; } else { return array(); } } if ($arr['sig']) { $r = q("select xchan_pubkey from xchan where xchan_hash = '%s' limit 1", dbesc($arr['author_xchan'])); if ($r && rsa_verify($x['body'], base64url_decode($arr['sig']), $r[0]['xchan_pubkey'])) { $arr['item_verified'] = 1; } else { logger('get_item_elements: message verification failed.'); } } if (array_key_exists('revision', $x)) { // extended export encoding $arr['revision'] = $x['revision']; $arr['allow_cid'] = $x['allow_cid']; $arr['allow_gid'] = $x['allow_gid']; $arr['deny_cid'] = $x['deny_cid']; $arr['deny_gid'] = $x['deny_gid']; $arr['layout_mid'] = $x['layout_mid']; $arr['postopts'] = $x['postopts']; $arr['resource_id'] = $x['resource_id']; $arr['resource_type'] = $x['resource_type']; $arr['attach'] = $x['attach']; $arr['item_origin'] = $x['item_origin']; $arr['item_unseen'] = $x['item_unseen']; $arr['item_starred'] = $x['item_starred']; $arr['item_uplink'] = $x['item_uplink']; $arr['item_consensus'] = $x['item_consensus']; $arr['item_wall'] = $x['item_wall']; $arr['item_thread_top'] = $x['item_thread_top']; $arr['item_notshown'] = $x['item_notshown']; $arr['item_nsfw'] = $x['item_nsfw']; // local only $arr['item_relay'] = $x['item_relay']; $arr['item_mentionsme'] = $x['item_mentionsme']; $arr['item_nocomment'] = $x['item_nocomment']; // local only $arr['item_obscured'] = $x['item_obscured']; // local only $arr['item_verified'] = $x['item_verified']; $arr['item_retained'] = $x['item_retained']; $arr['item_rss'] = $x['item_rss']; $arr['item_deleted'] = $x['item_deleted']; $arr['item_type'] = $x['item_type']; $arr['item_hidden'] = $x['item_hidden']; $arr['item_unpublished'] = $x['item_unpublished']; $arr['item_delayed'] = $x['item_delayed']; $arr['item_pending_remove'] = $x['item_pending_remove']; $arr['item_blocked'] = $x['item_blocked']; if (array_key_exists('item_flags', $x)) { if ($x['item_flags'] & 0x4) { $arr['item_starred'] = 1; } if ($x['item_flags'] & 0x8) { $arr['item_uplink'] = 1; } if ($x['item_flags'] & 0x10) { $arr['item_consensus'] = 1; } if ($x['item_flags'] & 0x20) { $arr['item_wall'] = 1; } if ($x['item_flags'] & 0x40) { $arr['item_thread_top'] = 1; } if ($x['item_flags'] & 0x80) { $arr['item_notshown'] = 1; } if ($x['item_flags'] & 0x100) { $arr['item_nsfw'] = 1; } if ($x['item_flags'] & 0x400) { $arr['item_mentionsme'] = 1; } if ($x['item_flags'] & 0x800) { $arr['item_nocomment'] = 1; } if ($x['item_flags'] & 0x4000) { $arr['item_retained'] = 1; } if ($x['item_flags'] & 0x8000) { $arr['item_rss'] = 1; } } if (array_key_exists('item_restrict', $x)) { if ($x['item_restrict'] & 0x1) { $arr['item_hidden'] = 1; } if ($x['item_restrict'] & 0x2) { $arr['item_blocked'] = 1; } if ($x['item_restrict'] & 0x10) { $arr['item_deleted'] = 1; } if ($x['item_restrict'] & 0x20) { $arr['item_unpublished'] = 1; } if ($x['item_restrict'] & 0x40) { $arr['item_type'] = ITEM_TYPE_WEBPAGE; } if ($x['item_restrict'] & 0x80) { $arr['item_delayed'] = 1; } if ($x['item_restrict'] & 0x100) { $arr['item_type'] = ITEM_TYPE_BLOCK; } if ($x['item_restrict'] & 0x200) { $arr['item_type'] = ITEM_TYPE_PDL; } if ($x['item_restrict'] & 0x400) { $arr['item_type'] = ITEM_TYPE_BUG; } if ($x['item_restrict'] & 0x800) { $arr['item_pending_remove'] = 1; } if ($x['item_restrict'] & 0x1000) { $arr['item_type'] = ITEM_TYPE_DOC; } } } return $arr; }
function limit_body_size($body) { // logger('limit_body_size: start', LOGGER_DEBUG); $maxlen = get_max_import_size(); // If the length of the body, including the embedded images, is smaller // than the maximum, then don't waste time looking for the images if ($maxlen && strlen($body) > $maxlen) { logger('limit_body_size: the total body length exceeds the limit', LOGGER_DEBUG); $orig_body = $body; $new_body = ''; $textlen = 0; $max_found = false; $img_start = strpos($orig_body, '[img'); $img_st_close = $img_start !== false ? strpos(substr($orig_body, $img_start), ']') : false; $img_end = $img_start !== false ? strpos(substr($orig_body, $img_start), '[/img]') : false; while ($img_st_close !== false && $img_end !== false) { $img_st_close++; // make it point to AFTER the closing bracket $img_end += $img_start; $img_end += strlen('[/img]'); if (!strcmp(substr($orig_body, $img_start + $img_st_close, 5), 'data:')) { // This is an embedded image if ($textlen + $img_start > $maxlen) { if ($textlen < $maxlen) { logger('limit_body_size: the limit happens before an embedded image', LOGGER_DEBUG); $new_body = $new_body . substr($orig_body, 0, $maxlen - $textlen); $textlen = $maxlen; } } else { $new_body = $new_body . substr($orig_body, 0, $img_start); $textlen += $img_start; } $new_body = $new_body . substr($orig_body, $img_start, $img_end - $img_start); } else { if ($textlen + $img_end > $maxlen) { if ($textlen < $maxlen) { logger('limit_body_size: the limit happens before the end of a non-embedded image', LOGGER_DEBUG); $new_body = $new_body . substr($orig_body, 0, $maxlen - $textlen); $textlen = $maxlen; } } else { $new_body = $new_body . substr($orig_body, 0, $img_end); $textlen += $img_end; } } $orig_body = substr($orig_body, $img_end); if ($orig_body === false) { // in case the body ends on a closing image tag $orig_body = ''; } $img_start = strpos($orig_body, '[img'); $img_st_close = $img_start !== false ? strpos(substr($orig_body, $img_start), ']') : false; $img_end = $img_start !== false ? strpos(substr($orig_body, $img_start), '[/img]') : false; } if ($textlen + strlen($orig_body) > $maxlen) { if ($textlen < $maxlen) { logger('limit_body_size: the limit happens after the end of the last image', LOGGER_DEBUG); $new_body = $new_body . substr($orig_body, 0, $maxlen - $textlen); $textlen = $maxlen; } } else { logger('limit_body_size: the text size with embedded images extracted did not violate the limit', LOGGER_DEBUG); $new_body = $new_body . $orig_body; $textlen += strlen($orig_body); } return $new_body; } else { return $body; } }
function diaspora_message($importer, $xml, $msg) { $a = get_app(); $msg_guid = notags(unxmlify($xml->guid)); $msg_parent_guid = notags(unxmlify($xml->parent_guid)); $msg_parent_author_signature = notags(unxmlify($xml->parent_author_signature)); $msg_author_signature = notags(unxmlify($xml->author_signature)); $msg_text = unxmlify($xml->text); $msg_created_at = datetime_convert('UTC', 'UTC', notags(unxmlify($xml->created_at))); $msg_diaspora_handle = notags(unxmlify($xml->diaspora_handle)); $msg_conversation_guid = notags(unxmlify($xml->conversation_guid)); $parent_uri = $msg_parent_guid; $contact = diaspora_get_contact_by_handle($importer['channel_id'], $msg_diaspora_handle); if (!$contact) { logger('diaspora_message: cannot find contact: ' . $msg_diaspora_handle); return; } if ($contact['rel'] == CONTACT_IS_FOLLOWER || $contact['blocked'] || $contact['readonly']) { logger('diaspora_message: Ignoring this author.'); return 202; } $conversation = null; $c = q("select * from conv where uid = %d and guid = '%s' limit 1", intval($importer['channel_id']), dbesc($msg_conversation_guid)); if ($c) { $conversation = $c[0]; } else { logger('diaspora_message: conversation not available.'); return; } $reply = 0; $subject = $conversation['subject']; $body = diaspora2bb($msg_text); $maxlen = get_max_import_size(); if ($maxlen && mb_strlen($body) > $maxlen) { $body = mb_substr($body, 0, $maxlen, 'UTF-8'); logger('message length exceeds max_import_size: truncated'); } $message_id = $msg_diaspora_handle . ':' . $msg_guid; $author_signed_data = $msg_guid . ';' . $msg_parent_guid . ';' . $msg_text . ';' . unxmlify($xml->created_at) . ';' . $msg_diaspora_handle . ';' . $msg_conversation_guid; $author_signature = base64_decode($msg_author_signature); $person = find_diaspora_person_by_handle($msg_diaspora_handle); if (is_array($person) && x($person, 'xchan_pubkey')) { $key = $person['xchan_pubkey']; } else { logger('diaspora_message: unable to find author details'); return; } if (!rsa_verify($author_signed_data, $author_signature, $key, 'sha256')) { logger('diaspora_message: verification failed.'); return; } $r = q("select id from mail where mid = '%s' and channel_id = %d limit 1", dbesc($message_id), intval($importer['channel_id'])); if ($r) { logger('diaspora_message: duplicate message already delivered.', LOGGER_DEBUG); return; } $key = get_config('system', 'pubkey'); if ($subject) { $subject = json_encode(crypto_encapsulate($subject, $key)); } if ($body) { $body = json_encode(crypto_encapsulate($body, $key)); } q("insert into mail ( `channel_id`, `convid`, `from_xchan`,`to_xchan`,`title`,`body`,`mail_flags`,`mid`,`parent_mid`,`created`) values ( %d, %d, '%s', '%s', '%s', '%s', '%d','%s','%s','%s')", intval($importer['channel_id']), intval($conversation['id']), dbesc($person['xchan_hash']), dbesc($importer['xchan_hash']), dbesc($subject), dbesc($body), intval(MAIL_OBSCURED), dbesc($msg_guid), dbesc($parent_uri), dbesc($msg_created_at)); q("update conv set updated = '%s' where id = %d", dbesc(datetime_convert()), intval($conversation['id'])); return; }
function diaspora_message($importer, $xml, $msg) { $a = get_app(); $msg_guid = notags(unxmlify($xml['guid'])); $msg_parent_guid = notags(unxmlify($xml['parent_guid'])); $msg_parent_author_signature = notags(unxmlify($xml['parent_author_signature'])); $msg_author_signature = notags(unxmlify($xml['author_signature'])); $msg_text = unxmlify($xml['text']); $msg_created_at = datetime_convert('UTC', 'UTC', notags(unxmlify($xml['created_at']))); $msg_diaspora_handle = notags(diaspora_get_author($xml)); $msg_conversation_guid = notags(unxmlify($xml['conversation_guid'])); $parent_uri = $msg_parent_guid; $contact = diaspora_get_contact_by_handle($importer['channel_id'], $msg_diaspora_handle); if (!$contact) { logger('diaspora_message: cannot find contact: ' . $msg_diaspora_handle); return; } if (!perm_is_allowed($importer['channel_id'], $contact['xchan_hash'], 'post_mail')) { logger('Ignoring this author.'); return 202; } $conversation = null; $c = q("select * from conv where uid = %d and guid = '%s' limit 1", intval($importer['channel_id']), dbesc($msg_conversation_guid)); if ($c) { $conversation = $c[0]; } else { logger('diaspora_message: conversation not available.'); return; } $reply = 0; $subject = $conversation['subject']; //this is already encoded $body = diaspora2bb($msg_text); $maxlen = get_max_import_size(); if ($maxlen && mb_strlen($body) > $maxlen) { $body = mb_substr($body, 0, $maxlen, 'UTF-8'); logger('message length exceeds max_import_size: truncated'); } $parent_ptr = $msg_parent_guid; if ($parent_ptr === $conversation['guid']) { // this should always be the case $x = q("select mid from mail where conv_guid = '%s' and channel_id = %d order by id asc limit 1", dbesc($conversation['guid']), intval($importer['channel_id'])); if ($x) { $parent_ptr = $x[0]['mid']; } } $author_signed_data = $msg_guid . ';' . $msg_parent_guid . ';' . $msg_text . ';' . unxmlify($xml['created_at']) . ';' . $msg_diaspora_handle . ';' . $msg_conversation_guid; $author_signature = base64_decode($msg_author_signature); $person = find_diaspora_person_by_handle($msg_diaspora_handle); if (is_array($person) && x($person, 'xchan_pubkey')) { $key = $person['xchan_pubkey']; } else { logger('diaspora_message: unable to find author details'); return; } if (!rsa_verify($author_signed_data, $author_signature, $key, 'sha256')) { logger('diaspora_message: verification failed.'); return; } $r = q("select id from mail where mid = '%s' and channel_id = %d limit 1", dbesc($msg_guid), intval($importer['channel_id'])); if ($r) { logger('diaspora_message: duplicate message already delivered.', LOGGER_DEBUG); return; } $key = get_config('system', 'pubkey'); // $subject is a copy of the already obscured subject from the conversation structure if ($body) { $body = str_rot47(base64url_encode($body)); } q("insert into mail ( `account_id`, `channel_id`, `convid`, `conv_guid`, `from_xchan`,`to_xchan`,`title`,`body`,`mail_obscured`,`mid`,`parent_mid`,`created`, mail_isreply) values ( %d, %d, %d, '%s', '%s', '%s', '%s', '%s', %d, '%s', '%s', '%s', %d)", intval($importer['channel_account_id']), intval($importer['channel_id']), intval($conversation['id']), dbesc($conversation['guid']), dbesc($person['xchan_hash']), dbesc($importer['xchan_hash']), dbesc($subject), dbesc($body), intval(1), dbesc($msg_guid), dbesc($parent_ptr), dbesc($msg_created_at), intval(1)); q("update conv set updated = '%s' where id = %d", dbesc(datetime_convert()), intval($conversation['id'])); $z = q("select * from mail where mid = '%s' and channel_id = %d limit 1", dbesc($msg_guid), intval($importer['channel_id'])); \Zotlabs\Lib\Enotify::submit(array('from_xchan' => $person['xchan_hash'], 'to_xchan' => $importer['channel_hash'], 'type' => NOTIFY_MAIL, 'item' => $z[0], 'verb' => ACTIVITY_POST, 'otype' => 'mail')); return; }
function get_atom_elements($feed, $item) { require_once 'library/HTMLPurifier.auto.php'; require_once 'include/html2bbcode.php'; $best_photo = array(); $res = array(); $author = $item->get_author(); if ($author) { $res['author-name'] = unxmlify($author->get_name()); $res['author-link'] = unxmlify($author->get_link()); } else { $res['author-name'] = unxmlify($feed->get_title()); $res['author-link'] = unxmlify($feed->get_permalink()); } $res['uri'] = unxmlify($item->get_id()); $res['title'] = unxmlify($item->get_title()); $res['body'] = unxmlify($item->get_content()); $res['plink'] = unxmlify($item->get_link(0)); if ($res['plink']) { $base_url = implode('/', array_slice(explode('/', $res['plink']), 0, 3)); } else { $base_url = ''; } // look for a photo. We should check media size and find the best one, // but for now let's just find any author photo $rawauthor = $item->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'author'); if ($rawauthor && $rawauthor[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['link']) { $base = $rawauthor[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['link']; foreach ($base as $link) { if (!x($res, 'author-avatar') || !$res['author-avatar']) { if ($link['attribs']['']['rel'] === 'photo' || $link['attribs']['']['rel'] === 'avatar') { $res['author-avatar'] = unxmlify($link['attribs']['']['href']); } } } } $rawactor = $item->get_item_tags(NAMESPACE_ACTIVITY, 'actor'); if ($rawactor && activity_match($rawactor[0]['child'][NAMESPACE_ACTIVITY]['object-type'][0]['data'], ACTIVITY_OBJ_PERSON)) { $base = $rawactor[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['link']; if ($base && count($base)) { foreach ($base as $link) { if ($link['attribs']['']['rel'] === 'alternate' && !$res['author-link']) { $res['author-link'] = unxmlify($link['attribs']['']['href']); } if (!x($res, 'author-avatar') || !$res['author-avatar']) { if ($link['attribs']['']['rel'] === 'avatar' || $link['attribs']['']['rel'] === 'photo') { $res['author-avatar'] = unxmlify($link['attribs']['']['href']); } } } } } // No photo/profile-link on the item - look at the feed level if (!x($res, 'author-link') || !x($res, 'author-avatar')) { $rawauthor = $feed->get_feed_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'author'); if ($rawauthor && $rawauthor[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['link']) { $base = $rawauthor[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['link']; foreach ($base as $link) { if ($link['attribs']['']['rel'] === 'alternate' && !$res['author-link']) { $res['author-link'] = unxmlify($link['attribs']['']['href']); } if (!$res['author-avatar']) { if ($link['attribs']['']['rel'] === 'photo' || $link['attribs']['']['rel'] === 'avatar') { $res['author-avatar'] = unxmlify($link['attribs']['']['href']); } } } } $rawactor = $feed->get_feed_tags(NAMESPACE_ACTIVITY, 'subject'); if ($rawactor && activity_match($rawactor[0]['child'][NAMESPACE_ACTIVITY]['object-type'][0]['data'], ACTIVITY_OBJ_PERSON)) { $base = $rawactor[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['link']; if ($base && count($base)) { foreach ($base as $link) { if ($link['attribs']['']['rel'] === 'alternate' && !$res['author-link']) { $res['author-link'] = unxmlify($link['attribs']['']['href']); } if (!x($res, 'author-avatar')) { if ($link['attribs']['']['rel'] === 'avatar' || $link['attribs']['']['rel'] === 'photo') { $res['author-avatar'] = unxmlify($link['attribs']['']['href']); } } } } } } $apps = $item->get_item_tags(NAMESPACE_STATUSNET, 'notice_info'); if ($apps && $apps[0]['attribs']['']['source']) { $res['app'] = strip_tags(unxmlify($apps[0]['attribs']['']['source'])); if ($res['app'] === 'web') { $res['app'] = 'OStatus'; } } // base64 encoded json structure representing Diaspora signature $dsig = $item->get_item_tags(NAMESPACE_DFRN, 'diaspora_signature'); if ($dsig) { $res['dsprsig'] = unxmlify($dsig[0]['data']); } $dguid = $item->get_item_tags(NAMESPACE_DFRN, 'diaspora_guid'); if ($dguid) { $res['guid'] = unxmlify($dguid[0]['data']); } $bm = $item->get_item_tags(NAMESPACE_DFRN, 'bookmark'); if ($bm) { $res['bookmark'] = unxmlify($bm[0]['data']) === 'true' ? 1 : 0; } /** * If there's a copy of the body content which is guaranteed to have survived mangling in transit, use it. */ $have_real_body = false; $rawenv = $item->get_item_tags(NAMESPACE_DFRN, 'env'); if ($rawenv) { $have_real_body = true; $res['body'] = $rawenv[0]['data']; $res['body'] = str_replace(array(' ', "\t", "\r", "\n"), array('', '', '', ''), $res['body']); // make sure nobody is trying to sneak some html tags by us $res['body'] = notags(base64url_decode($res['body'])); } $maxlen = get_max_import_size(); if ($maxlen && strlen($res['body']) > $maxlen) { $res['body'] = substr($res['body'], 0, $maxlen); } // It isn't certain at this point whether our content is plaintext or html and we'd be foolish to trust // the content type. Our own network only emits text normally, though it might have been converted to // html if we used a pubsubhubbub transport. But if we see even one html tag in our text, we will // have to assume it is all html and needs to be purified. // It doesn't matter all that much security wise - because before this content is used anywhere, we are // going to escape any tags we find regardless, but this lets us import a limited subset of html from // the wild, by sanitising it and converting supported tags to bbcode before we rip out any remaining // html. if (strpos($res['body'], '<') !== false && strpos($res['body'], '>') !== false) { $res['body'] = reltoabs($res['body'], $base_url); $res['body'] = html2bb_video($res['body']); $res['body'] = oembed_html2bbcode($res['body']); $config = HTMLPurifier_Config::createDefault(); $config->set('Cache.DefinitionImpl', null); // we shouldn't need a whitelist, because the bbcode converter // will strip out any unsupported tags. $purifier = new HTMLPurifier($config); $res['body'] = $purifier->purify($res['body']); $res['body'] = @html2bbcode($res['body']); } elseif (!$have_real_body) { // it's not one of our messages and it has no tags // so it's probably just text. We'll escape it just to be safe. $res['body'] = escape_tags($res['body']); } // this tag is obsolete but we keep it for really old sites $allow = $item->get_item_tags(NAMESPACE_DFRN, 'comment-allow'); if ($allow && $allow[0]['data'] == 1) { $res['last-child'] = 1; } else { $res['last-child'] = 0; } $private = $item->get_item_tags(NAMESPACE_DFRN, 'private'); if ($private && $private[0]['data'] == 1) { $res['private'] = 1; } else { $res['private'] = 0; } $extid = $item->get_item_tags(NAMESPACE_DFRN, 'extid'); if ($extid && $extid[0]['data']) { $res['extid'] = $extid[0]['data']; } $rawlocation = $item->get_item_tags(NAMESPACE_DFRN, 'location'); if ($rawlocation) { $res['location'] = unxmlify($rawlocation[0]['data']); } $rawcreated = $item->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'published'); if ($rawcreated) { $res['created'] = unxmlify($rawcreated[0]['data']); } $rawedited = $item->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'updated'); if ($rawedited) { $res['edited'] = unxmlify($rawedited[0]['data']); } if (x($res, 'edited') && !x($res, 'created')) { $res['created'] = $res['edited']; } if (!$res['created']) { $res['created'] = $item->get_date('c'); } if (!$res['edited']) { $res['edited'] = $item->get_date('c'); } // Disallow time travelling posts $d1 = strtotime($res['created']); $d2 = strtotime($res['edited']); $d3 = strtotime('now'); if ($d1 > $d3) { $res['created'] = datetime_convert(); } if ($d2 > $d3) { $res['edited'] = datetime_convert(); } $rawowner = $item->get_item_tags(NAMESPACE_DFRN, 'owner'); if ($rawowner[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data']) { $res['owner-name'] = unxmlify($rawowner[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data']); } elseif ($rawowner[0]['child'][NAMESPACE_DFRN]['name'][0]['data']) { $res['owner-name'] = unxmlify($rawowner[0]['child'][NAMESPACE_DFRN]['name'][0]['data']); } if ($rawowner[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['uri'][0]['data']) { $res['owner-link'] = unxmlify($rawowner[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['uri'][0]['data']); } elseif ($rawowner[0]['child'][NAMESPACE_DFRN]['uri'][0]['data']) { $res['owner-link'] = unxmlify($rawowner[0]['child'][NAMESPACE_DFRN]['uri'][0]['data']); } if ($rawowner[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['link']) { $base = $rawowner[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['link']; foreach ($base as $link) { if (!x($res, 'owner-avatar') || !$res['owner-avatar']) { if ($link['attribs']['']['rel'] === 'photo' || $link['attribs']['']['rel'] === 'avatar') { $res['owner-avatar'] = unxmlify($link['attribs']['']['href']); } } } } $rawgeo = $item->get_item_tags(NAMESPACE_GEORSS, 'point'); if ($rawgeo) { $res['coord'] = unxmlify($rawgeo[0]['data']); } $rawverb = $item->get_item_tags(NAMESPACE_ACTIVITY, 'verb'); // select between supported verbs if ($rawverb) { $res['verb'] = unxmlify($rawverb[0]['data']); } // translate OStatus unfollow to activity streams if it happened to get selected if (x($res, 'verb') && $res['verb'] === 'http://ostatus.org/schema/1.0/unfollow') { $res['verb'] = ACTIVITY_UNFOLLOW; } $cats = $item->get_categories(); if ($cats) { $tag_arr = array(); foreach ($cats as $cat) { $term = $cat->get_term(); if (!$term) { $term = $cat->get_label(); } $scheme = $cat->get_scheme(); if ($scheme && $term && stristr($scheme, 'X-DFRN:')) { $tag_arr[] = substr($scheme, 7, 1) . '[url=' . unxmlify(substr($scheme, 9)) . ']' . unxmlify($term) . '[/url]'; } elseif ($term) { $tag_arr[] = notags(trim($term)); } } $res['tag'] = implode(',', $tag_arr); } $attach = $item->get_enclosures(); if ($attach) { $att_arr = array(); foreach ($attach as $att) { $len = intval($att->get_length()); $link = str_replace(array(',', '"'), array('%2D', '%22'), notags(trim(unxmlify($att->get_link())))); $title = str_replace(array(',', '"'), array('%2D', '%22'), notags(trim(unxmlify($att->get_title())))); $type = str_replace(array(',', '"'), array('%2D', '%22'), notags(trim(unxmlify($att->get_type())))); if (strpos($type, ';')) { $type = substr($type, 0, strpos($type, ';')); } if (!$link || strpos($link, 'http') !== 0) { continue; } if (!$title) { $title = ' '; } if (!$type) { $type = 'application/octet-stream'; } $att_arr[] = '[attach]href="' . $link . '" length="' . $len . '" type="' . $type . '" title="' . $title . '"[/attach]'; } $res['attach'] = implode(',', $att_arr); } $rawobj = $item->get_item_tags(NAMESPACE_ACTIVITY, 'object'); if ($rawobj) { $res['object'] = '<object>' . "\n"; $child = $rawobj[0]['child']; if ($child[NAMESPACE_ACTIVITY]['object-type'][0]['data']) { $res['object-type'] = $child[NAMESPACE_ACTIVITY]['object-type'][0]['data']; $res['object'] .= '<type>' . $child[NAMESPACE_ACTIVITY]['object-type'][0]['data'] . '</type>' . "\n"; } if (x($child[SIMPLEPIE_NAMESPACE_ATOM_10], 'id') && $child[SIMPLEPIE_NAMESPACE_ATOM_10]['id'][0]['data']) { $res['object'] .= '<id>' . $child[SIMPLEPIE_NAMESPACE_ATOM_10]['id'][0]['data'] . '</id>' . "\n"; } if (x($child[SIMPLEPIE_NAMESPACE_ATOM_10], 'link') && $child[SIMPLEPIE_NAMESPACE_ATOM_10]['link']) { $res['object'] .= '<link>' . encode_rel_links($child[SIMPLEPIE_NAMESPACE_ATOM_10]['link']) . '</link>' . "\n"; } if (x($child[SIMPLEPIE_NAMESPACE_ATOM_10], 'title') && $child[SIMPLEPIE_NAMESPACE_ATOM_10]['title'][0]['data']) { $res['object'] .= '<title>' . $child[SIMPLEPIE_NAMESPACE_ATOM_10]['title'][0]['data'] . '</title>' . "\n"; } if (x($child[SIMPLEPIE_NAMESPACE_ATOM_10], 'content') && $child[SIMPLEPIE_NAMESPACE_ATOM_10]['content'][0]['data']) { $body = $child[SIMPLEPIE_NAMESPACE_ATOM_10]['content'][0]['data']; if (!$body) { $body = $child[SIMPLEPIE_NAMESPACE_ATOM_10]['summary'][0]['data']; } // preserve a copy of the original body content in case we later need to parse out any microformat information, e.g. events $res['object'] .= '<orig>' . xmlify($body) . '</orig>' . "\n"; if (strpos($body, '<') !== false || strpos($body, '>') !== false) { $body = html2bb_video($body); $config = HTMLPurifier_Config::createDefault(); $config->set('Cache.DefinitionImpl', null); $purifier = new HTMLPurifier($config); $body = $purifier->purify($body); $body = html2bbcode($body); } $res['object'] .= '<content>' . $body . '</content>' . "\n"; } $res['object'] .= '</object>' . "\n"; } $rawobj = $item->get_item_tags(NAMESPACE_ACTIVITY, 'target'); if ($rawobj) { $res['target'] = '<target>' . "\n"; $child = $rawobj[0]['child']; if ($child[NAMESPACE_ACTIVITY]['object-type'][0]['data']) { $res['target'] .= '<type>' . $child[NAMESPACE_ACTIVITY]['object-type'][0]['data'] . '</type>' . "\n"; } if (x($child[SIMPLEPIE_NAMESPACE_ATOM_10], 'id') && $child[SIMPLEPIE_NAMESPACE_ATOM_10]['id'][0]['data']) { $res['target'] .= '<id>' . $child[SIMPLEPIE_NAMESPACE_ATOM_10]['id'][0]['data'] . '</id>' . "\n"; } if (x($child[SIMPLEPIE_NAMESPACE_ATOM_10], 'link') && $child[SIMPLEPIE_NAMESPACE_ATOM_10]['link']) { $res['target'] .= '<link>' . encode_rel_links($child[SIMPLEPIE_NAMESPACE_ATOM_10]['link']) . '</link>' . "\n"; } if (x($child[SIMPLEPIE_NAMESPACE_ATOM_10], 'data') && $child[SIMPLEPIE_NAMESPACE_ATOM_10]['title'][0]['data']) { $res['target'] .= '<title>' . $child[SIMPLEPIE_NAMESPACE_ATOM_10]['title'][0]['data'] . '</title>' . "\n"; } if (x($child[SIMPLEPIE_NAMESPACE_ATOM_10], 'data') && $child[SIMPLEPIE_NAMESPACE_ATOM_10]['content'][0]['data']) { $body = $child[SIMPLEPIE_NAMESPACE_ATOM_10]['content'][0]['data']; if (!$body) { $body = $child[SIMPLEPIE_NAMESPACE_ATOM_10]['summary'][0]['data']; } // preserve a copy of the original body content in case we later need to parse out any microformat information, e.g. events $res['target'] .= '<orig>' . xmlify($body) . '</orig>' . "\n"; if (strpos($body, '<') !== false || strpos($body, '>') !== false) { $body = html2bb_video($body); $config = HTMLPurifier_Config::createDefault(); $config->set('Cache.DefinitionImpl', null); $purifier = new HTMLPurifier($config); $body = $purifier->purify($body); $body = html2bbcode($body); } $res['target'] .= '<content>' . $body . '</content>' . "\n"; } $res['target'] .= '</target>' . "\n"; } $arr = array('feed' => $feed, 'item' => $item, 'result' => $res); call_hooks('parse_atom', $arr); return $res; }