]> git.mxchange.org Git - friendica-addons.git/blob - tumblr/tumblr.php
fb844ffb70fa1992b1dfe54c9af4dbd8638d9bbb
[friendica-addons.git] / tumblr / tumblr.php
1 <?php
2 /**
3  * Name: Tumblr Post Connector
4  * Description: Post to Tumblr
5  * Version: 2.0
6  * Author: Mike Macgirvin <http://macgirvin.com/profile/mike>
7  * Author: Michael Vogel <https://pirati.ca/profile/heluecht>
8  */
9
10 require_once __DIR__ . DIRECTORY_SEPARATOR . 'library' . DIRECTORY_SEPARATOR . 'tumblroauth.php';
11
12 use Friendica\Content\Text\BBCode;
13 use Friendica\Core\Hook;
14 use Friendica\Core\Logger;
15 use Friendica\Core\Renderer;
16 use Friendica\DI;
17 use Friendica\Model\Item;
18 use Friendica\Model\Post;
19 use Friendica\Model\Tag;
20
21 function tumblr_install()
22 {
23         Hook::register('hook_fork',               'addon/tumblr/tumblr.php', 'tumblr_hook_fork');
24         Hook::register('post_local',              'addon/tumblr/tumblr.php', 'tumblr_post_local');
25         Hook::register('notifier_normal',         'addon/tumblr/tumblr.php', 'tumblr_send');
26         Hook::register('jot_networks',            'addon/tumblr/tumblr.php', 'tumblr_jot_nets');
27         Hook::register('connector_settings',      'addon/tumblr/tumblr.php', 'tumblr_settings');
28         Hook::register('connector_settings_post', 'addon/tumblr/tumblr.php', 'tumblr_settings_post');
29 }
30
31 /**
32  * This is a statement rather than an actual function definition. The simple
33  * existence of this method is checked to figure out if the addon offers a
34  * module.
35  */
36 function tumblr_module()
37 {
38 }
39
40 function tumblr_content()
41 {
42         if (!DI::userSession()->getLocalUserId()) {
43                 DI::sysmsg()->addNotice(DI::l10n()->t('Permission denied.'));
44                 return '';
45         }
46
47         if (isset(DI::args()->getArgv()[1])) {
48                 switch (DI::args()->getArgv()[1]) {
49                         case 'connect':
50                                 $o = tumblr_connect();
51                                 break;
52
53                         case 'callback':
54                                 $o = tumblr_callback();
55                                 break;
56
57                         default:
58                                 $o = print_r(DI::args()->getArgv(), true);
59                                 break;
60                 }
61         } else {
62                 $o = tumblr_connect();
63         }
64
65         return $o;
66 }
67
68 function tumblr_addon_admin(string &$o)
69 {
70         $t = Renderer::getMarkupTemplate('admin.tpl', 'addon/tumblr/');
71
72         $o = Renderer::replaceMacros($t, [
73                 '$submit' => DI::l10n()->t('Save Settings'),
74                 // name, label, value, help, [extra values]
75                 '$consumer_key' => ['consumer_key', DI::l10n()->t('Consumer Key'), DI::config()->get('tumblr', 'consumer_key'), ''],
76                 '$consumer_secret' => ['consumer_secret', DI::l10n()->t('Consumer Secret'), DI::config()->get('tumblr', 'consumer_secret'), ''],
77         ]);
78 }
79
80 function tumblr_addon_admin_post()
81 {
82         DI::config()->set('tumblr', 'consumer_key', trim($_POST['consumer_key'] ?? ''));
83         DI::config()->set('tumblr', 'consumer_secret', trim($_POST['consumer_secret'] ?? ''));
84 }
85
86 function tumblr_connect()
87 {
88         // Start a session.  This is necessary to hold on to  a few keys the callback script will also need
89         session_start();
90
91         // Define the needed keys
92         $consumer_key = DI::config()->get('tumblr', 'consumer_key');
93         $consumer_secret = DI::config()->get('tumblr', 'consumer_secret');
94
95         // The callback URL is the script that gets called after the user authenticates with tumblr
96         // In this example, it would be the included callback.php
97         $callback_url = DI::baseUrl() . '/tumblr/callback';
98
99         // Let's begin.  First we need a Request Token.  The request token is required to send the user
100         // to Tumblr's login page.
101
102         // Create a new instance of the TumblrOAuth library.  For this step, all we need to give the library is our
103         // Consumer Key and Consumer Secret
104         $tum_oauth = new TumblrOAuth($consumer_key, $consumer_secret);
105
106         // Ask Tumblr for a Request Token.  Specify the Callback URL here too (although this should be optional)
107         $request_token = $tum_oauth->getRequestToken($callback_url);
108
109         // Store the request token and Request Token Secret as out callback.php script will need this
110         $_SESSION['request_token'] = $token = $request_token['oauth_token'];
111         $_SESSION['request_token_secret'] = $request_token['oauth_token_secret'];
112
113         // Check the HTTP Code.  It should be a 200 (OK), if it's anything else then something didn't work.
114         switch ($tum_oauth->http_code) {
115                 case 200:
116                         // Ask Tumblr to give us a special address to their login page
117                         $url = $tum_oauth->getAuthorizeURL($token);
118
119                         // Redirect the user to the login URL given to us by Tumblr
120                         header('Location: ' . $url);
121
122                         /*
123                          * That's it for our side.  The user is sent to a Tumblr Login page and
124                          * asked to authroize our app.  After that, Tumblr sends the user back to
125                          * our Callback URL (callback.php) along with some information we need to get
126                          * an access token.
127                          */
128                         break;
129
130                 default:
131                         // Give an error message
132                         $o = 'Could not connect to Tumblr. Refresh the page or try again later.';
133         }
134
135         return $o;
136 }
137
138 function tumblr_callback()
139 {
140         // Start a session, load the library
141         session_start();
142
143         // Define the needed keys
144         $consumer_key = DI::config()->get('tumblr', 'consumer_key');
145         $consumer_secret = DI::config()->get('tumblr', 'consumer_secret');
146
147         // Once the user approves your app at Tumblr, they are sent back to this script.
148         // This script is passed two parameters in the URL, oauth_token (our Request Token)
149         // and oauth_verifier (Key that we need to get Access Token).
150         // We'll also need out Request Token Secret, which we stored in a session.
151
152         // Create instance of TumblrOAuth.
153         // It'll need our Consumer Key and Secret as well as our Request Token and Secret
154         $tum_oauth = new TumblrOAuth($consumer_key, $consumer_secret, $_SESSION['request_token'], $_SESSION['request_token_secret']);
155
156         // Ok, let's get an Access Token. We'll need to pass along our oauth_verifier which was given to us in the URL.
157         $access_token = $tum_oauth->getAccessToken($_REQUEST['oauth_verifier']);
158
159         // We're done with the Request Token and Secret so let's remove those.
160         unset($_SESSION['request_token']);
161         unset($_SESSION['request_token_secret']);
162
163         // Make sure nothing went wrong.
164         if (200 == $tum_oauth->http_code) {
165                 // good to go
166         } else {
167                 return 'Unable to authenticate';
168         }
169
170         // What's next?  Now that we have an Access Token and Secret, we can make an API call.
171         DI::pConfig()->set(DI::userSession()->getLocalUserId(), 'tumblr', 'oauth_token', $access_token['oauth_token']);
172         DI::pConfig()->set(DI::userSession()->getLocalUserId(), 'tumblr', 'oauth_token_secret', $access_token['oauth_token_secret']);
173
174         $o = DI::l10n()->t('You are now authenticated to tumblr.');
175         $o .= '<br /><a href="' . DI::baseUrl() . '/settings/connectors">' . DI::l10n()->t("return to the connector page") . '</a>';
176
177         return $o;
178 }
179
180 function tumblr_jot_nets(array &$jotnets_fields)
181 {
182         if (!DI::userSession()->getLocalUserId()) {
183                 return;
184         }
185
186         if (DI::pConfig()->get(DI::userSession()->getLocalUserId(), 'tumblr', 'post')) {
187                 $jotnets_fields[] = [
188                         'type' => 'checkbox',
189                         'field' => [
190                                 'tumblr_enable',
191                                 DI::l10n()->t('Post to Tumblr'),
192                                 DI::pConfig()->get(DI::userSession()->getLocalUserId(), 'tumblr', 'post_by_default')
193                         ]
194                 ];
195         }
196 }
197
198 function tumblr_settings(array &$data)
199 {
200         if (!DI::userSession()->getLocalUserId()) {
201                 return;
202         }
203
204         $enabled     = DI::pConfig()->get(DI::userSession()->getLocalUserId(), 'tumblr', 'post', false);
205         $def_enabled = DI::pConfig()->get(DI::userSession()->getLocalUserId(), 'tumblr', 'post_by_default', false);
206
207         $oauth_token        = DI::pConfig()->get(DI::userSession()->getLocalUserId(), 'tumblr', 'oauth_token');
208         $oauth_token_secret = DI::pConfig()->get(DI::userSession()->getLocalUserId(), 'tumblr', 'oauth_token_secret');
209
210         if ($oauth_token && $oauth_token_secret) {
211                 $page            = DI::pConfig()->get(DI::userSession()->getLocalUserId(), 'tumblr', 'page');
212                 $consumer_key    = DI::config()->get('tumblr', 'consumer_key');
213                 $consumer_secret = DI::config()->get('tumblr', 'consumer_secret');
214
215                 $tum_oauth = new TumblrOAuth($consumer_key, $consumer_secret, $oauth_token, $oauth_token_secret);
216                 $userinfo  = $tum_oauth->get('user/info');
217
218                 $blogs = array_map(function ($blog) {
219                         return substr(str_replace(['http://', 'https://'], ['', ''], $blog->url), 0, -1);
220                 }, $userinfo->response->user->blogs);
221
222                 $page_select = ['tumblr-page', DI::l10n()->t('Post to page:'), $page, '', $blogs];
223         }
224
225         $t    = Renderer::getMarkupTemplate('connector_settings.tpl', 'addon/tumblr/');
226         $html = Renderer::replaceMacros($t, [
227                 '$l10n' => [
228                         'connect'   => DI::l10n()->t('(Re-)Authenticate your tumblr page'),
229                         'noconnect' => DI::l10n()->t('You are not authenticated to tumblr'),
230                 ],
231
232                 '$authenticate_url' => DI::baseUrl() . '/tumblr/connect',
233
234                 '$enable'      => ['tumblr', DI::l10n()->t('Enable Tumblr Post Addon'), $enabled],
235                 '$bydefault'   => ['tumblr_bydefault', DI::l10n()->t('Post to Tumblr by default'), $def_enabled],
236                 '$page_select' => $page_select ?? '',
237         ]);
238
239         $data = [
240                 'connector' => 'tumblr',
241                 'title'     => DI::l10n()->t('Tumblr Export'),
242                 'image'     => 'images/tumblr.png',
243                 'enabled'   => $enabled,
244                 'html'      => $html,
245         ];
246 }
247
248 function tumblr_settings_post(array &$b)
249 {
250         if (!empty($_POST['tumblr-submit'])) {
251                 DI::pConfig()->set(DI::userSession()->getLocalUserId(), 'tumblr', 'post',            intval($_POST['tumblr']));
252                 DI::pConfig()->set(DI::userSession()->getLocalUserId(), 'tumblr', 'page',            $_POST['tumblr_page']);
253                 DI::pConfig()->set(DI::userSession()->getLocalUserId(), 'tumblr', 'post_by_default', intval($_POST['tumblr_bydefault']));
254         }
255 }
256
257 function tumblr_hook_fork(array &$b)
258 {
259         if ($b['name'] != 'notifier_normal') {
260                 return;
261         }
262
263         $post = $b['data'];
264
265         if (
266                 $post['deleted'] || $post['private'] || ($post['created'] !== $post['edited']) ||
267                 !strstr($post['postopts'] ?? '', 'tumblr') || ($post['parent'] != $post['id'])
268         ) {
269                 $b['execute'] = false;
270                 return;
271         }
272 }
273
274 function tumblr_post_local(array &$b)
275 {
276         // This can probably be changed to allow editing by pointing to a different API endpoint
277
278         if ($b['edit']) {
279                 return;
280         }
281
282         if (!DI::userSession()->getLocalUserId() || (DI::userSession()->getLocalUserId() != $b['uid'])) {
283                 return;
284         }
285
286         if ($b['private'] || $b['parent']) {
287                 return;
288         }
289
290         $tmbl_post   = intval(DI::pConfig()->get(DI::userSession()->getLocalUserId(), 'tumblr', 'post'));
291
292         $tmbl_enable = (($tmbl_post && !empty($_REQUEST['tumblr_enable'])) ? intval($_REQUEST['tumblr_enable']) : 0);
293
294         if ($b['api_source'] && intval(DI::pConfig()->get(DI::userSession()->getLocalUserId(), 'tumblr', 'post_by_default'))) {
295                 $tmbl_enable = 1;
296         }
297
298         if (!$tmbl_enable) {
299                 return;
300         }
301
302         if (strlen($b['postopts'])) {
303                 $b['postopts'] .= ',';
304         }
305
306         $b['postopts'] .= 'tumblr';
307 }
308
309 function tumblr_send(array &$b)
310 {
311
312         if ($b['deleted'] || $b['private'] || ($b['created'] !== $b['edited'])) {
313                 return;
314         }
315
316         if (!strstr($b['postopts'], 'tumblr')) {
317                 return;
318         }
319
320         if ($b['gravity'] != Item::GRAVITY_PARENT) {
321                 return;
322         }
323
324         $b['body'] = Post\Media::addAttachmentsToBody($b['uri-id'], DI::contentItem()->addSharedPost($b));
325
326         $oauth_token = DI::pConfig()->get($b['uid'], 'tumblr', 'oauth_token');
327         $oauth_token_secret = DI::pConfig()->get($b['uid'], 'tumblr', 'oauth_token_secret');
328         $page = DI::pConfig()->get($b['uid'], 'tumblr', 'page');
329         $tmbl_blog = 'blog/' . $page . '/post';
330
331         if ($oauth_token && $oauth_token_secret && $tmbl_blog) {
332                 $tags = Tag::getByURIId($b['uri-id']);
333
334                 $tag_arr = [];
335
336                 foreach ($tags as $tag) {
337                         $tag_arr[] = $tag['name'];
338                 }
339
340                 if (count($tag_arr)) {
341                         $tags = implode(',', $tag_arr);
342                 }
343
344                 $title = trim($b['title']);
345
346                 $media = Post\Media::getByURIId($b['uri-id'], [Post\Media::HTML, Post\Media::AUDIO, Post\Media::VIDEO, Post\Media::IMAGE]);
347
348                 $photo = array_search(Post\Media::IMAGE, array_column($media, 'type'));
349                 $link  = array_search(Post\Media::HTML, array_column($media, 'type'));
350                 $audio = array_search(Post\Media::AUDIO, array_column($media, 'type'));
351                 $video = array_search(Post\Media::VIDEO, array_column($media, 'type'));
352
353                 $params = [
354                         'state'  => 'published',
355                         'tags'   => $tags,
356                         'tweet'  => 'off',
357                         'format' => 'html',
358                 ];
359
360                 $body = BBCode::removeShareInformation($b['body']);
361
362                 if ($photo != false) {
363                         $params['type'] = 'photo';
364                         if (!empty($body)) {
365                                 $params['caption'] = BBCode::convertForUriId($b['uri-id'], $body, BBCode::CONNECTORS);
366                         } elseif (!empty($params['caption'])) {
367                                 $params['caption'] = $media[$photo]['description'];
368                         }
369                         $params['source'] = $media[$photo]['url'];
370                 } elseif ($link != false) {
371                         $params['type']        = 'link';
372                         $params['title']       = $media[$link]['name'];
373                         $params['url']         = $media[$link]['url'];
374                         $params['description'] = BBCode::convertForUriId($b['uri-id'], $body, BBCode::CONNECTORS);
375
376                         if (!empty($media[$link]['preview'])) {
377                                 $params['thumbnail'] = $media[$link]['preview'];
378                         }
379                         if (!empty($media[$link]['description'])) {
380                                 $params['excerpt'] = $media[$link]['description'];
381                         }
382                         if (!empty($media[$link]['author-name'])) {
383                                 $params['author'] = $media[$link]['author-name'];
384                         } elseif (!empty($media[$link]['publisher-name'])) {
385                                 $params['author'] = $media[$link]['publisher-name'];
386                         }
387                 } elseif ($audio != false) {
388                         $params['type']         = 'audio';
389                         $params['external_url'] = $media[$audio]['url'];
390                         $params['caption']      = BBCode::convertForUriId($b['uri-id'], $body, BBCode::CONNECTORS);
391                 } elseif ($video != false) {
392                         $params['type']    = 'video';
393                         $params['embed']   = $media[$video]['url'];
394                         $params['caption'] = BBCode::convertForUriId($b['uri-id'], $body, BBCode::CONNECTORS);
395                 } else {
396                         $params['type']  = 'text';
397                         $params['title'] = $title;
398                         $params['body']  = BBCode::convertForUriId($b['uri-id'], $b['body'], BBCode::CONNECTORS);
399                 }
400
401                 if (isset($params['caption']) && (trim($title) != '')) {
402                         $params['caption'] = '<h1>' . $title . '</h1>' .
403                                 '<p>' . $params['caption'] . '</p>';
404                 }
405
406                 $consumer_key    = DI::config()->get('tumblr', 'consumer_key');
407                 $consumer_secret = DI::config()->get('tumblr', 'consumer_secret');
408
409                 $tum_oauth = new TumblrOAuth($consumer_key, $consumer_secret, $oauth_token, $oauth_token_secret);
410
411                 // Make an API call with the TumblrOAuth instance.
412                 $x = $tum_oauth->post($tmbl_blog, $params);
413                 $ret_code = $tum_oauth->http_code;
414
415                 if ($ret_code == 201) {
416                         Logger::notice('tumblr_send: success');
417                 } elseif ($ret_code == 403) {
418                         Logger::notice('tumblr_send: authentication failure');
419                 } else {
420                         Logger::notice('tumblr_send: general error', ['error' => $x]);
421                 }
422         }
423 }