|                                                                                                                                                                                                                                                                                                          |  | <?phpuse 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');
    $source = $this->http->get($sourceURL, ['Accept: text/html, */*']);    $xray = new \p3k\XRay();    $parsed = $xray->parse($sourceURL, $source['body']);
    if($parsed && isset($parsed['data'])) {      $links = Telegraph\FindLinks::all($parsed['data']);    } else {      $links = [];    }
    // 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();  }}
 |