Handle HTTP errors when extracting links
[tt-rss-micropub.git] / init.php
index 5b26c226820075474a8fb7d149c537acd6cf3e59..3d8008fe4dd1ecb87810b42c79c4e4faf22d332d 100644 (file)
--- a/init.php
+++ b/init.php
@@ -185,30 +185,49 @@ class Micropub extends Plugin implements IHandler
         }
     }
 
+    /**
+     * Post a comment, like or bookmark via micropub
+     */
     protected function postAction()
     {
-        if (!isset($_POST['me'])) {
-            return $this->errorOut('"me" parameter missing');
+        $action = 'comment';
+        if (isset($_POST['action'])) {
+            $action = trim($_POST['action']);
         }
-        $me = trim($_POST['me']);
-
-        if (!isset($_POST['replyTo'])) {
-            return $this->errorOut('"replyTo" parameter missing');
+        if (array_search($action, ['bookmark', 'comment', 'like']) === false) {
+            return $this->errorOut('"action" parameter invalid');
         }
-        $replyTo = trim($_POST['replyTo']);
 
-        if (!isset($_POST['content'])) {
-            return $this->errorOut('"content" parameter missing');
+        if (!isset($_POST['me'])) {
+            return $this->errorOut('"me" parameter missing');
         }
-        $content = trim($_POST['content']);
-
+        $me = trim($_POST['me']);
         $accounts = PluginHost::getInstance()->get($this, 'accounts', []);
         if (!isset($accounts[$me])) {
             return $this->errorOut('"me" parameter invalid');
         }
         $account = $accounts[$me];
 
+        if (!isset($_POST['postUrl'])) {
+            return $this->errorOut('"postUrl" parameter missing');
+        }
+        $postUrl = trim($_POST['postUrl']);
+
+        if ($action == 'comment') {
+            if (!isset($_POST['content'])) {
+                return $this->errorOut('"content" parameter missing');
+            }
+            $content = trim($_POST['content']);
+            if (!strlen($_POST['content'])) {
+                return $this->errorOut('"content" is empty');
+            }
+        }
+
+
         $links = $this->getLinks($me);
+        if ($links === false) {
+            return $this->errorOut('Error fetching URL: ' . $me);
+        }
         if (!count($links)) {
             return $this->errorOut('No links found');
         }
@@ -216,20 +235,30 @@ class Micropub extends Plugin implements IHandler
             return $this->errorOut('No micropub endpoint found');
         }
 
+        $parameters = [
+            'access_token' => $account['access_token'],
+            'h'            => 'entry',
+        ];
+
+        if ($action == 'bookmark') {
+            $parameters['bookmark-of'] = $postUrl;
+
+        } else if ($action == 'comment') {
+            $parameters['in-reply-to'] = $postUrl;
+            $parameters['content']     = $content;
+
+        } else if ($action == 'like') {
+            $parameters['like-of'] = $postUrl;
+        }
+
+
         /* unfortunately fetch_file_contents() does not return headers
            so we have to bring our own way to POST data */
         $opts = [
             'http' => [
                 'method'  => 'POST',
                 'header'  => 'Content-type: application/x-www-form-urlencoded',
-                'content' => http_build_query(
-                    [
-                        'access_token' => $account['access_token'],
-                        'h'            => 'entry',
-                        'in-reply-to'  => $replyTo,
-                        'content'      => $content,
-                    ]
-                ),
+                'content' => http_build_query($parameters),
                 'ignore_errors' => true,
             ]
         ];
@@ -246,9 +275,18 @@ class Micropub extends Plugin implements IHandler
         $status = array_shift($headers);
         list($httpver, $code, $text) = explode(' ', $status, 3);
         if ($code != 201 && $code != 202) {
+            $errData = json_decode($content);
+            if (isset($errData->error_description)
+                && $errData->error_description != ''
+            ) {
+                return $this->errorOut(
+                    'Error creating post: '
+                    . $errData->error_description
+                );
+            }
             return $this->errorOut(
-                'An error occured: '
-                . $code . ' ' . $text
+                'Error creating post: '
+                . $code . ' ' . $text.$content
             );
         }
 
@@ -290,6 +328,9 @@ class Micropub extends Plugin implements IHandler
         //step 1: micropub discovery
         $links = $this->getLinks($url);
 
+        if ($links === false) {
+            return $this->errorOut('Error fetching URL: ' . $url);
+        }
         if (!count($links)) {
             return $this->errorOut('No links found');
         }
@@ -330,6 +371,9 @@ class Micropub extends Plugin implements IHandler
         }
 
         $links = $this->getLinks($_GET['me']);
+        if ($links === false) {
+            return $this->errorOut('Error fetching URL: ' . $_GET['me']);
+        }
         if (!isset($links['token_endpoint'])) {
             return $this->errorOut('No token endpoint found');
         }
@@ -504,6 +548,10 @@ class Micropub extends Plugin implements IHandler
 
     /**
      * Extract link relations from a given URL
+     *
+     * @param string $url URL to extract links from
+     *
+     * @return bool|array Array of links, or false on HTTP error
      */
     protected function getLinks($url)
     {
@@ -513,6 +561,10 @@ class Micropub extends Plugin implements IHandler
                 'url' => $url,
             ]
         );
+        if ($html === false) {
+            return false;
+        }
+
         //Loading invalid HTML is tedious.
         // quick hack with regex. yay!
         preg_match_all('#<link[^>]+?>#', $html, $matches);