-
-
Save barnabywalters/1640f384112ddebba2bf to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php namespace Taproot; use DateTime; ?> | |
<?= '<?xml version="1.0" encoding="utf-8"?>'; ?> | |
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en-GB"> | |
<title><?= $title ?></title> | |
<link href="<?= $url ?>" rel="alternate" title="<?= $title ?>" type="text/html"/> | |
<link href="<?= $feedUrl ?>" rel="self"/> | |
<id><?= $feedUrl ?></id> | |
<author> | |
<name><?= $author['name'] ?></name> | |
<uri><?= $author['url'] ?></uri> | |
</author> | |
<?php foreach ($items as $item): ?> | |
<entry xmlns:activity="http://activitystrea.ms/spec/1.0/"> | |
<id><?= $item['url'] ?></id> | |
<title><?= htmlspecialchars(strip_tags($item['name'])) ?></title> | |
<published><?= Text\toDateTime($item['published'])->format(DateTime::ATOM); ?></published> | |
<updated><?= isset($item['updated']) | |
? Text\toDateTime($item['updated'])->format(DateTime::ATOM) | |
: Text\toDateTime($item['published'])->format(DateTime::ATOM) ?></updated> | |
<link rel="alternate" type="text/html" href="<?= $item['url'] ?>" /> | |
<content type="xhtml"><div xmlns="http://www.w3.org/1999/xhtml"><?= $item['content'] ?></div></content> | |
<activity:object-type>http://activitystrea.ms/schema/1.0/article</activity:object-type> | |
</entry> | |
<?php endforeach ?> | |
</feed> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
namespace Taproot; | |
use Guzzle; | |
use DateTime; | |
use BarnabyWalters\Mf2 as M; | |
use Mf2; | |
use HTMLPurifier, HTMLPurifier_Config; | |
function getPurifier() { | |
$purifierConfig = HTMLPurifier_Config::createDefault(); | |
return new HTMLPurifier($purifierConfig); | |
} | |
function flattenFirstHEntry($mf, $url=null, $published=null) { | |
$hEntries = flattenHEntries($mf, $url, $published); | |
if (count($hEntries) == 0) | |
return null; | |
return $hEntries[0]; | |
} | |
function flattenHEntries($mf, $url=null, $published=null) { | |
$hEntries = M\findMicroformatsByType($mf, 'h-entry'); | |
$hEntries = array_map(function ($hEntry) use ($mf, $url, $published) { | |
return flattenHEntryWithContext($hEntry, $url, $published, $mf); | |
}, $hEntries); | |
return $hEntries; | |
} | |
function purifyValue($value, $purifier) { | |
if (is_array($value)) { | |
foreach ($value as $key => $val) { | |
$value[$key] = purifyValue($val, $purifier); | |
} | |
return $value; | |
} | |
return $purifier->purify($value); | |
} | |
function flattenHEntryWithContext($hEntry, $url, $published, $mf) { | |
$purifier = getPurifier(); | |
if ($published === null) | |
$published = new DateTime; | |
$entry = ['type' => 'h-entry']; | |
$entry['name'] = M\getHtml($hEntry, 'name'); | |
$entry['content'] = M\getHtml($hEntry, 'content', M\getHtml($hEntry, 'summary', M\getHtml($hEntry, 'name', ''))); | |
$entry['summary'] = M\getPlaintext($hEntry, 'summary', M\getPlaintext($hEntry, 'summary', M\getPlaintext($hEntry, 'name', ''))); | |
$entry['published'] = M\getPublished($hEntry, true, $published->format(DateTime::W3C)); | |
$entry['url'] = M\getHtml($hEntry, 'url', $url); | |
if (M\hasProp($hEntry, 'like') or M\hasProp($hEntry, 'like-of')) | |
$entry['like-of'] = M\getHtml($hEntry, 'like-of', M\getHtml($hEntry, 'like', null)); | |
foreach (['in-reply-to' => null, 'rsvp' => null, 'repost-of' => null] as $propName => $fallback) { | |
if (M\hasProp($hEntry, $propName)) | |
$entry[$propName] = M\getHtml($hEntry, $propName, $fallback); | |
} | |
foreach ($entry as $key => $value) | |
$entry[$key] = $purifier->purify($value); | |
$entry['syndication'] = M\hasProp($hEntry, 'syndication') ? M\getPlaintextArray($hEntry, 'syndication') : []; | |
if (!empty($mf['rels']['syndication'])) | |
$entry['syndication'] = array_merge($entry['syndication'], $mf['rels']['syndication']); | |
$entry['syndication'] = array_map([$purifier, 'purify'], array_unique($entry['syndication'])); | |
// TODO: actual authorship implementation here, or at least somewhere | |
$author = ['type' => 'h-card']; | |
$mfAuthor = M\getAuthor($hEntry, $mf, $url); | |
if (is_string($mfAuthor)) { | |
$author['name'] = $mfAuthor; | |
$author['url'] = Url\origin($url); | |
} elseif (M\isMicroformat($mfAuthor)) { | |
foreach ($mfAuthor['properties'] as $name => $val) { | |
if (!empty($val)) | |
$author[$name] = $val[0]; | |
} | |
} | |
foreach ($author as $key => $value) { | |
$author[$key] = purifyValue($value, $purifier); | |
} | |
$entry['author'] = $author; | |
return $entry; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
// $services is a Silex application or RouteCollection | |
// See http://silex.sensiolabs.org/ | |
$services->get('/microformats-to-atom/', function (Http\Request $request) use ($app) { | |
if (!$request->query->has('url')) { | |
return $app['render']('services/microformats-to-atom.html', [ | |
'pageClass' => 'form', | |
'title' => 'Convert microformats2 to ATOM', | |
'url' => '' | |
]); | |
} | |
$url = $request->query->get('url'); | |
$client = $app['http.client']; | |
try { | |
$html = $client->get($url)->send()->getBody(true); | |
} catch (Guzzle\Common\Exception\GuzzleException $e) { | |
return $app['render']('services/microformats-to-atom.html', [ | |
'pageClass' => 'form', | |
'title' => 'Convert microformats2 to ATOM', | |
'error' => 'That URL couldn’t be fetched!', | |
'url' => $url | |
]); | |
} | |
$parser = new Mf2\Parser($html, $url); | |
$mf = $parser->parse(); | |
$hEntries = Taproot\flattenHEntries($mf, $url); | |
$hFeeds = M\findMicroformatsByType($mf, 'h-feed'); | |
$hFeed = count($hFeeds) > 0 ? $hFeeds[0] : []; | |
foreach ($hEntries as &$hEntry) { | |
ob_start(); | |
$hEntry['name'] = ellipsize_to_word($hEntry['name'], 64, '…', 55); | |
ob_end_clean(); | |
} | |
$author = @($hEntries[0]['author'] ?: ['name' => '', 'url' => '']); | |
$title = strlen(M\getPlaintext($hFeed, 'name')) < 100 ? M\getPlaintext($hFeed, 'name') : $parser->query('//title')->item(0)->nodeValue; | |
return $app['render']('services/feed.atom', [ | |
'items' => $hEntries, | |
'author' => $author, | |
'title' => $title, | |
'url' => $url, | |
'feedUrl' => $app['url_generator']->generate('services.microformats-to-atom', ['url' => $url], true) | |
]); | |
})->bind('services.microformats-to-atom'); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment