[AVATAR] Handle avatar upload without js and save and validate uploaded files
This commit is contained in:
parent
48971b70a0
commit
2bf914f96f
@ -1,7 +1,6 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
// {{{ License
|
// {{{ License
|
||||||
|
|
||||||
// This file is part of GNU social - https://www.gnu.org/software/social
|
// 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
|
// GNU social is free software: you can redistribute it and/or modify
|
||||||
@ -16,7 +15,6 @@
|
|||||||
//
|
//
|
||||||
// You should have received a copy of the GNU Affero General Public License
|
// 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/>.
|
// along with GNU social. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
// }}}
|
// }}}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -39,8 +37,12 @@ use App\Core\DB\DB;
|
|||||||
use App\Core\Event;
|
use App\Core\Event;
|
||||||
use App\Core\Form;
|
use App\Core\Form;
|
||||||
use function App\Core\I18n\_m;
|
use function App\Core\I18n\_m;
|
||||||
|
use App\Core\Log;
|
||||||
|
use App\Entity\File;
|
||||||
|
use App\Util\ClientException;
|
||||||
use App\Util\Common;
|
use App\Util\Common;
|
||||||
use App\Util\Form\ArrayTransformer;
|
use App\Util\Form\ArrayTransformer;
|
||||||
|
use Component\Media\Media;
|
||||||
use Doctrine\DBAL\Types\Types;
|
use Doctrine\DBAL\Types\Types;
|
||||||
use Exception;
|
use Exception;
|
||||||
use Functional as F;
|
use Functional as F;
|
||||||
@ -53,6 +55,7 @@ use Symfony\Component\Form\Extension\Core\Type\LanguageType;
|
|||||||
use Symfony\Component\Form\Extension\Core\Type\SubmitType;
|
use Symfony\Component\Form\Extension\Core\Type\SubmitType;
|
||||||
use Symfony\Component\Form\Extension\Core\Type\TextareaType;
|
use Symfony\Component\Form\Extension\Core\Type\TextareaType;
|
||||||
use Symfony\Component\Form\Extension\Core\Type\TextType;
|
use Symfony\Component\Form\Extension\Core\Type\TextType;
|
||||||
|
use Symfony\Component\HttpFoundation\File\File as SymfonyFile;
|
||||||
use Symfony\Component\HttpFoundation\Request;
|
use Symfony\Component\HttpFoundation\Request;
|
||||||
|
|
||||||
// }}} Imports
|
// }}} Imports
|
||||||
@ -100,20 +103,53 @@ class UserPanel extends AbstractController
|
|||||||
public function avatar(Request $request)
|
public function avatar(Request $request)
|
||||||
{
|
{
|
||||||
$avatar = Form::create([
|
$avatar = Form::create([
|
||||||
['avatar', FileType::class, ['label' => _m('Avatar'), 'help' => _m('You can upload your personal avatar. The maximum file size is 2MB.')]],
|
['avatar', FileType::class, ['label' => _m('Avatar'), 'help' => _m('You can upload your personal avatar. The maximum file size is 2MB.')]],
|
||||||
['hidden', HiddenType::class, []],
|
['hidden', HiddenType::class, []],
|
||||||
['save', SubmitType::class, ['label' => _m('Submit')]],
|
['save', SubmitType::class, ['label' => _m('Submit')]],
|
||||||
]);
|
]);
|
||||||
|
|
||||||
$avatar->handleRequest($request);
|
$avatar->handleRequest($request);
|
||||||
|
|
||||||
if ($avatar->isSubmitted() && $avatar->isValid()) {
|
if ($avatar->isSubmitted() && $avatar->isValid()) {
|
||||||
$data = $avatar->getData()['hidden'];
|
$data = $avatar->getData();
|
||||||
list($type, $data) = explode(';', $data);
|
$sfile = $file_title = null;
|
||||||
list(, $data) = explode(',', $data);
|
if (isset($data['hidden'])) {
|
||||||
$data = base64_decode($data);
|
// Cropped client side
|
||||||
|
$matches = [];
|
||||||
file_put_contents('/tmp/image.png', $data);
|
if (!empty(preg_match('/data:([^;]*)(;(base64))?,(.*)/', $data['hidden'], $matches))) {
|
||||||
|
list(, $mimetype_user, , $encoding_user, $data_user) = $matches;
|
||||||
|
if ($encoding_user == 'base64') {
|
||||||
|
$data_user = base64_decode($data_user);
|
||||||
|
$tmp_file = tmpfile();
|
||||||
|
fwrite($tmp_file, $data_user);
|
||||||
|
try {
|
||||||
|
$sfile = new SymfonyFile(stream_get_meta_data($tmp_file)['uri']);
|
||||||
|
$file_title = $data['avatar']->getFilename();
|
||||||
|
} finally {
|
||||||
|
fclose($tmp_file);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
Log::info('Avatar upload got an invalid encoding, something\'s fishy and/or wrong');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} elseif (isset($data['avatar'])) {
|
||||||
|
// Cropping failed (e.g. disabled js), have file as uploaded
|
||||||
|
$sfile = $data['avatar'];
|
||||||
|
} else {
|
||||||
|
throw new ClientException('Invalid form');
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
$profile_id = Common::user()->getProfile()->getId();
|
||||||
|
$file = Media::validateAndStoreFile($sfile, Common::config('avatar', 'dir'), $file_title);
|
||||||
|
$fs_files_to_delete = DB::find('avatar', ['profile_id' => $profile_id])->delete();
|
||||||
|
DB::persist(Avatar::create(['profile_id' => $profile_id, 'file_id' => $file->getId()]));
|
||||||
|
DB::persist($file);
|
||||||
|
DB::flush();
|
||||||
|
// Only delete files if the commit went through
|
||||||
|
File::deleteFiles($fs_files_to_delete);
|
||||||
|
} catch (Exception $e) {
|
||||||
|
throw $e;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return ['_template' => 'settings/avatar.html.twig', 'avatar' => $avatar->createView()];
|
return ['_template' => 'settings/avatar.html.twig', 'avatar' => $avatar->createView()];
|
||||||
|
Loading…
Reference in New Issue
Block a user