2020-08-08 17:10:25 +01:00
< ? php
2021-10-10 09:26:18 +01:00
declare ( strict_types = 1 );
2020-08-08 17:10:25 +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/>.
// }}}
2021-04-18 02:17:57 +01:00
namespace Component\Avatar\Controller ;
2020-08-08 17:10:25 +01:00
use App\Core\Controller ;
2021-04-29 19:12:32 +01:00
use App\Core\DB\DB ;
use App\Core\Event ;
2021-04-29 13:55:26 +01:00
use App\Core\Form ;
2021-04-29 19:12:32 +01:00
use App\Core\GSFile ;
2021-04-18 02:17:57 +01:00
use App\Core\GSFile as M ;
2021-04-29 13:55:26 +01:00
use function App\Core\I18n\_m ;
2021-08-04 19:12:37 +01:00
use App\Core\Log ;
2021-04-29 19:12:32 +01:00
use App\Util\Common ;
2021-08-04 19:12:37 +01:00
use App\Util\Exception\ClientException ;
2021-04-29 19:12:32 +01:00
use App\Util\Exception\NotFoundException ;
2021-04-29 13:55:26 +01:00
use App\Util\TemporaryFile ;
2021-08-04 19:12:37 +01:00
use Component\Avatar\Entity\Avatar as AvatarEntity ;
2020-08-08 17:10:25 +01:00
use Exception ;
2021-04-29 13:55:26 +01:00
use Symfony\Component\Form\Extension\Core\Type\CheckboxType ;
use Symfony\Component\Form\Extension\Core\Type\FileType ;
use Symfony\Component\Form\Extension\Core\Type\HiddenType ;
use Symfony\Component\Form\Extension\Core\Type\SubmitType ;
2021-04-29 19:12:32 +01:00
use Symfony\Component\Form\FormError ;
2020-08-08 17:10:25 +01:00
use Symfony\Component\HttpFoundation\Request ;
2021-08-04 19:12:37 +01:00
use Symfony\Component\HttpFoundation\Response ;
2020-08-08 17:10:25 +01:00
2021-04-18 02:17:57 +01:00
class Avatar extends Controller
2020-08-08 17:10:25 +01:00
{
2021-09-20 17:01:36 +01:00
public function default_avatar_view ( Request $request , string $size ) : Response
{
return $this -> avatar_view ( $request , 0 , $size );
}
2021-04-18 02:17:57 +01:00
/**
* @ throws Exception
*/
2021-09-18 03:22:27 +01:00
public function avatar_view ( Request $request , int $actor_id , string $size ) : Response
2020-08-08 17:10:25 +01:00
{
switch ( $size ) {
2021-04-18 02:17:57 +01:00
case 'full' :
2021-09-18 03:22:27 +01:00
$res = \Component\Avatar\Avatar :: getAvatarFileInfo ( $actor_id );
2021-08-17 21:46:09 +01:00
return M :: sendFile ( $res [ 'filepath' ], $res [ 'mimetype' ], $res [ 'title' ]);
2021-04-18 02:17:57 +01:00
default :
throw new Exception ( 'Not implemented' );
2020-08-08 17:10:25 +01:00
}
}
2021-04-29 13:55:26 +01:00
/**
* Local user avatar panel
*/
2021-08-04 19:12:37 +01:00
public static function settings_avatar ( Request $request ) : array
2021-04-29 13:55:26 +01:00
{
$form = Form :: create ([
2021-07-29 20:20:32 +01:00
[ 'avatar' , FileType :: class , [ 'label' => _m ( 'Avatar' ), 'help' => _m ( 'You can upload your personal avatar. The maximum file size is 2MB.' ), 'multiple' => false , 'required' => false ]],
2021-04-29 19:12:32 +01:00
[ 'remove' , CheckboxType :: class , [ 'label' => _m ( 'Remove avatar' ), 'help' => _m ( 'Remove your avatar and use the default one' ), 'required' => false , 'value' => false ]],
2021-07-29 20:20:32 +01:00
[ 'hidden' , HiddenType :: class , []],
2021-08-18 18:38:54 +01:00
[ 'save_avatar' , SubmitType :: class , [ 'label' => _m ( 'Submit' )]],
2021-04-29 13:55:26 +01:00
]);
$form -> handleRequest ( $request );
if ( $form -> isSubmitted () && $form -> isValid ()) {
2021-09-18 03:22:27 +01:00
$data = $form -> getData ();
$user = Common :: user ();
$actor_id = $user -> getId ();
2021-04-29 13:55:26 +01:00
if ( $data [ 'remove' ] == true ) {
2021-04-29 19:12:32 +01:00
try {
2021-09-18 03:22:27 +01:00
$avatar = DB :: findOneBy ( 'avatar' , [ 'actor_id' => $actor_id ]);
2021-04-29 19:12:32 +01:00
$avatar -> delete ();
2021-08-05 03:15:07 +01:00
Event :: handle ( 'AvatarUpdate' , [ $user -> getId ()]);
2021-04-29 19:12:32 +01:00
} catch ( NotFoundException ) {
$form -> addError ( new FormError ( _m ( 'No avatar set, so cannot delete' )));
}
2021-04-29 13:55:26 +01:00
} else {
2021-09-06 20:59:36 +01:00
$attachment = null ;
2021-04-29 13:55:26 +01:00
if ( isset ( $data [ 'hidden' ])) {
// Cropped client side
$matches = [];
if ( ! empty ( preg_match ( '/data:([^;]*)(;(base64))?,(.*)/' , $data [ 'hidden' ], $matches ))) {
2021-10-10 09:26:18 +01:00
[, , , $encoding_user , $data_user ] = $matches ;
2021-07-20 21:17:53 +01:00
if ( $encoding_user === 'base64' ) {
2021-04-29 13:55:26 +01:00
$data_user = base64_decode ( $data_user );
2021-07-20 21:17:53 +01:00
$tempfile = new TemporaryFile ([ 'prefix' => 'gs-avatar' ]);
$tempfile -> write ( $data_user );
2021-09-22 15:04:45 +01:00
$attachment = GSFile :: storeFileAsAttachment ( $tempfile );
2021-04-29 13:55:26 +01:00
} else {
Log :: info ( 'Avatar upload got an invalid encoding, something\'s fishy and/or wrong' );
}
}
} elseif ( isset ( $data [ 'avatar' ])) {
2021-08-04 19:12:37 +01:00
// Cropping failed (e.g. disabled js), use file as uploaded
2021-09-06 20:59:36 +01:00
$file = $data [ 'avatar' ];
2021-09-22 15:04:45 +01:00
$attachment = GSFile :: storeFileAsAttachment ( $file );
2021-04-29 13:55:26 +01:00
} else {
throw new ClientException ( 'Invalid form' );
}
2021-08-05 03:15:07 +01:00
// Delete current avatar if there's one
2021-09-18 03:22:27 +01:00
$avatar = DB :: find ( 'avatar' , [ 'actor_id' => $actor_id ]);
2021-08-05 03:15:07 +01:00
$avatar ? -> delete ();
2021-04-29 19:12:32 +01:00
DB :: persist ( $attachment );
2021-04-29 13:55:26 +01:00
// Can only get new id after inserting
DB :: flush ();
2021-09-18 03:22:27 +01:00
DB :: persist ( AvatarEntity :: create ([ 'actor_id' => $actor_id , 'attachment_id' => $attachment -> getId ()]));
2021-04-29 13:55:26 +01:00
DB :: flush ();
2021-08-05 03:15:07 +01:00
Event :: handle ( 'AvatarUpdate' , [ $user -> getId ()]);
2021-04-29 13:55:26 +01:00
}
}
return [ '_template' => 'settings/avatar.html.twig' , 'avatar' => $form -> createView ()];
}
2020-08-08 17:10:25 +01:00
}