Extract final post URL after creation
authorChristian Weiske <cweiske@cweiske.de>
Tue, 23 May 2017 15:16:41 +0000 (17:16 +0200)
committerChristian Weiske <cweiske@cweiske.de>
Tue, 23 May 2017 15:16:41 +0000 (17:16 +0200)
commentform.phtml
init.css [deleted file]
init.php
settings.phtml

index f6282c9..adf0af2 100644 (file)
@@ -7,13 +7,19 @@
   <input type="hidden" name="mode"   value="post"/>
 
   <input type="hidden" name="replyTo" value="<?= htmlspecialchars($article['link']) ?>"/>
-  <label for="micropub-me">Identity:</label>
-  <select id="micropub-me" name="me" size="1">
-   <?php foreach ($accounts as $url) { ?>
-    <option value="<?= htmlspecialchars($url) ?>"><?= htmlspecialchars($url) ?></option>
-   <?php } ?>
-  </select><br/>
-  <textarea name="content" rows="4" cols="60"></textarea><br/>
+
+  <?php if (count($accounts) == 1) { ?>
+   <input type="hidden" name="me" value="<?= htmlspecialchars(reset($accounts)) ?>"/>
+  <?php } else { ?>
+   <label for="micropub-me">Identity:</label>
+   <select id="micropub-me" name="me" size="1">
+    <?php foreach ($accounts as $url) { ?>
+     <option value="<?= htmlspecialchars($url) ?>"><?= htmlspecialchars($url) ?></option>
+    <?php } ?>
+   </select><br/>
+  <?php } ?>
+
+  <textarea name="content" rows="4" cols="60" width="100%" class="dijitTextArea"></textarea><br/>
   <button type="submit">Post comment</button>
  </form>
 </div>
diff --git a/init.css b/init.css
deleted file mode 100644 (file)
index e69de29..0000000
index 986266d..863608c 100644 (file)
--- a/init.php
+++ b/init.php
@@ -55,11 +55,6 @@ class Micropub extends Plugin implements IHandler
         );
     }
 
-    function get_css()
-    {
-        return file_get_contents(__DIR__ . '/init.css');
-    }
-
     /**
      * @param array $article Article data. Keys:
      *                       - id
@@ -89,7 +84,10 @@ class Micropub extends Plugin implements IHandler
         // did I tell you I hate dojo/dijit?
 
         $accounts = array_keys(PluginHost::getInstance()->get($this, 'accounts', []));
-
+        if (!count($accounts)) {
+            return $article;
+        }
+        array_shift($accounts);
         ob_start();
         include __DIR__ . '/commentform.phtml';
         $html = ob_get_clean();
@@ -114,6 +112,7 @@ class Micropub extends Plugin implements IHandler
 
         $accounts = PluginHost::getInstance()->get($this, 'accounts', []);
 
+        //FIXME: default identity
         include __DIR__ . '/settings.phtml';
     }
 
@@ -130,6 +129,12 @@ class Micropub extends Plugin implements IHandler
         return $this->action($mode, $args);
     }
 
+    /**
+     * HTTP command.
+     * Also used by micropub() cli command method.
+     *
+     * /backend.php?op=pluginhandler&plugin=micropub&method=action
+     */
     public function action($mode = null, $args = [])
     {
         if (isset($_POST['mode'])) {
@@ -145,7 +150,7 @@ class Micropub extends Plugin implements IHandler
         } else if ($mode == 'post') {
             return $this->postAction();
         } else {
-            $this->errorOut('Unsupported mode');
+            return $this->errorOut('Unsupported mode');
         }
     }
 
@@ -180,14 +185,13 @@ class Micropub extends Plugin implements IHandler
             return $this->errorOut('No micropub endpoint found');
         }
 
