├── .gitignore
├── Like.php
├── LikeContentType.php
├── Main.php
├── Pages
├── Delete.php
├── Fetch.php
├── Like
│ └── Edit.php
└── Repost
│ └── Edit.php
├── README.md
├── Repost.php
├── RepostContentType.php
├── autoloader.php
├── composer.json
├── composer.lock
├── external
├── barnabywalters
│ └── mf-cleaner
│ │ ├── .gitignore
│ │ ├── README.md
│ │ ├── composer.json
│ │ ├── composer.lock
│ │ ├── nbproject
│ │ ├── project.properties
│ │ └── project.xml
│ │ ├── phpunit.xml
│ │ ├── src
│ │ └── BarnabyWalters
│ │ │ └── Mf2
│ │ │ └── Functions.php
│ │ └── test
│ │ ├── CleanerTest.php
│ │ └── bootstrap.php
└── mf2
│ └── shim
│ ├── .gitignore
│ ├── LICENSE.txt
│ ├── Mf2
│ ├── Shim
│ │ ├── Facebook.php
│ │ ├── Instagram.php
│ │ └── Twitter.php
│ └── functions.php
│ ├── README.md
│ ├── composer.json
│ ├── composer.lock
│ ├── phpunit.xml
│ └── tests
│ └── Mf2
│ ├── FacebookTest.php
│ ├── InstagramTest.php
│ ├── TwitterTest.php
│ ├── bootstrap.php
│ ├── example-facebook.html
│ ├── example-instagram.html
│ ├── example-twitter-2.html
│ ├── example-twitter.html
│ └── kartikprabhu-twitter.html
├── plugin.ini
└── templates
└── default
└── entity
├── IdnoPlugins
└── Reactions
│ ├── Like
│ ├── edit.tpl.php
│ └── icon.tpl.php
│ └── Repost
│ ├── edit.tpl.php
│ └── icon.tpl.php
├── Like.tpl.php
└── Repost.tpl.php
/.gitignore:
--------------------------------------------------------------------------------
1 | vendor
2 |
--------------------------------------------------------------------------------
/Like.php:
--------------------------------------------------------------------------------
1 | description)) {
14 | $result .= $this->description;
15 | }
16 | return $result;
17 | }
18 |
19 | function getActivityStreamsObjectType()
20 | {
21 | return 'like';
22 | }
23 |
24 | function saveDataFromInput()
25 | {
26 | $page = Idno::site()->currentPage();
27 | if (empty($this->_id)) {
28 | $new = true;
29 | } else {
30 | $new = false;
31 | }
32 |
33 | $this->likeof = $page->getInput('like-of');
34 | if ($this->likeof) {
35 | foreach ((array) $this->likeof as $likeofurl) {
36 | $this->syndicatedto = Webmention::addSyndicatedReplyTargets($likeofurl, $this->syndicatedto);
37 | }
38 | }
39 | $this->description = $page->getInput('description');
40 | if (empty($this->description)) {
41 | $result = \IdnoPlugins\Reactions\Pages\Fetch::fetch($this->likeof);
42 | if (!empty($result['description'])) {
43 | $this->description = $result['description'];
44 | }
45 | }
46 | $this->setAccess($page->getInput('access'));
47 | Idno::site()->logging()->log("saving like. new: $new");
48 | if ($this->publish($new)) {
49 | Idno::site()->logging()->log("sending webmentions from {$this->getURL()} to {$this->likeof}");
50 | Webmention::sendWebmentionPayload($this->getURL(), $this->likeof);
51 | }
52 | return true;
53 | }
54 |
55 | public function save($overrideAccess = false)
56 | {
57 | // generate our own meaningful, unique(ish) slug
58 | if (!$this->getSlug() && !$this->_id
59 | && $this->getTitle() && $this->likeof) {
60 | $this->setSlugResilient($this->getTitle() . '-' . substr(md5($this->likeof), 0, 10));
61 | }
62 |
63 | return parent::save($overrideAccess);
64 | }
65 |
66 | public function getEditURL()
67 | {
68 | return \Idno\Core\Idno::site()->config()->getDisplayURL() . 'indielike/edit/' . $this->getID();
69 | }
70 |
71 | }
72 |
73 | }
74 |
--------------------------------------------------------------------------------
/LikeContentType.php:
--------------------------------------------------------------------------------
1 | config()->url . 'indielike/edit';
15 | }
16 |
17 | }
18 |
19 | }
--------------------------------------------------------------------------------
/Main.php:
--------------------------------------------------------------------------------
1 | events()->addListener('plugins/loaded', function (Event $evt) {
16 | // make sure our content types are before IdnoPlugins\Like\ContentType
17 | $bookmarkType = '\IdnoPlugins\Like\ContentType';
18 | if (class_exists($bookmarkType)) {
19 |
20 | $bookmarkIndex = -1;
21 | for ($ii = 0 ; $ii < count(ContentType::$registered) ; $ii++) {
22 | $contentType = ContentType::$registered[$ii];
23 | if ($contentType instanceof $bookmarkType) {
24 | $bookmarkIndex = $ii;
25 | break;
26 | }
27 | }
28 |
29 | if ($bookmarkIndex > -1) {
30 | foreach (['LikeContentType', 'RepostContentType'] as $targetType) {
31 | $targetType = $this->getNamespace() . '\\' . $targetType;
32 | for ($ii = 0 ; $ii < count(ContentType::$registered) ; $ii++) {
33 | $contentType = ContentType::$registered[$ii];
34 | if ($contentType instanceof $targetType) {
35 | array_splice(ContentType::$registered, $ii, 1);
36 | array_splice(ContentType::$registered, $bookmarkIndex, 0, [$contentType]);
37 | $bookmarkIndex++;
38 | break;
39 | }
40 | }
41 | }
42 | }
43 | }
44 | });
45 |
46 | \Idno\Core\Idno::site()->events()->addListener('share/types', function (Event $evt) {
47 | $types = $evt->data()['types'];
48 | $newTypes = ['like'=>'Like', 'repost'=>'Repost'];
49 | $evt->setResponse(array_merge($types, $newTypes));
50 | });
51 | }
52 |
53 | function registerPages()
54 | {
55 | parent::registerPages();
56 | \Idno\Core\Idno::site()->routes()->addRoute('/indielike/edit/?', '\IdnoPlugins\Reactions\Pages\Like\Edit');
57 | \Idno\Core\Idno::site()->routes()->addRoute('/indielike/edit/(\w+)/?', '\IdnoPlugins\Reactions\Pages\Like\Edit');
58 | \Idno\Core\Idno::site()->routes()->addRoute('/like/delete/(\w+)/?', '\IdnoPlugins\Reactions\Pages\Delete');
59 | \Idno\Core\Idno::site()->routes()->addRoute('/repost/edit/?', '\IdnoPlugins\Reactions\Pages\Repost\Edit');
60 | \Idno\Core\Idno::site()->routes()->addRoute('/repost/edit/(\w+)/?', '\IdnoPlugins\Reactions\Pages\Repost\Edit');
61 | \Idno\Core\Idno::site()->routes()->addRoute('/repost/delete/(\w+)/?', '\IdnoPlugins\Reactions\Pages\Delete');
62 | \Idno\Core\Idno::site()->routes()->addRoute('/reactions/fetch/?', '\IdnoPlugins\Reactions\Pages\Fetch');
63 |
64 | }
65 |
66 | function registerContentTypes()
67 | {
68 | parent::registerContentTypes();
69 | \Idno\Common\ContentType::register($this->getNamespace() . '\\LikeContentType');
70 | \Idno\Common\ContentType::register($this->getNamespace() . '\\RepostContentType');
71 | }
72 |
73 |
74 | }
75 | }
76 |
--------------------------------------------------------------------------------
/Pages/Delete.php:
--------------------------------------------------------------------------------
1 | createGatekeeper();
12 |
13 | if (!empty($this->arguments)) {
14 | $object = Entity::getByID($this->arguments[0]);
15 | }
16 |
17 | if ($object) {
18 | if (!$object->canEdit()) {
19 | $this->setResponse(403);
20 | Idno::site()->session()->addErrorMessage("You don't have permission to delete this object.");
21 | } else {
22 | if ($object->delete()) {
23 | Idno::site()->session()->addMessage($object->getTitle() . ' was deleted.');
24 | } else {
25 | Idno::site()->session()->addErrorMessage("We couldn't delete " . $object->getTitle() . ".");
26 | }
27 | }
28 | }
29 |
30 | $this->forward($_SERVER['HTTP_REFERER']);
31 | }
32 |
33 | }
34 |
35 | }
--------------------------------------------------------------------------------
/Pages/Fetch.php:
--------------------------------------------------------------------------------
1 | template();
13 | $t->setTemplateType('json');
14 |
15 | $url = $this->getInput('url');
16 | $t->__(self::fetch($url))->drawPage();
17 | }
18 |
19 | public static function fetch($url)
20 | {
21 | $result = [];
22 | $response = Webservice::get($url);
23 |
24 | $status = $response['response'];
25 | $html = $response['content'];
26 |
27 | if ($status < 200 || $status >= 300) {
28 | $result['status'] = $status;
29 | $result['error'] = $response['error'];
30 | return $result;
31 | }
32 |
33 | $host = parse_url($url)['host'];
34 | if (preg_match('/(www\.|m\.)?twitter.com/', $host)) {
35 | $parsed = self::parseTwitter($html, $url);
36 | } else {
37 | $parsed = (new \Mf2\Parser($html, $url))->parse();
38 | }
39 |
40 | $hentries = \BarnabyWalters\Mf2\findMicroformatsByType($parsed, 'h-entry');
41 | if (!empty($hentries)) {
42 | $hentry = $hentries[0];
43 | $author = \BarnabyWalters\Mf2\getAuthor($hentry, $parsed);
44 | if (!empty($author)) {
45 | if (is_string($author)) {
46 | $result['author'] = ['url' => $author];
47 | } else {
48 | $result['author'] = [
49 | 'name' => \BarnabyWalters\Mf2\getPlaintext($author, 'name'),
50 | 'url' => \BarnabyWalters\Mf2\getPlaintext($author, 'url'),
51 | ];
52 | }
53 | }
54 | $name = \BarnabyWalters\Mf2\getPlaintext($hentry, 'name');
55 | $content_plain = \BarnabyWalters\Mf2\getPlaintext($hentry, 'content');
56 | $content_html = \BarnabyWalters\Mf2\getHtml($hentry, 'content');
57 |
58 | $result['content'] = $content_html;
59 | if (!strstr($name, $content_plain) && !strstr($content_plain, $name)) {
60 | $result['name'] = $name;
61 | }
62 | }
63 | // let's try OGP and Twitter cards
64 | else {
65 | $doc = new \DOMDocument();
66 | $doc->loadHTML($html);
67 | $metas = $doc->getElementsByTagName('meta');
68 | $metaprops = [];
69 |
70 | foreach ($metas as $meta) {
71 | if ($meta->hasAttribute('name')) {
72 | $metaprops[$meta->getAttribute('name')] = $meta->getAttribute('content');
73 | } else if ($meta->hasAttribute('property')) {
74 | $metaprops[$meta->getAttribute('property')] = $meta->getAttribute('content');
75 | }
76 | }
77 |
78 | if (!empty($metaprops['twitter:title'])) {
79 | $result['name'] = $metaprops['twitter:title'];
80 | } else if (!empty($metaprops['og:title'])) {
81 | $result['name'] = $metaprops['og:title'];
82 | } else {
83 | $titles = $doc->getElementsByTagName('title');
84 | foreach ($titles as $title) {
85 | $result['name'] = $title->nodeValue;
86 | break;
87 | }
88 | }
89 |
90 | if (!empty($metaprops['twitter:description'])) {
91 | $result['content'] = $metaprops['twitter:description'];
92 | } else if (!empty($metaprops['og:description'])) {
93 | $result['content'] = $metaprops['og:description'];
94 | }
95 | }
96 |
97 | $desc = '';
98 | if (!empty($result['author']) && !empty($result['author']['name'])) {
99 | $desc .= trim($result['author']['name']) . '\'s ';
100 | }
101 |
102 | if (!empty($result['name'])) {
103 | $desc .= preg_replace('/\s{2,}/', ' ', $result['name']);
104 | } else if (strstr($url, 'twitter.com')) {
105 | if ($desc == '') { $desc .= 'a '; }
106 | $desc .= 'tweet';
107 | } else {
108 | if ($desc == '') { $desc .= 'a '; }
109 | $desc .= 'post on ' . preg_replace('/^\w+:\/+([^\/]+).*/', '$1', $url);
110 | }
111 |
112 | $result['description'] = $desc;
113 | return $result;
114 | }
115 |
116 | private static function parseTwitter($html, $url) {
117 | $parsed = \Mf2\Shim\parseTwitter($html, $url);
118 |
119 | if (!empty($parsed['items'][0]['properties']['content'][0]['html'])) {
120 | $content = $parsed['items'][0]['properties']['content'][0]['html'];
121 |
122 | $config = \HTMLPurifier_Config::createDefault();
123 | $config->set('URI.Base', $url);
124 | $config->set('URI.MakeAbsolute', true);
125 | $config->set('HTML.Allowed', 'a[href],img[src],p,br');
126 | $purifier = new \HTMLPurifier($config);
127 | $content = $purifier->purify($content);
128 |
129 | $parsed['items'][0]['properties']['content'][0]['html'] = $content;
130 | }
131 |
132 | return $parsed;
133 | }
134 | }
135 |
136 | }
137 |
--------------------------------------------------------------------------------
/Pages/Like/Edit.php:
--------------------------------------------------------------------------------
1 | createGatekeeper();
13 |
14 | if (!empty($this->arguments)) {
15 | $title = 'Edit Like';
16 | $object = Like::getByID($this->arguments[0]);
17 | } else {
18 | $title = 'New Like';
19 | $object = new Like();
20 | if ($this->getInput('url')) {
21 | $object->likeof = $this->getInput('url');
22 | }
23 | }
24 |
25 | if ($owner = $object->getOwner()) {
26 | $this->setOwner($owner);
27 | }
28 |
29 | $body = $object->drawEdit();
30 |
31 | if (!empty($this->xhr)) {
32 | echo $body;
33 | } else {
34 | Idno::site()->template()->__([
35 | 'body' => $body,
36 | 'title' => $title,
37 | ])->drawPage();
38 | }
39 | }
40 |
41 | function postContent() {
42 | $this->createGatekeeper();
43 |
44 | if (!empty($this->arguments)) {
45 | $object = Like::getByID($this->arguments[0]);
46 | } else {
47 | $object = new Like();
48 | }
49 |
50 | if ($object->saveDataFromInput()) {
51 | $forward = $this->getInput('forward-to', $object->getDisplayURL());
52 | $this->forward($forward);
53 | }
54 | }
55 |
56 | }
57 |
58 | }
--------------------------------------------------------------------------------
/Pages/Repost/Edit.php:
--------------------------------------------------------------------------------
1 | createGatekeeper();
13 |
14 | if (!empty($this->arguments)) {
15 | $title = 'Edit Repost';
16 | $object = Repost::getByID($this->arguments[0]);
17 | } else {
18 | $title = 'New Repost';
19 | $object = new Repost();
20 | if ($this->getInput('url')) {
21 | $object->repostof = $this->getInput('url');
22 | }
23 | }
24 |
25 | if ($owner = $object->getOwner()) {
26 | $this->setOwner($owner);
27 | }
28 |
29 | $body = $object->drawEdit();
30 |
31 | if (!empty($this->xhr)) {
32 | echo $body;
33 | } else {
34 | Idno::site()->template()->__([
35 | 'body' => $body,
36 | 'title' => $title,
37 | ])->drawPage();
38 | }
39 | }
40 |
41 | function postContent() {
42 | $this->createGatekeeper();
43 |
44 | if (!empty($this->arguments)) {
45 | $object = Repost::getByID($this->arguments[0]);
46 | } else {
47 | $object = new Repost();
48 | }
49 |
50 | if ($object->saveDataFromInput()) {
51 | $forward = $this->getInput('forward-to', $object->getDisplayURL());
52 | $this->forward($forward);
53 | }
54 | }
55 |
56 | }
57 |
58 | }
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # KnownReactions
2 |
3 | Publish IndieWeb-style [likes](http://indiewebcamp.com/like) and [reposts](http://indiewebcamp.com/reposts) from Known.
4 |
5 | 
6 |
7 | The original Like plugin evolved to support Bookmarks instead (I
8 | suspect because that's what most users want), so this plugin intends
9 | to fill the gap.
10 |
11 | ## Installation
12 |
13 | [Download](https://github.com/kylewm/KnownReactions/archive/master.zip) the [repository](https://github.com/kylewm/KnownReactions) and upload it to your server into a folder named Reactions
within the IdnoPlugins
folder your [Known](https://github.com/idno/Known) installation. Once uploaded, go to the plugins tab of the Site Configuration for your Known site (typically http://www.yoursitname.com/admin/plugins) and click "Enable" on the Reactions plugin. The "Like" and "Repost" icons and functionality should then be available in your posting interface.
14 |
15 | ## License
16 |
17 | This software is dedicated to the public domain under Creative Commons [CC0][].
18 |
19 | [CC0]: http://creativecommons.org/publicdomain/zero/1.0/
20 |
21 |
22 | ## Changelog
23 |
24 | - 0.1.5 - 2016-06-19: Use HTMLPurifier to clean up the
25 | HTML we get from the mf-shim. Makes URLs absolute
26 | and removes spurious classes
27 | - 0.1.4 - 2016-03-13: show title and description boxes
28 | even if there was an error fetching the source.
29 | - 0.1.3 - 2016-02-09: add argument drawSyndication call
30 | to support new retroactive posse feature in core.
31 |
--------------------------------------------------------------------------------
/Repost.php:
--------------------------------------------------------------------------------
1 | description)) {
14 | $result .= $this->description;
15 | }
16 | return $result;
17 | }
18 |
19 | function getActivityStreamsObjectType()
20 | {
21 | return 'share';
22 | }
23 |
24 | function saveDataFromInput()
25 | {
26 | $page = Idno::site()->currentPage();
27 | if (empty($this->_id)) {
28 | $new = true;
29 | } else {
30 | $new = false;
31 | }
32 |
33 | $this->repostof = $page->getInput('repost-of');
34 | if ($this->repostof) {
35 | foreach ((array) $this->repostof as $repostofurl) {
36 | $this->syndicatedto = Webmention::addSyndicatedReplyTargets($repostofurl, $this->syndicatedto);
37 | }
38 | }
39 | $this->description = $page->getInput('description');
40 | $this->body = $page->getInput('body');
41 | if (empty($this->description) && empty($this->body)) {
42 | $result = \IdnoPlugins\Reactions\Pages\Fetch::fetch($this->repostof);
43 | if (isset($result['description'])) {
44 | $this->description = $result['description'];
45 | }
46 | if (isset($result['content'])) {
47 | $this->body = $result['content'];
48 | }
49 | }
50 | $this->setAccess($page->getInput('access'));
51 | if ($this->publish($new)) {
52 | Webmention::sendWebmentionPayload($this->getURL(), $this->repostof);
53 |
54 | }
55 | return true;
56 | }
57 |
58 | public function save($overrideAccess = false)
59 | {
60 | // generate our own meaningful, unique(ish) slug
61 | if (!$this->getSlug() && !$this->_id
62 | && $this->getTitle() && $this->repostof) {
63 | $this->setSlugResilient($this->getTitle() . '-' . substr(md5($this->repostof), 0, 10));
64 | }
65 |
66 | return parent::save($overrideAccess);
67 | }
68 |
69 | }
70 |
71 | }
72 |
--------------------------------------------------------------------------------
/RepostContentType.php:
--------------------------------------------------------------------------------
1 | =5.3",
25 | "phpunit/phpunit": "*"
26 | },
27 | "suggest": {
28 | "mf2/mf2": "To parse microformats2 structures from (X)HTML"
29 | },
30 | "type": "library",
31 | "autoload": {
32 | "files": [
33 | "src/BarnabyWalters/Mf2/Functions.php"
34 | ]
35 | },
36 | "notification-url": "https://packagist.org/downloads/",
37 | "license": [
38 | "MIT"
39 | ],
40 | "authors": [
41 | {
42 | "name": "Barnaby Walters",
43 | "email": "barnaby@waterpigs.co.uk"
44 | }
45 | ],
46 | "description": "Cleans up microformats2 array structures",
47 | "support": {
48 | "issues": "https://github.com/barnabywalters/php-mf-cleaner/issues",
49 | "source": "https://github.com/barnabywalters/php-mf-cleaner/tree/v0.1.4"
50 | },
51 | "time": "2014-10-06T23:11:15+00:00"
52 | },
53 | {
54 | "name": "mf2/mf2",
55 | "version": "v0.2.12",
56 | "source": {
57 | "type": "git",
58 | "url": "https://github.com/indieweb/php-mf2.git",
59 | "reference": "6701504876d6c9242eb310b35f41d40d9785ab4e"
60 | },
61 | "dist": {
62 | "type": "zip",
63 | "url": "https://api.github.com/repos/indieweb/php-mf2/zipball/6701504876d6c9242eb310b35f41d40d9785ab4e",
64 | "reference": "6701504876d6c9242eb310b35f41d40d9785ab4e",
65 | "shasum": ""
66 | },
67 | "require": {
68 | "php": ">=5.3.0"
69 | },
70 | "require-dev": {
71 | "phpunit/phpunit": "3.7.*"
72 | },
73 | "suggest": {
74 | "barnabywalters/mf-cleaner": "To more easily handle the canonical data php-mf2 gives you"
75 | },
76 | "bin": [
77 | "bin/fetch-mf2",
78 | "bin/parse-mf2"
79 | ],
80 | "type": "library",
81 | "autoload": {
82 | "files": [
83 | "Mf2/Parser.php"
84 | ]
85 | },
86 | "notification-url": "https://packagist.org/downloads/",
87 | "license": [
88 | "MIT"
89 | ],
90 | "authors": [
91 | {
92 | "name": "Barnaby Walters",
93 | "homepage": "http://waterpigs.co.uk"
94 | }
95 | ],
96 | "description": "A pure, generic microformats2 parser — makes HTML as easy to consume as a JSON API",
97 | "keywords": [
98 | "html",
99 | "microformats",
100 | "microformats 2",
101 | "parser",
102 | "semantic"
103 | ],
104 | "support": {
105 | "issues": "https://github.com/indieweb/php-mf2/issues",
106 | "source": "https://github.com/indieweb/php-mf2/tree/v0.2.12"
107 | },
108 | "time": "2015-07-12T14:10:01+00:00"
109 | },
110 | {
111 | "name": "mf2/shim",
112 | "version": "v0.2.4",
113 | "source": {
114 | "type": "git",
115 | "url": "https://github.com/indieweb/php-mf2-shim.git",
116 | "reference": "8a72b720bf60f0d5ceb2edf2b5e2ffc9f252bf1c"
117 | },
118 | "dist": {
119 | "type": "zip",
120 | "url": "https://api.github.com/repos/indieweb/php-mf2-shim/zipball/8a72b720bf60f0d5ceb2edf2b5e2ffc9f252bf1c",
121 | "reference": "8a72b720bf60f0d5ceb2edf2b5e2ffc9f252bf1c",
122 | "shasum": ""
123 | },
124 | "require": {
125 | "mf2/mf2": "~0.2.6",
126 | "php": ">=5.3.0"
127 | },
128 | "require-dev": {
129 | "phpunit/phpunit": "3.7.*"
130 | },
131 | "type": "library",
132 | "autoload": {
133 | "files": [
134 | "Mf2/functions.php",
135 | "Mf2/Shim/Twitter.php",
136 | "Mf2/Shim/Instagram.php",
137 | "Mf2/Shim/Facebook.php"
138 | ]
139 | },
140 | "notification-url": "https://packagist.org/downloads/",
141 | "license": [
142 | "MIT"
143 | ],
144 | "authors": [
145 | {
146 | "name": "Barnaby Walters",
147 | "homepage": "http://waterpigs.co.uk"
148 | },
149 | {
150 | "name": "Aaron Parecki",
151 | "homepage": "http://aaronparecki.com"
152 | }
153 | ],
154 | "description": "A parsing library for parsing pages from a few common non-mf2 sites into the mf2 structure",
155 | "keywords": [
156 | "instagram",
157 | "microformats",
158 | "microformats 2",
159 | "parser",
160 | "semantic",
161 | "twitter"
162 | ],
163 | "support": {
164 | "issues": "https://github.com/indieweb/php-mf2-shim/issues",
165 | "source": "https://github.com/indieweb/php-mf2-shim/tree/v0.2.4"
166 | },
167 | "time": "2014-04-29T17:50:56+00:00"
168 | }
169 | ],
170 | "packages-dev": [],
171 | "aliases": [],
172 | "minimum-stability": "stable",
173 | "stability-flags": {},
174 | "prefer-stable": false,
175 | "prefer-lowest": false,
176 | "platform": {},
177 | "platform-dev": {},
178 | "plugin-api-version": "2.6.0"
179 | }
180 |
--------------------------------------------------------------------------------
/external/barnabywalters/mf-cleaner/.gitignore:
--------------------------------------------------------------------------------
1 | /nbproject/private/
2 | /vendor/
3 | .DS_Store
4 | tmp
5 | composer.phar
6 | .idea/
7 |
--------------------------------------------------------------------------------
/external/barnabywalters/mf-cleaner/README.md:
--------------------------------------------------------------------------------
1 | # php-mf-cleaner
2 |
3 | Lots of little helpers for processing canonical [microformats2](http://microformats.org/wiki/microformats2) array structures. Counterpart to indieweb/php-mf2
4 |
5 | ## Installation
6 |
7 | Install using [Composer](https://getcomposer.org) by adding `barnabywalters/mf-cleaner` to your composer.json:
8 |
9 | ```json
10 | {
11 | "require: {
12 | "barnabywalters/mf-cleaner": "0.*"
13 | }
14 | }
15 | ```
16 |
17 | Then require `vendor/autoload.php` as usual, and you’re ready to go.
18 |
19 | ## Usage
20 |
21 | Should be pretty much self-documenting, you can always look in the tests to see
22 | exactly what a function is supposed to do. Here are some common examples:
23 |
24 | ```php
25 | ['h-card'],
36 | 'properties' => [
37 | 'name' => ['Mr. Bran']
38 | ]
39 | ];
40 |
41 | Mf2\isMicroformat($hCard); // true
42 | Mf2\isMicroformat([1, 2, 3, 4, 'key' => 'value']); // false
43 |
44 | Mf2\hasProp($hCard, 'name'); // true
45 |
46 | Mf2\getPlaintext($hCard, 'name'); // 'Mr. Bran'
47 |
48 | $hEntry = [
49 | 'type' => ['h-entry'],
50 | 'properties' => [
51 | 'published' => ['2013-06-12 12:00:00'],
52 | 'author' => $hCard
53 | ]
54 | ];
55 |
56 | Mf2\flattenMicroformats($hEntry); // returns array with $hEntry followed by $hCard
57 | Mf2\getAuthor($hEntry); // returns $hCard, can do all sorts of handy searching
58 |
59 | // Get the published datetime, fall back to updated if that’s present check that
60 | // it can be parsed by \DateTime, return null if it can’t be found or is invalid
61 | Mf2\getPublished($hEntry, true, null); // '2013-06-12 12:00:00'
62 |
63 | $microformats = [
64 | 'items' => [$hEntry, $hCard]
65 | ];
66 |
67 | Mf2\isMicroformatCollection($microformats); // true
68 |
69 | Mf2\findMicroformatsByType($microformats, 'h-card'); // [$hCard]
70 |
71 | Mf2\findMicroformatsByProperty($microformats, 'published'); // [$hEntry]
72 |
73 | Mf2\findMicroformatsByCallable($microformats, function ($mf) {
74 | return Mf2\hasProp($mf, 'published') and Mf2\hasProp($mf, 'author');
75 | }); // [$hEntry]
76 |
77 | ```
78 |
79 | ## Contributing
80 |
81 | Pull requests very welcome, please try to maintain stylistic, structural
82 | and naming consistency with the existing codebase, and don’t be too upset if I
83 | make naming changes :)
84 |
85 | Please add tests which cover changes you plan to make or have made. I use PHPUnit,
86 | which is the de-facto standard for modern PHP development.
87 |
88 | At the very least, run the test suite before and after making your changes to
89 | make sure you haven’t broken anything.
90 |
91 | Issues/bug reports welcome. If you know how to write tests then please do so as
92 | code always expresses problems and intent much better than English, and gives me
93 | a way of measuring whether or not fixes have actually solved your problem. If you
94 | don’t know how to write tests, don’t worry :) Just include as much useful information
95 | in the issue as you can.
96 |
97 | ## Changelog
98 |
99 | ### v0.1.3 2014-10-06
100 | * Improved getAuthor() algorithm, made non-standard portions optional
101 | * Added getRepresentativeHCard() function implementing http://microformats.org/wiki/representative-h-card-parsing
102 |
103 | ### v0.1.3 2014-05-16
104 | * Fixed issue causing getAuthor to return non-h-card microformats
105 |
106 | ### v0.1.2
107 |
108 | ### v0.1.1
109 |
110 | ### v0.1.0
111 | * Initial version
--------------------------------------------------------------------------------
/external/barnabywalters/mf-cleaner/composer.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "barnabywalters/mf-cleaner",
3 | "description": "Cleans up microformats2 array structures",
4 | "require": {},
5 | "require-dev": {
6 | "phpunit/phpunit": "*",
7 | "php": ">=5.3"
8 | },
9 | "autoload": {
10 | "files": ["src/BarnabyWalters/Mf2/Functions.php"]
11 | },
12 | "license": "MIT",
13 | "authors": [
14 | {
15 | "name": "Barnaby Walters",
16 | "email": "barnaby@waterpigs.co.uk"
17 | }
18 | ],
19 | "suggest": {
20 | "mf2/mf2": "To parse microformats2 structures from (X)HTML"
21 | },
22 | "minimum-stability": "dev"
23 | }
24 |
--------------------------------------------------------------------------------
/external/barnabywalters/mf-cleaner/composer.lock:
--------------------------------------------------------------------------------
1 | {
2 | "_readme": [
3 | "This file locks the dependencies of your project to a known state",
4 | "Read more about it at http://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file"
5 | ],
6 | "hash": "2f749075feeae07b1377efd707633138",
7 | "packages": [
8 |
9 | ],
10 | "packages-dev": [
11 | {
12 | "name": "phpunit/php-code-coverage",
13 | "version": "dev-master",
14 | "source": {
15 | "type": "git",
16 | "url": "https://github.com/sebastianbergmann/php-code-coverage.git",
17 | "reference": "dff200806109072c6f2f788b9499492fd73cae02"
18 | },
19 | "dist": {
20 | "type": "zip",
21 | "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/dff200806109072c6f2f788b9499492fd73cae02",
22 | "reference": "dff200806109072c6f2f788b9499492fd73cae02",
23 | "shasum": ""
24 | },
25 | "require": {
26 | "php": ">=5.4.7",
27 | "phpunit/php-file-iterator": ">=1.3.0",
28 | "phpunit/php-text-template": ">=1.1.1",
29 | "phpunit/php-token-stream": ">=1.1.3",
30 | "sebastian/version": ">=1.0.0"
31 | },
32 | "require-dev": {
33 | "ext-xdebug": ">=2.2.1",
34 | "phpunit/phpunit": "dev-master"
35 | },
36 | "suggest": {
37 | "ext-dom": "*",
38 | "ext-xdebug": ">=2.2.1"
39 | },
40 | "type": "library",
41 | "extra": {
42 | "branch-alias": {
43 | "dev-master": "1.3.x-dev"
44 | }
45 | },
46 | "autoload": {
47 | "classmap": [
48 | "PHP/"
49 | ]
50 | },
51 | "notification-url": "https://packagist.org/downloads/",
52 | "include-path": [
53 | ""
54 | ],
55 | "license": [
56 | "BSD-3-Clause"
57 | ],
58 | "authors": [
59 | {
60 | "name": "Sebastian Bergmann",
61 | "email": "sb@sebastian-bergmann.de",
62 | "role": "lead"
63 | }
64 | ],
65 | "description": "Library that provides collection, processing, and rendering functionality for PHP code coverage information.",
66 | "homepage": "https://github.com/sebastianbergmann/php-code-coverage",
67 | "keywords": [
68 | "coverage",
69 | "testing",
70 | "xunit"
71 | ],
72 | "time": "2013-10-04 20:11:09"
73 | },
74 | {
75 | "name": "phpunit/php-file-iterator",
76 | "version": "dev-master",
77 | "source": {
78 | "type": "git",
79 | "url": "https://github.com/sebastianbergmann/php-file-iterator.git",
80 | "reference": "acd690379117b042d1c8af1fafd61bde001bf6bb"
81 | },
82 | "dist": {
83 | "type": "zip",
84 | "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/acd690379117b042d1c8af1fafd61bde001bf6bb",
85 | "reference": "acd690379117b042d1c8af1fafd61bde001bf6bb",
86 | "shasum": ""
87 | },
88 | "require": {
89 | "php": ">=5.3.3"
90 | },
91 | "type": "library",
92 | "autoload": {
93 | "classmap": [
94 | "File/"
95 | ]
96 | },
97 | "notification-url": "https://packagist.org/downloads/",
98 | "include-path": [
99 | ""
100 | ],
101 | "license": [
102 | "BSD-3-Clause"
103 | ],
104 | "authors": [
105 | {
106 | "name": "Sebastian Bergmann",
107 | "email": "sb@sebastian-bergmann.de",
108 | "role": "lead"
109 | }
110 | ],
111 | "description": "FilterIterator implementation that filters files based on a list of suffixes.",
112 | "homepage": "https://github.com/sebastianbergmann/php-file-iterator/",
113 | "keywords": [
114 | "filesystem",
115 | "iterator"
116 | ],
117 | "time": "2013-10-10 15:34:57"
118 | },
119 | {
120 | "name": "phpunit/php-text-template",
121 | "version": "dev-master",
122 | "source": {
123 | "type": "git",
124 | "url": "https://github.com/sebastianbergmann/php-text-template.git",
125 | "reference": "1eeef106193d2f8c539728e566bb4793071a9e18"
126 | },
127 | "dist": {
128 | "type": "zip",
129 | "url": "https://api.github.com/repos/sebastianbergmann/php-text-template/zipball/1eeef106193d2f8c539728e566bb4793071a9e18",
130 | "reference": "1eeef106193d2f8c539728e566bb4793071a9e18",
131 | "shasum": ""
132 | },
133 | "require": {
134 | "php": ">=5.3.3"
135 | },
136 | "type": "library",
137 | "autoload": {
138 | "classmap": [
139 | "Text/"
140 | ]
141 | },
142 | "notification-url": "https://packagist.org/downloads/",
143 | "include-path": [
144 | ""
145 | ],
146 | "license": [
147 | "BSD-3-Clause"
148 | ],
149 | "authors": [
150 | {
151 | "name": "Sebastian Bergmann",
152 | "email": "sb@sebastian-bergmann.de",
153 | "role": "lead"
154 | }
155 | ],
156 | "description": "Simple template engine.",
157 | "homepage": "https://github.com/sebastianbergmann/php-text-template/",
158 | "keywords": [
159 | "template"
160 | ],
161 | "time": "2013-01-07 10:56:17"
162 | },
163 | {
164 | "name": "phpunit/php-timer",
165 | "version": "dev-master",
166 | "source": {
167 | "type": "git",
168 | "url": "https://github.com/sebastianbergmann/php-timer.git",
169 | "reference": "19689d4354b295ee3d8c54b4f42c3efb69cbc17c"
170 | },
171 | "dist": {
172 | "type": "zip",
173 | "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/19689d4354b295ee3d8c54b4f42c3efb69cbc17c",
174 | "reference": "19689d4354b295ee3d8c54b4f42c3efb69cbc17c",
175 | "shasum": ""
176 | },
177 | "require": {
178 | "php": ">=5.3.3"
179 | },
180 | "type": "library",
181 | "autoload": {
182 | "classmap": [
183 | "PHP/"
184 | ]
185 | },
186 | "notification-url": "https://packagist.org/downloads/",
187 | "include-path": [
188 | ""
189 | ],
190 | "license": [
191 | "BSD-3-Clause"
192 | ],
193 | "authors": [
194 | {
195 | "name": "Sebastian Bergmann",
196 | "email": "sb@sebastian-bergmann.de",
197 | "role": "lead"
198 | }
199 | ],
200 | "description": "Utility class for timing",
201 | "homepage": "https://github.com/sebastianbergmann/php-timer/",
202 | "keywords": [
203 | "timer"
204 | ],
205 | "time": "2013-08-02 07:42:54"
206 | },
207 | {
208 | "name": "phpunit/php-token-stream",
209 | "version": "dev-master",
210 | "source": {
211 | "type": "git",
212 | "url": "https://github.com/sebastianbergmann/php-token-stream.git",
213 | "reference": "292f4d5772dad5a12775be69f4a8dd663b20f103"
214 | },
215 | "dist": {
216 | "type": "zip",
217 | "url": "https://api.github.com/repos/sebastianbergmann/php-token-stream/zipball/292f4d5772dad5a12775be69f4a8dd663b20f103",
218 | "reference": "292f4d5772dad5a12775be69f4a8dd663b20f103",
219 | "shasum": ""
220 | },
221 | "require": {
222 | "ext-tokenizer": "*",
223 | "php": ">=5.3.3"
224 | },
225 | "type": "library",
226 | "extra": {
227 | "branch-alias": {
228 | "dev-master": "1.2-dev"
229 | }
230 | },
231 | "autoload": {
232 | "classmap": [
233 | "PHP/"
234 | ]
235 | },
236 | "notification-url": "https://packagist.org/downloads/",
237 | "include-path": [
238 | ""
239 | ],
240 | "license": [
241 | "BSD-3-Clause"
242 | ],
243 | "authors": [
244 | {
245 | "name": "Sebastian Bergmann",
246 | "email": "sb@sebastian-bergmann.de",
247 | "role": "lead"
248 | }
249 | ],
250 | "description": "Wrapper around PHP's tokenizer extension.",
251 | "homepage": "https://github.com/sebastianbergmann/php-token-stream/",
252 | "keywords": [
253 | "tokenizer"
254 | ],
255 | "time": "2013-10-21 14:03:39"
256 | },
257 | {
258 | "name": "phpunit/phpunit",
259 | "version": "dev-master",
260 | "source": {
261 | "type": "git",
262 | "url": "https://github.com/sebastianbergmann/phpunit.git",
263 | "reference": "5efcfe5bb670fcfaf072c5567f7b7ec7b8e06956"
264 | },
265 | "dist": {
266 | "type": "zip",
267 | "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/5efcfe5bb670fcfaf072c5567f7b7ec7b8e06956",
268 | "reference": "5efcfe5bb670fcfaf072c5567f7b7ec7b8e06956",
269 | "shasum": ""
270 | },
271 | "require": {
272 | "ext-dom": "*",
273 | "ext-pcre": "*",
274 | "ext-reflection": "*",
275 | "ext-spl": "*",
276 | "php": ">=5.4.7",
277 | "phpunit/php-code-coverage": "1.3.*@dev",
278 | "phpunit/php-file-iterator": ">=1.3.1",
279 | "phpunit/php-text-template": ">=1.1.1",
280 | "phpunit/php-timer": ">=1.0.2",
281 | "phpunit/phpunit-mock-objects": "1.3.*@dev",
282 | "sebastian/diff": ">=1.1.0",
283 | "sebastian/exporter": ">=1.0.0",
284 | "sebastian/version": ">=1.0.0",
285 | "symfony/yaml": "~2.0"
286 | },
287 | "require-dev": {
288 | "pear-pear/pear": "1.9.4"
289 | },
290 | "suggest": {
291 | "ext-json": "*",
292 | "ext-simplexml": "*",
293 | "ext-tokenizer": "*",
294 | "phpunit/php-invoker": ">=1.1.0"
295 | },
296 | "bin": [
297 | "composer/bin/phpunit"
298 | ],
299 | "type": "library",
300 | "extra": {
301 | "branch-alias": {
302 | "dev-master": "3.8.x-dev"
303 | }
304 | },
305 | "autoload": {
306 | "classmap": [
307 | "PHPUnit/"
308 | ]
309 | },
310 | "notification-url": "https://packagist.org/downloads/",
311 | "include-path": [
312 | "",
313 | "../../symfony/yaml/"
314 | ],
315 | "license": [
316 | "BSD-3-Clause"
317 | ],
318 | "authors": [
319 | {
320 | "name": "Sebastian Bergmann",
321 | "email": "sebastian@phpunit.de",
322 | "role": "lead"
323 | }
324 | ],
325 | "description": "The PHP Unit Testing framework.",
326 | "homepage": "http://www.phpunit.de/",
327 | "keywords": [
328 | "phpunit",
329 | "testing",
330 | "xunit"
331 | ],
332 | "time": "2013-10-30 07:57:43"
333 | },
334 | {
335 | "name": "phpunit/phpunit-mock-objects",
336 | "version": "dev-master",
337 | "source": {
338 | "type": "git",
339 | "url": "https://github.com/sebastianbergmann/phpunit-mock-objects.git",
340 | "reference": "346591b047bc04e22c0f608110087579f7518dba"
341 | },
342 | "dist": {
343 | "type": "zip",
344 | "url": "https://api.github.com/repos/sebastianbergmann/phpunit-mock-objects/zipball/346591b047bc04e22c0f608110087579f7518dba",
345 | "reference": "346591b047bc04e22c0f608110087579f7518dba",
346 | "shasum": ""
347 | },
348 | "require": {
349 | "php": ">=5.4.7",
350 | "phpunit/php-text-template": ">=1.1.1"
351 | },
352 | "require-dev": {
353 | "pear-pear/pear": "1.9.4",
354 | "phpunit/phpunit": "dev-master"
355 | },
356 | "suggest": {
357 | "ext-soap": "*"
358 | },
359 | "type": "library",
360 | "extra": {
361 | "branch-alias": {
362 | "dev-master": "1.3.x-dev"
363 | }
364 | },
365 | "autoload": {
366 | "classmap": [
367 | "PHPUnit/"
368 | ]
369 | },
370 | "notification-url": "https://packagist.org/downloads/",
371 | "include-path": [
372 | ""
373 | ],
374 | "license": [
375 | "BSD-3-Clause"
376 | ],
377 | "authors": [
378 | {
379 | "name": "Sebastian Bergmann",
380 | "email": "sb@sebastian-bergmann.de",
381 | "role": "lead"
382 | }
383 | ],
384 | "description": "Mock Object library for PHPUnit",
385 | "homepage": "https://github.com/sebastianbergmann/phpunit-mock-objects/",
386 | "keywords": [
387 | "mock",
388 | "xunit"
389 | ],
390 | "time": "2013-08-31 07:18:20"
391 | },
392 | {
393 | "name": "sebastian/diff",
394 | "version": "dev-master",
395 | "source": {
396 | "type": "git",
397 | "url": "https://github.com/sebastianbergmann/diff.git",
398 | "reference": "1e091702a5a38e6b4c1ba9ca816e3dd343df2e2d"
399 | },
400 | "dist": {
401 | "type": "zip",
402 | "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/1e091702a5a38e6b4c1ba9ca816e3dd343df2e2d",
403 | "reference": "1e091702a5a38e6b4c1ba9ca816e3dd343df2e2d",
404 | "shasum": ""
405 | },
406 | "require": {
407 | "php": ">=5.3.3"
408 | },
409 | "type": "library",
410 | "extra": {
411 | "branch-alias": {
412 | "dev-master": "1.1-dev"
413 | }
414 | },
415 | "autoload": {
416 | "classmap": [
417 | "src/"
418 | ]
419 | },
420 | "notification-url": "https://packagist.org/downloads/",
421 | "license": [
422 | "BSD-3-Clause"
423 | ],
424 | "authors": [
425 | {
426 | "name": "Sebastian Bergmann",
427 | "email": "sebastian@phpunit.de",
428 | "role": "lead"
429 | },
430 | {
431 | "name": "Kore Nordmann",
432 | "email": "mail@kore-nordmann.de"
433 | }
434 | ],
435 | "description": "Diff implementation",
436 | "homepage": "http://www.github.com/sebastianbergmann/diff",
437 | "keywords": [
438 | "diff"
439 | ],
440 | "time": "2013-08-03 16:46:33"
441 | },
442 | {
443 | "name": "sebastian/exporter",
444 | "version": "dev-master",
445 | "source": {
446 | "type": "git",
447 | "url": "https://github.com/sebastianbergmann/exporter.git",
448 | "reference": "7c801c2db02018e00a91026994eadb9fae51701f"
449 | },
450 | "dist": {
451 | "type": "zip",
452 | "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/7c801c2db02018e00a91026994eadb9fae51701f",
453 | "reference": "7c801c2db02018e00a91026994eadb9fae51701f",
454 | "shasum": ""
455 | },
456 | "require": {
457 | "php": ">=5.3.3"
458 | },
459 | "type": "library",
460 | "extra": {
461 | "branch-alias": {
462 | "dev-master": "1.0.x-dev"
463 | }
464 | },
465 | "autoload": {
466 | "classmap": [
467 | "src/"
468 | ]
469 | },
470 | "notification-url": "https://packagist.org/downloads/",
471 | "license": [
472 | "BSD-3-Clause"
473 | ],
474 | "authors": [
475 | {
476 | "name": "Sebastian Bergmann",
477 | "email": "sebastian@phpunit.de",
478 | "role": "lead"
479 | },
480 | {
481 | "name": "Jeff Welch",
482 | "email": "whatthejeff@gmail.com"
483 | },
484 | {
485 | "name": "Volker Dusch",
486 | "email": "github@wallbash.com"
487 | },
488 | {
489 | "name": "Adam Harvey",
490 | "email": "aharvey@php.net"
491 | },
492 | {
493 | "name": "Bernhard Schussek",
494 | "email": "bschussek@2bepublished.at"
495 | }
496 | ],
497 | "description": "Provides the functionality to export PHP variables for visualization",
498 | "homepage": "http://www.github.com/sebastianbergmann/exporter",
499 | "keywords": [
500 | "export",
501 | "exporter"
502 | ],
503 | "time": "2013-07-09 05:47:49"
504 | },
505 | {
506 | "name": "sebastian/version",
507 | "version": "dev-master",
508 | "source": {
509 | "type": "git",
510 | "url": "https://github.com/sebastianbergmann/version.git",
511 | "reference": "b5ed060223916b485002b02605e20ba04a741f03"
512 | },
513 | "dist": {
514 | "type": "zip",
515 | "url": "https://api.github.com/repos/sebastianbergmann/version/zipball/b5ed060223916b485002b02605e20ba04a741f03",
516 | "reference": "b5ed060223916b485002b02605e20ba04a741f03",
517 | "shasum": ""
518 | },
519 | "type": "library",
520 | "autoload": {
521 | "classmap": [
522 | "src/"
523 | ]
524 | },
525 | "notification-url": "https://packagist.org/downloads/",
526 | "license": [
527 | "BSD-3-Clause"
528 | ],
529 | "authors": [
530 | {
531 | "name": "Sebastian Bergmann",
532 | "email": "sebastian@phpunit.de",
533 | "role": "lead"
534 | }
535 | ],
536 | "description": "Library that helps with managing the version number of Git-hosted PHP projects",
537 | "homepage": "https://github.com/sebastianbergmann/version",
538 | "time": "2013-07-31 05:26:57"
539 | },
540 | {
541 | "name": "symfony/yaml",
542 | "version": "dev-master",
543 | "target-dir": "Symfony/Component/Yaml",
544 | "source": {
545 | "type": "git",
546 | "url": "https://github.com/symfony/Yaml.git",
547 | "reference": "1f7cabb841e62ec49615bd965ac780fd994b3f64"
548 | },
549 | "dist": {
550 | "type": "zip",
551 | "url": "https://api.github.com/repos/symfony/Yaml/zipball/1f7cabb841e62ec49615bd965ac780fd994b3f64",
552 | "reference": "1f7cabb841e62ec49615bd965ac780fd994b3f64",
553 | "shasum": ""
554 | },
555 | "require": {
556 | "php": ">=5.3.3"
557 | },
558 | "type": "library",
559 | "extra": {
560 | "branch-alias": {
561 | "dev-master": "2.4-dev"
562 | }
563 | },
564 | "autoload": {
565 | "psr-0": {
566 | "Symfony\\Component\\Yaml\\": ""
567 | }
568 | },
569 | "notification-url": "https://packagist.org/downloads/",
570 | "license": [
571 | "MIT"
572 | ],
573 | "authors": [
574 | {
575 | "name": "Fabien Potencier",
576 | "email": "fabien@symfony.com"
577 | },
578 | {
579 | "name": "Symfony Community",
580 | "homepage": "http://symfony.com/contributors"
581 | }
582 | ],
583 | "description": "Symfony Yaml Component",
584 | "homepage": "http://symfony.com",
585 | "time": "2013-10-17 11:48:11"
586 | }
587 | ],
588 | "aliases": [
589 |
590 | ],
591 | "minimum-stability": "dev",
592 | "stability-flags": [
593 |
594 | ],
595 | "platform": [
596 |
597 | ],
598 | "platform-dev": {
599 | "php": ">=5.3"
600 | }
601 | }
602 |
--------------------------------------------------------------------------------
/external/barnabywalters/mf-cleaner/nbproject/project.properties:
--------------------------------------------------------------------------------
1 | file.reference.php-mf-cleaner-vendor=vendor
2 | ignore.path=\
3 | ${file.reference.php-mf-cleaner-vendor}
4 | include.path=${php.global.include.path}
5 | php.version=PHP_54
6 | source.encoding=UTF-8
7 | src.dir=.
8 | tags.asp=false
9 | tags.short=true
10 | test.src.dir=test
11 | web.root=.
12 |
--------------------------------------------------------------------------------
/external/barnabywalters/mf-cleaner/nbproject/project.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | org.netbeans.modules.php.project
4 |
5 |
6 | php-mf-cleaner
7 |
8 |
9 |
10 |
--------------------------------------------------------------------------------
/external/barnabywalters/mf-cleaner/phpunit.xml:
--------------------------------------------------------------------------------
1 |
19 |
20 |
21 | test/
22 |
23 |
24 |
25 |
27 |
28 |
29 |
30 |
--------------------------------------------------------------------------------
/external/barnabywalters/mf-cleaner/src/BarnabyWalters/Mf2/Functions.php:
--------------------------------------------------------------------------------
1 | $val) if (is_numeric($key)) return true;
10 | return false;
11 | }
12 |
13 | function isMicroformat($mf) {
14 | return (is_array($mf) and !hasNumericKeys($mf) and !empty($mf['type']) and isset($mf['properties']));
15 | }
16 |
17 | function isMicroformatCollection($mf) {
18 | return (is_array($mf) and isset($mf['items']) and is_array($mf['items']));
19 | }
20 |
21 | function isEmbeddedHtml($p) {
22 | return is_array($p) and !hasNumericKeys($p) and isset($p['value']) and isset($p['html']);
23 | }
24 |
25 | function hasProp(array $mf, $propName) {
26 | return !empty($mf['properties'][$propName]) and is_array($mf['properties'][$propName]);
27 | }
28 |
29 | /** shortcut for getPlaintext, use getPlaintext from now on */
30 | function getProp(array $mf, $propName, $fallback = null) {
31 | return getPlaintext($mf, $propName, $fallback);
32 | }
33 |
34 | function toPlaintext($v) {
35 | if (isMicroformat($v) or isEmbeddedHtml($v))
36 | return $v['value'];
37 | return $v;
38 | }
39 |
40 | function getPlaintext(array $mf, $propName, $fallback = null) {
41 | if (!empty($mf['properties'][$propName]) and is_array($mf['properties'][$propName])) {
42 | return toPlaintext(current($mf['properties'][$propName]));
43 | }
44 |
45 | return $fallback;
46 | }
47 |
48 | function getPlaintextArray(array $mf, $propName, $fallback = null) {
49 | if (!empty($mf['properties'][$propName]) and is_array($mf['properties'][$propName]))
50 | return array_map(__NAMESPACE__ . '\toPlaintext', $mf['properties'][$propName]);
51 |
52 | return $fallback;
53 | }
54 |
55 | function toHtml($v) {
56 | if (isEmbeddedHtml($v))
57 | return $v['html'];
58 | elseif (isMicroformat($v))
59 | return htmlspecialchars($v['value']);
60 | return htmlspecialchars($v);
61 | }
62 |
63 | function getHtml(array $mf, $propName, $fallback = null) {
64 | if (!empty($mf['properties'][$propName]) and is_array($mf['properties'][$propName]))
65 | return toHtml(current($mf['properties'][$propName]));
66 |
67 | return $fallback;
68 | }
69 |
70 | /** @deprecated as not often used **/
71 | function getSummary(array $mf) {
72 | if (hasProp($mf, 'summary'))
73 | return getProp($mf, 'summary');
74 |
75 | if (!empty($mf['properties']['content']))
76 | return substr(strip_tags(getPlaintext($mf, 'content')), 0, 19) . '…';
77 | }
78 |
79 | function getPublished(array $mf, $ensureValid = false, $fallback = null) {
80 | return getDateTimeProperty('published', $mf, $ensureValid, $fallback);
81 | }
82 |
83 | function getUpdated(array $mf, $ensureValid = false, $fallback = null) {
84 | return getDateTimeProperty('updated', $mf, $ensureValid, $fallback);
85 | }
86 |
87 | function getDateTimeProperty($name, array $mf, $ensureValid = false, $fallback = null) {
88 | $compliment = 'published' === $name ? 'updated' : 'published';
89 |
90 | if (hasProp($mf, $name))
91 | $return = getProp($mf, $name);
92 | elseif (hasProp($mf, $compliment))
93 | $return = getProp($mf, $compliment);
94 | else
95 | return $fallback;
96 |
97 | if (!$ensureValid)
98 | return $return;
99 | else {
100 | try {
101 | new DateTime($return);
102 | return $return;
103 | } catch (Exception $e) {
104 | return $fallback;
105 | }
106 | }
107 | }
108 |
109 | function sameHostname($u1, $u2) {
110 | return parse_url($u1, PHP_URL_HOST) === parse_url($u2, PHP_URL_HOST);
111 | }
112 |
113 | // TODO: maybe split some bits of this out into separate functions
114 | // TODO: this needs to be just part of an indiewebcamp.com/authorship algorithm, at the moment it tries to do too much
115 | function getAuthor(array $mf, array $context = null, $url = null, $matchName = true, $matchHostname = true) {
116 | $entryAuthor = null;
117 |
118 | if (null === $url and hasProp($mf, 'url'))
119 | $url = getProp($mf, 'url');
120 |
121 | if (hasProp($mf, 'author') and isMicroformat(current($mf['properties']['author'])))
122 | $entryAuthor = current($mf['properties']['author']);
123 | elseif (hasProp($mf, 'reviewer') and isMicroformat(current($mf['properties']['author'])))
124 | $entryAuthor = current($mf['properties']['reviewer']);
125 | elseif (hasProp($mf, 'author'))
126 | $entryAuthor = getPlaintext($mf, 'author');
127 |
128 | // If we have no context that’s the best we can do
129 | if (null === $context)
130 | return $entryAuthor;
131 |
132 | // Whatever happens after this we’ll need these
133 | $flattenedMf = flattenMicroformats($context);
134 | $hCards = findMicroformatsByType($flattenedMf, 'h-card', false);
135 |
136 | if (is_string($entryAuthor)) {
137 | // look through all page h-cards for one with this URL
138 | $authorHCards = findMicroformatsByProperty($hCards, 'url', $entryAuthor, false);
139 |
140 | if (!empty($authorHCards))
141 | $entryAuthor = current($authorHCards);
142 | }
143 |
144 | if (is_string($entryAuthor) and $matchName) {
145 | // look through all page h-cards for one with this name
146 | $authorHCards = findMicroformatsByProperty($hCards, 'name', $entryAuthor, false);
147 |
148 | if (!empty($authorHCards))
149 | $entryAuthor = current($authorHCards);
150 | }
151 |
152 | if (null !== $entryAuthor)
153 | return $entryAuthor;
154 |
155 | // look for page-wide rel-author, h-card with that
156 | if (!empty($context['rels']) and !empty($context['rels']['author'])) {
157 | // Grab first href with rel=author
158 | $relAuthorHref = current($context['rels']['author']);
159 |
160 | $relAuthorHCards = findMicroformatsByProperty($hCards, 'url', $relAuthorHref);
161 |
162 | if (!empty($relAuthorHCards))
163 | return current($relAuthorHCards);
164 | }
165 |
166 | // look for h-card with same hostname as $url if given
167 | if (null !== $url and $matchHostname) {
168 | $sameHostnameHCards = findMicroformatsByCallable($hCards, function ($mf) use ($url) {
169 | if (!hasProp($mf, 'url'))
170 | return false;
171 |
172 | foreach ($mf['properties']['url'] as $u) {
173 | if (sameHostname($url, $u))
174 | return true;
175 | }
176 | }, false);
177 |
178 | if (!empty($sameHostnameHCards))
179 | return current($sameHostnameHCards);
180 | }
181 |
182 | // Without fetching, this is the best we can do. Return the found string value, or null.
183 | return empty($relAuthorHref)
184 | ? null
185 | : $relAuthorHref;
186 | }
187 |
188 | function parseUrl($url) {
189 | $r = parse_url($url);
190 | $r['pathname'] = empty($r['path']) ? '/' : $r['path'];
191 | return $r;
192 | }
193 |
194 | function urlsMatch($url1, $url2) {
195 | $u1 = parseUrl($url1);
196 | $u2 = parseUrl($url2);
197 |
198 | foreach (array_merge(array_keys($u1), array_keys($u2)) as $component) {
199 | if (!array_key_exists($component, $u1) or !array_key_exists($component, $u1)) {
200 | return false;
201 | }
202 |
203 | if ($u1[$component] != $u2[$component]) {
204 | return false;
205 | }
206 | }
207 |
208 | return true;
209 | }
210 |
211 | /**
212 | * Representative h-card
213 | *
214 | * Given the microformats on a page representing a person or organisation (h-card), find the single h-card which is
215 | * representative of the page, or null if none is found.
216 | *
217 | * @see http://microformats.org/wiki/representative-h-card-parsing
218 | *
219 | * @param array $mfs The parsed microformats of a page to search for a representative h-card
220 | * @param string $url The URL the microformats were fetched from
221 | * @return array|null Either a single h-card array structure, or null if none was found
222 | */
223 | function getRepresentativeHCard(array $mfs, $url) {
224 | $hCardsMatchingUidUrlPageUrl = findMicroformatsByCallable($mfs, function ($hCard) use ($url) {
225 | return hasProp($hCard, 'uid') and hasProp($hCard, 'url')
226 | and urlsMatch(getPlaintext($hCard, 'uid'), $url)
227 | and count(array_filter($hCard['properties']['url'], function ($u) use ($url) {
228 | return urlsMatch($u, $url);
229 | })) > 0;
230 | });
231 | if (!empty($hCardsMatchingUidUrlPageUrl)) return $hCardsMatchingUidUrlPageUrl[0];
232 |
233 | if (!empty($mfs['rels']['me'])) {
234 | $hCardsMatchingUrlRelMe = findMicroformatsByCallable($mfs, function ($hCard) use ($mfs) {
235 | if (hasProp($hCard, 'url')) {
236 | foreach ($mfs['rels']['me'] as $relUrl) {
237 | foreach ($hCard['properties']['url'] as $url) {
238 | if (urlsMatch($url, $relUrl)) {
239 | return true;
240 | }
241 | }
242 | }
243 | }
244 | return false;
245 | });
246 | if (!empty($hCardsMatchingUrlRelMe)) return $hCardsMatchingUrlRelMe[0];
247 | }
248 |
249 | $hCardsMatchingUrlPageUrl = findMicroformatsByCallable($mfs, function ($hCard) use ($url) {
250 | return hasProp($hCard, 'url')
251 | and count(array_filter($hCard['properties']['url'], function ($u) use ($url) {
252 | return urlsMatch($u, $url);
253 | })) > 0;
254 | });
255 | if (count($hCardsMatchingUrlPageUrl) === 1) return $hCardsMatchingUrlPageUrl[0];
256 |
257 | // Otherwise, no representative h-card could be found.
258 | return null;
259 | }
260 |
261 | function flattenMicroformatProperties(array $mf) {
262 | $items = array();
263 |
264 | if (!isMicroformat($mf))
265 | return $items;
266 |
267 | foreach ($mf['properties'] as $propArray) {
268 | foreach ($propArray as $prop) {
269 | if (isMicroformat($prop)) {
270 | $items[] = $prop;
271 | $items = array_merge($items, flattenMicroformatProperties($prop));
272 | }
273 | }
274 | }
275 |
276 | return $items;
277 | }
278 |
279 | function flattenMicroformats(array $mfs) {
280 | if (isMicroformatCollection($mfs))
281 | $mfs = $mfs['items'];
282 | elseif (isMicroformat($mfs))
283 | $mfs = array($mfs);
284 |
285 | $items = array();
286 |
287 | foreach ($mfs as $mf) {
288 | $items[] = $mf;
289 |
290 | $items = array_merge($items, flattenMicroformatProperties($mf));
291 |
292 | if (empty($mf['children']))
293 | continue;
294 |
295 | foreach ($mf['children'] as $child) {
296 | $items[] = $child;
297 | $items = array_merge($items, flattenMicroformatProperties($child));
298 | }
299 | }
300 |
301 | return $items;
302 | }
303 |
304 | function findMicroformatsByType(array $mfs, $name, $flatten = true) {
305 | return findMicroformatsByCallable($mfs, function ($mf) use ($name) {
306 | return in_array($name, $mf['type']);
307 | }, $flatten);
308 | }
309 |
310 | function findMicroformatsByProperty(array $mfs, $propName, $propValue, $flatten = true) {
311 | return findMicroformatsByCallable($mfs, function ($mf) use ($propName, $propValue) {
312 | if (!hasProp($mf, $propName))
313 | return false;
314 |
315 | if (in_array($propValue, $mf['properties'][$propName]))
316 | return true;
317 |
318 | return false;
319 | }, $flatten);
320 | }
321 |
322 | function findMicroformatsByCallable(array $mfs, $callable, $flatten = true) {
323 | if (!is_callable($callable))
324 | throw new \InvalidArgumentException('$callable must be callable');
325 |
326 | if ($flatten and (isMicroformat($mfs) or isMicroformatCollection($mfs)))
327 | $mfs = flattenMicroformats($mfs);
328 |
329 | return array_values(array_filter($mfs, $callable));
330 | }
331 |
--------------------------------------------------------------------------------
/external/barnabywalters/mf-cleaner/test/CleanerTest.php:
--------------------------------------------------------------------------------
1 | $arg) {
20 | if (is_array($arg) and !isMicroformat($arg) and !isEmbeddedHtml($arg))
21 | $properties[$name] = $arg;
22 | else
23 | $properties[$name] = [$arg];
24 | }
25 |
26 | return [
27 | 'type' => $type,
28 | 'properties' => $properties,
29 | 'value' => $value
30 | ];
31 | }
32 |
33 | public function testIsMicroformatReturnsFalseIfNotArray() {
34 | $this->assertFalse(isMicroformat(''));
35 | }
36 |
37 | public function testIsMicroformatReturnsFalseIfTypeMissing() {
38 | $this->assertFalse(isMicroformat(['properties' => []]));
39 | }
40 |
41 | public function testIsMicroformatReturnsFalseIfPropertiesMissing() {
42 | $this->assertFalse(isMicroformat(['type' => ['h-thing']]));
43 | }
44 |
45 | public function testIsMicroformatReturnsFalseIfHasNumericKeys() {
46 | $this->assertFalse(isMicroformat([[], 'thing' => []]));
47 | }
48 |
49 | public function testIsMicroformatReturnsTrueIfValueIsSet() {
50 | $this->assertTrue(isMicroformat([
51 | 'type' => ['h-card'],
52 | 'properties' => [],
53 | 'value' => 'a string'
54 | ]));
55 | }
56 |
57 | public function testHasNumericKeysWorks() {
58 | $withNumericKeys = ['a', 'b', 'c'];
59 | $noNumericKeys = ['key' => 'value'];
60 |
61 | $this->assertTrue(hasNumericKeys($withNumericKeys));
62 | $this->assertFalse(hasNumericKeys($noNumericKeys));
63 | }
64 |
65 | public function testIsMicroformatCollectionChecksForItemsKey() {
66 | $this->assertTrue(isMicroformatCollection(['items' => []]));
67 | $this->assertFalse(isMicroformatCollection(['notItems' => []]));
68 | }
69 |
70 | public function testGetSummaryPassesIfSummaryPresent() {
71 | $mf = $this->mf('h-entry', ['summary' => 'Hello Summary']);
72 | $result = getSummary($mf);
73 | $this->assertEquals($mf['properties']['summary'][0], $result);
74 | }
75 |
76 | public function testGetSummaryUsesStrippedFirstCharactersOfContent() {
77 | $result = getSummary([
78 | 'type' => ['h-entry'],
79 | 'properties' => [
80 | 'content' => ['
Hello hello hello there indeed
']
81 | ]
82 | ]);
83 |
84 | $this->assertEquals('Hello hello hello t…', $result);
85 | }
86 |
87 | public function testGetPublishedPassesIfPublishedPresent() {
88 | $mf = $this->mf('h-entry', ['published' => '2013-12-06']);
89 | $result = getPublished($mf);
90 | $this->assertEquals(getProp($mf, 'published'), $result);
91 | }
92 |
93 | public function testGetPublishedFallsBackToUpdated() {
94 | $mf = $this->mf('h-entry', ['updated' => '2013-12-06']);
95 | $result = getPublished($mf);
96 | $this->assertEquals(getProp($mf, 'updated'), $result);
97 | }
98 |
99 | public function testGetPublishedReturnsNullIfValidDatetimeRequested() {
100 | $mf = $this->mf('h-entry', ['published' => 'werty']);
101 | $result = getPublished($mf, true);
102 | $this->assertNull($result);
103 | }
104 |
105 | public function testGetPublishedReturnsNullIfNoPotentialValueFound() {
106 | $mf = $this->mf('h-entry', []);
107 | $result = getPublished($mf);
108 | $this->assertNull($result);
109 | }
110 |
111 | public function testGetPublishedReturnsFallbackIfProvided() {
112 | $mf = $this->mf('h-entry', []);
113 | $this->assertEquals('fallback', getPublished($mf, true, 'fallback'));
114 | }
115 |
116 | public function testGetAuthorPassesIfAuthorPresent() {
117 | $mf = $this->mf('h-entry', ['author' => [$this->mf('h-card', ['name' => 'Me'])]]);
118 | $result = getAuthor($mf);
119 | $this->assertEquals('Me', getProp($result, 'name'));
120 | }
121 |
122 | public function testGetAuthorFindsSeparateHCardWithSameName() {
123 | $nonAuthorCard = $this->mf('h-card', ['name' => 'Someone Else', 'url' => 'http://example.org']);
124 | $card = $this->mf('h-card', ['name' => 'Me', 'url' => 'http://waterpigs.co.uk']);
125 | $entry = $this->mf('h-entry', ['name' => 'Entry', 'author' => 'Me']);
126 | $mfs = [
127 | 'items' => [$nonAuthorCard, $card, $entry]
128 | ];
129 |
130 | $result = getAuthor($entry, $mfs);
131 |
132 | $this->assertEquals('http://waterpigs.co.uk', getProp($result, 'url'));
133 | }
134 |
135 | public function testGetAuthorFindsSeparateHCardWithSameDomain() {
136 | $card = $this->mf('h-card', ['name' => 'Me', 'url' => 'http://waterpigs.co.uk']);
137 | $entry = $this->mf('h-entry', ['name' => 'The Entry']);
138 | $mfs = ['items' => [$entry, $card]];
139 |
140 | $result = getAuthor($entry, $mfs, 'http://waterpigs.co.uk/notes/1234');
141 |
142 | $this->assertEquals('Me', getProp($result, 'name'));
143 | }
144 |
145 | public function testGetAuthorDoesntFallBackToFirstHCard() {
146 | $cards = [$this->mf('h-card', ['name' => 'Bill']), $this->mf('h-card', ['name' => 'James'])];
147 | $entry = $this->mf('h-entry', ['name' => 'Entry']);
148 | $mfs = ['items' => $cards];
149 |
150 | $result = getAuthor($entry, $mfs);
151 |
152 | $this->assertEquals(null, $result);
153 | }
154 |
155 | public function testGetAuthorFindsAuthorWithUrlOfPageRelAuthor() {
156 | $cards = [$this->mf('h-card', ['name' => 'N. T. Author']), $this->mf('h-card', ['name' => 'The Author', 'url' => 'http://example.com'])];
157 | $entry = $this->mf('h-entry', ['name' => 'Entry']);
158 | $mfs = [
159 | 'items' => $cards,
160 | 'rels' => [
161 | 'author' => ['http://example.com']
162 | ]
163 | ];
164 |
165 | $result = getAuthor($entry, $mfs);
166 |
167 | $this->assertEquals($cards[1], $result);
168 | }
169 |
170 | public function testFindMicroformatsByTypeFindsRootMicroformats() {
171 | $mfs = [
172 | 'items' => [[
173 | 'type' => ['h-card'],
174 | 'properties' => [
175 | 'name' => ['me']
176 | ]
177 | ]]
178 | ];
179 |
180 | $result = findMicroformatsByType($mfs, 'h-card');
181 | $this->assertEquals('me', getProp($result[0], 'name'));
182 | }
183 |
184 | public function testFlattenMicroformatsReturnsFlatArrayOfMicroformats() {
185 | $org = $this->mf('h-card', ['name' => 'organisation']);
186 | $card = $this->mf('h-card', ['name' => 'me', 'org' => [$org]]);
187 | $entry = $this->mf('h-entry', ['name' => 'blog posting']);
188 | $card['children'] = [$entry];
189 |
190 | $mfs = [
191 | 'items' => [$card]
192 | ];
193 |
194 | $result = flattenMicroformats($mfs);
195 |
196 | $this->assertTrue(in_array($org, $result));
197 | $this->assertTrue(in_array($card, $result));
198 | $this->assertTrue(in_array($entry, $result));
199 | }
200 |
201 | public function testFindMicroformatsByProperty() {
202 | $mfs = [
203 | 'items' => [$this->mf('h-card', ['name' => 'Me'])]
204 | ];
205 |
206 | $results = findMicroformatsByProperty($mfs, 'name', 'Me');
207 | $this->assertEquals(1, count($results));
208 | }
209 |
210 | public function testFindMicroformatsByCallable() {
211 | $mfs = [
212 | 'items' => [$this->mf('h-card', ['url' => 'http://waterpigs.co.uk/'])]
213 | ];
214 |
215 | $results = findMicroformatsByCallable($mfs, function ($mf) {
216 | if (!hasProp($mf, 'url'))
217 | return false;
218 |
219 | $urls = $mf['properties']['url'];
220 |
221 | foreach ($urls as $url) {
222 | if (parse_url($url, PHP_URL_HOST) === parse_url('http://waterpigs.co.uk', PHP_URL_HOST))
223 | return true;
224 | }
225 |
226 | return false;
227 | });
228 |
229 | $this->assertEquals(1, count($results));
230 | }
231 |
232 | public function testFindMicroformatsSearchesSingleMicroformatStructure() {
233 | $card = $this->mf('h-card', ['name' => 'Me']);
234 | $entry = $this->mf('h-entry', ['author' => [$card], 'name' => 'entry']);
235 |
236 | $results = findMicroformatsByType($entry, 'h-card');
237 | $this->assertEquals(1, count($results));
238 | }
239 |
240 | public function testIsEmbeddedHtml() {
241 | $e = array('value' => '', 'html' => '');
242 | $this->assertTrue(isEmbeddedHtml($e));
243 | $this->assertFalse(isEmbeddedHtml(array()));
244 | }
245 |
246 | public function testGetPlaintextProperty() {
247 | $e = $this->mf('h-entry', [
248 | 'name' => 'text',
249 | 'content' => ['text' => 'content', 'html' => 'content'],
250 | 'author' => [$this->mf('h-card', [], 'name')]
251 | ]);
252 | $this->assertEquals('text', getPlaintext($e, 'name'));
253 | $this->assertEquals('content', getPlaintext($e, 'content'));
254 | $this->assertEquals('name', getPlaintext($e, 'author'));
255 | }
256 |
257 | public function testGetPlaintextArray() {
258 | $e = $this->mf('h-entry', [
259 | 'category' => ['text', 'more']
260 | ]);
261 | $this->assertEquals(['text', 'more'], getPlaintextArray($e, 'category'));
262 | }
263 |
264 | public function testGetHtmlProperty() {
265 | $e = $this->mf('h-entry', [
266 | 'name' => ['"text"<>'],
267 | 'content' => ['value' => 'content', 'html' => 'content'],
268 | 'author' => [$this->mf('h-card', [], '"name"<>')]
269 | ]);
270 | $this->assertEquals('"text"<>', getHtml($e, 'name'));
271 | $this->assertEquals('content', getHtml($e, 'content'));
272 | $this->assertEquals('"name"<>', getHtml($e, 'author'));
273 | }
274 |
275 | public function testExpandAuthorExpandsFromLargerHCardsInContext() {
276 | $this->markTestSkipped();
277 | }
278 |
279 | public function testMergeMicroformatsRecursivelyMerges() {
280 | $this->markTestSkipped();
281 | }
282 |
283 | public function testGetAuthorDoesntReturnNonHCards() {
284 | $mf = [
285 | 'items' => [[
286 | 'type' => ['h-entry'],
287 | 'properties' => [
288 | 'url' => ['http://example.com/post/100'],
289 | 'name' => ['Some Entry']
290 | ]
291 | ],
292 | [
293 | 'type' => ['h-card'],
294 | 'properties' => [
295 | 'url' => ['http://example.com/'],
296 | 'name' => ['Mrs. Example']
297 | ]
298 | ]]
299 | ];
300 |
301 | $author = getAuthor($mf['items'][0], $mf, 'http://example.com/post/100');
302 |
303 | $this->assertContains('h-card', $author['type']);
304 | }
305 |
306 | public function testGetRepresentativeHCardFindsUidUrlPageUrlAllMatching() {
307 | $url = 'https://example.com';
308 | $mf = [
309 | 'items' => [[
310 | 'type' => ['h-entry'],
311 | 'properties' => [
312 | 'url' => ['https://example.com'],
313 | 'uid' => ['https://example.com'],
314 | 'name' => ['Correct h-card']
315 | ]
316 | ]]
317 | ];
318 |
319 | $repHCard = getRepresentativeHCard($mf, $url);
320 |
321 | $this->assertEquals('Correct h-card', getPlaintext($repHCard, 'name'));
322 | }
323 |
324 | public function testGetRepresentativeHCardFindsUrlRelMeMatching() {
325 | $url = 'https://example.com';
326 | $mf = [
327 | 'items' => [[
328 | 'type' => ['h-entry'],
329 | 'properties' => [
330 | 'url' => ['https://example.org'],
331 | 'name' => ['Correct h-card']
332 | ]
333 | ]],
334 | 'rels' => [
335 | 'me' => ['https://example.org']
336 | ]
337 | ];
338 |
339 | $repHCard = getRepresentativeHCard($mf, $url);
340 |
341 | $this->assertEquals('Correct h-card', getPlaintext($repHCard, 'name'));
342 | }
343 |
344 | public function testGetRepresentativeHCardFindsSingleUrlPageUrlMatching() {
345 | $url = 'https://example.com';
346 | $mf = [
347 | 'items' => [[
348 | 'type' => ['h-entry'],
349 | 'properties' => [
350 | 'url' => ['https://example.com'],
351 | 'name' => ['Correct h-card']
352 | ]
353 | ]],
354 | 'rels' => [
355 | 'me' => ['https://example.org']
356 | ]
357 | ];
358 |
359 | $repHCard = getRepresentativeHCard($mf, $url);
360 |
361 | $this->assertEquals('Correct h-card', getPlaintext($repHCard, 'name'));
362 | }
363 |
364 | public function testGetRepresentativeHCardIgnoresMultipleUrlPageUrlMatching() {
365 | $url = 'https://example.com';
366 | $mf = [
367 | 'items' => [[
368 | 'type' => ['h-entry'],
369 | 'properties' => [
370 | 'url' => ['https://example.com'],
371 | 'name' => ['Incorrect h-card']
372 | ]
373 | ], [
374 | 'type' => ['h-entry'],
375 | 'properties' => [
376 | 'url' => ['https://example.com'],
377 | 'name' => ['Another Incorrect h-card']
378 | ]
379 | ]]
380 | ];
381 |
382 | $repHCard = getRepresentativeHCard($mf, $url);
383 |
384 | $this->assertEquals(null, $repHCard);
385 | }
386 | }
387 |
--------------------------------------------------------------------------------
/external/barnabywalters/mf-cleaner/test/bootstrap.php:
--------------------------------------------------------------------------------
1 | parseRelsAndAlternates();
12 | return array_merge(array('rels' => $rels, 'alternates' => $alternates), $parser->parse());
13 | }
14 |
15 | function fbTimeToIso8601($t) {
16 | echo $t;
17 | $dt = DateTime::createFromFormat('l, F j, Y \a\t g:ia', $t);
18 | return $dt ? $dt->format(DateTime::ISO8601) : null;
19 | }
20 |
21 | class Facebook extends Mf2\Parser {
22 | public function parsePost(DOMElement $el) {
23 | $authorPhoto = $this->query('.//*' . Mf2\xpcs('fbStreamPermalinkHeader') . '//*' . Mf2\xpcs('profilePic'))->item(0)->getAttribute('src');
24 | $authorLink = $this->query('.//*' . Mf2\xpcs('permalinkHeaderInfo') . '/a')->item(0);
25 | $authorUrl = $this->resolveUrl($authorLink->getAttribute('href'));
26 | $authorName = trim($authorLink->textContent);
27 |
28 | $postLink = $this->query('.//*' . Mf2\xpcs('permalinkHeaderContentText') . '//*' . Mf2\xpcs('uiStreamSource') . '/a')->item(0);
29 | // TODO: resolve once php-mf2 is updated making ->resolveUrl() public
30 | $postUrl = $this->resolveUrl($postLink->getAttribute('href'));
31 | $postPublished = fbTimeToIso8601($this->query('./abbr', $postLink)->item(0)->getAttribute('title'));
32 |
33 | $contentEl = $this->query('.//*' . Mf2\xpcs('userContentWrapper') . '//*' . Mf2\xpcs('userContent'))->item(0);
34 | foreach ($this->query('.//a[starts-with(@onmouseover, "LinkshimAsyncLink")]') as $linkEl) {
35 | $linkEl->setAttribute('href', $linkEl->textContent);
36 | $linkEl->removeAttribute('onclick');
37 | $linkEl->removeAttribute('onmouseover');
38 | $linkEl->removeAttribute('target');
39 | }
40 | $contentPlaintext = $contentEl->textContent;
41 | $contentHtml = '';
42 | foreach ($contentEl->childNodes as $node) {
43 | $contentHtml .= $node->C14N();
44 | }
45 |
46 | $post = array(
47 | 'type' => array('h-entry'),
48 | 'properties' => array(
49 | 'author' => array(
50 | 'type' => array('h-card'),
51 | 'properties' => array(
52 | 'photo' => array($authorPhoto),
53 | 'name' => array($authorName),
54 | 'url' => array($authorUrl)
55 | )
56 | ),
57 | 'url' => array($postUrl),
58 | 'published' => array($postPublished),
59 | 'content' => array(array('value' => $contentPlaintext, 'html' => $contentHtml))
60 | )
61 | );
62 |
63 | return $post;
64 | }
65 |
66 | /**
67 | * Parse
68 | *
69 | * @return array
70 | */
71 | public function parse() {
72 | $items = array();
73 |
74 | foreach($this->query('//*[@id="content"]') as $node) {
75 | $items[] = $this->parsePost($node);
76 | }
77 |
78 | return array('items' => array_values(array_filter($items)));
79 | }
80 | }
81 |
--------------------------------------------------------------------------------
/external/mf2/shim/Mf2/Shim/Instagram.php:
--------------------------------------------------------------------------------
1 | array_values(array_filter($mfs)));
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/external/mf2/shim/Mf2/Shim/Twitter.php:
--------------------------------------------------------------------------------
1 | parseRelsAndAlternates();
12 | return array_merge(array('rels' => $rels, 'alternates' => $alternates), $parser->parse());
13 | }
14 |
15 | class Twitter extends Mf2\Parser {
16 | public function parseTweet(DOMElement $el, $parseReplies=true) {
17 | $linksToExpand = $this->query('.//*[@data-expanded-url]', $el);
18 | /** @var $linkEl DOMElement */
19 | foreach ($linksToExpand as $linkEl) {
20 | foreach ($linkEl->childNodes as $child) {
21 | $linkEl->removeChild($child);
22 | }
23 | $newLinkEl = $this->doc->createElement('a');
24 | $newLinkEl->setAttribute('href', $linkEl->getAttribute('data-expanded-url'));
25 | $newLinkEl->nodeValue = $linkEl->getAttribute('data-expanded-url');
26 | $linkEl->parentNode->replaceChild($newLinkEl, $linkEl);
27 | }
28 |
29 | $tweetTextEl = $this->query('.//p' . Mf2\xpcs('tweet-text'), $el)->item(0);
30 |
31 | $authorNameEl = $this->query('.//*' . Mf2\xpcs('fullname'), $el)->item(0);
32 | $authorNickEl = $this->query('.//*' . Mf2\xpcs('username'), $el)->item(0);
33 | $authorPhotoEl = $this->query('.//*' . Mf2\xpcs('avatar'), $el)->item(0);
34 |
35 | $publishedEl = $this->query('.//*' . Mf2\xpcs('_timestamp'), $el)->item(0);
36 | $publishedTimestamp = $publishedEl->getAttribute('data-time');
37 | try {
38 | $publishedDateTime = DateTime::createFromFormat('U', $publishedTimestamp)->format(DateTime::W3C);
39 | } catch (Exception $e) {
40 | $publishedDateTime = '';
41 | }
42 |
43 | $urlEl = $this->query('.//*' . Mf2\xpcs('tweet-timestamp'), $el)->item(0);
44 |
45 | $htmlTweetContent = '';
46 | foreach ($tweetTextEl->childNodes as $node) {
47 | $htmlTweetContent .= $node->C14N();
48 | }
49 |
50 | $tweet = array(
51 | 'type' => array('h-entry'),
52 | 'properties' => array(
53 | 'uid' => array(),
54 | 'name' => array($tweetTextEl->nodeValue),
55 | 'content' => array(array(
56 | 'value' => $tweetTextEl->nodeValue,
57 | 'html' => $htmlTweetContent
58 | )),
59 | 'summary' => array($tweetTextEl->nodeValue),
60 | 'url' => array($this->resolveUrl($urlEl->getAttribute('href'))),
61 | 'published' => array($publishedDateTime),
62 | 'author' => array(
63 | array(
64 | 'type' => array('h-card'),
65 | 'properties' => array(
66 | 'uid' => array(),
67 | 'name' => array($authorNameEl->nodeValue),
68 | 'nickname' => array($authorNickEl->nodeValue),
69 | 'photo' => array($authorPhotoEl->getAttribute('src')),
70 | 'url' => array('https://twitter.com/' . ltrim($authorNickEl->nodeValue, '@'))
71 | )
72 | )
73 | )
74 | )
75 | );
76 |
77 | if ($parseReplies) {
78 | foreach ($this->query('//*' . Mf2\xpcs('permalink-replies') . '//*' . Mf2\xpcs('tweet')) as $reply) {
79 | $tweet['properties']['comment'][] = $this->parseTweet($reply, false);
80 | }
81 | }
82 |
83 | return $tweet;
84 | }
85 |
86 | public function parseProfile(DOMElement $el) {
87 | $photoEl = $this->query('.//*' . Mf2\xpcs('profile-picture') . '/img')->item(0);
88 | $bio = $this->query('.//*' . Mf2\xpcs('bio'))->item(0)->nodeValue;
89 | $location = $this->query('.//*' . Mf2\xpcs('location'))->item(0)->nodeValue;
90 | $url = $this->query('.//*' . Mf2\xpcs('url') . '//a')->item(0)->getAttribute('title');
91 |
92 | return array(
93 | 'type' => array('h-card'),
94 | 'properties' => array(
95 | 'name' => array($photoEl->getAttribute('alt')),
96 | 'photo' => array($photoEl->getAttribute('src')),
97 | 'note' => array($bio),
98 | 'adr' => array($location),
99 | 'url' => array($url)
100 | )
101 | );
102 | }
103 |
104 | /**
105 | * Parse
106 | *
107 | * @return array
108 | */
109 | public function parse($convertClassic = true, ?DOMElement $context = NULL) {
110 | $items = array();
111 |
112 | foreach($this->query('//*' . Mf2\xpcs('profile-card')) as $node) {
113 | $items[] = $this->parseProfile($node);
114 | }
115 |
116 | $permalinkTweets = $this->query('//*' . Mf2\xpcs('tweet', 'permalink-tweet'));
117 | if ($permalinkTweets->length > 0) {
118 | foreach($permalinkTweets as $node) {
119 | $items[] = $this->parseTweet($node);
120 | // In some cases there are multiple “permalink” tweets — only grab the first.
121 | break;
122 | }
123 | } else {
124 | foreach ($this->query('//*' . Mf2\xpcs('stream-items') . '//*' . Mf2\xpcs('tweet')) as $node) {
125 | $items[] = $this->parseTweet($node, false);
126 | }
127 | }
128 |
129 | return array('items' => array_values(array_filter($items)));
130 | }
131 | }
132 |
--------------------------------------------------------------------------------
/external/mf2/shim/Mf2/functions.php:
--------------------------------------------------------------------------------
1 | =5.3.0",
19 | "mf2/mf2": "~0.2.6"
20 | },
21 | "require-dev": {
22 | "phpunit/phpunit": "3.7.*"
23 | },
24 | "autoload": {
25 | "files": ["Mf2/functions.php", "Mf2/Shim/Twitter.php", "Mf2/Shim/Instagram.php", "Mf2/Shim/Facebook.php"]
26 | },
27 | "minimum-stability": "dev"
28 | }
29 |
--------------------------------------------------------------------------------
/external/mf2/shim/composer.lock:
--------------------------------------------------------------------------------
1 | {
2 | "_readme": [
3 | "This file locks the dependencies of your project to a known state",
4 | "Read more about it at http://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file"
5 | ],
6 | "hash": "bbc5279b56bd886e13253b515b2445a3",
7 | "packages": [
8 | {
9 | "name": "mf2/mf2",
10 | "version": "v0.2.6",
11 | "source": {
12 | "type": "git",
13 | "url": "https://github.com/indieweb/php-mf2.git",
14 | "reference": "e6a063f530ffdb93e241108581e1df41e767e4a4"
15 | },
16 | "dist": {
17 | "type": "zip",
18 | "url": "https://api.github.com/repos/indieweb/php-mf2/zipball/e6a063f530ffdb93e241108581e1df41e767e4a4",
19 | "reference": "e6a063f530ffdb93e241108581e1df41e767e4a4",
20 | "shasum": ""
21 | },
22 | "require": {
23 | "php": ">=5.3.0"
24 | },
25 | "require-dev": {
26 | "phpunit/phpunit": "3.7.*"
27 | },
28 | "suggest": {
29 | "barnabywalters/mf-cleaner": "To more easily handle the canonical data php-mf2 gives you"
30 | },
31 | "bin": [
32 | "bin/fetch-mf2",
33 | "bin/parse-mf2"
34 | ],
35 | "type": "library",
36 | "autoload": {
37 | "files": [
38 | "Mf2/Parser.php"
39 | ]
40 | },
41 | "notification-url": "https://packagist.org/downloads/",
42 | "license": [
43 | "MIT"
44 | ],
45 | "authors": [
46 | {
47 | "name": "Barnaby Walters",
48 | "homepage": "http://waterpigs.co.uk"
49 | }
50 | ],
51 | "description": "A pure, generic microformats2 parser — makes HTML as easy to consume as a JSON API",
52 | "keywords": [
53 | "html",
54 | "microformats",
55 | "microformats 2",
56 | "parser",
57 | "semantic"
58 | ],
59 | "time": "2014-04-07 23:10:46"
60 | }
61 | ],
62 | "packages-dev": [
63 | {
64 | "name": "phpunit/php-code-coverage",
65 | "version": "1.2.x-dev",
66 | "source": {
67 | "type": "git",
68 | "url": "https://github.com/sebastianbergmann/php-code-coverage.git",
69 | "reference": "6ef2bf3a1c47eca07ea95f0d8a902a6340390b34"
70 | },
71 | "dist": {
72 | "type": "zip",
73 | "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/6ef2bf3a1c47eca07ea95f0d8a902a6340390b34",
74 | "reference": "6ef2bf3a1c47eca07ea95f0d8a902a6340390b34",
75 | "shasum": ""
76 | },
77 | "require": {
78 | "php": ">=5.3.3",
79 | "phpunit/php-file-iterator": ">=1.3.0@stable",
80 | "phpunit/php-text-template": ">=1.2.0@stable",
81 | "phpunit/php-token-stream": ">=1.1.3@stable"
82 | },
83 | "require-dev": {
84 | "phpunit/phpunit": "3.7.*@dev"
85 | },
86 | "suggest": {
87 | "ext-dom": "*",
88 | "ext-xdebug": ">=2.0.5"
89 | },
90 | "type": "library",
91 | "extra": {
92 | "branch-alias": {
93 | "dev-master": "1.2.x-dev"
94 | }
95 | },
96 | "autoload": {
97 | "classmap": [
98 | "PHP/"
99 | ]
100 | },
101 | "notification-url": "https://packagist.org/downloads/",
102 | "include-path": [
103 | ""
104 | ],
105 | "license": [
106 | "BSD-3-Clause"
107 | ],
108 | "authors": [
109 | {
110 | "name": "Sebastian Bergmann",
111 | "email": "sb@sebastian-bergmann.de",
112 | "role": "lead"
113 | }
114 | ],
115 | "description": "Library that provides collection, processing, and rendering functionality for PHP code coverage information.",
116 | "homepage": "https://github.com/sebastianbergmann/php-code-coverage",
117 | "keywords": [
118 | "coverage",
119 | "testing",
120 | "xunit"
121 | ],
122 | "time": "2014-03-28 10:53:45"
123 | },
124 | {
125 | "name": "phpunit/php-file-iterator",
126 | "version": "1.3.4",
127 | "source": {
128 | "type": "git",
129 | "url": "https://github.com/sebastianbergmann/php-file-iterator.git",
130 | "reference": "acd690379117b042d1c8af1fafd61bde001bf6bb"
131 | },
132 | "dist": {
133 | "type": "zip",
134 | "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/acd690379117b042d1c8af1fafd61bde001bf6bb",
135 | "reference": "acd690379117b042d1c8af1fafd61bde001bf6bb",
136 | "shasum": ""
137 | },
138 | "require": {
139 | "php": ">=5.3.3"
140 | },
141 | "type": "library",
142 | "autoload": {
143 | "classmap": [
144 | "File/"
145 | ]
146 | },
147 | "notification-url": "https://packagist.org/downloads/",
148 | "include-path": [
149 | ""
150 | ],
151 | "license": [
152 | "BSD-3-Clause"
153 | ],
154 | "authors": [
155 | {
156 | "name": "Sebastian Bergmann",
157 | "email": "sb@sebastian-bergmann.de",
158 | "role": "lead"
159 | }
160 | ],
161 | "description": "FilterIterator implementation that filters files based on a list of suffixes.",
162 | "homepage": "https://github.com/sebastianbergmann/php-file-iterator/",
163 | "keywords": [
164 | "filesystem",
165 | "iterator"
166 | ],
167 | "time": "2013-10-10 15:34:57"
168 | },
169 | {
170 | "name": "phpunit/php-text-template",
171 | "version": "1.2.0",
172 | "source": {
173 | "type": "git",
174 | "url": "https://github.com/sebastianbergmann/php-text-template.git",
175 | "reference": "206dfefc0ffe9cebf65c413e3d0e809c82fbf00a"
176 | },
177 | "dist": {
178 | "type": "zip",
179 | "url": "https://api.github.com/repos/sebastianbergmann/php-text-template/zipball/206dfefc0ffe9cebf65c413e3d0e809c82fbf00a",
180 | "reference": "206dfefc0ffe9cebf65c413e3d0e809c82fbf00a",
181 | "shasum": ""
182 | },
183 | "require": {
184 | "php": ">=5.3.3"
185 | },
186 | "type": "library",
187 | "autoload": {
188 | "classmap": [
189 | "Text/"
190 | ]
191 | },
192 | "notification-url": "https://packagist.org/downloads/",
193 | "include-path": [
194 | ""
195 | ],
196 | "license": [
197 | "BSD-3-Clause"
198 | ],
199 | "authors": [
200 | {
201 | "name": "Sebastian Bergmann",
202 | "email": "sb@sebastian-bergmann.de",
203 | "role": "lead"
204 | }
205 | ],
206 | "description": "Simple template engine.",
207 | "homepage": "https://github.com/sebastianbergmann/php-text-template/",
208 | "keywords": [
209 | "template"
210 | ],
211 | "time": "2014-01-30 17:20:04"
212 | },
213 | {
214 | "name": "phpunit/php-timer",
215 | "version": "1.0.5",
216 | "source": {
217 | "type": "git",
218 | "url": "https://github.com/sebastianbergmann/php-timer.git",
219 | "reference": "19689d4354b295ee3d8c54b4f42c3efb69cbc17c"
220 | },
221 | "dist": {
222 | "type": "zip",
223 | "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/19689d4354b295ee3d8c54b4f42c3efb69cbc17c",
224 | "reference": "19689d4354b295ee3d8c54b4f42c3efb69cbc17c",
225 | "shasum": ""
226 | },
227 | "require": {
228 | "php": ">=5.3.3"
229 | },
230 | "type": "library",
231 | "autoload": {
232 | "classmap": [
233 | "PHP/"
234 | ]
235 | },
236 | "notification-url": "https://packagist.org/downloads/",
237 | "include-path": [
238 | ""
239 | ],
240 | "license": [
241 | "BSD-3-Clause"
242 | ],
243 | "authors": [
244 | {
245 | "name": "Sebastian Bergmann",
246 | "email": "sb@sebastian-bergmann.de",
247 | "role": "lead"
248 | }
249 | ],
250 | "description": "Utility class for timing",
251 | "homepage": "https://github.com/sebastianbergmann/php-timer/",
252 | "keywords": [
253 | "timer"
254 | ],
255 | "time": "2013-08-02 07:42:54"
256 | },
257 | {
258 | "name": "phpunit/php-token-stream",
259 | "version": "dev-master",
260 | "source": {
261 | "type": "git",
262 | "url": "https://github.com/sebastianbergmann/php-token-stream.git",
263 | "reference": "ad4e1e23ae01b483c16f600ff1bebec184588e32"
264 | },
265 | "dist": {
266 | "type": "zip",
267 | "url": "https://api.github.com/repos/sebastianbergmann/php-token-stream/zipball/ad4e1e23ae01b483c16f600ff1bebec184588e32",
268 | "reference": "ad4e1e23ae01b483c16f600ff1bebec184588e32",
269 | "shasum": ""
270 | },
271 | "require": {
272 | "ext-tokenizer": "*",
273 | "php": ">=5.3.3"
274 | },
275 | "type": "library",
276 | "extra": {
277 | "branch-alias": {
278 | "dev-master": "1.2-dev"
279 | }
280 | },
281 | "autoload": {
282 | "classmap": [
283 | "PHP/"
284 | ]
285 | },
286 | "notification-url": "https://packagist.org/downloads/",
287 | "include-path": [
288 | ""
289 | ],
290 | "license": [
291 | "BSD-3-Clause"
292 | ],
293 | "authors": [
294 | {
295 | "name": "Sebastian Bergmann",
296 | "email": "sb@sebastian-bergmann.de",
297 | "role": "lead"
298 | }
299 | ],
300 | "description": "Wrapper around PHP's tokenizer extension.",
301 | "homepage": "https://github.com/sebastianbergmann/php-token-stream/",
302 | "keywords": [
303 | "tokenizer"
304 | ],
305 | "time": "2014-03-03 05:10:30"
306 | },
307 | {
308 | "name": "phpunit/phpunit",
309 | "version": "3.7.x-dev",
310 | "source": {
311 | "type": "git",
312 | "url": "https://github.com/sebastianbergmann/phpunit.git",
313 | "reference": "248d6ce95e6ca7f0e3135252c0b984bbe1f52f19"
314 | },
315 | "dist": {
316 | "type": "zip",
317 | "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/248d6ce95e6ca7f0e3135252c0b984bbe1f52f19",
318 | "reference": "248d6ce95e6ca7f0e3135252c0b984bbe1f52f19",
319 | "shasum": ""
320 | },
321 | "require": {
322 | "ext-dom": "*",
323 | "ext-pcre": "*",
324 | "ext-reflection": "*",
325 | "ext-spl": "*",
326 | "php": ">=5.3.3",
327 | "phpunit/php-code-coverage": "~1.2",
328 | "phpunit/php-file-iterator": "~1.3",
329 | "phpunit/php-text-template": "~1.1",
330 | "phpunit/php-timer": "~1.0",
331 | "phpunit/phpunit-mock-objects": "~1.2",
332 | "symfony/yaml": "~2.0"
333 | },
334 | "require-dev": {
335 | "pear-pear.php.net/pear": "1.9.4"
336 | },
337 | "suggest": {
338 | "ext-json": "*",
339 | "ext-simplexml": "*",
340 | "ext-tokenizer": "*",
341 | "phpunit/php-invoker": "~1.1"
342 | },
343 | "bin": [
344 | "composer/bin/phpunit"
345 | ],
346 | "type": "library",
347 | "extra": {
348 | "branch-alias": {
349 | "dev-master": "3.7.x-dev"
350 | }
351 | },
352 | "autoload": {
353 | "classmap": [
354 | "PHPUnit/"
355 | ]
356 | },
357 | "notification-url": "https://packagist.org/downloads/",
358 | "include-path": [
359 | "",
360 | "../../symfony/yaml/"
361 | ],
362 | "license": [
363 | "BSD-3-Clause"
364 | ],
365 | "authors": [
366 | {
367 | "name": "Sebastian Bergmann",
368 | "email": "sebastian@phpunit.de",
369 | "role": "lead"
370 | }
371 | ],
372 | "description": "The PHP Unit Testing framework.",
373 | "homepage": "http://www.phpunit.de/",
374 | "keywords": [
375 | "phpunit",
376 | "testing",
377 | "xunit"
378 | ],
379 | "time": "2014-03-28 11:04:36"
380 | },
381 | {
382 | "name": "phpunit/phpunit-mock-objects",
383 | "version": "1.2.x-dev",
384 | "source": {
385 | "type": "git",
386 | "url": "https://github.com/sebastianbergmann/phpunit-mock-objects.git",
387 | "reference": "c39c4511c3b007539eb170c32cbc2af49a07351a"
388 | },
389 | "dist": {
390 | "type": "zip",
391 | "url": "https://api.github.com/repos/sebastianbergmann/phpunit-mock-objects/zipball/c39c4511c3b007539eb170c32cbc2af49a07351a",
392 | "reference": "c39c4511c3b007539eb170c32cbc2af49a07351a",
393 | "shasum": ""
394 | },
395 | "require": {
396 | "php": ">=5.3.3",
397 | "phpunit/php-text-template": ">=1.1.1@stable"
398 | },
399 | "require-dev": {
400 | "phpunit/phpunit": "3.7.*@dev"
401 | },
402 | "suggest": {
403 | "ext-soap": "*"
404 | },
405 | "type": "library",
406 | "extra": {
407 | "branch-alias": {
408 | "dev-master": "1.2.x-dev"
409 | }
410 | },
411 | "autoload": {
412 | "classmap": [
413 | "PHPUnit/"
414 | ]
415 | },
416 | "notification-url": "https://packagist.org/downloads/",
417 | "include-path": [
418 | ""
419 | ],
420 | "license": [
421 | "BSD-3-Clause"
422 | ],
423 | "authors": [
424 | {
425 | "name": "Sebastian Bergmann",
426 | "email": "sb@sebastian-bergmann.de",
427 | "role": "lead"
428 | }
429 | ],
430 | "description": "Mock Object library for PHPUnit",
431 | "homepage": "https://github.com/sebastianbergmann/phpunit-mock-objects/",
432 | "keywords": [
433 | "mock",
434 | "xunit"
435 | ],
436 | "time": "2014-02-16 12:43:56"
437 | },
438 | {
439 | "name": "symfony/yaml",
440 | "version": "dev-master",
441 | "target-dir": "Symfony/Component/Yaml",
442 | "source": {
443 | "type": "git",
444 | "url": "https://github.com/symfony/Yaml.git",
445 | "reference": "cee3067d680232674c6505d91db9d3d635a9a8f4"
446 | },
447 | "dist": {
448 | "type": "zip",
449 | "url": "https://api.github.com/repos/symfony/Yaml/zipball/cee3067d680232674c6505d91db9d3d635a9a8f4",
450 | "reference": "cee3067d680232674c6505d91db9d3d635a9a8f4",
451 | "shasum": ""
452 | },
453 | "require": {
454 | "php": ">=5.3.3"
455 | },
456 | "type": "library",
457 | "extra": {
458 | "branch-alias": {
459 | "dev-master": "2.5-dev"
460 | }
461 | },
462 | "autoload": {
463 | "psr-0": {
464 | "Symfony\\Component\\Yaml\\": ""
465 | }
466 | },
467 | "notification-url": "https://packagist.org/downloads/",
468 | "license": [
469 | "MIT"
470 | ],
471 | "authors": [
472 | {
473 | "name": "Fabien Potencier",
474 | "email": "fabien@symfony.com",
475 | "homepage": "http://fabien.potencier.org",
476 | "role": "Lead Developer"
477 | },
478 | {
479 | "name": "Symfony Community",
480 | "homepage": "http://symfony.com/contributors"
481 | }
482 | ],
483 | "description": "Symfony Yaml Component",
484 | "homepage": "http://symfony.com",
485 | "time": "2014-03-26 11:51:10"
486 | }
487 | ],
488 | "aliases": [
489 |
490 | ],
491 | "minimum-stability": "dev",
492 | "stability-flags": [
493 |
494 | ],
495 | "platform": {
496 | "php": ">=5.3.0"
497 | },
498 | "platform-dev": [
499 |
500 | ]
501 | }
502 |
--------------------------------------------------------------------------------
/external/mf2/shim/phpunit.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | tests/mf2
6 |
7 |
8 |
--------------------------------------------------------------------------------
/external/mf2/shim/tests/Mf2/FacebookTest.php:
--------------------------------------------------------------------------------
1 | assertArrayHasKey('items', $output);
24 | $this->assertCount(1, $output['items']);
25 |
26 | return $output;
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/external/mf2/shim/tests/Mf2/InstagramTest.php:
--------------------------------------------------------------------------------
1 | parse();
23 |
24 | $this->assertArrayHasKey('items', $output);
25 | $this->assertArrayHasKey(0, $output['items']);
26 | $this->assertArrayHasKey('content', $output['items'][0]['properties']);
27 | }
28 |
29 | }
30 |
31 |
--------------------------------------------------------------------------------
/external/mf2/shim/tests/Mf2/TwitterTest.php:
--------------------------------------------------------------------------------
1 | assertArrayHasKey('items', $output);
21 | $this->assertCount(1, $output['items']);
22 |
23 | return $output;
24 | }
25 |
26 | /**
27 | * @depends testParsesHEntryFromTweetPermalinkHtml
28 | * @todo what’s with the space before the closing paren? More nbsp annoyance? Fix
29 | */
30 | public function testHEntryHasContent($output) {
31 | $this->assertArrayHasKey('content', $output['items'][0]['properties']);
32 | $this->assertEquals('Started off the week getting up at 5am, ended the week going to sleep at 5am. I am my own little timezone. (http://aaron.pk/n4Px1 )', $output['items'][0]['properties']['content'][0]['value']);
33 | }
34 |
35 | /**
36 | * @depends testParsesHEntryFromTweetPermalinkHtml
37 | */
38 | public function testHEntryHasPublished($output) {
39 | $this->assertArrayHasKey('published', $output['items'][0]['properties']);
40 | $this->assertEquals('2013-05-13T02:30:56+00:00', $output['items'][0]['properties']['published'][0]);
41 | }
42 |
43 | /**
44 | * @depends testParsesHEntryFromTweetPermalinkHtml
45 | */
46 | public function testHEntryHasAuthor($output) {
47 | $this->assertArrayHasKey('author', $output['items'][0]['properties']);
48 |
49 | $author = $output['items'][0]['properties']['author'][0];
50 |
51 | $this->assertEquals('Aaron Parecki', $author['properties']['name'][0]);
52 | $this->assertEquals('https://twitter.com/aaronpk', $author['properties']['url'][0]);
53 | $this->assertEquals('https://si0.twimg.com/profile_images/3657148842/934fb225b84b8fd3effe5ab95bb18005_normal.jpeg', $author['properties']['photo'][0]);
54 | }
55 |
56 | /**
57 | * @depends testParsesHEntryFromTweetPermalinkHtml
58 | */
59 | public function testHEntryHasComments($output) {
60 | $this->assertArrayHasKey('comment', $output['items'][0]['properties']);
61 | $comments = $output['items'][0]['properties']['comment'];
62 |
63 | $this->assertCount(1, $comments);
64 |
65 | $comment = $comments[0]['properties'];
66 | $author = $comment['author'][0]['properties'];
67 |
68 | $this->assertEquals('Rachel Kalmar', $author['name'][0]);
69 | $this->assertEquals('@grapealope', $author['nickname'][0]);
70 | }
71 |
72 | public function testParsesHCardHEntriesFromProfilePage() {
73 | $input = file_get_contents('./tests/Mf2/example-twitter-2.html');
74 | $output = Mf2\Shim\parseTwitter($input, 'https://twitter.com/briansuda');
75 | $this->assertArrayHasKey('items', $output);
76 | return $output;
77 | }
78 |
79 | public function testPreprocessesTweetContent() {
80 | $input = file_get_contents('./tests/Mf2/kartikprabhu-twitter.html');
81 | $output = Mf2\shim\parseTwitter($input, 'https://twitter.com/kartik_prabhu/status/449032538476929024');
82 | $this->assertEquals('The #indieweb or: how I learnt to stop worrying and love the #blog. Comes about a year since I went indie (http://kartikprabhu.com/article/indieweb-love-blog)', $output['items'][0]['properties']['content'][0]['value']);
83 | }
84 | }
85 |
--------------------------------------------------------------------------------
/external/mf2/shim/tests/Mf2/bootstrap.php:
--------------------------------------------------------------------------------
1 |
2 |
3 | Barnaby Walters - Trying to find some creativecommons.org... | Facebook
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
17 |
18 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
--------------------------------------------------------------------------------
/external/mf2/shim/tests/Mf2/example-instagram.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | Photo by aaronpk • Instagram
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
116 |
117 |
118 |
119 |
120 |
121 |
122 |
123 |
124 |
125 |
126 |
272 |
273 |
274 |
275 |
276 |
277 |
278 |
279 |
293 |
294 |
295 |
296 |
297 |
298 |
299 |
300 |
301 |
302 |
303 |
304 |
305 |
306 |
307 |
322 |
323 |
324 |
325 |
--------------------------------------------------------------------------------
/plugin.ini:
--------------------------------------------------------------------------------
1 | [Plugin description]
2 | name = "Reactions"
3 | version = 0.1.5
4 | author = "Kyle Mahan"
5 | author_email = "kyle@kylewm.com"
6 | author_url = "https://kylewm.com"
7 | description = "IndieWeb-style likes and reposts"
8 |
9 | [requirements]
10 | idno = 0.9.1
11 |
--------------------------------------------------------------------------------
/templates/default/entity/IdnoPlugins/Reactions/Like/edit.tpl.php:
--------------------------------------------------------------------------------
1 | getActivityStreamsObjectType();
5 | $target = $type == 'like' ? $object->likeof : $object->repostof;
6 | $target_name = $type == 'like' ? 'like-of' : 'repost-of';
7 | $desc = $vars['object']->description;
8 | $body = $vars['object']->body;
9 | $body_id = 'body'.rand(0,9999);
10 |
11 | if ($type == 'like') {
12 | $title = $object->getID() ? 'Edit Like' : 'New Like';
13 | } else {
14 | $title = $object->getID() ? 'Edit Repost' : 'New Repost';
15 | }
16 |
17 | ?>
18 |
19 | = $this->draw('entity/edit/header'); ?>
20 |
77 | = $this->draw('entity/edit/footer'); ?>
78 |
79 |
122 |
--------------------------------------------------------------------------------
/templates/default/entity/IdnoPlugins/Reactions/Like/icon.tpl.php:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/templates/default/entity/IdnoPlugins/Reactions/Repost/edit.tpl.php:
--------------------------------------------------------------------------------
1 | = $this->draw('entity/IdnoPlugins/Reactions/Like/edit'); ?>
--------------------------------------------------------------------------------
/templates/default/entity/IdnoPlugins/Reactions/Repost/icon.tpl.php:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/templates/default/entity/Like.tpl.php:
--------------------------------------------------------------------------------
1 | ';
5 |
6 | if (!empty($vars['object']->pageTitle)) {
7 | $body = $vars['object']->pageTitle;
8 | $thisTitle = $vars['object']->pageTitle;
9 | } else {
10 | $body = $vars['object']->body;
11 | $thisTitle = $vars['object']->description;
12 | }
13 |
14 | $url = $vars['object']->likeof;
15 | $description = $vars['object']->description;
16 |
17 | ?>
18 |
19 |
24 |
25 |
26 | description)) {
31 | echo '
';
32 | echo $this->__(['value' => $vars['object']->description, 'object' => $vars['object']])->draw('forms/output/richtext');
33 | ?>
34 |
Link
36 | ';
38 |
39 | }
40 |
41 |
42 |
43 | if (!empty($vars['object']->tags)) {
44 |
45 | echo $this->__(['tags' => $vars['object']->tags])->draw('forms/output/tags');
46 | }
47 |
48 | ?>
49 |
50 | draw('entity/content/embed');
51 |
--------------------------------------------------------------------------------
/templates/default/entity/Repost.tpl.php:
--------------------------------------------------------------------------------
1 | ';
5 |
6 | if (!empty($vars['object']->pageTitle)) {
7 | $body = $vars['object']->pageTitle;
8 | $thisTitle = $vars['object']->pageTitle;
9 | } else {
10 | $body = $vars['object']->body;
11 | $thisTitle = $vars['object']->description;
12 | }
13 |
14 | $url = $vars['object']->repostof;
15 | $description = $vars['object']->description;
16 |
17 | ?>
18 |
19 |
24 |
25 |
26 | body)) {
31 | echo '
';
32 | echo $this->__(['value' => $vars['object']->body, 'object' => $vars['object']])->draw('forms/output/richtext');
33 | ?>
34 |
Link
36 | ';
38 |
39 | }
40 |
41 |
42 |
43 | if (!empty($vars['object']->tags)) {
44 |
45 | echo $this->__(['tags' => $vars['object']->tags])->draw('forms/output/tags');
46 | }
47 |
48 | ?>
49 |
50 | draw('entity/content/embed');
51 |
--------------------------------------------------------------------------------
Likes
161 | 162 |No likes yet.
163 | 164 |166 | 167 |-
168 |
169 |
170 |
171 |
172 |
173 |
174 | aaronpk
175 |
176 |
177 |
178 |
179 | -
180 |
181 |
182 |
183 |
184 |
185 |
186 | erinjo
187 |
188 |
189 | -
190 |
191 |
192 |
193 |
194 |
195 |
196 | basilleaf
197 |
198 |
199 | -
200 |
201 |
202 |
203 |
204 |
205 |
206 | katrillion
207 |
208 |
209 |
210 |Comments
217 | 218 | 219 |220 | 221 |
222 | 223 |243 |-
244 | Likes
245 |
246 | Like
247 |
248 |
249 |
250 |
251 |
252 |
253 | -
254 | Comments
255 |
256 | Comment
257 |
258 |
259 |
260 |
261 |
262 | 263 | 264 |