2014-12-24 16:47:24 +01:00
|
|
|
<?php
|
|
|
|
|
2016-08-25 03:17:58 +02:00
|
|
|
namespace Miniflux\Handler\Service;
|
2014-12-24 16:47:24 +01:00
|
|
|
|
2016-12-26 15:44:53 +01:00
|
|
|
use Miniflux\Model;
|
|
|
|
use Miniflux\Helper;
|
2014-12-24 16:47:24 +01:00
|
|
|
use PicoFeed\Client\Client;
|
|
|
|
use PicoFeed\Client\ClientException;
|
|
|
|
|
2016-12-26 15:44:53 +01:00
|
|
|
function sync($user_id, $item_id)
|
2014-12-24 16:47:24 +01:00
|
|
|
{
|
2016-12-26 15:44:53 +01:00
|
|
|
$item = Model\Item\get_item($user_id, $item_id);
|
2014-12-24 19:50:20 +01:00
|
|
|
|
2016-12-26 15:44:53 +01:00
|
|
|
if (Helper\bool_config('pinboard_enabled')) {
|
2016-08-19 04:53:52 +02:00
|
|
|
pinboard_sync($item);
|
2014-12-24 19:50:20 +01:00
|
|
|
}
|
|
|
|
|
2016-12-26 15:44:53 +01:00
|
|
|
if (Helper\bool_config('instapaper_enabled')) {
|
2016-08-19 04:53:52 +02:00
|
|
|
instapaper_sync($item);
|
2014-12-24 19:50:20 +01:00
|
|
|
}
|
2016-11-30 04:49:45 +01:00
|
|
|
|
2016-12-26 15:44:53 +01:00
|
|
|
if (Helper\bool_config('wallabag_enabled')) {
|
2016-11-30 04:49:45 +01:00
|
|
|
wallabag_sync($item);
|
|
|
|
}
|
2017-06-11 16:12:29 +02:00
|
|
|
|
|
|
|
if (Helper\bool_config('shaarli_enabled')) {
|
|
|
|
shaarli_sync($item);
|
|
|
|
}
|
2014-12-24 19:50:20 +01:00
|
|
|
}
|
|
|
|
|
2016-08-19 04:53:52 +02:00
|
|
|
function instapaper_sync(array $item)
|
2014-12-24 19:50:20 +01:00
|
|
|
{
|
|
|
|
$params = array(
|
2016-12-26 15:44:53 +01:00
|
|
|
'username' => Helper\config('instapaper_username'),
|
|
|
|
'password' => Helper\config('instapaper_password'),
|
2014-12-24 19:50:20 +01:00
|
|
|
'url' => $item['url'],
|
|
|
|
'title' => $item['title'],
|
|
|
|
);
|
|
|
|
|
|
|
|
$url = 'https://www.instapaper.com/api/add?'.http_build_query($params);
|
|
|
|
|
2016-11-30 04:49:45 +01:00
|
|
|
$client = api_get_call($url);
|
2014-12-24 19:50:20 +01:00
|
|
|
|
|
|
|
if ($client !== false) {
|
|
|
|
return $client->getStatusCode() === 201;
|
2014-12-24 16:47:24 +01:00
|
|
|
}
|
2014-12-24 19:50:20 +01:00
|
|
|
|
|
|
|
return false;
|
2014-12-24 16:47:24 +01:00
|
|
|
}
|
|
|
|
|
2016-08-19 04:53:52 +02:00
|
|
|
function pinboard_sync(array $item)
|
2014-12-24 16:47:24 +01:00
|
|
|
{
|
2014-12-24 19:50:20 +01:00
|
|
|
$params = array(
|
2016-12-26 15:44:53 +01:00
|
|
|
'auth_token' => Helper\config('pinboard_token'),
|
2014-12-24 19:50:20 +01:00
|
|
|
'format' => 'json',
|
2014-12-24 16:47:24 +01:00
|
|
|
'url' => $item['url'],
|
|
|
|
'description' => $item['title'],
|
2016-12-26 15:44:53 +01:00
|
|
|
'tags' => Helper\config('pinboard_tags'),
|
2017-06-12 23:59:51 +02:00
|
|
|
'toread' => Helper\bool_config('pinboard_mark_unread') ? 'yes' : 'no',
|
2014-12-24 19:50:20 +01:00
|
|
|
);
|
|
|
|
|
|
|
|
$url = 'https://api.pinboard.in/v1/posts/add?'.http_build_query($params);
|
|
|
|
|
2016-11-30 04:49:45 +01:00
|
|
|
$client = api_get_call($url);
|
2014-12-24 19:50:20 +01:00
|
|
|
|
|
|
|
if ($client !== false) {
|
|
|
|
$response = json_decode($client->getContent(), true);
|
|
|
|
return is_array($response) && $response['result_code'] === 'done';
|
|
|
|
}
|
|
|
|
|
|
|
|
return false;
|
2014-12-24 16:47:24 +01:00
|
|
|
}
|
|
|
|
|
2016-11-30 04:49:45 +01:00
|
|
|
function wallabag_sync(array $item)
|
|
|
|
{
|
|
|
|
return wallabag_has_url($item['url'])
|
|
|
|
? false
|
|
|
|
: wallabag_add_item($item['url'], $item['title']);
|
|
|
|
}
|
|
|
|
|
|
|
|
function wallabag_has_url($url)
|
|
|
|
{
|
|
|
|
$token = wallabag_get_access_token();
|
|
|
|
if ($token === false) {
|
|
|
|
return false;
|
|
|
|
}
|
2016-12-26 15:44:53 +01:00
|
|
|
$apiUrl = rtrim(Helper\config('wallabag_url'), '\/') . '/api/entries/exists.json?url=' . urlencode($url);
|
2016-11-30 04:49:45 +01:00
|
|
|
$headers = array('Authorization: Bearer ' . $token);
|
|
|
|
$response = api_get_call($apiUrl, $headers);
|
|
|
|
if ($response !== false) {
|
|
|
|
$response = json_decode($response->getContent(), true);
|
|
|
|
}
|
|
|
|
return !empty($response['exists']);
|
|
|
|
}
|
|
|
|
|
|
|
|
function wallabag_add_item($url, $title)
|
|
|
|
{
|
|
|
|
$token = wallabag_get_access_token();
|
|
|
|
if ($token === false) {
|
|
|
|
return false;
|
|
|
|
}
|
2016-12-26 15:44:53 +01:00
|
|
|
$apiUrl = rtrim(Helper\config('wallabag_url'), '\/') . '/api/entries.json';
|
2016-11-30 04:49:45 +01:00
|
|
|
$headers = array('Authorization: Bearer ' . $token);
|
|
|
|
$data = array(
|
|
|
|
'url' => $url,
|
|
|
|
'title' => $title,
|
|
|
|
);
|
|
|
|
$response = api_post_call($apiUrl, $data, $headers);
|
|
|
|
if ($response !== false) {
|
|
|
|
$response = json_decode($response, true);
|
|
|
|
}
|
|
|
|
return !empty($response['id']);
|
|
|
|
}
|
|
|
|
|
|
|
|
function wallabag_get_access_token()
|
|
|
|
{
|
|
|
|
if (!empty($_SESSION['wallabag_access_token'])) {
|
|
|
|
return $_SESSION['wallabag_access_token'];
|
|
|
|
}
|
2016-12-26 15:44:53 +01:00
|
|
|
$url = rtrim(Helper\config('wallabag_url'), '\/') . '/oauth/v2/token';
|
2016-11-30 04:49:45 +01:00
|
|
|
$data = array(
|
|
|
|
'grant_type' => 'password',
|
2016-12-26 15:44:53 +01:00
|
|
|
'client_id' => Helper\config('wallabag_client_id'),
|
|
|
|
'client_secret' => Helper\config('wallabag_client_secret'),
|
|
|
|
'username' => Helper\config('wallabag_username'),
|
|
|
|
'password' => Helper\config('wallabag_password')
|
2016-11-30 04:49:45 +01:00
|
|
|
);
|
|
|
|
$response = api_post_call($url, $data);
|
|
|
|
if ($response !== false) {
|
|
|
|
$response = json_decode($response, true);
|
|
|
|
if (!empty($response['access_token'])) {
|
|
|
|
$_SESSION['wallabag_access_token'] = $response['access_token'];
|
|
|
|
return $_SESSION['wallabag_access_token'];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2017-06-11 16:12:29 +02:00
|
|
|
function shaarli_sync(array $item)
|
|
|
|
{
|
|
|
|
$headers = array(
|
|
|
|
'Authorization: Bearer ' . shaarli_get_access_token()
|
|
|
|
);
|
|
|
|
$apiUrl = rtrim(Helper\config('shaarli_url'), '\/') . '/api/v1/links';
|
|
|
|
$tags = explode(',', Helper\config('shaarli_tags'));
|
|
|
|
$data = array(
|
|
|
|
'url' => $item['url'],
|
|
|
|
'title' => $item['title'],
|
|
|
|
'description' => '',
|
|
|
|
'tags' => $tags,
|
|
|
|
'private' => Helper\bool_config('shaarli_private'),
|
|
|
|
);
|
|
|
|
$response = api_post_json_call($apiUrl, $data, $headers);
|
|
|
|
if ($response !== false) {
|
|
|
|
$response = json_decode($response, true);
|
|
|
|
}
|
|
|
|
return empty($response['id']);
|
|
|
|
}
|
|
|
|
|
|
|
|
function shaarli_get_access_token()
|
|
|
|
{
|
|
|
|
$secret = Helper\config('shaarli_secret');
|
|
|
|
$header = base64_encode('{
|
|
|
|
"typ": "JWT",
|
|
|
|
"alg": "HS512"
|
|
|
|
}');
|
|
|
|
$payload = base64_encode('{
|
|
|
|
"iat": '. time() .'
|
|
|
|
}');
|
|
|
|
$signature = hash_hmac('sha512', $header . '.' . $payload, $secret, true);
|
|
|
|
// Base64Url Encoding:
|
|
|
|
$signature = rtrim(strtr(base64_encode($signature), '+/' , '-_' ), '=' );
|
|
|
|
return $header . '.' . $payload . '.' . $signature;
|
|
|
|
}
|
|
|
|
|
2016-11-30 04:49:45 +01:00
|
|
|
function api_get_call($url, array $headers = array())
|
2014-12-24 16:47:24 +01:00
|
|
|
{
|
|
|
|
try {
|
|
|
|
$client = Client::getInstance();
|
2016-12-26 15:44:53 +01:00
|
|
|
$client->setUserAgent(HTTP_USER_AGENT);
|
2016-11-30 04:49:45 +01:00
|
|
|
if ($headers) {
|
|
|
|
$client->setHeaders($headers);
|
|
|
|
}
|
2014-12-24 16:47:24 +01:00
|
|
|
$client->execute($url);
|
2014-12-24 19:50:20 +01:00
|
|
|
return $client;
|
2016-04-18 01:44:45 +02:00
|
|
|
} catch (ClientException $e) {
|
2014-12-24 16:47:24 +01:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
2016-11-30 04:49:45 +01:00
|
|
|
|
|
|
|
function api_post_call($url, array $data, array $headers = array())
|
2017-06-11 16:12:29 +02:00
|
|
|
{
|
|
|
|
$data = http_build_query($data);
|
|
|
|
$additionalHeaders = array(
|
|
|
|
'Content-Type: application/x-www-form-urlencoded'
|
|
|
|
);
|
|
|
|
$headers = $headers
|
|
|
|
? array_merge($headers, $additionalHeaders)
|
|
|
|
: $additionalHeaders;
|
|
|
|
return api_post($url, $data, $headers);
|
|
|
|
}
|
|
|
|
|
|
|
|
function api_post_json_call($url, array $data, array $headers = array())
|
|
|
|
{
|
|
|
|
$data = json_encode($data);
|
|
|
|
$additionalHeaders = array(
|
|
|
|
'Content-Type: application/json',
|
|
|
|
'Content-Length:' . strlen($data)
|
|
|
|
);
|
|
|
|
$headers = $headers
|
|
|
|
? array_merge($headers, $additionalHeaders)
|
|
|
|
: $additionalHeaders;
|
|
|
|
return api_post($url, $data, $headers);
|
|
|
|
}
|
|
|
|
|
|
|
|
function api_post($url, $data, array $headers)
|
2016-11-30 04:49:45 +01:00
|
|
|
{
|
|
|
|
return function_exists('curl_init')
|
|
|
|
? post_curl($url, $data, $headers)
|
|
|
|
: post_stream($url, $data, $headers);
|
|
|
|
}
|
|
|
|
|
2017-06-11 16:12:29 +02:00
|
|
|
function post_stream($url, $data, array $headers = array())
|
|
|
|
{
|
|
|
|
$options = array(
|
|
|
|
'http' => array(
|
|
|
|
'method' => 'POST',
|
|
|
|
'header' => implode("\r\n", $headers),
|
|
|
|
'content' => $data
|
|
|
|
)
|
|
|
|
);
|
|
|
|
$context = stream_context_create($options);
|
|
|
|
$result = file_get_contents($url, false, $context);
|
|
|
|
return $result;
|
|
|
|
}
|
|
|
|
|
|
|
|
function post_curl($url, $data, array $headers = array())
|
2016-11-30 04:49:45 +01:00
|
|
|
{
|
|
|
|
$ch = curl_init();
|
|
|
|
curl_setopt($ch, CURLOPT_URL, $url);
|
|
|
|
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
|
|
|
|
if ($headers) {
|
|
|
|
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
|
|
|
|
}
|
|
|
|
curl_setopt($ch, CURLOPT_POST, true);
|
2017-06-11 16:12:29 +02:00
|
|
|
curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
|
2016-11-30 04:49:45 +01:00
|
|
|
$result = curl_exec($ch);
|
|
|
|
curl_close($ch);
|
|
|
|
return $result;
|
|
|
|
}
|