function postContent() { $this->adminGatekeeper(); $request = $this->getInput('request'); $key = $this->getInput('key'); $username = $this->getInput('username'); $json = $this->getInput('json'); $follow_redirects = $this->getInput('follow_redirects'); $method = $this->getInput('method', 'GET'); $url = \Idno\Core\Idno::site()->config()->getURL(); if (strripos($url, '/') == strlen($url) - 1) { $url = substr($url, 0, strlen($url) - 1); } $url .= $request; $client = new Webservice(); if ($method == 'POST') { $result = $client->post($url, $json, array('X-KNOWN-USERNAME: '******'X-KNOWN-SIGNATURE: ' . base64_encode(hash_hmac('sha256', $request, $key, true)))); } else { $result = $client->get($url, null, array('X-KNOWN-USERNAME: '******'X-KNOWN-SIGNATURE: ' . base64_encode(hash_hmac('sha256', $request, $key, true)))); } $response = Webservice::getLastResponse(); $sent_request = Webservice::getLastRequest() . $json; $api_request = array('request' => $request, 'key' => $key, 'username' => $username, 'json' => $json, 'sent_request' => $sent_request, 'response' => gzencode($response, 9), 'method' => $method); \Idno\Core\Idno::site()->session()->set('api_request', $api_request); $this->forward(\Idno\Core\Idno::site()->config()->getURL() . 'admin/apitester/'); }
/** * Given an array of URLs (or an empty array) and a target URL to check, * adds and rel="syndication" URLs in the target to the array * @param $url * @param array $inreplyto * @param array $response (optional) response from fetching $url * @return array */ static function addSyndicatedReplyTargets($url, $inreplyto = array(), $response = false) { $inreplyto = (array) $inreplyto; if (!$response) { $response = \Idno\Core\Webservice::get($url); } if ($response && $response['response'] >= 200 && $response['response'] < 300) { if ($mf2 = self::parseContent($response['content'], $url)) { // first check rel-syndication if (!empty($mf2['rels']['syndication'])) { if (is_array($mf2['rels']['syndication'])) { foreach ($mf2['rels']['syndication'] as $syndication) { if (!in_array($syndication, $inreplyto) && !empty($syndication)) { $inreplyto[] = $syndication; } } } } // then look for u-syndication if ($entry = self::findRepresentativeHEntry($mf2, $url, ['h-entry', 'h-event'])) { if (!empty($entry['properties']['syndication'])) { foreach ($entry['properties']['syndication'] as $syndication) { if (!in_array($syndication, $inreplyto) && is_string($syndication)) { $inreplyto[] = $syndication; } } } } } } return $inreplyto; }
function registerEventHooks() { \Idno\Core\site()->events()->addListener('syndicate', function (\Idno\Core\Event $event) { $eventdata = $event->data(); if (!empty($eventdata['object'])) { if (!empty(site()->config()->wayback_machine)) { if ($eventdata['object'] instanceof Entity) { if ($eventdata['object']->isPublic()) { Webservice::get('https://web.archive.org/save/' . $eventdata['object']->getDisplayURL()); } } } $content_type = $eventdata['object']->getActivityStreamsObjectType(); if ($services = \Idno\Core\site()->syndication()->getServices($content_type)) { if ($selected_services = \Idno\Core\site()->currentPage()->getInput('syndication')) { if (!empty($selected_services) && is_array($selected_services)) { foreach ($selected_services as $selected_service) { $event->data()['syndication_account'] = false; if (in_array($selected_service, $services)) { site()->triggerEvent('post/' . $content_type . '/' . $selected_service, $eventdata); } else { if ($implied_service = $this->getServiceByAccountString($selected_service)) { $eventdata['syndication_account'] = $this->getAccountFromAccountString($selected_service); site()->triggerEvent('post/' . $content_type . '/' . $implied_service, $eventdata); } } } } } } } }); }
function postContent() { $body = strip_tags($this->getInput('body')); $name = strip_tags($this->getInput('name')); $url = trim($this->getInput('url')); $url2 = trim($this->getInput('url-2')); $validator = $this->getInput('validator'); if (!empty($url2)) { $this->deniedContent(); } $this->referrerGatekeeper(); if (!empty($body) && !empty($name) && !empty($validator)) { if ($object = Entity::getByUUID($validator)) { if ($url = Webservice::sanitizeURL($url)) { if ($content = Webservice::get($url)) { if ($content['response'] == '200') { $icon = Webmention::getIconFromWebsiteContent($content['content'], $url); } } } if (empty($icon)) { $bn = hexdec(substr(md5($url), 0, 15)); $number = 1 + $bn % 5; $icon = \Idno\Core\site()->config()->url . 'gfx/users/default-' . str_pad($number, 2, '0', STR_PAD_LEFT) . '.png'; } $object->addAnnotation('reply', $name, $url, $icon, $body); $this->forward($object->getDisplayURL()); } } }
/** * Get parsed items from this feed * @return array|bool */ function retrieveItems() { if ($content = Webservice::get($this->getFeedURL())) { return \Idno\Core\Idno::site()->reader()->parseFeed($content['content'], $this->getFeedURL()); } return false; }
function getContent() { $this->createGatekeeper(); $user = \Idno\Core\site()->session()->currentUser(); $u = $this->getInput('u'); if ($content = \Idno\Core\Webservice::get($u)['content']) { $parser = new \Mf2\Parser($content, $u); if ($return = $parser->parse()) { if (isset($return['items'])) { $t = \Idno\Core\site()->template(); $body = ''; $hcard = []; $this->findHcard($return['items'], $hcard); $hcard = $this->removeDuplicateProfiles($hcard); if (!count($hcard)) { throw new \Exception("Sorry, could not find any users on that page, perhaps they need to mark up their profile in <a href=\"http://microformats.org/wiki/microformats-2\">Microformats</a>?"); } // TODO: Add a manual way to add the user foreach ($hcard as $card) { $body .= $t->__(['mf2' => $card])->draw('account/settings/following/mf2user'); } // List user $t->body = $body; $t->title = 'Found users'; $t->drawPage(); } } else { throw new \Exception("Sorry, there was a problem parsing the page!"); } } else { throw new \Exception("Sorry, {$u} could not be retrieved!"); } // forward back $this->forward($_SERVER['HTTP_REFERER']); }
/** * Get parsed items from this feed * @return array|bool */ function retrieveItems() { $ws = new Webservice(); if ($content = $ws->get($this->getFeedURL())) { return \Idno\Core\site()->reader()->parseFeed($content['content'], $this->getFeedURL()); } return false; }
public function testConnection() { $user = \Tests\KnownTestCase::user(); $result = \Idno\Core\Webservice::get(\Idno\Core\Idno::site()->config()->url . '', [], ['Accept: application/json']); $content = json_decode($result['content']); $response = $result['response']; $this->assertTrue(empty($result['error'])); $this->assertTrue(!empty($content)); $this->assertTrue($response == 200); }
function parseTitle($url) { $response = Webservice::get($url); if ($response['response'] == 200) { $doc = \DOMDocument::loadHTML($response['content']); foreach ($doc->getElementsByTagName('title') as $title) { return trim($title->textContent); } } return false; }
/** * Given an array of URLs (or an empty array) and a target URL to check, * adds and rel="syndication" URLs in the target to the array * @param $url * @param array $inreplyto * @return array */ static function addSyndicatedReplyTargets($url, $inreplyto = array()) { if (!is_array($inreplyto)) { $inreplyto = array($inreplyto); } if ($content = \Idno\Core\Webservice::get($url)) { if ($mf2 = self::parseContent($content['content'], $url)) { $mf2 = (array) $mf2; $mf2['rels'] = (array) $mf2['rels']; if (!empty($mf2['rels']['syndication'])) { if (is_array($mf2['rels']['syndication'])) { foreach ($mf2['rels']['syndication'] as $syndication) { if (!in_array($syndication, $inreplyto) && !empty($syndication)) { $inreplyto[] = $syndication; } } } } } } return $inreplyto; }
function getContent() { $this->createGatekeeper(); $user = \Idno\Core\site()->session()->currentUser(); $u = $this->getInput('u'); if ($content = \Idno\Core\Webservice::get($u)['content']) { $parser = new \Mf2\Parser($content, $u); if ($return = $parser->parse()) { if (isset($return['items'])) { $t = \Idno\Core\site()->template(); $body = ''; $hcard = array(); $this->findHcard($return['items'], $hcard); $hcard = $this->removeDuplicateProfiles($hcard); if (!count($hcard)) { //throw new \Exception("Sorry, could not find any users on that page, perhaps they need to mark up their profile in <a href=\"http://microformats.org/wiki/microformats-2\">Microformats</a>?"); // TODO: Add a manual way to add the user // No entry could be found, so lets fake one and allow manual entry $hcard[] = ['properties' => ['name' => [$this->findPageTitle($content)], 'photo' => [], 'email' => [], 'nickname' => [], 'url' => [$u]]]; // Display a warning \Idno\Core\site()->session()->addErrorMessage('Page did not contain any <a href=\\"http://microformats.org/wiki/microformats-2\\">Microformats</a> markup... doing my best with what I have!'); } foreach ($hcard as $card) { $body .= $t->__(array('mf2' => $card))->draw('account/settings/following/mf2user'); } // List user $t->body = $body; $t->title = 'Found users'; $t->drawPage(); } } else { throw new \Exception("Sorry, there was a problem parsing the page!"); } } else { throw new \Exception("Sorry, {$u} could not be retrieved!"); } // forward back $this->forward($_SERVER['HTTP_REFERER']); }
public function testAdminGatekeeper() { $result = \Idno\Core\Webservice::get(\Idno\Core\Idno::site()->config()->url . 'admin/', [], []); $response = $result['response']; $this->assertTrue(empty($result['error'])); $this->assertTrue($response == 403); $user = \Tests\KnownTestCase::user(); $this->assertTrue(is_object(\Idno\Core\Idno::site()->session()->logUserOn($user))); // Try normal user \Idno\Core\Idno::site()->session()->logUserOff(); $result = \Idno\Core\Webservice::get(\Idno\Core\Idno::site()->config()->url . 'admin/', [], ['X-KNOWN-USERNAME: '******'X-KNOWN-SIGNATURE: ' . base64_encode(hash_hmac('sha256', '/admin/', $user->getAPIkey(), true))]); $response = $result['response']; $this->assertTrue(empty($result['error'])); $this->assertTrue($response == 403); // Try admin $user = \Tests\KnownTestCase::admin(); $this->assertTrue(is_object(\Idno\Core\Idno::site()->session()->logUserOn($user))); $result = \Idno\Core\Webservice::get(\Idno\Core\Idno::site()->config()->url . 'admin/', [], ['X-KNOWN-USERNAME: '******'X-KNOWN-SIGNATURE: ' . base64_encode(hash_hmac('sha256', '/admin/', $user->getAPIkey(), true))]); $response = $result['response']; $this->assertTrue(empty($result['error'])); $this->assertTrue($response == 200); \Idno\Core\Idno::site()->session()->logUserOff(); }
/** * Fetch and parse the Bridgy user page for this service, * update its status and return true if it has changed. */ function checkService($user, $service) { if (!isset($user->bridgy) || !isset($user->bridgy[$service])) { return false; } $bridgy_url = $user->bridgy[$service]['user']; if (!empty($bridgy_url) and $resp = \Idno\Core\Webservice::get($bridgy_url)) { $parsed = (new \Mf2\Parser($resp['content'], $bridgy_url))->parse(); $status = 'disabled'; if (!empty($parsed['items'])) { $hcard = $parsed['items'][0]; if (!empty($hcard['properties']['bridgy-account-status']) && $hcard['properties']['bridgy-account-status'][0] == 'enabled' && !empty($hcard['properties']['bridgy-listen-status']) && $hcard['properties']['bridgy-listen-status'][0] == 'enabled') { $status = 'enabled'; } } if ($user->bridgy[$service]['status'] != $status) { $user->bridgy[$service]['status'] = $status; $user->save(); return true; } return false; } }
/** * Given the URL of a website, returns a single linked array containing the URL and title of a feed * (whether Microformats or RSS / Atom). The function will attempt to discover RSS and Atom feeds in * the page if this is an HTML site. Returns false if there is no feed. * @param $url * @return array|false */ function getFeedDetails($url) { if (!filter_var($url, FILTER_VALIDATE_URL)) { return false; } $client = new Webservice(); if ($result = $client->get($url)) { $feed = array(); if (!empty($result['content'])) { $feed['webmention'] = Webmention::supportsMentions($url, $result['content']); if ($html = @\DOMDocument::loadHTML($result['content'])) { $xpath = new \DOMXpath($html); $title = $xpath->query('//title')->item(0)->nodeValue; if ($xpath->query("//*[contains(concat(' ', @class, ' '), ' h-entry ')]")->length > 0) { $feed['type'] = 'mf2'; $feed['url'] = $url; if (!empty($title)) { $feed['title'] = $title; } return $feed; } if ($rss_url = $this->findXMLFeedURL($html)) { $feed['type'] = 'xml'; $feed['url'] = $rss_url; if (!empty($title)) { $feed['title'] = $title; } return $feed; } } if ($xml = @simplexml_load_string($result['content'])) { if (!empty($xml->rss->channel->item) || !empty($xml->feed) || !empty($xml->channel->item)) { $feed['type'] = 'xml'; $feed['url'] = $url; if (!empty($xml->rss->channel->title)) { $feed['title'] = $xml->rss->channel->title; } else { if (!empty($xml->channel->title)) { $feed['title'] = $xml->channel->title; } else { if (!empty($xml->title)) { $feed['title'] = $xml->title; } } } return $feed; } } } } return false; }
function post() { parse_str(trim(file_get_contents("php://input")), $vars); // Check that both source and target are non-empty if (!empty($vars['source']) && !empty($vars['target']) && $vars['source'] != $vars['target']) { $source = $vars['source']; $target = $vars['target']; // Remove anchors from target URL, but save them to '#' input so we can still reference them later if (strpos($target, '#')) { list($target, $fragment) = explode('#', $target, 2); if (!empty($fragment)) { $this->setInput('#', $fragment); } } // Get the page handler for target if ($page = \Idno\Core\Idno::site()->getPageHandler($target)) { // First of all, make sure the target page isn't the source page. Let's not webmention ourselves! $webmention_ok = true; if (\Idno\Common\Entity::isLocalUUID($source)) { if ($source_page = \Idno\Core\Idno::site()->getPageHandler($source)) { if ($source_page == $page) { $webmention_ok = false; } } } // Check that source exists, parse it for mf2 content, // and ensure that it genuinely mentions this page if ($webmention_ok) { if ($source_content = \Idno\Core\Webservice::get($source)) { if (substr_count($source_content['content'], $target) || $source_content['response'] == 410) { $source_mf2 = \Idno\Core\Webmention::parseContent($source_content['content'], $source); // Set source and target information as input variables $page->setPermalink(); if ($page->webmentionContent($source, $target, $source_content, $source_mf2)) { $this->setResponse(202); // Webmention received a-ok. exit; } else { $error = 'target_not_supported'; $error_text = 'This is not webmentionable.'; } } else { $error = 'no_link_found'; $error_text = 'The source URI does not contain a link to the target URI.'; \Idno\Core\Idno::site()->logging->warning('No link from ' . $source . ' to ' . $target); } } else { $error = 'source_not_found'; $error_text = 'The source content for ' . $source . ' could not be obtained.'; \Idno\Core\Idno::site()->logging->warning('No content from ' . $source); } } else { $error = 'target_not_supported'; $error_text = 'A page can\'t webmention itself.'; } } else { $error = 'target_not_found'; $error_text = 'The target page ' . $target . ' does not exist.'; \Idno\Core\Idno::site()->logging()->error('Could not find handler for ' . $target); } } $this->setResponse(400); // Webmention failed. if (empty($error)) { $error = 'unknown_error'; $error_text = 'Not all the required webmention variables were set.'; } echo json_encode(array('error' => $error, 'error_text' => $error_text)); }
function getContent() { $this->gatekeeper(); $url = $this->getInput('share_url'); $title = $this->getInput('share_title'); $type = $this->getInput('share_type'); // Provide a hook to a URL shortener (TODO: Tidy this up when #237 is merged) $event = new \Idno\Core\Event(); $event->setResponse($url); \Idno\Core\site()->events()->dispatch('url/shorten', $event); $url = $event->response(); if (!in_array($type, ['note', 'reply', 'rsvp', 'like'])) { $share_type = 'note'; if ($content = \Idno\Core\Webservice::get($url)) { if ($mf2 = \Idno\Core\Webmention::parseContent($content['content'])) { if (!empty($mf2['items'])) { foreach ($mf2['items'] as $item) { if (!empty($item['type'])) { if (in_array('h-entry', $item['type'])) { $share_type = 'reply'; } if (in_array('h-event', $item['type'])) { $share_type = 'rsvp'; } } } } } } } else { $share_type = $type; } $content_type = \Idno\Common\ContentType::getRegisteredForIndieWebPostType($share_type); $hide_nav = false; if ($this->getInput('via') == 'ff_social') { $hide_nav = true; } if (!empty($content_type)) { if ($page = \Idno\Core\site()->getPageHandler('/' . $content_type->camelCase($content_type->getEntityClassName()) . '/edit')) { if ($share_type == 'note') { $page->setInput('body', $title . ' ' . $url); } else { $page->setInput('url', $url); if (substr_count($url, 'twitter.com')) { preg_match("|https?://(www\\.)?twitter\\.com/(#!/)?@?([^/]*)|", $url, $matches); if (!empty($matches[3])) { $page->setInput('body', '@' . $matches[3] . ' '); } } } $page->setInput('hidenav', $hide_nav); $page->setInput('sharing', true); $page->setInput('share_type', $share_type); $page->get(); } } else { $t = \Idno\Core\site()->template(); $body = $t->__(['share_type' => $share_type, 'content_type' => $content_type, 'sharing' => true])->draw('entity/share'); $t->__(['title' => 'Share', 'body' => $body, 'hidenav' => $hide_nav])->drawPage(); } }
function test404Page() { $result = Webservice::get(Idno::site()->config()->getURL() . 'this-resource-does-not-exist'); $this->assertEquals(404, $result['response']); }
function getContent() { $this->gatekeeper(); $url = $this->getInput('share_url', $this->getInput('url')); $title = $this->getInput('share_title', $this->getInput('title')); $type = $this->getInput('share_type'); $syndicatedto = []; // remove cruft added by mobile apps if (preg_match('~\\b(?:f|ht)tps?://[^\\s]+\\b~i', $url, $matches)) { $url = $matches[0]; } $event = new \Idno\Core\Event(); $event->setResponse($url); \Idno\Core\Idno::site()->events()->dispatch('url/shorten', $event); $short_url = $event->response(); if (!$type || !\Idno\Common\ContentType::getRegisteredForIndieWebPostType($type)) { $share_type = 'note'; // Probe to see if this is something we can MF2 parse, before we do $headers = []; if ($head = \Idno\Core\Webservice::head($url)) { $headers = http_parse_headers($head['header']); } // Only MF2 Parse supported types if (isset($headers['Content-Type']) && preg_match('/text\\/(html|plain)+/', $headers['Content-Type'])) { if ($response = \Idno\Core\Webservice::get($url)) { if ($mf2 = \Idno\Core\Webmention::parseContent($response['content'])) { if (!empty($mf2['items'])) { foreach ($mf2['items'] as $item) { if (!empty($item['type'])) { if (in_array('h-entry', $item['type'])) { $share_type = 'reply'; } if (in_array('h-event', $item['type'])) { $share_type = 'rsvp'; } } } } } $syndicatedto = \Idno\Core\Webmention::addSyndicatedReplyTargets($url, $syndicatedto, $response); } } } else { $share_type = $type; } $content_type = \Idno\Common\ContentType::getRegisteredForIndieWebPostType($share_type); $hide_nav = false; if ($this->getInput('via') == 'ff_social') { $hide_nav = true; } if (!empty($content_type)) { if ($page = \Idno\Core\Idno::site()->getPageHandler($content_type->getEditURL())) { if ($share_type == 'note') { $page->setInput('body', $title . ' ' . $short_url); } else { $page->setInput('short-url', $short_url); $page->setInput('url', $url); $page->setInput('syndicatedto', $syndicatedto); // prefill the @-name of the person we're replying to $atusers = []; foreach (array_merge((array) $url, (array) $syndicatedto) as $tweeturl) { if (strstr($tweeturl, 'twitter.com') !== false) { if (preg_match("|https?://([a-z]+\\.)?twitter\\.com/(#!/)?@?([^/]*)|", $tweeturl, $matches) && !empty($matches[3])) { $atusers[] = '@' . $matches[3]; } if (preg_match_all("|@([^\\s^\\)]+)|", $title, $matches)) { $atusers = array_merge($atusers, $matches[0]); } } } if ($atusers) { // See if one of your registered twitter handles is present, if so remove it. $user = \Idno\Core\Idno::site()->session()->currentUser(); if (!empty($user->twitter) && is_array($user->twitter)) { $me = []; foreach ($user->twitter as $k => $v) { $me[] = '@' . $k; } $atusers = array_diff($atusers, $me); } } if ($atusers) { $atusers = array_unique($atusers); $page->setInput('body', implode(' ', $atusers) . ' '); } } $page->setInput('hidenav', $hide_nav); $page->setInput('sharing', true); $page->setInput('share_type', $share_type); $page->get(); } } else { $t = \Idno\Core\Idno::site()->template(); $body = $t->__(array('share_type' => $share_type, 'content_type' => $content_type, 'sharing' => true))->draw('entity/share'); $t->__(array('title' => 'Share', 'body' => $body, 'hidenav' => $hide_nav))->drawPage(); } }
function getContent() { $this->gatekeeper(); $url = $this->getInput('share_url', $this->getInput('url')); $title = $this->getInput('share_title', $this->getInput('title')); $type = $this->getInput('share_type'); $event = new \Idno\Core\Event(); $event->setResponse($url); \Idno\Core\site()->events()->dispatch('url/shorten', $event); $short_url = $event->response(); if (!in_array($type, array('note', 'reply', 'rsvp', 'like', 'bookmark'))) { $share_type = 'note'; if ($content = \Idno\Core\Webservice::get($url)) { if ($mf2 = \Idno\Core\Webmention::parseContent($content['content'])) { if (!empty($mf2['items'])) { foreach ($mf2['items'] as $item) { if (!empty($item['type'])) { if (in_array('h-entry', $item['type'])) { $share_type = 'reply'; } if (in_array('h-event', $item['type'])) { $share_type = 'rsvp'; } } } } } } } else { $share_type = $type; } $content_type = \Idno\Common\ContentType::getRegisteredForIndieWebPostType($share_type); $hide_nav = false; if ($this->getInput('via') == 'ff_social') { $hide_nav = true; } if (!empty($content_type)) { if ($page = \Idno\Core\site()->getPageHandler('/' . $content_type->camelCase($content_type->getEntityClassName()) . '/edit')) { if ($share_type == 'note') { $page->setInput('body', $title . ' ' . $short_url); } else { $page->setInput('short-url', $short_url); $page->setInput('url', $url); if (substr_count($url, 'twitter.com')) { $atusers = []; preg_match("|https?://([a-z]+\\.)?twitter\\.com/(#!/)?@?([^/]*)|", $url, $matches); if (!empty($matches[3])) { $atusers[] = '@' . $matches[3]; // $page->setInput('body', '@' . $matches[3] . ' '); } if (preg_match_all("|@([^\\s^\\)]+)|", $title, $matches)) { $atusers = array_merge($atusers, $matches[0]); } // See if one of your registered twitter handles is present, if so remove it. $user = \Idno\Core\site()->session()->currentUser(); if (!empty($user->twitter) && is_array($user->twitter)) { $me = []; foreach ($user->twitter as $k => $v) { $me[] = "@{$k}"; } $atusers = array_diff($atusers, $me); } $atusers = array_unique($atusers); $page->setInput('body', implode(' ', $atusers) . ' '); } } $page->setInput('hidenav', $hide_nav); $page->setInput('sharing', true); $page->setInput('share_type', $share_type); $page->get(); } } else { $t = \Idno\Core\site()->template(); $body = $t->__(array('share_type' => $share_type, 'content_type' => $content_type, 'sharing' => true))->draw('entity/share'); $t->__(array('title' => 'Share', 'body' => $body, 'hidenav' => $hide_nav))->drawPage(); } }
/** * A particularly knotty case when we get a webmention from *our * own* feed. It looks valid because it includes a link, but it's * not really. */ function testAddWebmentions_LocalFeed() { for ($i = 0; $i < 5; $i++) { $entity = new Entity(); $entity->setOwner($this->user()); $entity->title = "This post will be the webmention target"; $entity->publish(); $entities[] = $entity; $this->toDelete[] = $entity; } // take one from the middle $entity = $entities[2]; $source = \Idno\Core\Idno::site()->config()->url; $target = $entity->getURL(); // render the homepage feed $sourceResp = Webservice::get($source); $sourceContent = $sourceResp['content']; $sourceMf2 = (new \Mf2\Parser($sourceContent, $source))->parse(); $entity->addWebmentions($source, $target, $sourceResp, $sourceMf2); $this->assertEmpty($entity->getAllAnnotations()); }
public static function fetch($url) { $result = []; $response = Webservice::get($url); $status = $response['response']; $html = $response['content']; if ($status < 200 || $status >= 300) { $result['status'] = $status; $result['error'] = $response['error']; return $result; } $host = parse_url($url)['host']; if (preg_match('/(www\\.|m\\.)?twitter.com/', $host)) { $parsed = self::parseTwitter($html, $url); } else { $parsed = (new \Mf2\Parser($html, $url))->parse(); } $hentries = \BarnabyWalters\Mf2\findMicroformatsByType($parsed, 'h-entry'); if (!empty($hentries)) { $hentry = $hentries[0]; $author = \BarnabyWalters\Mf2\getAuthor($hentry, $parsed); if (!empty($author)) { if (is_string($author)) { $result['author'] = ['url' => $author]; } else { $result['author'] = ['name' => \BarnabyWalters\Mf2\getPlaintext($author, 'name'), 'url' => \BarnabyWalters\Mf2\getPlaintext($author, 'url')]; } } $name = \BarnabyWalters\Mf2\getPlaintext($hentry, 'name'); $content_plain = \BarnabyWalters\Mf2\getPlaintext($hentry, 'content'); $content_html = \BarnabyWalters\Mf2\getHtml($hentry, 'content'); $result['content'] = $content_html; if (!strstr($name, $content_plain) && !strstr($content_plain, $name)) { $result['name'] = $name; } } else { $doc = new \DOMDocument(); $doc->loadHTML($html); $metas = $doc->getElementsByTagName('meta'); $metaprops = []; foreach ($metas as $meta) { if ($meta->hasAttribute('name')) { $metaprops[$meta->getAttribute('name')] = $meta->getAttribute('content'); } else { if ($meta->hasAttribute('property')) { $metaprops[$meta->getAttribute('property')] = $meta->getAttribute('content'); } } } if (!empty($metaprops['twitter:title'])) { $result['name'] = $metaprops['twitter:title']; } else { if (!empty($metaprops['og:title'])) { $result['name'] = $metaprops['og:title']; } else { $titles = $doc->getElementsByTagName('title'); foreach ($titles as $title) { $result['name'] = $title->nodeValue; break; } } } if (!empty($metaprops['twitter:description'])) { $result['content'] = $metaprops['twitter:description']; } else { if (!empty($metaprops['og:description'])) { $result['content'] = $metaprops['og:description']; } } } $desc = ''; if (!empty($result['author']) && !empty($result['author']['name'])) { $desc .= trim($result['author']['name']) . '\'s '; } if (!empty($result['name'])) { $desc .= preg_replace('/\\s{2,}/', ' ', $result['name']); } else { if (strstr($url, 'twitter.com')) { if ($desc == '') { $desc .= 'a '; } $desc .= 'tweet'; } else { if ($desc == '') { $desc .= 'a '; } $desc .= 'post on ' . preg_replace('/^\\w+:\\/+([^\\/]+).*/', '$1', $url); } } $result['description'] = $desc; return $result; }
/** * Takes an address and returns OpenStreetMap data via Nominatim, including latitude and longitude * * @param string $address * @return array|bool */ static function queryAddress($address, $limit = 1) { $query = self::getNominatimEndpoint() . "search?q=" . urlencode($address) . "&format=json"; $http_response = \Idno\Core\Webservice::get($query)['content']; if (!empty($http_response)) { if ($contents = @json_decode($http_response)) { $contents = (array) $contents; $contents = (array) array_pop($contents); // This will have been an array wrapped in an array $contents['latitude'] = $contents['lat']; $contents['longitude'] = $contents['lon']; return $contents; } } return false; }
function getContent() { $this->gatekeeper(); // Logged-in users only try { if ($linkedin = \Idno\Core\site()->plugins()->get('LinkedIn')) { if ($linkedinAPI = $linkedin->connect()) { if ($response = $linkedinAPI->getAccessToken(\IdnoPlugins\LinkedIn\Main::$TOKEN_ENDPOINT, 'authorization_code', ['code' => $this->getInput('code'), 'redirect_uri' => \IdnoPlugins\LinkedIn\Main::getRedirectUrl(), 'state' => \IdnoPlugins\LinkedIn\Main::getState()])) { /** Catch various errors */ if ($response->error) { throw new \Exception($response->error_description); } // Verify access token if (!$response->access_token) { throw new \Exception('Sorry, access token is unavailable.'); } if ($this->getInput('error') && ($error = $this->getInput('error_description'))) { throw new \Exception($error); } /**/ $user = \Idno\Core\site()->session()->currentUser(); $result = \Idno\Core\Webservice::get('https://api.linkedin.com/v1/people/~:(id,first-name,last-name,site-standard-profile-request)', ['oauth2_access_token' => $response->access_token, 'format' => 'json']); $basic_profile = json_decode($result['content']); if (!$basic_profile->id) { if ($basic_profile->message) { throw new \Exception($basic_profile->message); } else { throw new \Exception("Sorry, there was a problem getting your profile. Does your app have appropriate permissions?"); } } $id = $basic_profile->id; $name = $basic_profile->firstName . ' ' . $basic_profile->lastName; $user->linkedin[$id] = ['access_token' => $response->access_token, 'name' => $name]; // Get company pages if (\Idno\Core\site()->config()->multipleSyndicationAccounts()) { $result = \Idno\Core\Webservice::get('https://api.linkedin.com/v1/companies', array('oauth2_access_token' => $response->access_token, 'format' => 'json', 'is-company-admin' => 'true')); $admin_pages = $result['content']; if (!empty($admin_pages)) { if (!empty($admin_pages->values)) { foreach ($admin_pages->values as $company) { $id = $company['id']; $name = $company['name']; $user->linkedin[$id] = ['access_token' => $response->access_token, 'name' => $name, 'company' => true]; } } } } $user->save(); \Idno\Core\site()->session()->addMessage('Your LinkedIn account was connected.'); } } } } catch (\Exception $e) { \Idno\Core\site()->session()->addErrorMessage($e->getMessage()); } if (!empty($_SESSION['onboarding_passthrough'])) { unset($_SESSION['onboarding_passthrough']); $this->forward(\Idno\Core\site()->config()->getDisplayURL() . 'begin/connect-forwarder'); } $this->forward(\Idno\Core\site()->config()->getDisplayURL() . 'account/linkedin'); }