2021-10-27 20:39:34 +01:00
< ? php
2021-11-16 19:39:03 +00:00
declare ( strict_types = 1 );
2021-10-27 20:39:34 +01:00
// {{{ License
// This file is part of GNU social - https://www.gnu.org/software/social
//
// GNU social is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// GNU social is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with GNU social. If not, see <http://www.gnu.org/licenses/>.
// }}}
namespace Plugin\Repeat\Controller ;
use App\Core\Controller ;
use App\Core\DB\DB ;
use App\Core\Form ;
2021-11-16 19:39:03 +00:00
use function App\Core\I18n\_m ;
use App\Core\Log ;
2021-10-27 20:39:34 +01:00
use App\Core\Router\Router ;
use App\Entity\Note ;
use App\Util\Common ;
2021-11-16 19:39:03 +00:00
use App\Util\Exception\ClientException ;
2021-10-27 20:39:34 +01:00
use App\Util\Exception\NoLoggedInUser ;
use App\Util\Exception\NoSuchNoteException ;
use App\Util\Exception\RedirectException ;
2021-11-01 21:19:20 +00:00
use Plugin\Repeat\Entity\NoteRepeat ;
2021-10-27 20:39:34 +01:00
use Symfony\Component\Form\Extension\Core\Type\SubmitType ;
use Symfony\Component\HttpFoundation\Request ;
class Repeat extends Controller
{
/**
2021-11-16 19:39:03 +00:00
* Controller for the note repeat non - JS page
*
2021-10-27 20:39:34 +01:00
* @ throws \App\Util\Exception\ServerException
2021-11-16 19:39:03 +00:00
* @ throws ClientException
2021-10-27 20:39:34 +01:00
* @ throws NoLoggedInUser
2021-11-16 19:39:03 +00:00
* @ throws NoSuchNoteException
* @ throws RedirectException
2021-10-27 20:39:34 +01:00
*/
public function repeatAddNote ( Request $request , int $id ) : bool | array
{
2021-11-16 19:39:03 +00:00
$user = Common :: ensureLoggedIn ();
$opts = [ 'actor_id' => $user -> getId (), 'repeat_of' => $id ];
2021-11-01 21:19:20 +00:00
$note_already_repeated = DB :: count ( 'note_repeat' , $opts ) >= 1 ;
2021-11-16 19:39:03 +00:00
// Before the form is rendered for the first time
if ( \is_null ( $note_already_repeated )) {
throw new ClientException ( _m ( 'Note already repeated!' ));
2021-10-27 20:39:34 +01:00
}
2021-11-16 19:39:03 +00:00
$note = Note :: getWithPK ([ 'id' => $id ]);
2021-10-27 20:39:34 +01:00
$form_add_to_repeat = Form :: create ([
[ 'add_repeat' , SubmitType :: class ,
[
'label' => _m ( 'Repeat note!' ),
'attr' => [
2021-11-16 19:39:03 +00:00
'title' => _m ( 'Repeat this note!' ),
2021-10-27 20:39:34 +01:00
],
],
],
]);
$form_add_to_repeat -> handleRequest ( $request );
if ( $form_add_to_repeat -> isSubmitted ()) {
2021-11-16 19:39:03 +00:00
// If the user goes back to the form, again
if ( DB :: count ( 'note_repeat' , [ 'actor_id' => $user -> getId (), 'repeat_of' => $id ]) >= 1 ) {
throw new ClientException ( _m ( 'Note already repeated!' ));
}
2021-11-01 21:19:20 +00:00
2021-11-16 19:39:03 +00:00
if ( ! \is_null ( $note )) {
2021-11-01 21:19:20 +00:00
$actor_id = $user -> getId ();
2021-11-16 19:39:03 +00:00
$content = $note -> getContent ();
2021-11-01 21:19:20 +00:00
// Create a new note with the same content as the original
$repeat = Note :: create ([
2021-11-16 19:39:03 +00:00
'actor_id' => $actor_id ,
'content' => $content ,
2021-10-27 20:39:34 +01:00
'content_type' => $note -> getContentType (),
2021-11-16 19:39:03 +00:00
'rendered' => $note -> getRendered (),
'is_local' => true ,
2021-11-01 21:19:20 +00:00
]);
// Update DB
2021-11-16 19:39:03 +00:00
DB :: persist ( $repeat );
2021-11-01 21:19:20 +00:00
DB :: flush ();
// Find the id of the note we just created
$repeat_id = $repeat -> getId ();
2021-11-16 19:39:03 +00:00
$og_id = $note -> getId ();
2021-11-01 21:19:20 +00:00
// Add it to note_repeat table
2021-11-16 19:39:03 +00:00
if ( ! \is_null ( $repeat_id )) {
2021-11-01 21:19:20 +00:00
DB :: persist ( NoteRepeat :: create ([
2021-11-16 19:39:03 +00:00
'note_id' => $repeat_id ,
'actor_id' => $actor_id ,
'repeat_of' => $og_id ,
2021-11-01 21:19:20 +00:00
]));
}
// Update DB one last time
2021-10-27 20:39:34 +01:00
DB :: flush ();
}
2021-11-16 19:39:03 +00:00
// Redirect user to where they came from
// Prevent open redirect
if ( \array_key_exists ( 'from' , ( array ) $get_params = $this -> params ())) {
if ( Router :: isAbsolute ( $get_params [ 'from' ])) {
Log :: warning ( " Actor { $actor_id } attempted to reply to a note and then get redirected to another host, or the URL was invalid ( { $get_params [ 'from' ] } ) " );
throw new ClientException ( _m ( 'Can not redirect to outside the website from here' ), 400 ); // 400 Bad request (deceptive)
} else {
// TODO anchor on element id
throw new RedirectException ( $get_params [ 'from' ]);
}
} else {
// If we don't have a URL to return to, go to the instance root
throw new RedirectException ( 'root' );
2021-10-27 20:39:34 +01:00
}
}
return [
2021-11-16 19:39:03 +00:00
'_template' => 'repeat/add_to_repeats.html.twig' ,
'note' => $note ,
2021-10-27 20:39:34 +01:00
'add_repeat' => $form_add_to_repeat -> createView (),
];
}
/**
* @ throws \App\Util\Exception\ServerException
2021-11-16 19:39:03 +00:00
* @ throws ClientException
2021-10-27 20:39:34 +01:00
* @ throws NoLoggedInUser
2021-11-16 19:39:03 +00:00
* @ throws NoSuchNoteException
* @ throws RedirectException
2021-10-27 20:39:34 +01:00
*/
public function repeatRemoveNote ( Request $request , int $id ) : array
{
2021-11-16 19:39:03 +00:00
$user = Common :: ensureLoggedIn ();
$opts = [ 'id' => $id ];
2021-10-27 20:39:34 +01:00
$remove_repeat_note = DB :: find ( 'note' , $opts );
2021-11-16 19:39:03 +00:00
if ( \is_null ( $remove_repeat_note )) {
2021-10-27 20:39:34 +01:00
throw new NoSuchNoteException ();
}
$form_remove_repeat = Form :: create ([
[ 'remove_repeat' , SubmitType :: class ,
[
'label' => _m ( 'Remove repeat' ),
'attr' => [
2021-11-16 19:39:03 +00:00
'title' => _m ( 'Remove note from repeats.' ),
2021-10-27 20:39:34 +01:00
],
],
],
]);
$form_remove_repeat -> handleRequest ( $request );
if ( $form_remove_repeat -> isSubmitted ()) {
if ( $remove_repeat_note ) {
2021-11-15 17:19:20 +00:00
// Remove the note itself
2021-10-27 20:39:34 +01:00
DB :: remove ( $remove_repeat_note );
DB :: flush ();
2021-11-15 17:19:20 +00:00
// Remove from the note_repeat table
2021-11-16 19:39:03 +00:00
$opts = [ 'note_id' => $id ];
2021-11-15 17:19:20 +00:00
$remove_note_repeat = DB :: find ( 'note_repeat' , $opts );
DB :: remove ( $remove_note_repeat );
DB :: flush ();
2021-10-27 20:39:34 +01:00
}
2021-11-16 19:39:03 +00:00
// Redirect user to where they came from
// Prevent open redirect
if ( \array_key_exists ( 'from' , ( array ) $get_params = $this -> params ())) {
if ( Router :: isAbsolute ( $get_params [ 'from' ])) {
Log :: warning ( " Actor { $actor_id } attempted to reply to a note and then get redirected to another host, or the URL was invalid ( { $get_params [ 'from' ] } ) " );
throw new ClientException ( _m ( 'Can not redirect to outside the website from here' ), 400 ); // 400 Bad request (deceptive)
} else {
// TODO anchor on element id
throw new RedirectException ( $get_params [ 'from' ]);
}
} else {
throw new RedirectException ( 'root' ); // If we don't have a URL to return to, go to the instance root
2021-10-27 20:39:34 +01:00
}
}
return [
2021-11-16 19:39:03 +00:00
'_template' => 'repeat/remove_from_repeats.html.twig' ,
'note' => $remove_repeat_note ,
'remove_repeat' => $form_remove_repeat -> createView (),
2021-10-27 20:39:34 +01:00
];
}
}