fediplan/src/Controller/FediPlanController.php

344 lines
14 KiB
PHP
Raw Normal View History

2019-08-08 17:29:59 +02:00
<?php
/**
* Created by fediplan.
* User: tom79
* Date: 08/08/19
* Time: 10:16
*/
namespace App\Controller;
2019-08-09 13:55:27 +02:00
use App\Form\ComposeType;
2019-08-08 17:29:59 +02:00
use App\Form\ConnectMastodonAccountFlow;
use App\Services\Mastodon_api;
use App\SocialEntity\Client;
2019-08-09 13:55:27 +02:00
use App\SocialEntity\Compose;
2019-08-09 14:11:13 +02:00
use App\SocialEntity\MastodonAccount;
2020-05-01 15:19:30 +02:00
use App\SocialEntity\PollOption;
2019-08-10 14:23:06 +02:00
use DateTime;
use DateTimeZone;
2019-08-08 17:29:59 +02:00
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\Form\FormError;
2019-08-11 18:24:07 +02:00
use Symfony\Component\HttpFoundation\JsonResponse;
2019-08-08 17:29:59 +02:00
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Component\Security\Core\Authorization\AuthorizationCheckerInterface;
use Symfony\Component\Security\Http\Event\InteractiveLoginEvent;
use Symfony\Contracts\EventDispatcher\EventDispatcherInterface;
use Symfony\Contracts\Translation\TranslatorInterface;
use Symfony\Component\Security\Core\Authentication\Token\UsernamePasswordToken;
2019-08-21 17:49:04 +02:00
2019-08-08 17:29:59 +02:00
class FediPlanController extends AbstractController
{
2019-08-09 14:11:13 +02:00
2019-08-08 17:29:59 +02:00
/**
2019-08-22 09:54:45 +02:00
* @Route("/{_locale}",name="index", defaults={"_locale"="en"}, requirements={"_locale": "%allowed_language%"})
2019-08-08 17:29:59 +02:00
*/
public function indexAction(Request $request, AuthorizationCheckerInterface $authorizationChecker, ConnectMastodonAccountFlow $flow, Mastodon_api $mastodon_api, TranslatorInterface $translator, EventDispatcherInterface $eventDispatcher)
{
if ($authorizationChecker->isGranted('IS_AUTHENTICATED_FULLY')){
2019-08-21 16:33:04 +02:00
$local = $request->getSession()->get('_locale');
return $this->redirect($this->generateUrl('schedule',['_locale' => $local]));
2019-08-08 17:29:59 +02:00
}
$client = new Client();
$flow->bind($client);
$form = $flow->createForm();
$urlToMastodon = null;
$client_id = null;
$client_secret = null;
if ($flow->isValid($form)) {
if( $flow->getCurrentStep() == 1){
$host = $client->getHost();
$result = $mastodon_api->getInstanceNodeInfo($host);
//We currently only support Mastodon accounts
if( $result != "MASTODON" && $result != "PLEROMA"){
$form->get('host')->addError(new FormError($translator->trans('error.instance.mastodon_only',[],'fediplan','en')));
}else{
$mastodon_api->set_url("https://" . $host);
$mastodon_api->set_scopes([]);
2019-08-10 15:38:12 +02:00
$createApp = $mastodon_api->create_app("FediPlan", [], '', "https://plan.fedilab.app");
2019-08-08 17:29:59 +02:00
if( isset($createApp['error']) ){
$form->get('host')->addError(new FormError($translator->trans('error.instance.mastodon_client_id',[],'fediplan','en')));
}else{
// form for the next step
$mastodon_api->set_client($createApp['response']['client_id'], $createApp['response']['client_secret']);
$urlToMastodon = $mastodon_api->getAuthorizationUrl();
if( isset($createApp['error']) ){
$form->get('host')->addError(new FormError($translator->trans('error.instance.mastodon_oauth_url',[],'fediplan','en')));
}else{
$flow->saveCurrentStepData($form);
$client_id = $createApp['response']['client_id'];
$client_secret = $createApp['response']['client_secret'];
$flow->nextStep();
$form = $flow->createForm();
}
}
}
} else if ($flow->getCurrentStep() == 2) {
2019-08-09 15:17:44 +02:00
$host = $client->getHost();
2019-08-08 17:29:59 +02:00
$code = $client->getCode();
$mastodon_api->set_url("https://" . $client->getHost());
$mastodon_api->set_scopes([]);
$mastodon_api->set_client($client->getClientId(), $client->getClientSecret());
$reply = $mastodon_api->loginAuthorization($code);
if( isset($reply['error']) ){
2019-08-12 15:50:41 +02:00
/* $access_token = $code;
$token_type = "Bearer";
$mastodon_api->set_url("https://" . $client->getHost());
$mastodon_api->set_token($access_token, $token_type);
try {
$accountReply = $mastodon_api->accounts_verify_credentials();
} catch (\ErrorException $e) {
}
if( isset($accountReply['error']) ){
$form->get('code')->addError(new FormError($translator->trans('error.instance.mastodon_account',[],'fediplan','en')));
}else{
$Account = $mastodon_api->getSingleAccount($accountReply['response']);
$Account->setInstance($host);
$Account->setToken($token_type ." ".$access_token);
$token = new UsernamePasswordToken($Account, null, 'main', array('ROLE_USER'));
$this->get('security.token_storage')->setToken($token);
$event = new InteractiveLoginEvent($request, $token);
$eventDispatcher->dispatch("security.interactive_login", $event);
return $this->redirectToRoute('schedule');
}*/
2019-08-08 17:29:59 +02:00
$form->get('code')->addError(new FormError($translator->trans('error.instance.mastodon_token',[],'fediplan','en')));
}else{
$access_token = $reply['response']['access_token'];
$token_type = $reply['response']['token_type'];
$mastodon_api->set_url("https://" . $client->getHost());
$mastodon_api->set_token($access_token, $token_type);
2019-08-12 15:50:41 +02:00
try {
$accountReply = $mastodon_api->accounts_verify_credentials();
} catch (\ErrorException $e) {
}
2019-08-08 17:29:59 +02:00
if( isset($accountReply['error']) ){
$form->get('code')->addError(new FormError($translator->trans('error.instance.mastodon_account',[],'fediplan','en')));
}else{
$Account = $mastodon_api->getSingleAccount($accountReply['response']);
2019-08-09 15:17:44 +02:00
$Account->setInstance($host);
2019-08-09 14:11:13 +02:00
$Account->setToken($token_type ." ".$access_token);
2019-08-08 17:29:59 +02:00
$token = new UsernamePasswordToken($Account, null, 'main', array('ROLE_USER'));
$this->get('security.token_storage')->setToken($token);
$event = new InteractiveLoginEvent($request, $token);
$eventDispatcher->dispatch("security.interactive_login", $event);
return $this->redirectToRoute('schedule');
}
}
}
}
return $this->render('fediplan/index.html.twig', [
'form' => $form->createView(),
'flow' => $flow,
'urlToMastodon' => $urlToMastodon,
'client_id' => $client_id,
'client_secret' => $client_secret,
]);
}
/**
2019-08-22 09:54:45 +02:00
* @Route("/{_locale}/schedule", name="schedule", defaults={"_locale"="en"}, requirements={"_locale": "%allowed_language%"})
2019-08-08 17:29:59 +02:00
*/
2019-08-10 14:23:06 +02:00
public function schedule(Request $request, Mastodon_api $mastodon_api)
2019-08-08 17:29:59 +02:00
{
2019-08-09 13:55:27 +02:00
$compose = new Compose();
2020-05-01 15:19:30 +02:00
$pollOption1 = new PollOption();
$pollOption1->setTitle("");
$compose->getPollOptions()->add($pollOption1);
$pollOption2 = new PollOption();
$pollOption2->setTitle("");
$compose->getPollOptions()->add($pollOption2);
$form = $this->createForm(ComposeType::class, $compose, ['user' => $this->getUser()]);
2019-08-10 09:41:59 +02:00
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
/** @var $data Compose */
2019-08-10 14:23:06 +02:00
$data = $form->getData();
/* @var $user MastodonAccount */
$user = $this->getUser();
$mastodon_api->set_url("https://" . $user->getInstance());
$token = explode(" " ,$user->getToken())[1];
$type = explode(" ", $user->getToken())[0];
$mastodon_api->set_token($token, $type);
$params = [];
//Update media description and store their id
2019-08-10 09:41:59 +02:00
foreach ($_POST as $key => $value){
if( $key != "compose"){
2019-08-10 14:23:06 +02:00
2019-08-10 09:41:59 +02:00
if (strpos($key, 'media_id_') !== false){
2019-08-10 14:23:06 +02:00
2019-08-10 09:41:59 +02:00
$mediaId = $value;
$description = $_POST['media_description_'.$mediaId];
2019-08-10 14:23:06 +02:00
//update description if needed
2019-08-10 09:41:59 +02:00
if( $description != null && trim($description) != ""){
2019-08-10 14:23:06 +02:00
try {
$res = $mastodon_api->update_media($mediaId, ['description' => $description]);
} catch (\ErrorException $e) {}
2019-08-10 09:41:59 +02:00
}
2019-08-10 14:23:06 +02:00
$params['media_ids'][] = $mediaId;
2019-08-10 09:41:59 +02:00
}
}
}
2019-08-10 14:23:06 +02:00
//Schedule status
if( $data->getContentWarning() ){
$params['spoiler_text'] = $data->getContentWarning();
}
if( $data->getContent() ){
$params['status'] = $data->getContent();
}
if( $data->getVisibility() ){
$params['visibility'] = $data->getVisibility();
}
$params['sensitive'] = ($data->getSensitive() == null || !$data->getSensitive())?false:true;
2020-05-01 16:40:07 +02:00
$pollOptions = $data->getPollOptions();
$pollExpiresAt = $data->getPollExpiresAt();
$isPollMultiple = $data->isPollMultiple();
if( count($pollOptions) > 0){
$count_correct_values = 0;
foreach($pollOptions as $po) {
/** @var $po PollOption */
if( $po->getTitle() != null && strlen(trim($po->getTitle())) > 0){
$count_correct_values++;
}
}
if( $count_correct_values > 1 ){
$params['poll']['options'] = [];
foreach($pollOptions as $po) {
/** @var $po PollOption */
if( $po->getTitle() != null && strlen(trim($po->getTitle())) > 0){
$params['poll']['options'][] = trim($po->getTitle());
}
}
$params['poll']['expires_in'] = $pollExpiresAt;
$params['poll']['multiple'] = $isPollMultiple;
}
}
2019-08-10 14:23:06 +02:00
try {
2019-08-20 19:16:46 +02:00
$date = new DateTime( $data->getScheduledAt()->format("Y-m-d H:i"), new DateTimeZone($data->getTimeZone()) );
2019-08-10 14:23:06 +02:00
$date->setTimezone( new DateTimeZone("UTC"));
2019-08-20 19:16:46 +02:00
$params['scheduled_at'] = $date->format(DateTime::ISO8601);
2019-08-10 14:23:06 +02:00
} catch (\Exception $e) {}
try {
$response = $mastodon_api->post_statuses($params);
} catch (\ErrorException $e) {}
2020-05-01 16:40:07 +02:00
2019-08-10 14:23:06 +02:00
$session = $request->getSession();
if( isset($response['error']) ){
$session->getFlashBag()->add(
'Error',
$response['error_message']
);
}else{
unset($compose);
unset($form);
$compose = new Compose();
$session->getFlashBag()->add(
'Success',
'The message has been scheduled'
);
2019-08-11 11:51:32 +02:00
$form = $this->createForm(ComposeType::class, $compose, ['user' => $this->getUser()]);
2019-08-10 14:23:06 +02:00
}
2019-08-08 17:29:59 +02:00
}
2019-08-09 14:11:13 +02:00
$user = $this->getUser();
/** @var $user MastodonAccount */
return $this->render("fediplan/schedule.html.twig",[
'form' => $form->createView(),
2019-08-09 15:17:44 +02:00
'instance' => $user->getInstance(),
2019-08-09 14:11:13 +02:00
'token' => $user->getToken(),
]);
2019-08-08 17:29:59 +02:00
}
/**
2019-08-22 09:54:45 +02:00
* @Route("/{_locale}/scheduled", name="scheduled", defaults={"_locale"="en"}, requirements={"_locale": "%allowed_language%"})
2019-08-08 17:29:59 +02:00
*/
public function scheduled()
{
2019-08-11 18:24:07 +02:00
return $this->render("fediplan/scheduled.html.twig");
}
/**
2019-08-21 17:49:04 +02:00
* @Route("/{_locale}/scheduled/messages/{max_id}", options={"expose"=true}, name="load_more")
2019-08-11 18:24:07 +02:00
*/
2019-08-11 19:02:11 +02:00
public function loadMoreAction(Mastodon_api $mastodon_api, String $max_id = null){
2019-08-11 18:24:07 +02:00
$user = $this->getUser();
/** @var $mastodon_api Mastodon_api */
$mastodon_api->set_url("https://" . $user->getInstance());
$token = explode(" " ,$user->getToken())[1];
$type = explode(" ", $user->getToken())[0];
$mastodon_api->set_token($token, $type);
$params = [];
if( $max_id != null){
$params['max_id'] = $max_id;
}
$scheduled_reply = [];
try {
$scheduled_reply = $mastodon_api->get_scheduled($params);
} catch (\ErrorException $e) {
}
$statuses = $mastodon_api->getScheduledStatuses($scheduled_reply['response'], $this->getUser());
$data['max_id'] = $scheduled_reply['max_id'];
$data['html'] = $this->renderView('fediplan/Ajax/layout.html.twig', ['statuses' => $statuses]);
return new JsonResponse($data);
}
/**
2019-08-22 09:54:45 +02:00
* @Route("/{_locale}/scheduled/delete/messages/{id}", options={"expose"=true}, name="delete_message", methods={"POST"}, defaults={"_locale"="en"}, requirements={"_locale": "%allowed_language%"})
2019-08-11 18:24:07 +02:00
*/
2019-08-11 19:02:11 +02:00
public function deleteMessage(Mastodon_api $mastodon_api, String $id = null){
2019-08-11 18:24:07 +02:00
$user = $this->getUser();
/** @var $mastodon_api Mastodon_api */
$mastodon_api->set_url("https://" . $user->getInstance());
$token = explode(" " ,$user->getToken())[1];
$type = explode(" ", $user->getToken())[0];
$mastodon_api->set_token($token, $type);
$response = [];
try {
$response = $mastodon_api->delete_scheduled($id);
} catch (\ErrorException $e) {}
return new JsonResponse($response);
2019-08-08 17:29:59 +02:00
}
2019-08-21 10:16:55 +02:00
/**
2019-08-21 17:49:04 +02:00
* @Route("/about",defaults={"_locale"="en"})
2019-08-22 09:54:45 +02:00
* @Route("/{_locale}/about", name="about", defaults={"_locale":"en"}, requirements={"_locale": "%allowed_language%"})
2019-08-21 10:16:55 +02:00
*/
public function about()
{
return $this->render("fediplan/about.html.twig");
}
2019-08-08 17:29:59 +02:00
/**
* @Route("/logout", name="logout")
*/
public function logout()
{
return $this->render("fediplan/index.html.twig");
}
}