Browse Source

Rough support for types (likes, replies, etc.)

master
Chimo 4 years ago
parent
commit
3e5a5deb8a
4 changed files with 105 additions and 96 deletions
  1. 2
    1
      composer.json
  2. 30
    4
      get.php
  3. 66
    84
      index.php
  4. 7
    7
      schema.sql

+ 2
- 1
composer.json View File

@@ -1,6 +1,7 @@
1 1
 {
2 2
     "require": {
3 3
         "mf2/mf2": "0.2.10",
4
-        "barnabywalters/mf-cleaner": "0.1.4"
4
+        "barnabywalters/mf-cleaner": "0.1.4",
5
+        "indieweb/comments": "0.1.9"
5 6
     }
6 7
 }

+ 30
- 4
get.php View File

@@ -20,7 +20,7 @@ try {
20 20
     exit('Err');
21 21
 }
22 22
 
23
-$sth = $dbh->prepare('SELECT rendered FROM webmentions WHERE local_url = ? ORDER BY created');
23
+$sth = $dbh->prepare('SELECT * FROM webmentions WHERE local_url = ? ORDER BY published');
24 24
 
25 25
 if ($sth === false) {
26 26
     error_log('Could not prepare SQL statement.');
@@ -36,9 +36,36 @@ if ($res === false) {
36 36
     error_log('Error info: ' . $dbh->errorInfo());
37 37
 }
38 38
 
39
-$data = array();
39
+$data = array(
40
+    'likes' => array(),
41
+    'mentions' => array(),
42
+    'replies'=> array(),
43
+    'reposts' => array(),
44
+    'rsvps' => array()
45
+);
46
+
40 47
 while ($row = $sth->fetch()) {
41
-    $data[] = $row[0];
48
+    switch($row['type']) {
49
+        case "like":
50
+            $data['likes'][] = $row;
51
+            break;
52
+
53
+        case "reply":
54
+            $data['replies'][] = $row;
55
+            break;
56
+
57
+        case "repost":
58
+            $data['reposts'][] = $row;
59
+            break;
60
+
61
+        case "rsvp":
62
+            $data['rsvps'][] = $row;
63
+            break;
64
+
65
+        default:
66
+            $data['mentions'][] = $row;
67
+            break;
68
+    }
42 69
 }
43 70
 
44 71
 $json = json_encode($data);
@@ -46,7 +73,6 @@ $json = json_encode($data);
46 73
 if ($json === false) {
47 74
     header($_SERVER['SERVER_PROTOCOL'] . ' 500 Internal Server Error');
48 75
     exit;
49
-
50 76
 } else {
51 77
     header('Content-Type: application/json');
52 78
     echo $json;

+ 66
- 84
index.php View File

@@ -10,20 +10,24 @@
10 10
 require_once('config.php');
11 11
 require_once('extlib/webmention.php');
12 12
 require_once('vendor/autoload.php');
13
-use BarnabyWalters\Mf2 as Cleaner;
14 13
 
15 14
 /*********
16 15
  * Utils *
17 16
  *********/
18 17
 
19
-function safe($obj, $prop) {
20
-    $unsafe = Cleaner\getPlaintext($obj, $prop, "");
18
+function safe($unsafe) {
21 19
     $unsafe = strip_tags($unsafe);
22 20
     $safe = htmlspecialchars($unsafe, ENT_QUOTES);
23
-
24 21
     return $safe;
25 22
 }
26 23
 
24
+// Returns author info as well as truncated post text suitable for display.
25
+function getWebmention($mf, $url) {
26
+    foreach($mf['items'] as $microformat) {
27
+        return IndieWeb\comments\parse($microformat, $url);
28
+    }
29
+}
30
+
27 31
 $source_url = $_POST['source'];
28 32
 $target_url = $_POST['target'];
29 33
 
@@ -37,12 +41,13 @@ if (parse_url($target_url, PHP_URL_HOST) !== $config["site"]["host"]) {
37 41
     exit("Err");
38 42
 }
39 43
 
40
-// Make sure the page exists
44
+// Make sure the mentioned page exists
41 45
 if (head($target_url) === null) {
42 46
     error_log("Webmention for a page that doesn't exist: " . $target_url, 4);
43 47
     exit("Err");
44 48
 }
45 49
 
50
+// HTTP GET
46 51
 $source_html = get($source_url, $target_url);
47 52
 
48 53
 if ($source_html === null) {
@@ -54,97 +59,74 @@ if ($source_html === null) {
54 59
  * Mf2 stuffs *
55 60
  **************/
56 61
 
57
-// TODO: https://github.com/pear2/Services_Linkback/blob/2afd453254c531925484196670e2953f669ae141/src/PEAR2/Services/Linkback/Server/Callback/LinkExists.php#L40
58
-if (stristr($source_html, $target_url)) {
59
-    $mf = Mf2\parse($source_html, $source_url);
60
-
61
-    // FIXME: Just use the first item -- for testing purposes, at least
62
-    $hEntry = $mf["items"][0];
63
-
64
-    $entry_name = safe($hEntry, 'name');
65
-    $entry_url = $source_url;
66
-    // $entryUrl = safe($hEntry, 'url');
67
-
68
-    if ($entry_name === "") {
69
-        $entry_name = $entry_url;
70
-    }
71
-
72
-    // Truncate this since it could be the entire page
73
-    if (strlen($entry_name) > 150) {
74
-        $entry_name = substr($entry_name, 0, 150) . '[...]';
75
-    }
76
-
77
-    $hCard = Cleaner\getAuthor($hEntry);
78
-    $author_name = safe($hCard, 'name');
79
-    $author_url = safe($hCard, 'url');
80
-
81
-    // Prevent authorship spoofing
82
-    if (parse_url($author_url, PHP_URL_HOST) !== parse_url($source_url, PHP_URL_HOST)) {
83
-        error_log('Author URL host does not match source url host; discarding...', 4);
84
-        error_log('Author URL: ' . $author_url, 4);
85
-        error_log('Source URL: ' . $source_url, 4);
86
-
87
-        $author_url = '';
88
-    }
62
+$mf = Mf2\parse($source_html, $source_url);
89 63
 
90
-    if ($author_name !== '') {
91
-        $by = 'by ' . $author_name;
64
+$webmention = getWebmention($mf, $target_url);
92 65
 
93
-        if ($author_url !== '') {
94
-            $by = 'by <a href="' . $author_url . '">' . $author_name . '</a>';
95
-        }
96
-    }
66
+// FIXME:
67
+//      https://github.com/pear2/Services_Linkback/blob/2afd453254c531925484196670e2953f669ae141/src/PEAR2/Services/Linkback/Server/Callback/LinkExists.php#L40
68
+//      https://github.com/indieweb/php-mf2/blob/master/Mf2/Parser.php#L966
69
+//      https://stackoverflow.com/questions/2087103/how-to-get-innerhtml-of-domnode
70
+if (!stristr($source_html, $target_url) || $webmention === null) {
71
+    error_log("Fake webmention from: " . $source_url, 4);
72
+    exit("Fake");
73
+}
97 74
 
98
-    $on = '<a href="' . $entry_url . '">' . $entry_name . '</a>' ;
75
+/*************
76
+ * DB Stuffs *
77
+ *************/
99 78
 
100
-    /*************
101
-     * DB Stuffs *
102
-     *************/
79
+$dsn = 'mysql:dbname=' . $config['db']['name'] . ';host=' . $config['db']['host'];
80
+$user = $config['db']['username'];
81
+$password = $config['db']['password'];
103 82
 
104
-    $dsn = 'mysql:dbname=' . $config['db']['name'] . ';host=' . $config['db']['host'];
105
-    $user = $config['db']['username'];
106
-    $password = $config['db']['password'];
83
+try {
84
+    $dbh = new PDO($dsn, $user, $password);
85
+} catch (PDOException $e) {
86
+    error_log('Connection failed: ' . $e->getMessage(), 4);
87
+    exit("Err");
88
+}
107 89
 
108
-    try {
109
-        $dbh = new PDO($dsn, $user, $password);
110
-    } catch (PDOException $e) {
111
-        error_log('Connection failed: ' . $e->getMessage(), 4);
112
-        exit("Err");
113
-    }
90
+$sth = $dbh->prepare(
91
+    'INSERT INTO webmentions (local_url, url, name, text, author_name, author_url, type) ' .
92
+    'VALUES(?, ?, ?, ?, ?, ?, ?)'
93
+);
114 94
 
115
-    $rendered = 'This page has been mentioned ' . $by . ' on ' . $on;
95
+if ($sth === false) {
96
+    error_log("Could not prepare SQL statement.");
97
+    error_log("Error code: " . $dbh->errorCode());
98
+    error_log("Error info: " . $dbh->errorInfo());
99
+}
116 100
 
117
-    $sth = $dbh->prepare(
118
-        'INSERT INTO webmentions (local_url, remote_url, remote_name, remote_author, remote_author_url, rendered) ' .
119
-        'VALUES(?, ?, ?, ?, ?, ?)'
120
-    );
101
+$remote_url = safe(($webmention['url'] !== false) ? $webmention['url'] : $source_url);
121 102
 
122
-    if ($sth === false) {
123
-        error_log("Could not prepare SQL statement.");
124
-        error_log("Error code: " . $dbh->errorCode());
125
-        error_log("Error info: " . $dbh->errorInfo());
126
-    }
103
+// Prevent authorship spoofing
104
+// FIXME: make better.
105
+$author_url = $webmention['author']['url'];
106
+if (parse_url($author_url, PHP_URL_HOST) !== parse_url($source_url, PHP_URL_HOST)) {
107
+    error_log('Author URL host does not match source url host; discarding...', 4);
108
+    error_log('Author URL: ' . $author_url, 4);
109
+    error_log('Source URL: ' . $source_url, 4);
110
+    $author_url = '';
111
+}
127 112
 
128
-    $res = $sth->execute(array(
129
-        $target_url,
130
-        $entry_url,
131
-        $entry_name,
132
-        $author_name,
133
-        $author_url,
134
-        $rendered
135
-    ));
136
-
137
-    if ($res === false) {
138
-        error_log("Could not execute SQL query.");
139
-        error_log("Error code: " . $dbh->errorCode());
140
-        error_log("Error info: " . $dbh->errorInfo());
141
-    }
113
+$res = $sth->execute(array(
114
+    $target_url,
115
+    $remote_url,
116
+    safe($webmention['name']),
117
+    safe($webmention['text']),
118
+    safe($webmention['author']['name']),
119
+    safe($author_url),
120
+    safe($webmention['type'])
121
+));
122
+
123
+if ($res === false) {
124
+    error_log("Could not execute SQL query.");
125
+    error_log("Error code: " . $dbh->errorCode());
126
+    error_log("Error info: " . print_r($dbh->errorInfo(), true));
142 127
 
143 128
     error_log(
144
-        $rendered,
129
+        print_r($webmention, true),
145 130
         4
146 131
     );
147
-
148
-} else {
149
-    error_log("Fake webmention from: " . $source_url, 4);
150 132
 }

+ 7
- 7
schema.sql View File

@@ -1,12 +1,12 @@
1 1
 CREATE TABLE `webmentions` (
2 2
     `id` int(11) NOT NULL AUTO_INCREMENT,
3 3
     `local_url` text NOT NULL,
4
-    `remote_url` text NOT NULL,
5
-    `remote_name` varchar(255) NOT NULL,
6
-    `remote_author` varchar(255),
7
-    `remote_author_url` text,
8
-    `rendered` text NOT NULL,
9
-    `created` datetime NOT NULL DEFAULT NOW(),
10
-    `last_checked` datetime NOT NULL DEFAULT NOW(),
4
+    `url` text NOT NULL,
5
+    `name` varchar(255),
6
+    `text` text NOT NULL,
7
+    `author_name` varchar(255),
8
+    `author_url` text,
9
+    `type` varchar(255),
10
+    `published` datetime NOT NULL DEFAULT NOW(),
11 11
     PRIMARY KEY (`id`)
12 12
 ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;

Loading…
Cancel
Save