├── .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 | ![](http://i.giphy.com/VW9xuM3avNffW.gif) 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 |
Facebook logo
Forgot your password?
Sign Up
Options

Follow
Barnaby Walters · 3 followers
October 13 at 3:53pm ·
  • Trying to find some creativecommons.org licensed folk/traditional recordings — any ideas?

    cc Blowzabella Jon Loomes Show of Hands solarference Rique Meirelles et al

    http://waterpigs.co.uk/notes/4SXNrP/
    Barnaby Walters • Trying to find some creativecommons.org licensed f…
    waterpigs.co.uk
    Trying to find some creativecommons.org licensed folk/trad recordings — any ideas? 22:51 13th October 2013 ReplyTweetFavourite← PreviousTagged with #music#ccView on twitter.comBarnaby Walterswaterpigs.co.uk
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 |

Instagram

84 | 85 |
86 | 87 | 88 | 89 |
90 |
    91 | 92 |
  • 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | aaronpk 101 | 102 | 103 |
    104 | 105 | 106 |
      107 |
    • View Profile
    • 108 |
    • Edit Profile
    • 109 |
    • Badges
    • 110 |
    • Log Out
    • 111 |
    112 |
    113 |
  • 114 | 115 |
116 | 117 | 118 | 119 |
120 |
121 |
122 | 123 | 124 | 125 | 126 |
127 | 128 |
129 | 130 |
131 |
132 |
133 |

aaronpk

134 |
135 | 136 | 137 | 138 | 139 | 140 | 141 |
142 | 143 | 144 | 145 |
146 | 147 | 148 | 149 | Photo by aaronpk 150 | 151 | 152 | 153 |
154 | 155 |
156 | 157 | 158 | 159 |
160 |

Likes

161 | 162 |

No likes yet.

163 | 164 |
165 |
    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 |
211 | 212 | 213 |
214 | 215 |
216 |

Comments

217 | 218 | 219 |
    220 | 221 |
222 | 223 |
224 | 225 |
226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | 234 |
235 | 236 | 237 | 238 | 239 |
240 | 241 | 242 |
    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 |
265 |
266 |
267 |
268 | 269 |
270 | 271 |
272 | 273 | 274 |
275 | 276 | 277 | 278 | 279 |
280 |
281 | 282 | 283 |
284 |
    285 |
  • Privacy
  • 286 |
  • Terms
  • 287 |
288 |
289 | 290 |

© 2013 Instagram

291 |
292 |
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 | draw('entity/edit/header'); ?> 20 |
21 |
22 |
23 |

24 | 25 |
26 | 27 |
28 | 29 | 31 |
32 | 33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 | 41 |
42 | 43 |
44 | 45 |
46 |
47 | 48 | 49 |
50 | 51 | Body"; 54 | echo $this->__([ 55 | 'name' => 'body', 56 | 'unique_id' => $body_id, 57 | 'value' => $body, 58 | ])->draw('forms/input/richtext'); 59 | } 60 | ?> 61 |
62 |
63 | 64 | drawSyndication($type, $object->getPosseLinks()); ?> 65 | 66 | draw('content/access'); ?> 67 |

68 | actions()->signForm('/like/edit') ?> 69 | 70 | 71 |

72 | 73 |
74 |
75 | 76 |
77 | 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 | 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 | --------------------------------------------------------------------------------