-        $res = fetch_file_contents(
-            [
-                //FIXME: add content-type header once this is fixed:
-                // https://discourse.tt-rss.org/t//207
-                'url'        => $links['micropub'],
-                //we use http_build_query to force cURL
-                // to use x-www-form-urlencoded
-                'post_query' => http_build_query(
+        /* 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',
@@ -195,20 +199,49 @@ class Micropub extends Plugin implements IHandler
                         'content'      => $content,
                     ]
                 ),
-                'followlocation' => false,
+                'ignore_errors' => true,
             ]
+        ];
+        $stream = fopen(
+            $links['micropub'], 'r', false,
+            stream_context_create($opts)
         );
-
-        if ($GLOBALS['fetch_last_error_code'] == 201) {
-            //FIXME: extract location header
-            echo "OK, comment post created\n";
-        } else {
-            $this->errorOut(
+        $meta    = stream_get_meta_data($stream);
+        $headers = $meta['wrapper_data'];
+        $content = stream_get_contents($stream);
+
+        //we hope there were no redirects and this is actually the only
+        // HTTP line in the headers
+        $status = array_shift($headers);
+        list($httpver, $code, $text) = explode(' ', $status, 3);
+        if ($code != 201 && $code != 202) {
+            return $this->errorOut(
                 'An error occured: '
-                . $GLOBALS['fetch_last_error_code']
-                . ' ' . $GLOBALS['fetch_last_error_code_content']
+                . $code . ' ' . $text
             );
         }
+
+        $location = null;
+        foreach ($headers as $header) {
+            $parts = explode(':', $header, 2);
+            if (count($parts) == 2 && strtolower($parts[0]) == 'location') {
+                $location = trim($parts[1]);
+            }
+        }
+        if ($location === null) {
+            return $this->errorOut(
+                'Location header missing in successful creation response.'
+            );
+        }
+
+        header('Content-type: application/json');
+        echo json_encode(
+            [
+                'code'     => intval($code),
+                'location' => $location,
+            ]
+        );
+        exit();
     }
 
     protected function authorizeAction($args = [])
@@ -316,12 +349,39 @@ class Micropub extends Plugin implements IHandler
         header('Location: prefs.php');
     }
 
+    /**
+     * Send an error message.
+     * Automatically in the correct format (plain text or json)
+     *
+     * @param string $msg Error message
+     *
+     * @return void
+     */
     protected function errorOut($msg)
     {
-        echo $msg . "\n";
+        header('HTTP/1.0 400 Bad Request');
+
+        //this does not take "q"uality values into account, I know.
+        if (isset($_SERVER['HTTP_ACCEPT'])
+            && strpos($_SERVER['HTTP_ACCEPT'], 'application/json') !== false
+        ) {
+            //send json error
+            header('Content-type: application/json');
+            echo json_encode(
+                [
+                    'error' => $msg,
+                ]
+            );
+        } else {
+            header('Content-type: text/plain');
+            echo $msg . "\n";
+        }
         exit(1);
     }
 
+    /**
+     * Extract link relations from a given URL
+     */
     protected function getLinks($url)
     {
         //FIXME: HTTP Link header support with HTTP2
index 6783d21..a06f2ea 100644 (file)
@@ -1,14 +1,22 @@
 <div dojoType="dijit.layout.AccordionPane" title="Micropub">
  <div>
-  <h1>Existing identities</h1>
-  <table border="1">
+  <h2>Registered identities</h2>
+  <table width="100%">
    <thead>
-    <tr><th>Identity URL</th></tr>
+    <tr class="title">
+     <td width="5%">Default</td>
+     <td>Identity URL</td>
+    </tr>
    </thead>
    <tbody>
     <?php foreach ($accounts as $accurl => $account) { ?>
      <tr>
-      <td><?= $accurl ?></td>
+      <td align='center'>
+       <input disabled='1' dojoType="dijit.form.CheckBox" type="checkbox"/>
+      </td>
+      <td>
+       <a href="<?= htmlspecialchars($accurl) ?>"><?= htmlspecialchars($accurl) ?></a>
+      </td>
      </tr>
     <?php } ?>
    </tbody>
  </div>
 
  <div>
-  <h1>Add new identity</h1>
+  <h2>Add new identity</h2>
   <form method="post" action="backend.php">
    <input type="hidden" name="op" value="pluginhandler"/>
    <input type="hidden" name="plugin" value="micropub"/>
    <input type="hidden" name="method" value="action"/>
    <input type="hidden" name="mode"   value="authorize"/>
 
-   <input name="url" type="url" size="40"/>
+   <input name="url" type="url" size="40" dojoType="dijit.form.TextBox" required="1"/>
    <button type="submit">Authorize</button>
   </form>
  </div>