|
|
- <?php
- use Symfony\Component\HttpFoundation\Request;
- use Symfony\Component\HttpFoundation\Response;
-
- class Controller {
-
- public $http;
-
- public function __construct() {
- $this->http = new Telegraph\HTTP();
- }
-
- private function _is_logged_in(Request $request, Response $response) {
- session_start();
- if(!session('user_id')) {
- session_destroy();
- $response->setStatusCode(302);
- $response->headers->set('Location', '/login?return_to='.$request->getRequestURI());
- return false;
- } else {
- return true;
- }
- }
-
- private function _get_role(Request $request, Response $response) {
- // Default to load their first site, but let the query string override it
- $role = ORM::for_table('roles')->join('sites', 'roles.site_id = sites.id')
- ->where('user_id', session('user_id'))->order_by_asc('sites.created_at')->find_one();
-
- if($request->get('account')) {
- $role = ORM::for_table('roles')->where('user_id', session('user_id'))->where('site_id', $request->get('account'))->find_one();
- // Check that the user has permission to access this account
- if(!$role) {
- $response->setStatusCode(302);
- $response->headers->set('Location', '/dashboard');
- return false;
- }
- }
-
- return $role;
- }
-
- public function index(Request $request, Response $response) {
- p3k\session_setup();
-
- $response->setContent(view('index', [
- 'title' => 'Telegraph',
- 'user' => $this->_user(),
- ]));
- return $response;
- }
-
- public function api(Request $request, Response $response) {
- session_start();
- if(session('user_id')) {
- $role = $this->_get_role($request, $response);
- $site = ORM::for_table('sites')->where_id_is($role->site_id)->find_one();
- } else {
- $role = false;
- $site = false;
- }
-
- $response->setContent(view('api', [
- 'title' => 'Telegraph API Documentation',
- 'user' => $this->_user(),
- 'accounts' => $this->_accounts(),
- 'site' => $site,
- 'role' => $role,
- 'return_to' => $request->getRequestURI()
- ]));
- return $response;
- }
-
- public function superfeedr(Request $request, Response $response) {
- session_start();
- if(session('user_id')) {
- $role = $this->_get_role($request, $response);
- $site = ORM::for_table('sites')->where_id_is($role->site_id)->find_one();
- } else {
- $role = false;
- $site = false;
- }
-
- $response->setContent(view('superfeedr', [
- 'title' => 'Telegraph Superfeedr Documentation',
- 'user' => $this->_user(),
- 'accounts' => $this->_accounts(),
- 'site' => $site,
- 'role' => $role,
- 'return_to' => $request->getRequestURI()
- ]));
- return $response;
- }
-
- private static function _icon_for_status($status) {
- switch($status) {
- case 'success':
- case 'accepted':
- return 'green checkmark';
- case 'not_supported':
- return 'yellow x';
- case 'error':
- return 'red x';
- case 'pending':
- return 'orange wait';
- default:
- return '';
- }
- }
-
- public function dashboard(Request $request, Response $response) {
- if(!$this->_is_logged_in($request, $response)) {
- return $response;
- }
-
- if(!$role=$this->_get_role($request, $response)) {
- return $response;
- }
-
- $site = ORM::for_table('sites')->where_id_is($role->site_id)->find_one();
-
- $query = ORM::for_table('webmentions')->where('site_id', $site->id)
- ->order_by_desc('created_at')
- ->limit(20)
- ->find_many();
-
- $webmentions = [];
- foreach($query as $m) {
- $statuses = ORM::for_table('webmention_status')->where('webmention_id', $m->id)->order_by_desc('created_at')->find_many();
- if(count($statuses) == 0) {
- $status = 'pending';
- } else {
- $status = $statuses[0]->status;
- }
- $icon = self::_icon_for_status($status);
-
- $webmentions[] = [
- 'webmention' => $m,
- 'statuses' => $statuses,
- 'status' => $status,
- 'icon' => $icon
- ];
- }
-
- $response->setContent(view('dashboard', [
- 'title' => 'Telegraph Dashboard',
- 'user' => $this->_user(),
- 'accounts' => $this->_accounts(),
- 'site' => $site,
- 'role' => $role,
- 'webmentions' => $webmentions
- ]));
- return $response;
- }
-
- public function send_a_webmention(Request $request, Response $response) {
- session_start();
-
- $_SESSION['_csrf'] = random_string(16);
-
- $response->setContent(view('send-a-webmention', [
- 'title' => 'Send a Webmention with Telegraph',
- 'user' => $this->_user(),
- 'accounts' => $this->_accounts(),
- 'csrf' => $_SESSION['_csrf'],
- ]));
- return $response;
- }
-
- public function new_site(Request $request, Response $response) {
- if(!$this->_is_logged_in($request, $response)) {
- return $response;
- }
-
- if(!$role=$this->_get_role($request, $response)) {
- return $response;
- }
-
- if($request->get('account')) {
- // permissions are checked already by _get_role
- $site = ORM::for_table('sites')->where_id_is($request->get('account'))->find_one();
- } else {
- $site = null;
- }
-
- $response->setContent(view('new-site', [
- 'title' => 'Create New Site',
- 'user' => $this->_user(),
- 'accounts' => $this->_accounts(),
- 'role' => $role,
- 'site' => $site
- ]));
- return $response;
- }
-
- public function save_site(Request $request, Response $response) {
- if(!$this->_is_logged_in($request, $response)) {
- return $response;
- }
-
- if(!$role=$this->_get_role($request, $response)) {
- return $response;
- }
-
- if($request->get('account')) {
- // permissions are checked already by _get_role
- $site = ORM::for_table('sites')->where_id_is($request->get('account'))->find_one();
- $site->name = $request->get('name');
- $site->url = $request->get('url');
- $site->save();
- } else {
- $site = ORM::for_table('sites')->create();
- $site->created_by = session('user_id');
- $site->created_at = date('Y-m-d H:i:s');
- $site->name = $request->get('name');
- $site->url = $request->get('url');
- $site->save();
-
- $role = ORM::for_table('roles')->create();
- $role->site_id = $site->id;
- $role->user_id = session('user_id');
- $role->role = 'owner';
- $role->token = random_string(32);
- $role->save();
- }
-
- $response->setStatusCode(302);
- $response->headers->set('Location', '/dashboard?account='.$site->id);
- return $response;
- }
-
- public function webmention_details(Request $request, Response $response, $args) {
- session_start();
-
- // Look up the webmention by its token
- $webmention = ORM::for_table('webmentions')->where('token', $args['code'])->find_one();
-
- if(!$webmention) {
- $response->setContent(view('not-found'));
- return $response;
- }
-
- $site = ORM::for_table('sites')->where_id_is($webmention->site_id)->find_one();
-
- // Find the user's role for this site
- if($site && $this->_user()) {
- $role = ORM::for_table('roles')
- ->where('site_id', $site['id'])
- ->where('user_id', $this->_user()['id'])
- ->find_one();
- }
-
- $statuses = ORM::for_table('webmention_status')->where('webmention_id', $webmention->id)->order_by_desc('created_at')->find_many();
-
- if(count($statuses) == 0) {
- $status = 'pending';
- } else {
- $status = $statuses[0]->status;
- }
- $icon = self::_icon_for_status($status);
-
- $response->setContent(view('webmention-details', [
- 'title' => 'Webmention Details',
- 'user' => $this->_user(),
- 'accounts' => $this->_accounts(),
- 'site' => $site,
- 'role' => isset($role) ? $role : false,
- 'webmention' => $webmention,
- 'statuses' => $statuses,
- 'icon' => $icon,
- 'status' => $status
- ]));
- return $response;
- }
-
- public function dashboard_send(Request $request, Response $response) {
- if(!$this->_is_logged_in($request, $response)) {
- return $response;
- }
-
- if(!$role=$this->_get_role($request, $response)) {
- return $response;
- }
-
- $site = ORM::for_table('sites')->where_id_is($role->site_id)->find_one();
-
- $response->setContent(view('webmention-send', [
- 'title' => 'Webmention Details',
- 'user' => $this->_user(),
- 'accounts' => $this->_accounts(),
- 'site' => $site,
- 'role' => $role,
- 'url' => $request->get('url')
- ]));
- return $response;
- }
-
- public function get_outgoing_links(Request $request, Response $response) {
- if(!$this->_is_logged_in($request, $response)) {
- return $response;
- }
-
- $sourceURL = $request->get('url');
-
- $client = new IndieWeb\MentionClient();
- $source = $this->http->get($sourceURL, ['Accept: text/html, */*']);
- $parsed = \Mf2\parse($source['body'], $sourceURL);
-
- $links = array_values($client->findOutgoingLinks($parsed));
-
- // Remove the source URL from the list if present
- $links = array_filter($links, function($link) use($sourceURL) {
- // Remove URL fragment when comparing to ignore more self-links
- $link = preg_replace('/#.+$/', '', $link);
- return $link != $sourceURL;
- });
-
- $response->headers->set('Content-Type', 'application/json');
- $response->setContent(json_encode([
- 'links' => $links
- ]));
- return $response;
- }
-
- public function discover_endpoint(Request $request, Response $response) {
- if(!$this->_is_logged_in($request, $response)) {
- return $response;
- }
-
- $targetURL = $request->get('target');
-
- if(!Telegraph\Webmention::isProbablySupported($targetURL)) {
- $status = 'none';
- $cached = -1;
- } else {
- // Cache the discovered result
- $cacheKey = 'telegraph:discover_endpoint:'.$targetURL;
- if($request->get('ignore_cache') == 'true' || (!$status = redis()->get($cacheKey))) {
- $client = new IndieWeb\MentionClient();
- $endpoint = $client->discoverWebmentionEndpoint($targetURL);
- if($endpoint) {
- $status = 'webmention';
- } else {
- $endpoint = $client->discoverPingbackEndpoint($targetURL);
- if($endpoint) {
- $status = 'pingback';
- } else {
- $status = 'none';
- }
- }
- $cached = false;
- redis()->setex($cacheKey, 600, $status);
- } else {
- $cached = true;
- }
- }
-
- $response->headers->set('Content-Type', 'application/json');
- $response->setContent(json_encode([
- 'status' => $status,
- 'cached' => $cached
- ]));
- return $response;
- }
-
- private function _user() {
- if(!session('user_id')) return null;
- return ORM::for_table('users')->where_id_is(session('user_id'))->find_one();
- }
-
- private function _accounts() {
- if(!session('user_id')) return [];
- return ORM::for_table('sites')->join('roles', 'roles.site_id = sites.id')
- ->where('roles.user_id', session('user_id'))
- ->find_many();
- }
- }
|