2016-05-19 15:01:28 +01:00
|
|
|
|
<?php
|
|
|
|
|
|
|
|
|
|
namespace App\Http\Controllers;
|
|
|
|
|
|
2017-04-21 16:38:39 +01:00
|
|
|
|
use App\IndieWebUser;
|
2016-05-19 15:01:28 +01:00
|
|
|
|
use IndieAuth\Client as IndieClient;
|
|
|
|
|
use GuzzleHttp\Client as GuzzleClient;
|
2017-03-18 20:09:11 +00:00
|
|
|
|
use Illuminate\Http\{Request, Response};
|
|
|
|
|
use GuzzleHttp\Exception\{ClientException, ServerException};
|
2016-05-19 15:01:28 +01:00
|
|
|
|
|
|
|
|
|
class MicropubClientController extends Controller
|
|
|
|
|
{
|
|
|
|
|
/**
|
|
|
|
|
* Inject the dependencies.
|
|
|
|
|
*/
|
|
|
|
|
public function __construct(
|
2017-09-04 19:34:39 +01:00
|
|
|
|
IndieClient $indieClient,
|
|
|
|
|
GuzzleClient $guzzleClient
|
2016-05-19 15:01:28 +01:00
|
|
|
|
) {
|
2017-09-04 19:34:39 +01:00
|
|
|
|
$this->indieClient = $indieClient;
|
|
|
|
|
$this->guzzleClient = $guzzleClient;
|
2016-05-19 15:01:28 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Display the new notes form.
|
|
|
|
|
*
|
|
|
|
|
* @param \Illuminate\Http\Request $request
|
|
|
|
|
* @return \Illuminate\View\Factory view
|
|
|
|
|
*/
|
2017-02-15 20:19:11 +00:00
|
|
|
|
public function create(Request $request)
|
2016-05-19 15:01:28 +01:00
|
|
|
|
{
|
2017-05-18 16:19:37 +01:00
|
|
|
|
//initiate varaibles
|
|
|
|
|
$indiewebUser = null;
|
|
|
|
|
$syndication = null;
|
|
|
|
|
$mediaEndpoint = null;
|
|
|
|
|
$mediaURLs = null;
|
2016-05-19 15:01:28 +01:00
|
|
|
|
$url = $request->session()->get('me');
|
2017-04-21 16:38:39 +01:00
|
|
|
|
if ($url) {
|
|
|
|
|
$indiewebUser = IndieWebUser::where('me', $url)->first();
|
|
|
|
|
}
|
2017-05-18 15:59:30 +01:00
|
|
|
|
if ($indiewebUser) {
|
|
|
|
|
$syndication = $this->parseSyndicationTargets($indiewebUser->syndication);
|
|
|
|
|
$mediaEndpoint = $indiewebUser->mediaEndpoint ?? null;
|
|
|
|
|
$mediaURLs = $request->session()->get('media-links');
|
|
|
|
|
}
|
2016-05-19 15:01:28 +01:00
|
|
|
|
|
2017-03-15 12:23:42 +00:00
|
|
|
|
return view('micropub.create', compact('url', 'syndication', 'mediaEndpoint', 'mediaURLs'));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Process an upload to the media endpoint.
|
|
|
|
|
*
|
|
|
|
|
* @param Illuminate\Http\Request $request
|
|
|
|
|
* @return Illuminate\Http\Response
|
|
|
|
|
*/
|
|
|
|
|
public function processMedia(Request $request)
|
|
|
|
|
{
|
2017-07-20 10:39:58 +01:00
|
|
|
|
if ($request->hasFile('files') == false) {
|
|
|
|
|
return back()->with('error', 'No files uploaded');
|
2017-03-15 12:23:42 +00:00
|
|
|
|
}
|
|
|
|
|
|
2017-04-21 16:38:39 +01:00
|
|
|
|
$user = IndieWebUser::where('me', $request->session()->get('me'))->firstOrFail();
|
|
|
|
|
if ($user->mediaEndpoint == null || $user->token == null) {
|
2017-07-20 10:10:17 +01:00
|
|
|
|
return back()->with('error', 'No user token or known endpoint');
|
2017-03-15 12:23:42 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
$mediaURLs = [];
|
2017-07-20 10:39:58 +01:00
|
|
|
|
foreach ($request->file('files') as $file) {
|
2017-03-15 12:23:42 +00:00
|
|
|
|
try {
|
2017-04-21 16:38:39 +01:00
|
|
|
|
$response = $this->guzzleClient->request('POST', $user->mediaEndpoint, [
|
2017-03-18 20:09:11 +00:00
|
|
|
|
'headers' => [
|
2017-04-21 16:38:39 +01:00
|
|
|
|
'Authorization' => 'Bearer ' . $user->token,
|
2017-03-18 20:09:11 +00:00
|
|
|
|
],
|
|
|
|
|
'multipart' => [
|
2017-03-15 12:23:42 +00:00
|
|
|
|
[
|
2017-03-18 20:09:11 +00:00
|
|
|
|
'name' => 'file',
|
|
|
|
|
'contents' => fopen($file->path(), 'r'),
|
|
|
|
|
'filename' => $file->getClientOriginalName(),
|
2017-03-15 12:23:42 +00:00
|
|
|
|
],
|
|
|
|
|
],
|
|
|
|
|
]);
|
|
|
|
|
} catch (ClientException | ServerException $e) {
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
2017-03-18 20:09:11 +00:00
|
|
|
|
$mediaURLs[] = $response->getHeader('Location')[0];
|
2017-03-15 12:23:42 +00:00
|
|
|
|
}
|
|
|
|
|
|
2017-03-19 15:19:12 +00:00
|
|
|
|
$storedMediaURLs = $request->session()->get('media-links') ?? [];
|
|
|
|
|
$mediaURLsToSave = array_merge($storedMediaURLs, $mediaURLs);
|
|
|
|
|
$request->session()->put('media-links', $mediaURLsToSave);
|
2017-03-15 12:23:42 +00:00
|
|
|
|
|
2017-05-18 17:17:08 +01:00
|
|
|
|
return redirect()->route('micropub-client');
|
2017-03-15 12:23:42 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public function clearLinks(Request $request)
|
|
|
|
|
{
|
|
|
|
|
$request->session()->forget('media-links');
|
|
|
|
|
|
|
|
|
|
return redirect(route('micropub-client'));
|
2016-05-19 15:01:28 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Post the notes content to the relavent micropub API endpoint.
|
|
|
|
|
*
|
|
|
|
|
* @todo make sure this works with multiple syndication targets
|
|
|
|
|
*
|
|
|
|
|
* @param \Illuminate\Http\Request $request
|
|
|
|
|
* @return mixed
|
|
|
|
|
*/
|
2017-02-15 20:19:11 +00:00
|
|
|
|
public function store(Request $request)
|
2016-05-19 15:01:28 +01:00
|
|
|
|
{
|
2017-04-21 16:38:39 +01:00
|
|
|
|
$url = normalize_url($request->session()->get('me'));
|
|
|
|
|
$user = IndieWebUser::where('me', $url)->firstOrFail();
|
2016-05-19 15:01:28 +01:00
|
|
|
|
|
2017-04-21 16:38:39 +01:00
|
|
|
|
if ($user->token == null) {
|
2017-05-18 17:17:08 +01:00
|
|
|
|
return redirect()->route('micropub-client')->with('error', 'You haven’t requested a token yet');
|
2017-04-21 16:38:39 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
$micropubEndpoint = $this->indieClient->discoverMicropubEndpoint($url);
|
2016-05-19 15:01:28 +01:00
|
|
|
|
if (! $micropubEndpoint) {
|
2017-05-18 17:17:08 +01:00
|
|
|
|
return redirect()->route('micropub-client')->with('error', 'Unable to determine micropub API endpoint');
|
2016-05-19 15:01:28 +01:00
|
|
|
|
}
|
|
|
|
|
|
2017-04-21 16:38:39 +01:00
|
|
|
|
$headers = [
|
|
|
|
|
'Authorization' => 'Bearer ' . $user->token,
|
|
|
|
|
];
|
2016-05-19 15:01:28 +01:00
|
|
|
|
|
2017-04-21 16:38:39 +01:00
|
|
|
|
if ($user->syntax == 'html') {
|
|
|
|
|
$multipart = [
|
|
|
|
|
[
|
|
|
|
|
'name' => 'h',
|
|
|
|
|
'contents' => 'entry',
|
|
|
|
|
],
|
|
|
|
|
[
|
|
|
|
|
'name' => 'content',
|
|
|
|
|
'contents' => $request->input('content'),
|
|
|
|
|
],
|
|
|
|
|
];
|
|
|
|
|
if ($request->hasFile('photo')) {
|
|
|
|
|
$photos = $request->file('photo');
|
|
|
|
|
foreach ($photos as $photo) {
|
|
|
|
|
$multipart[] = [
|
|
|
|
|
'name' => 'photo[]',
|
|
|
|
|
'contents' => fopen($photo->path(), 'r'),
|
|
|
|
|
'filename' => $photo->getClientOriginalName(),
|
|
|
|
|
];
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if ($request->input('in-reply-to') != '') {
|
|
|
|
|
$multipart[] = [
|
|
|
|
|
'name' => 'in-reply-to',
|
|
|
|
|
'contents' => $request->input('in-reply-to'),
|
|
|
|
|
];
|
|
|
|
|
}
|
|
|
|
|
if ($request->input('mp-syndicate-to')) {
|
|
|
|
|
foreach ($request->input('mp-syndicate-to') as $syn) {
|
|
|
|
|
$multipart[] = [
|
|
|
|
|
'name' => 'mp-syndicate-to[]',
|
|
|
|
|
'contents' => $syn,
|
|
|
|
|
];
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if ($request->input('location')) {
|
|
|
|
|
if ($request->input('location') !== 'no-location') {
|
|
|
|
|
$multipart[] = [
|
|
|
|
|
'name' => 'location',
|
|
|
|
|
'contents' => $request->input('location'),
|
|
|
|
|
];
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if ($request->input('media')) {
|
|
|
|
|
foreach ($request->input('media') as $media) {
|
|
|
|
|
$multipart[] = [
|
|
|
|
|
'name' => 'photo[]',
|
|
|
|
|
'contents' => $media,
|
|
|
|
|
];
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
try {
|
|
|
|
|
$response = $this->guzzleClient->post($micropubEndpoint, [
|
|
|
|
|
'multipart' => $multipart,
|
|
|
|
|
'headers' => $headers,
|
|
|
|
|
]);
|
|
|
|
|
} catch (\GuzzleHttp\Exception\BadResponseException $e) {
|
2017-05-18 17:17:08 +01:00
|
|
|
|
return redirect()->route('micropub-client')->with(
|
2017-04-21 16:38:39 +01:00
|
|
|
|
'error',
|
|
|
|
|
'There was a bad response from the micropub endpoint.'
|
|
|
|
|
);
|
2016-05-19 15:01:28 +01:00
|
|
|
|
}
|
|
|
|
|
|
2017-04-21 16:38:39 +01:00
|
|
|
|
if ($response->getStatusCode() == 201) {
|
|
|
|
|
$request->session()->forget('media-links');
|
|
|
|
|
$location = $response->getHeader('Location');
|
|
|
|
|
if (is_array($location)) {
|
|
|
|
|
return redirect($location[0]);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return redirect($location);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if ($user->syntax == 'json') {
|
|
|
|
|
$json = [];
|
|
|
|
|
$json['type'] = ['h-entry'];
|
|
|
|
|
$json['properties'] = ['content' => [$request->input('content')]];
|
|
|
|
|
|
|
|
|
|
if ($request->input('in-reply-to') != '') {
|
2017-05-19 10:07:43 +01:00
|
|
|
|
$json['properties']['in-reply-to'][] = $request->input('in-reply-to');
|
2017-04-21 16:38:39 +01:00
|
|
|
|
}
|
|
|
|
|
if ($request->input('mp-syndicate-to')) {
|
|
|
|
|
foreach ($request->input('mp-syndicate-to') as $syn) {
|
2017-05-19 10:07:43 +01:00
|
|
|
|
$json['properties']['mp-syndicate-to'][] = $syn;
|
2017-04-21 16:38:39 +01:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if ($request->input('location')) {
|
|
|
|
|
if ($request->input('location') !== 'no-location') {
|
2017-05-19 10:07:43 +01:00
|
|
|
|
$json['properties']['location'][] = $request->input('location');
|
2017-04-21 16:38:39 +01:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if ($request->input('media')) {
|
|
|
|
|
$json['properties']['photo'] = [];
|
|
|
|
|
foreach ($request->input('media') as $media) {
|
|
|
|
|
$json['properties']['photo'][] = $media;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
try {
|
|
|
|
|
$response = $this->guzzleClient->post($micropubEndpoint, [
|
|
|
|
|
'json' => $json,
|
|
|
|
|
'headers' => $headers,
|
|
|
|
|
]);
|
|
|
|
|
} catch (\GuzzleHttp\Exception\BadResponseException $e) {
|
2017-05-18 17:17:08 +01:00
|
|
|
|
return redirect()->route('micropub-client')->with(
|
2017-04-21 16:38:39 +01:00
|
|
|
|
'error',
|
|
|
|
|
'There was a bad response from the micropub endpoint.'
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if ($response->getStatusCode() == 201) {
|
|
|
|
|
$request->session()->forget('media-links');
|
|
|
|
|
$location = $response->getHeader('Location');
|
|
|
|
|
if (is_array($location)) {
|
|
|
|
|
return redirect($location[0]);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return redirect($location);
|
|
|
|
|
}
|
2016-05-19 15:01:28 +01:00
|
|
|
|
}
|
2017-02-23 08:59:56 +00:00
|
|
|
|
|
2017-05-18 17:17:08 +01:00
|
|
|
|
return redirect()->route('micropub-client')->with('error', 'Endpoint didn’t create the note.');
|
2016-05-19 15:01:28 +01:00
|
|
|
|
}
|
|
|
|
|
|
2017-03-13 16:18:15 +00:00
|
|
|
|
/**
|
|
|
|
|
* Show currently stored configuration values.
|
|
|
|
|
*
|
|
|
|
|
* @param Illuminate\Http\Request $request
|
|
|
|
|
* @return view
|
|
|
|
|
*/
|
|
|
|
|
public function config(Request $request)
|
|
|
|
|
{
|
2017-04-21 16:38:39 +01:00
|
|
|
|
//default values
|
|
|
|
|
$data = [
|
|
|
|
|
'me' => '',
|
|
|
|
|
'token' => 'none',
|
|
|
|
|
'syndication' => 'none defined',
|
|
|
|
|
'media-endpoint' => 'none defined',
|
|
|
|
|
'syntax' => 'html',
|
|
|
|
|
];
|
|
|
|
|
if ($request->session()->has('me')) {
|
|
|
|
|
$data['me'] = normalize_url($request->session()->get('me'));
|
2017-08-09 22:15:45 +01:00
|
|
|
|
$user = IndieWebUser::where('me', $request->session()->get('me'))->firstOrFail();
|
2017-04-21 16:38:39 +01:00
|
|
|
|
$data['token'] = $user->token ?? 'none defined';
|
|
|
|
|
$data['syndication'] = $user->syndication ?? 'none defined';
|
|
|
|
|
$data['media-endpoint'] = $user->mediaEndpoint ?? 'none defined';
|
|
|
|
|
$data['syntax'] = $user->syntax;
|
|
|
|
|
}
|
2017-03-15 12:23:42 +00:00
|
|
|
|
|
2017-03-13 16:18:15 +00:00
|
|
|
|
return view('micropub.config', compact('data'));
|
|
|
|
|
}
|
|
|
|
|
|
2017-03-15 12:23:42 +00:00
|
|
|
|
/**
|
2017-04-21 16:38:39 +01:00
|
|
|
|
* Get a new token.
|
|
|
|
|
*
|
|
|
|
|
* @param Illuminate\Http\Request $request
|
|
|
|
|
* @return view
|
|
|
|
|
*/
|
|
|
|
|
public function getNewToken(Request $request)
|
|
|
|
|
{
|
|
|
|
|
if ($request->session()->has('me')) {
|
|
|
|
|
$url = normalize_url($request->session()->get('me'));
|
|
|
|
|
$authozationEndpoint = $this->indieClient->discoverAuthorizationEndpoint($url);
|
|
|
|
|
if ($authozationEndpoint) {
|
|
|
|
|
$state = bin2hex(random_bytes(16));
|
|
|
|
|
$request->session()->put('state', $state);
|
|
|
|
|
$authorizationURL = $this->indieClient->buildAuthorizationURL(
|
|
|
|
|
$authozationEndpoint,
|
|
|
|
|
$url,
|
|
|
|
|
route('micropub-client-get-new-token-callback'), // redirect_uri
|
|
|
|
|
route('micropub-client'), //client_id
|
|
|
|
|
$state,
|
|
|
|
|
'create update' // scope needs to be a setting
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
return redirect($authorizationURL);
|
|
|
|
|
}
|
|
|
|
|
|
2017-05-18 17:17:08 +01:00
|
|
|
|
return redirect()->route('micropub-config')->with('error', 'Unable to find authorisation endpoint');
|
2017-04-21 16:38:39 +01:00
|
|
|
|
}
|
|
|
|
|
|
2017-05-18 17:17:08 +01:00
|
|
|
|
return redirect()->route('micropub-config')->with('error', 'You aren’t logged in');
|
2017-04-21 16:38:39 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* The callback for getting a token.
|
|
|
|
|
*/
|
|
|
|
|
public function getNewTokenCallback(Request $request)
|
|
|
|
|
{
|
|
|
|
|
if ($request->input('state') !== $request->session()->get('state')) {
|
2017-05-18 17:17:08 +01:00
|
|
|
|
return redirect()->route('micropub-config')->with('error', 'The <code>state</code> didn’t match.');
|
2017-04-21 16:38:39 +01:00
|
|
|
|
}
|
|
|
|
|
$tokenEndpoint = $this->indieClient->discoverTokenEndpoint(normalize_url($request->input('me')));
|
|
|
|
|
if ($tokenEndpoint) {
|
|
|
|
|
$token = $this->indieClient->getAccessToken(
|
|
|
|
|
$tokenEndpoint,
|
|
|
|
|
$request->input('code'),
|
|
|
|
|
$request->input('me'),
|
|
|
|
|
route('micropub-client-get-new-token-callback'), // redirect_uri
|
2017-05-18 18:40:51 +01:00
|
|
|
|
route('micropub-client') // client_id
|
2017-04-21 16:38:39 +01:00
|
|
|
|
);
|
|
|
|
|
if (array_key_exists('access_token', $token)) {
|
|
|
|
|
$url = normalize_url($token['me']);
|
|
|
|
|
$user = IndieWebUser::where('me', $url)->firstOrFail();
|
|
|
|
|
$user->token = $token['access_token'];
|
|
|
|
|
$user->save();
|
|
|
|
|
|
2017-05-18 17:17:08 +01:00
|
|
|
|
return redirect()->route('micropub-config');
|
2017-04-21 16:38:39 +01:00
|
|
|
|
}
|
2017-05-18 17:17:08 +01:00
|
|
|
|
|
|
|
|
|
return redirect()->route('micropub-config')->with('error', 'Error getting token from the endpoint');
|
2017-04-21 16:38:39 +01:00
|
|
|
|
}
|
2017-05-18 17:17:08 +01:00
|
|
|
|
|
|
|
|
|
return redirect()->route('micropub-config')->with('error', 'Unable to find token endpoint');
|
2017-04-21 16:38:39 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Query the micropub endpoint and store response.
|
2017-03-15 12:23:42 +00:00
|
|
|
|
*
|
|
|
|
|
* @param Illuminate\Http\Request $request
|
|
|
|
|
* @return redirect
|
|
|
|
|
*/
|
|
|
|
|
public function queryEndpoint(Request $request)
|
|
|
|
|
{
|
2017-04-21 16:38:39 +01:00
|
|
|
|
$url = normalize_url($request->session()->get('me'));
|
|
|
|
|
$user = IndieWebUser::where('me', $url)->firstOrFail();
|
|
|
|
|
$token = $user->token;
|
|
|
|
|
$micropubEndpoint = $this->indieClient->discoverMicropubEndpoint($url);
|
|
|
|
|
if ($micropubEndpoint) {
|
2017-03-15 12:23:42 +00:00
|
|
|
|
try {
|
|
|
|
|
$response = $this->guzzleClient->get($micropubEndpoint, [
|
|
|
|
|
'headers' => ['Authorization' => 'Bearer ' . $token],
|
|
|
|
|
'query' => 'q=config',
|
|
|
|
|
]);
|
|
|
|
|
} catch (ClientException | ServerException $e) {
|
|
|
|
|
return back();
|
|
|
|
|
}
|
|
|
|
|
$body = (string) $response->getBody();
|
2017-04-21 16:38:39 +01:00
|
|
|
|
$data = json_decode($body, true);
|
2017-03-15 12:23:42 +00:00
|
|
|
|
|
2017-04-21 16:38:39 +01:00
|
|
|
|
if (array_key_exists('syndicate-to', $data)) {
|
|
|
|
|
$user->syndication = json_encode($data['syndicate-to']);
|
|
|
|
|
}
|
2017-03-15 12:23:42 +00:00
|
|
|
|
|
2017-04-21 16:38:39 +01:00
|
|
|
|
if (array_key_exists('media-endpoint', $data)) {
|
|
|
|
|
$user->mediaEndpoint = $data['media-endpoint'];
|
|
|
|
|
}
|
|
|
|
|
$user->save();
|
2017-03-15 12:23:42 +00:00
|
|
|
|
|
|
|
|
|
return back();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2016-05-19 15:01:28 +01:00
|
|
|
|
/**
|
2017-04-21 16:38:39 +01:00
|
|
|
|
* Update the syntax setting.
|
2016-05-19 15:01:28 +01:00
|
|
|
|
*
|
2017-04-21 16:38:39 +01:00
|
|
|
|
* @param Illuminate\Http\Request $request
|
|
|
|
|
* @return Illuminate\Http\RedirectResponse
|
|
|
|
|
* @todo validate input
|
2016-05-19 15:01:28 +01:00
|
|
|
|
*/
|
2017-04-21 16:38:39 +01:00
|
|
|
|
public function updateSyntax(Request $request)
|
|
|
|
|
{
|
|
|
|
|
$user = IndieWebUser::where('me', $request->session()->get('me'))->firstOrFail();
|
|
|
|
|
$user->syntax = $request->syntax;
|
|
|
|
|
$user->save();
|
2016-05-19 15:01:28 +01:00
|
|
|
|
|
2017-05-18 17:17:08 +01:00
|
|
|
|
return redirect()->route('micropub-config');
|
2016-05-19 15:01:28 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Create a new place.
|
|
|
|
|
*
|
|
|
|
|
* @param \Illuminate\Http\Request $request
|
|
|
|
|
* @return mixed
|
|
|
|
|
*/
|
2017-02-16 15:35:25 +00:00
|
|
|
|
public function newPlace(Request $request)
|
2016-05-19 15:01:28 +01:00
|
|
|
|
{
|
2017-04-21 16:38:39 +01:00
|
|
|
|
$url = normalize_url($request->session()->get('me'));
|
|
|
|
|
$user = IndieWebUser::where('me', $url)->firstOrFail();
|
|
|
|
|
|
|
|
|
|
if ($user->token === null) {
|
2016-09-23 12:26:43 +01:00
|
|
|
|
return response()->json([
|
|
|
|
|
'error' => true,
|
|
|
|
|
'error_description' => 'No known token',
|
|
|
|
|
], 400);
|
|
|
|
|
}
|
2016-05-19 15:01:28 +01:00
|
|
|
|
|
2017-04-21 16:38:39 +01:00
|
|
|
|
$micropubEndpoint = $this->indieClient->discoverMicropubEndpoint($url);
|
2016-05-19 15:01:28 +01:00
|
|
|
|
if (! $micropubEndpoint) {
|
2016-09-23 12:26:43 +01:00
|
|
|
|
return response()->json([
|
2016-05-19 15:01:28 +01:00
|
|
|
|
'error' => true,
|
2016-09-23 12:26:43 +01:00
|
|
|
|
'error_description' => 'Could not determine the micropub endpoint.',
|
|
|
|
|
], 400);
|
2016-05-19 15:01:28 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
$formParams = [
|
|
|
|
|
'h' => 'card',
|
|
|
|
|
'name' => $request->input('place-name'),
|
|
|
|
|
'description' => $request->input('place-description'),
|
|
|
|
|
'geo' => 'geo:' . $request->input('place-latitude') . ',' . $request->input('place-longitude'),
|
|
|
|
|
];
|
|
|
|
|
$headers = [
|
2017-04-21 16:38:39 +01:00
|
|
|
|
'Authorization' => 'Bearer ' . $user->token,
|
2016-05-19 15:01:28 +01:00
|
|
|
|
];
|
|
|
|
|
try {
|
|
|
|
|
$response = $this->guzzleClient->request('POST', $micropubEndpoint, [
|
|
|
|
|
'form_params' => $formParams,
|
|
|
|
|
'headers' => $headers,
|
|
|
|
|
]);
|
|
|
|
|
} catch (ClientException $e) {
|
2017-04-21 16:38:39 +01:00
|
|
|
|
return response()->json([
|
|
|
|
|
'error' => true,
|
|
|
|
|
'error_description' => 'Unable to create the new place',
|
|
|
|
|
], 400);
|
2016-05-19 15:01:28 +01:00
|
|
|
|
}
|
2017-04-21 16:38:39 +01:00
|
|
|
|
$place = $response->getHeader('Location')[0];
|
2016-05-19 15:01:28 +01:00
|
|
|
|
|
2017-04-21 16:38:39 +01:00
|
|
|
|
return response()->json([
|
|
|
|
|
'uri' => $place,
|
|
|
|
|
'name' => $request->input('place-name'),
|
|
|
|
|
'latitude' => $request->input('place-latitude'),
|
|
|
|
|
'longitude' => $request->input('place-longitude'),
|
|
|
|
|
]);
|
2016-05-19 15:01:28 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Make a request to the micropub endpoint requesting any nearby places.
|
|
|
|
|
*
|
|
|
|
|
* @param \Illuminate\Http\Request $request
|
|
|
|
|
* @return \Illuminate\Http\Response
|
|
|
|
|
*/
|
2017-02-16 15:35:25 +00:00
|
|
|
|
public function nearbyPlaces(Request $request)
|
|
|
|
|
{
|
2017-04-21 16:38:39 +01:00
|
|
|
|
$url = normalize_url($request->session()->get('me'));
|
|
|
|
|
$user = IndieWebUser::where('me', $url)->firstOrFail();
|
|
|
|
|
|
|
|
|
|
if ($user->token === null) {
|
2016-09-23 12:26:43 +01:00
|
|
|
|
return response()->json([
|
|
|
|
|
'error' => true,
|
|
|
|
|
'error_description' => 'No known token',
|
|
|
|
|
], 400);
|
|
|
|
|
}
|
|
|
|
|
|
2017-04-21 16:38:39 +01:00
|
|
|
|
$micropubEndpoint = $this->indieClient->discoverMicropubEndpoint($url);
|
2016-05-19 15:01:28 +01:00
|
|
|
|
|
|
|
|
|
if (! $micropubEndpoint) {
|
2016-09-23 12:26:43 +01:00
|
|
|
|
return response()->json([
|
|
|
|
|
'error' => true,
|
|
|
|
|
'error_description' => 'No known endpoint',
|
|
|
|
|
], 400);
|
2016-05-19 15:01:28 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
try {
|
2017-02-16 15:35:25 +00:00
|
|
|
|
$query = 'geo:' . $request->input('latitude') . ',' . $request->input('longitude');
|
2016-10-03 14:46:53 +01:00
|
|
|
|
if ($request->input('u') !== null) {
|
2016-10-03 16:28:09 +01:00
|
|
|
|
$query .= ';u=' . $request->input('u');
|
2016-09-29 11:28:31 +01:00
|
|
|
|
}
|
2016-05-19 15:01:28 +01:00
|
|
|
|
$response = $this->guzzleClient->get($micropubEndpoint, [
|
2017-04-21 16:38:39 +01:00
|
|
|
|
'headers' => ['Authorization' => 'Bearer ' . $user->token],
|
2016-09-29 11:28:31 +01:00
|
|
|
|
'query' => ['q' => $query],
|
2016-05-19 15:01:28 +01:00
|
|
|
|
]);
|
|
|
|
|
} catch (\GuzzleHttp\Exception\BadResponseException $e) {
|
2016-09-23 12:26:43 +01:00
|
|
|
|
return response()->json([
|
|
|
|
|
'error' => true,
|
2016-11-22 16:08:02 +00:00
|
|
|
|
'error_description' => 'The endpoint ' . $micropubEndpoint . ' returned a non-good response',
|
2016-09-23 12:26:43 +01:00
|
|
|
|
], 400);
|
2016-05-19 15:01:28 +01:00
|
|
|
|
}
|
|
|
|
|
|
2017-02-16 15:35:25 +00:00
|
|
|
|
return response($response->getBody(), 200)
|
2016-05-19 15:01:28 +01:00
|
|
|
|
->header('Content-Type', 'application/json');
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
2017-04-21 16:38:39 +01:00
|
|
|
|
* Parse the syndication targets JSON into a an array.
|
2016-05-19 15:01:28 +01:00
|
|
|
|
*
|
2017-04-21 16:38:39 +01:00
|
|
|
|
* @param string|null
|
2016-05-19 15:01:28 +01:00
|
|
|
|
* @return array|null
|
|
|
|
|
*/
|
|
|
|
|
private function parseSyndicationTargets($syndicationTargets = null)
|
|
|
|
|
{
|
2017-04-21 16:38:39 +01:00
|
|
|
|
if ($syndicationTargets === null || $syndicationTargets === '') {
|
2017-02-24 14:38:52 +00:00
|
|
|
|
return;
|
2016-05-19 15:01:28 +01:00
|
|
|
|
}
|
2016-06-23 23:13:38 +01:00
|
|
|
|
$syndicateTo = [];
|
2016-06-29 23:53:48 +01:00
|
|
|
|
$data = json_decode($syndicationTargets, true);
|
2017-04-21 16:38:39 +01:00
|
|
|
|
if (array_key_exists('uid', $data)) {
|
|
|
|
|
$syndicateTo[] = [
|
|
|
|
|
'target' => $data['uid'],
|
|
|
|
|
'name' => $data['name'],
|
|
|
|
|
];
|
|
|
|
|
}
|
|
|
|
|
foreach ($data as $syn) {
|
|
|
|
|
if (array_key_exists('uid', $syn)) {
|
2016-07-13 17:32:10 +01:00
|
|
|
|
$syndicateTo[] = [
|
|
|
|
|
'target' => $syn['uid'],
|
|
|
|
|
'name' => $syn['name'],
|
|
|
|
|
];
|
2016-07-13 16:39:08 +01:00
|
|
|
|
}
|
2016-05-19 15:01:28 +01:00
|
|
|
|
}
|
2017-04-21 16:38:39 +01:00
|
|
|
|
|
|
|
|
|
return $syndicateTo;
|
2016-05-19 15:01:28 +01:00
|
|
|
|
}
|
2017-03-15 12:23:42 +00:00
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Parse the media-endpoint retrieved from querying a micropub endpoint.
|
|
|
|
|
*
|
|
|
|
|
* @param string|null
|
|
|
|
|
* @return string
|
|
|
|
|
*/
|
|
|
|
|
private function parseMediaEndpoint($queryResponse = null)
|
|
|
|
|
{
|
|
|
|
|
if ($queryResponse === null) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
$data = json_decode($queryResponse, true);
|
|
|
|
|
if (array_key_exists('media-endpoint', $data)) {
|
|
|
|
|
return $data['media-endpoint'];
|
|
|
|
|
}
|
|
|
|
|
}
|
2016-05-19 15:01:28 +01:00
|
|
|
|
}
|