xmlify(Zotlabs\Lib\System::get_project_version()), '$generator' => xmlify(Zotlabs\Lib\System::get_platform_name()), '$generator_uri' => 'https://codeberg.org/zot/' . PLATFORM_NAME, '$feed_id' => xmlify($channel['xchan_url']), '$feed_title' => xmlify($channel['channel_name']), '$feed_updated' => xmlify(datetime_convert('UTC', 'UTC', 'now', ATOM_TIME)), '$author' => $feed_author, '$owner' => $owner, '$profile_page' => xmlify($channel['xchan_url']), )); $x = [ 'xml' => $atom, 'channel' => $channel, 'observer_hash' => $observer_hash, 'params' => $params ]; /** * @hooks atom_feed_top * * \e string \b xml - the generated feed and what will get returned from the hook * * \e array \b channel * * \e string \b observer_hash * * \e array \b params */ call_hooks('atom_feed_top', $x); $atom = $x['xml']; /** * @hooks atom_feed * A much simpler interface than atom_feed_top. * * \e string - the feed after atom_feed_top hook */ call_hooks('atom_feed', $atom); $items = items_fetch( [ 'wall' => '1', 'datequery' => $params['end'], 'datequery2' => $params['begin'], 'start' => intval($params['start']), 'records' => intval($params['records']), 'direction' => dbesc($params['direction']), 'pages' => $params['pages'], 'order' => dbesc('post'), 'top' => $params['top'], 'cat' => $params['cat'], 'compat' => $params['compat'] ], $channel, $observer_hash, CLIENT_MODE_NORMAL, App::$module ); if($items) { $type = 'html'; foreach($items as $item) { if($item['item_private']) continue; $atom .= atom_entry($item, $type, null, $owner, true, '', $params['compat']); } } /** * @hooks atom_feed_end * \e string - The created XML feed as a string without closing tag */ call_hooks('atom_feed_end', $atom); $atom .= '' . "\r\n"; return $atom; } /** * @brief Return a XML tag with author information. * * @param string $tag The XML tag to create * @param string $nick preferred username * @param string $name displayed name of the author * @param string $uri * @param int $h image height * @param int $w image width * @param string $type profile photo mime type * @param string $photo Fully qualified URL to a profile/avator photo * @return string XML tag */ function atom_author($tag, $nick, $name, $uri, $h, $w, $type, $photo) { $o = ''; if(! $tag) return $o; $nick = xmlify($nick); $name = xmlify($name); $uri = xmlify($uri); $h = intval($h); $w = intval($w); $photo = xmlify($photo); $o .= "<$tag>\r\n"; $o .= " $name\r\n"; $o .= " $uri\r\n"; $o .= ' ' . "\r\n"; $o .= ' ' . "\r\n"; /** * @hooks atom_author * Possibility to add further tags to returned XML string * * \e string - The created XML tag as a string without closing tag */ call_hooks('atom_author', $o); $o .= "\r\n"; return $o; } /** * @brief Return an atom tag with author information from an xchan. * * @param string $tag * @param array $xchan * @return string */ function atom_render_author($tag, $xchan) { $nick = xmlify(substr($xchan['xchan_addr'], 0, strpos($xchan['xchan_addr'], '@'))); $id = xmlify($xchan['xchan_url']); $name = xmlify($xchan['xchan_name']); $photo = xmlify($xchan['xchan_photo_l']); $type = xmlify($xchan['xchan_photo_mimetype']); $w = $h = 300; $o = "<$tag>\r\n"; $o .= " $name\r\n"; $o .= " $id\r\n"; $o .= ' ' . "\r\n"; $o .= ' ' . "\r\n"; /** * @hooks atom_render_author * Possibility to add further tags to returned XML string. * * \e string The created XML tag as a string without closing tag */ call_hooks('atom_render_author', $o); $o .= "\r\n"; return $o; } function compat_photos_list($s) { $ret = []; $found = preg_match_all('/\[[zi]mg(.*?)\](.*?)\[/ism',$s,$matches,PREG_SET_ORDER); if($found) { foreach($matches as $match) { $entry = [ 'href' => $match[2], 'type' => guess_image_type($match[2]) ]; $sizer = new Img_filesize($match[2]); $size = $sizer->getSize(); if(intval($size)) { $entry['length'] = intval($size); } $ret[] = $entry; } } return $ret; } /** * @brief Create an item for the Atom feed. * * @see get_feed_for() * * @param array $item * @param string $type * @param array $author * @param array $owner * @param string $comment default false * @param number $cid default 0 * @param boolean $compat default false * @return void|string */ function atom_entry($item, $type, $author, $owner, $comment = false, $cid = 0, $compat = false) { if(! $item['parent']) return; if($item['deleted']) return '' . "\r\n"; create_export_photo_body($item); // provide separate summary and content unless compat is true; as summary represents a content-warning on some networks $summary = $item['summary']; $body = $item['body']; $compat_photos = null; $o = "\r\n\r\n\r\n"; if(is_array($author)) { $o .= atom_render_author('author',$author); } else { $o .= atom_render_author('author',$item['author']); } if(($item['parent'] != $item['id']) || ($item['parent_mid'] !== $item['mid']) || (($item['thr_parent'] !== '') && ($item['thr_parent'] !== $item['mid']))) { $parent_item = (($item['thr_parent']) ? $item['thr_parent'] : $item['parent_mid']); $o .= '' . "\r\n"; } else { $o .= '' . xmlify($item['title']) . '' . "\r\n"; if($summary) $o .= '' . xmlify(prepare_text($summary,$item['mimetype'])) . '' . "\r\n"; $o .= '' . xmlify(prepare_text($body,$item['mimetype'])) . '' . "\r\n"; } $o .= '' . xmlify($item['mid']) . '' . "\r\n"; $o .= '' . xmlify(datetime_convert('UTC','UTC',$item['created'] . '+00:00',ATOM_TIME)) . '' . "\r\n"; $o .= '' . xmlify(datetime_convert('UTC','UTC',$item['edited'] . '+00:00',ATOM_TIME)) . '' . "\r\n"; $o .= '' . "\r\n"; if($item['attach']) { $enclosures = json_decode($item['attach'], true); if($enclosures) { foreach($enclosures as $enc) { $o .= '' . "\r\n"; } } } if($item['term']) { foreach($item['term'] as $term) { $scheme = ''; $label = ''; switch($term['ttype']) { case TERM_HASHTAG: $scheme = NAMESPACE_ZOT . '/term/hashtag'; $label = '#' . str_replace('"','',$term['term']); break; case TERM_CATEGORY: $scheme = NAMESPACE_ZOT . '/term/category'; $label = str_replace('"','',$term['term']); break; default: break; } if(! $scheme) continue; $o .= '' . "\r\n"; } } $o .= '' . "\r\n"; // build array to pass to hook $x = [ 'item' => $item, 'type' => $type, 'author' => $author, 'owner' => $owner, 'comment' => $comment, 'abook_id' => $cid, 'entry' => $o ]; /** * @hooks atom_entry * * \e array \b item * * \e string \b type * * \e array \b author * * \e array \b owner * * \e string \b comment * * \e number \b abook_id * * \e string \b entry - The generated entry and what will get returned */ call_hooks('atom_entry', $x); return $x['entry']; } function get_mentions($item,$tags) { $o = ''; if(! count($tags)) return $o; foreach($tags as $x) { if($x['ttype'] == TERM_MENTION) { $o .= "\t\t" . '' . "\r\n"; } } return $o; }