<?php
$debug = ($_GET['d'] ?? "0") == 1;
if ($debug) {
ini_set('display_errors', 1);
ini_set('display_startup_errors', 1);
error_reporting(E_ALL);
}
function d() {
echo "<pre>";
call_user_func_array('var_dump', func_get_args());
}
function dd() {
call_user_func_array('d', func_get_args());
die();
}
class HttpException extends Exception {}
function http_get($url, $accept='application/activity+json') {
$options = [
CURLOPT_RETURNTRANSFER => true, // return web page
CURLOPT_HEADER => false, // don't return headers
CURLOPT_FOLLOWLOCATION => true, // follow redirects
CURLOPT_MAXREDIRS => 10, // stop after 10 redirects
CURLOPT_ENCODING => "", // handle compressed
CURLOPT_USERAGENT => "apthread", // name of client
CURLOPT_AUTOREFERER => true, // set referrer on redirect
CURLOPT_CONNECTTIMEOUT => 120, // time-out on connect
CURLOPT_TIMEOUT => 120, // time-out on response
];
$headers = [
"Accept: $accept",
];
$ch = curl_init($url);
curl_setopt_array($ch, $options);
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
$server_output = curl_exec ($ch);
$res = curl_getinfo($ch);
curl_close ($ch);
if ($res['http_code'] >= 400) {
throw new HttpException("HTTP Error " . $res['http_code']);
}
return $server_output;
}
function as_obj($data) {
if (is_array($data)) {
return $data;
}
elseif (is_string($data)) {
try {
return json_decode(http_get($data), true);
} catch (HttpException $e) {
error($e->getMessage());
}
}
return null;
}
function as_url($obj) {
if (is_array($obj)) return $obj['id'];
return $obj;
}
function get_first_reply($obj) {
$replies = as_obj($obj['replies'] ?? null);
if (is_null($replies)) return null;
$page = as_obj($replies['first']);
$items = $page['items'] ?? [];
if (count($items) > 0) {
return as_obj($items[0]);
}
return null;
}
function title($obj, $max=8) {
// $t = preg_replace("|<[^>]*>|", "", $obj['content']);
$t = $obj['summary'] ?? "";
if ($t != "")
return $t;
$t = $obj['content'];
$t = preg_replace("%(</p>|br\w*/?>)%", "\$1\n", $t);
$t = explode("\n", trim($t))[0];
$t = strip_tags($t);
$t = html_entity_decode($t);
$t = preg_split("|[.!?(\[{]|", $t)[0];
$ta = preg_split("|\s+|", $t);
$tb = array_slice($ta, 0, $max);
$t = implode(" ", $tb);
if (count($ta) > $max) $t = $t . "...";
//$t = htmlentities($t);
return $t;
}
$ogcache = [];
function get_opengraph($url) {
// twitter to nitter
$url = str_replace("https://twitter.com/", "https://nitter.net/", $url);
if (isset($ogcache[$url])) {
return $ogcache[$url];
}
try {
$page = http_get($url, 'text/*');
} catch (HttpException $e) {
return null;
}
return parse_opengraph($page, $url);
}
function parse_opengraph($page, $url) {
if (! strpos(trim($page), '<?xml') !== 0) {
// force utf8. looks like load html doesn't read encoding from html tags
$page = '<' .'?xml encoding="utf-8" ?' .'>'.$page;
}
$dom = new DomDocument();
$dom->loadHTML($page, LIBXML_NONET|LIBXML_NOERROR|LIBXML_NOWARNING);
$xpath = new DOMXpath($dom);
// defaults from page
$parsed = parse_url($url, PHP_URL_HOST);
$data = [
'og:type' => 'article',
'og:url' => $url,
'og:title' => $url,
'og:site_name' => parse_url($url, PHP_URL_HOST),
];
$items = $xpath->query('//title');
if ($items->length > 0) {
$data['og:title'] = $items->item(0)->nodeValue;
}
// look for opengraph meta tags
$items = $xpath->query('//meta[starts-with(@property, "og:")]');
if ($items->length > 0) {
for ($i = 0; $i < $items->length; $i++) {
$key = $items->item($i)->attributes->getNamedItem('property')->value;
$value = $items->item($i)->attributes->getNamedItem('content')->value;
$data[$key] = $value;
}
}
$ogcache[$url] = $data;
return $data;
}
function first_url_in_text($obj) {
$t = preg_replace('|<br[ /]*>|', "\n", $obj['content']);
$t = preg_replace("|</p>([^\n])|", "</p>\n\$1", $obj['content']);
$t = strip_tags($t);
$toks = preg_split('|(https?://)|', $t, 2, PREG_SPLIT_DELIM_CAPTURE);
if (isset($toks[2])){
[$_, $prot, $res] = $toks;
$toks = preg_split('|[^A-Za-z0-9._~:\/?#[\]@!$\'()*+,;=-]|', $res, 2);
$url = $toks[0];
return $prot . $url;
}
return null;
}
function error($error) {
global $body, $footer, $title;
$title .= " - Error";
$body .= "<p>$error</p>";
include "page.tpl.php";
die();
}