[TOOLS] Fix all level 0 errors found by PHPStan and move constant definition to bootstrap file

This commit is contained in:
Hugo Sales 2021-09-06 19:49:03 +01:00
parent 0eb0236feb
commit eb833b62e2
No known key found for this signature in database
GPG Key ID: 7D0C7EAFC9D835A0
33 changed files with 312 additions and 285 deletions

View File

@ -23,4 +23,26 @@ $_SERVER['APP_ENV'] = $_ENV['APP_ENV'] = ($_SERVER['APP_ENV'] ?? $_ENV['APP_
$_SERVER['APP_DEBUG'] = $_SERVER['APP_DEBUG'] ?? $_ENV['APP_DEBUG'] ?? 'prod' !== $_SERVER['APP_ENV'];
$_SERVER['APP_DEBUG'] = $_ENV['APP_DEBUG'] = (int) $_SERVER['APP_DEBUG'] || filter_var($_SERVER['APP_DEBUG'], FILTER_VALIDATE_BOOLEAN) ? '1' : '0';
define('INSTALLDIR', dirname(__DIR__));
define('SRCDIR', INSTALLDIR . '/src');
define('PUBLICDIR', INSTALLDIR . '/public');
define('GNUSOCIAL_ENGINE_NAME', 'GNU social');
// MERGE Change to https://gnu.io/social/
define('GNUSOCIAL_PROJECT_URL', 'https://gnusocial.rocks/');
// MERGE Change to https://git.gnu.io/gnu/gnu-social
define('GNUSOCIAL_REPOSITORY_URL', 'https://code.undefinedhackers.net/GNUsocial/gnu-social');
// Current base version, major.minor.patch
define('GNUSOCIAL_BASE_VERSION', '3.0.0');
// 'dev', 'alpha[0-9]+', 'beta[0-9]+', 'rc[0-9]+', 'release'
define('GNUSOCIAL_LIFECYCLE', 'dev');
define('GNUSOCIAL_VERSION', GNUSOCIAL_BASE_VERSION . '-' . GNUSOCIAL_LIFECYCLE);
define('GNUSOCIAL_CODENAME', 'Big bang');
define('URL_REGEX_DOMAIN_NAME', '(?:(?!-)[A-Za-z0-9\-]{1,63}(?<!-)\.)+[A-Za-z]{2,10}');
// Work internally in UTC
date_default_timezone_set('UTC');
// Work internally with UTF-8
mb_internal_encoding('UTF-8');
ModuleManager::setLoader($loader);

View File

@ -14,7 +14,7 @@ class TypeResponse extends JsonResponse
*/
public function __construct($data = null, int $status = 202, array $headers = [], bool $json = false)
{
return parent::__construct(
parent::__construct(
data: !is_null($data) ? $data->toJson() : null,
status: $status,
headers: ['content-type' => 'application/ld+json; profile="https://www.w3.org/ns/activitystreams"'],

View File

@ -23,14 +23,13 @@ namespace Plugin\Cover\Controller;
use App\Core\DB\DB;
use App\Core\Form;
use App\Core\GSFile;
use function App\Core\I18n\_m;
use App\Entity\Cover as CoverEntity;
use App\Util\Common;
use App\Util\Exception\ClientException;
use App\Util\Exception\RedirectException;
use App\Util\Exception\ServerException;
use Component\Media\Attachment;
use Component\Media\Attachment as M;
use Plugin\Cover\Entity\Cover as CoverEntity;
use Symfony\Component\Form\Extension\Core\Type\FileType;
use Symfony\Component\Form\Extension\Core\Type\HiddenType;
use Symfony\Component\Form\Extension\Core\Type\SubmitType;
@ -97,7 +96,7 @@ class Cover
if (explode('/',$sfile->getMimeType())[0] != 'image') {
throw new ServerException('Invalid file type');
}
$file = Attachment::validateAndStoreFile($sfile, Common::config('cover', 'dir'), $title = null, $is_local = true, $use_unique = $actor_id);
$file = GSFile::sanitizeAndStoreFileAsAttachment($sfile);
$old_file = null;
$cover = DB::find('cover', ['gsactor_id' => $actor_id]);
// Must get old id before inserting another one
@ -152,6 +151,6 @@ class Cover
if ($file == null) {
return new Response('Cover File not found',Response::HTTP_NOT_FOUND);
}
return M::sendFile($cover->getFilePath(), $file->getMimetype(), $file->getTitle());
return GSFile::sendFile($cover->getFilePath(), $file->getMimetype(), $file->getTitle());
}
}

View File

@ -23,6 +23,7 @@ namespace Plugin\Cover\Entity;
use App\Core\DB\DB;
use App\Core\Entity;
use App\Entity\Attachment;
use App\Util\Common;
use DateTimeInterface;

View File

@ -33,6 +33,7 @@
namespace Plugin\Embed\Controller;
use App\Core\Controller;
use App\Util\Exception\NotImplementedException;
use Symfony\Component\HttpFoundation\Request;
/**
@ -52,208 +53,211 @@ class Embed extends Controller
*/
protected function handle(Request $request)
{
$url = $this->trimmed('url');
$tls = parse_url($url, PHP_URL_SCHEME) == 'https';
$root_url = common_root_url($tls);
throw new NotImplementedException();
// $url = $this->trimmed('url');
// $tls = parse_url($url, PHP_URL_SCHEME) == 'https';
// $root_url = common_root_url($tls);
if (substr(strtolower($url), 0, mb_strlen($root_url)) !== strtolower($root_url)) {
// TRANS: Error message displaying attachments. %s is the site's base URL.
throw new ClientException(sprintf(_('Embed data will only be provided for %s URLs.'), $root_url));
}
// if (substr(strtolower($url), 0, mb_strlen($root_url)) !== strtolower($root_url)) {
// // TRANS: Error message displaying attachments. %s is the site's base URL.
// throw new ClientException(sprintf(_('Embed data will only be provided for %s URLs.'), $root_url));
// }
$path = substr($url, strlen($root_url));
// $path = substr($url, strlen($root_url));
$r = Router::get();
// $r = Router::get();
// $r->map will throw ClientException 404 if it fails to find a mapping
$proxy_args = $r->map($path);
// // $r->map will throw ClientException 404 if it fails to find a mapping
// $proxy_args = $r->map($path);
$oembed = [];
$oembed['version'] = '1.0';
$oembed['provider_name'] = common_config('site', 'name');
$oembed['provider_url'] = common_root_url();
// $oembed = [];
// $oembed['version'] = '1.0';
// $oembed['provider_name'] = common_config('site', 'name');
// $oembed['provider_url'] = common_root_url();
switch ($proxy_args['action']) {
case 'shownotice':
$oembed['type'] = 'link';
try {
$notice = Notice::getByID($proxy_args['notice']);
} catch (NoResultException $e) {
throw new ClientException($e->getMessage(), 404);
}
$profile = $notice->getProfile();
$authorname = $profile->getFancyName();
// TRANS: oEmbed title. %1$s is the author name, %2$s is the creation date.
$oembed['title'] = sprintf(
_('%1$s\'s status on %2$s'),
$authorname,
common_exact_date($notice->created)
);
$oembed['author_name'] = $authorname;
$oembed['author_url'] = $profile->profileurl;
$oembed['url'] = $notice->getUrl();
$oembed['html'] = $notice->getRendered();
// switch ($proxy_args['action']) {
// case 'shownotice':
// $oembed['type'] = 'link';
// try {
// $notice = Notice::getByID($proxy_args['notice']);
// } catch (NoResultException $e) {
// throw new ClientException($e->getMessage(), 404);
// }
// $profile = $notice->getProfile();
// $authorname = $profile->getFancyName();
// // TRANS: oEmbed title. %1$s is the author name, %2$s is the creation date.
// $oembed['title'] = sprintf(
// _('%1$s\'s status on %2$s'),
// $authorname,
// common_exact_date($notice->created)
// );
// $oembed['author_name'] = $authorname;
// $oembed['author_url'] = $profile->profileurl;
// $oembed['url'] = $notice->getUrl();
// $oembed['html'] = $notice->getRendered();
// maybe add thumbnail
foreach ($notice->attachments() as $attachment) {
if (!$attachment instanceof File) {
common_debug('ATTACHMENTS array entry from notice id==' . _ve($notice->getID()) .
' is something else than a File dataobject: ' . _ve($attachment));
continue;
}
try {
$thumb = $attachment->getThumbnail();
$thumb_url = $thumb->getUrl();
$oembed['thumbnail_url'] = $thumb_url;
break; // only first one
} catch (UseFileAsThumbnailException $e) {
$oembed['thumbnail_url'] = $attachment->getUrl();
break; // we're happy with that
} catch (ServerException $e) {
} catch (ClientException $e) {
}
}
break;
// // maybe add thumbnail
// foreach ($notice->attachments() as $attachment) {
// if (!$attachment instanceof File) {
// common_debug('ATTACHMENTS array entry from notice id==' . _ve($notice->getID()) .
// ' is something else than a File dataobject: ' . _ve($attachment));
// continue;
// }
// try {
// $thumb = $attachment->getThumbnail();
// $thumb_url = $thumb->getUrl();
// $oembed['thumbnail_url'] = $thumb_url;
// break; // only first one
// } catch (UseFileAsThumbnailException $e) {
// $oembed['thumbnail_url'] = $attachment->getUrl();
// break; // we're happy with that
// } catch (ServerException $e) {
// } catch (ClientException $e) {
// }
// }
// break;
case 'attachment':
$id = $proxy_args['attachment'];
$attachment = File::getKV($id);
if (empty($attachment)) {
// TRANS: Client error displayed in oEmbed action when attachment not found.
// TRANS: %d is an attachment ID.
$this->clientError(sprintf(_('Attachment %s not found.'), $id), 404);
}
if (
empty($attachment->filename)
&& !empty($file_oembed = File_oembed::getKV(
'file_id',
$attachment->id
))
) {
// Proxy the existing oembed information
$oembed['type'] = $file_oembed->type;
$oembed['provider'] = $file_oembed->provider;
$oembed['provider_url'] = $file_oembed->provider_url;
$oembed['width'] = $file_oembed->width;
$oembed['height'] = $file_oembed->height;
$oembed['html'] = $file_oembed->html;
$oembed['title'] = $file_oembed->title;
$oembed['author_name'] = $file_oembed->author_name;
$oembed['author_url'] = $file_oembed->author_url;
$oembed['url'] = $file_oembed->getUrl();
} elseif (substr($attachment->mimetype, 0, strlen('image/')) === 'image/') {
$oembed['type'] = 'photo';
if ($attachment->filename) {
$filepath = File::path($attachment->filename);
$gis = @getimagesize($filepath);
if ($gis) {
$oembed['width'] = $gis[0];
$oembed['height'] = $gis[1];
} else {
// TODO Either throw an error or find a fallback?
}
}
$oembed['url'] = $attachment->getUrl();
try {
$thumb = $attachment->getThumbnail();
$oembed['thumbnail_url'] = $thumb->getUrl();
$oembed['thumbnail_width'] = $thumb->width;
$oembed['thumbnail_height'] = $thumb->height;
unset($thumb);
} catch (UnsupportedMediaException $e) {
// No thumbnail data available
}
} else {
$oembed['type'] = 'link';
$oembed['url'] = common_local_url(
'attachment',
['attachment' => $attachment->id]
);
}
if ($attachment->title) {
$oembed['title'] = $attachment->title;
}
break;
default:
// TRANS: Server error displayed in oEmbed request when a path is not supported.
// TRANS: %s is a path.
$this->serverError(sprintf(_('"%s" not supported for oembed requests.'), $path), 501);
}
// case 'attachment':
// $id = $proxy_args['attachment'];
// $attachment = File::getKV($id);
// if (empty($attachment)) {
// // TRANS: Client error displayed in oEmbed action when attachment not found.
// // TRANS: %d is an attachment ID.
// $this->clientError(sprintf(_('Attachment %s not found.'), $id), 404);
// }
// if (
// empty($attachment->filename)
// && !empty($file_oembed = File_oembed::getKV(
// 'file_id',
// $attachment->id
// ))
// ) {
// // Proxy the existing oembed information
// $oembed['type'] = $file_oembed->type;
// $oembed['provider'] = $file_oembed->provider;
// $oembed['provider_url'] = $file_oembed->provider_url;
// $oembed['width'] = $file_oembed->width;
// $oembed['height'] = $file_oembed->height;
// $oembed['html'] = $file_oembed->html;
// $oembed['title'] = $file_oembed->title;
// $oembed['author_name'] = $file_oembed->author_name;
// $oembed['author_url'] = $file_oembed->author_url;
// $oembed['url'] = $file_oembed->getUrl();
// } elseif (substr($attachment->mimetype, 0, strlen('image/')) === 'image/') {
// $oembed['type'] = 'photo';
// if ($attachment->filename) {
// $filepath = File::path($attachment->filename);
// $gis = @getimagesize($filepath);
// if ($gis) {
// $oembed['width'] = $gis[0];
// $oembed['height'] = $gis[1];
// } else {
// // TODO Either throw an error or find a fallback?
// }
// }
// $oembed['url'] = $attachment->getUrl();
// try {
// $thumb = $attachment->getThumbnail();
// $oembed['thumbnail_url'] = $thumb->getUrl();
// $oembed['thumbnail_width'] = $thumb->width;
// $oembed['thumbnail_height'] = $thumb->height;
// unset($thumb);
// } catch (UnsupportedMediaException $e) {
// // No thumbnail data available
// }
// } else {
// $oembed['type'] = 'link';
// $oembed['url'] = common_local_url(
// 'attachment',
// ['attachment' => $attachment->id]
// );
// }
// if ($attachment->title) {
// $oembed['title'] = $attachment->title;
// }
// break;
// default:
// // TRANS: Server error displayed in oEmbed request when a path is not supported.
// // TRANS: %s is a path.
// $this->serverError(sprintf(_('"%s" not supported for oembed requests.'), $path), 501);
// }
switch ($this->trimmed('format')) {
case 'xml':
$this->init_document('xml');
$this->elementStart('oembed');
foreach ([
'version', 'type', 'provider_name',
'provider_url', 'title', 'author_name',
'author_url', 'url', 'html', 'width',
'height', 'cache_age', 'thumbnail_url',
'thumbnail_width', 'thumbnail_height',
] as $key) {
if (isset($oembed[$key]) && $oembed[$key] != '') {
$this->element($key, null, $oembed[$key]);
}
}
$this->elementEnd('oembed');
$this->end_document('xml');
break;
// switch ($this->trimmed('format')) {
// case 'xml':
// $this->init_document('xml');
// $this->elementStart('oembed');
// foreach ([
// 'version', 'type', 'provider_name',
// 'provider_url', 'title', 'author_name',
// 'author_url', 'url', 'html', 'width',
// 'height', 'cache_age', 'thumbnail_url',
// 'thumbnail_width', 'thumbnail_height',
// ] as $key) {
// if (isset($oembed[$key]) && $oembed[$key] != '') {
// $this->element($key, null, $oembed[$key]);
// }
// }
// $this->elementEnd('oembed');
// $this->end_document('xml');
// break;
case 'json':
case null:
$this->init_document('json');
$this->raw(json_encode($oembed));
$this->end_document('json');
break;
default:
// TRANS: Error message displaying attachments. %s is a raw MIME type (eg 'image/png')
$this->serverError(sprintf(_('Content type %s not supported.'), $apidata['content-type']), 501);
}
// case 'json':
// case null:
// $this->init_document('json');
// $this->raw(json_encode($oembed));
// $this->end_document('json');
// break;
// default:
// // TRANS: Error message displaying attachments. %s is a raw MIME type (eg 'image/png')
// $this->serverError(sprintf(_('Content type %s not supported.'), $apidata['content-type']), 501);
// }
}
/** Placeholder */
public function init_document($type)
{
switch ($type) {
case 'xml':
header('Content-Type: application/xml; charset=utf-8');
$this->startXML();
break;
case 'json':
header('Content-Type: application/json; charset=utf-8');
throw new NotImplementedException;
// switch ($type) {
// case 'xml':
// header('Content-Type: application/xml; charset=utf-8');
// $this->startXML();
// break;
// case 'json':
// header('Content-Type: application/json; charset=utf-8');
// Check for JSONP callback
$callback = $this->arg('callback');
if ($callback) {
echo $callback . '(';
}
break;
default:
// TRANS: Server error displayed in oEmbed action when request specifies an unsupported data format.
$this->serverError(_('Not a supported data format.'), 501);
break;
}
// // Check for JSONP callback
// $callback = $this->arg('callback');
// if ($callback) {
// echo $callback . '(';
// }
// break;
// default:
// // TRANS: Server error displayed in oEmbed action when request specifies an unsupported data format.
// $this->serverError(_('Not a supported data format.'), 501);
// break;
// }
}
/** Placeholder */
public function end_document($type)
{
switch ($type) {
case 'xml':
$this->endXML();
break;
case 'json':
// Check for JSONP callback
$callback = $this->arg('callback');
if ($callback) {
echo ')';
}
break;
default:
// TRANS: Server error displayed in oEmbed action when request specifies an unsupported data format.
$this->serverError(_('Not a supported data format.'), 501);
break;
}
throw new NotImplementedException;
// switch ($type) {
// case 'xml':
// $this->endXML();
// break;
// case 'json':
// // Check for JSONP callback
// $callback = $this->arg('callback');
// if ($callback) {
// echo ')';
// }
// break;
// default:
// // TRANS: Server error displayed in oEmbed action when request specifies an unsupported data format.
// $this->serverError(_('Not a supported data format.'), 501);
// break;
// }
}
/**

View File

@ -43,31 +43,31 @@ final class EmbedTest extends TestCase
*/
public function testEmbed($url, $expectedType)
{
try {
$data = EmbedHelper::getObject($url);
static::assertSame($expectedType, $data->type);
if ($data->type == 'photo') {
static::assertTrue(!empty($data->thumbnail_url), 'Photo must have a URL.');
static::assertTrue(!empty($data->thumbnail_width), 'Photo must have a width.');
static::assertTrue(!empty($data->thumbnail_height), 'Photo must have a height.');
} elseif ($data->type == 'video') {
static::assertTrue(!empty($data->html), 'Video must have embedding HTML.');
static::assertTrue(!empty($data->thumbnail_url), 'Video should have a thumbnail.');
} else {
static::assertTrue(!empty($data->title), 'Page must have a title');
static::assertTrue(!empty($data->url), 'Page must have a URL');
}
if (!empty($data->thumbnail_url)) {
static::assertTrue(!empty($data->thumbnail_width), 'Thumbnail must list a width.');
static::assertTrue(!empty($data->thumbnail_height), 'Thumbnail must list a height.');
}
} catch (Exception $e) {
if ($expectedType == 'none') {
static::assertSame($expectedType, 'none', 'Should not have data for this URL.');
} else {
throw $e;
}
}
// try {
// $data = EmbedHelper::getObject($url);
// static::assertSame($expectedType, $data->type);
// if ($data->type == 'photo') {
// static::assertTrue(!empty($data->thumbnail_url), 'Photo must have a URL.');
// static::assertTrue(!empty($data->thumbnail_width), 'Photo must have a width.');
// static::assertTrue(!empty($data->thumbnail_height), 'Photo must have a height.');
// } elseif ($data->type == 'video') {
// static::assertTrue(!empty($data->html), 'Video must have embedding HTML.');
// static::assertTrue(!empty($data->thumbnail_url), 'Video should have a thumbnail.');
// } else {
// static::assertTrue(!empty($data->title), 'Page must have a title');
// static::assertTrue(!empty($data->url), 'Page must have a URL');
// }
// if (!empty($data->thumbnail_url)) {
// static::assertTrue(!empty($data->thumbnail_width), 'Thumbnail must list a width.');
// static::assertTrue(!empty($data->thumbnail_height), 'Thumbnail must list a height.');
// }
// } catch (Exception $e) {
// if ($expectedType == 'none') {
// static::assertSame($expectedType, 'none', 'Should not have data for this URL.');
// } else {
// throw $e;
// }
// }
}
public static function sources()

View File

@ -35,7 +35,8 @@ class Favourite
'where f.gsactor_id = :id ' .
'order by f.created DESC', ['id' => $actor_id]);
Event::handle('FormatNoteList', [$notes, &$note_out]);
$notes_out = null;
Event::handle('FormatNoteList', [$notes, &$notes_out]);
return [
'_template' => 'network/public.html.twig',
@ -62,6 +63,7 @@ class Favourite
'order by f.created DESC' ,
['id' => $actor_id]);
$notes_out = null;
Event::handle('FormatNoteList', [$notes, &$notes_out]);
return [

View File

@ -22,13 +22,14 @@
namespace Plugin\Poll\Controller;
use App\Core\DB\DB;
use App\Entity\Poll;
use App\Entity\PollResponse;
use App\Core\Form;
use App\Util\Common;
use App\Util\Exception\InvalidFormException;
use App\Util\Exception\NotFoundException;
use App\Util\Exception\RedirectException;
use App\Util\Exception\ServerException;
use Plugin\Poll\Entity\Poll;
use Plugin\Poll\Entity\PollResponse;
use Plugin\Poll\Forms\PollResponseForm;
use Symfony\Component\HttpFoundation\Request;
@ -62,14 +63,14 @@ class AnswerPoll
{
$user = Common::ensureLoggedIn();
$poll = Poll::getFromId((int) $id);
$poll = Poll::getWithPk((int) $id);
if ($poll == null) {
throw new NotFoundException('Poll does not exist');
}
$question = $poll->getQuestion();
$opts = $poll->getOptionsArr();
$form = PollResponseForm::make($poll, $poll->getNoteId());
$form = Form::create([]); //PollResponseForm::make($poll, $poll->getNoteId());
$form->handleRequest($request);
if ($form->isSubmitted()) {
if ($form->isValid()) {

View File

@ -26,10 +26,10 @@ use App\Core\Form;
use function App\Core\I18n\_m;
use App\Core\Security;
use App\Entity\Note;
use App\Entity\Poll;
use App\Util\Common;
use App\Util\Exception\InvalidFormException;
use App\Util\Exception\RedirectException;
use Plugin\Poll\Entity\Poll;
use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
use Symfony\Component\Form\Extension\Core\Type\SubmitType;
use Symfony\Component\Form\Extension\Core\Type\TextType;

View File

@ -27,7 +27,6 @@ use function App\Core\I18n\_m;
use App\Core\Modules\NoteHandlerPlugin;
use App\Core\Router\RouteLoader;
use App\Entity\Note;
use App\Entity\PollResponse;
use App\Util\Common;
use App\Util\Exception\InvalidFormException;
use App\Util\Exception\NotFoundException;
@ -117,7 +116,7 @@ class Poll extends NoteHandlerPlugin
return Event::next;
}
if (Common::isLoggedIn() && !PollResponse::exits($poll->getId(), Common::ensureLoggedIn()->getId())) {
if (Common::isLoggedIn() && !Entity\PollResponse::exits($poll->getId(), Common::ensureLoggedIn()->getId())) {
$opts = $poll->getOptionsArr();
$options = [];
for ($i = 1; $i <= count($opts); ++$i) {
@ -143,7 +142,7 @@ class Poll extends NoteHandlerPlugin
return Event::next;
}
if (PollResponse::exits($poll->getId(), $user->getId())) {
if (Entity\PollResponse::exits($poll->getId(), $user->getId())) {
return Event::next;
}
@ -151,10 +150,10 @@ class Poll extends NoteHandlerPlugin
if (!$poll->isValidSelection($selection)) {
throw new InvalidFormException();
}
if (PollResponse::exits($poll->getId(), $user->getId())) {
if (Entity\PollResponse::exits($poll->getId(), $user->getId())) {
throw new ServerException('User already responded to poll');
}
$pollResponse = PollResponse::create(['poll_id' => $poll->getId(), 'gsactor_id' => $user->getId(), 'selection' => $selection]);
$pollResponse = Entity\PollResponse::create(['poll_id' => $poll->getId(), 'gsactor_id' => $user->getId(), 'selection' => $selection]);
DB::persist($pollResponse);
DB::flush();

View File

@ -24,9 +24,9 @@ namespace Plugin\ProfileColor\Controller;
use App\Core\DB\DB;
use App\Core\Form;
use function App\Core\I18n\_m;
use App\Entity\ProfileColor as PColor;
use App\Util\Common;
use App\Util\Exception\RedirectException;
use Plugin\ProfileColor\Entity;
use Symfony\Component\Form\Extension\Core\Type\ColorType;
use Symfony\Component\Form\Extension\Core\Type\HiddenType;
use Symfony\Component\Form\Extension\Core\Type\SubmitType;
@ -78,7 +78,7 @@ class ProfileColor
DB::flush();
}
$pcolor = PColor::create(['gsactor_id' => $actor_id, 'color' => $data['color']]);
$pcolor = Entity\ProfileColor::create(['gsactor_id' => $actor_id, 'color' => $data['color']]);
DB::persist($pcolor);
DB::flush();
throw new RedirectException();

View File

@ -34,6 +34,7 @@ use App\Entity\Note;
use App\Util\Common;
use App\Util\Exception\ClientException;
use App\Util\Exception\InvalidFormException;
use App\Util\Exception\NoSuchNoteException;
use App\Util\Exception\RedirectException;
use Component\Posting\Posting;
use Symfony\Component\Form\Extension\Core\Type\FileType;

View File

@ -27,6 +27,7 @@ use App\Core\Modules\NoteHandlerPlugin;
use App\Entity\Note;
use App\Util\Common;
use App\Util\Exception\RedirectException;
use Component\Posting\Posting;
use Plugin\Reply\Controller\Reply as ReplyController;
use Symfony\Component\Form\Extension\Core\Type\HiddenType;
use Symfony\Component\Form\Extension\Core\Type\SubmitType;

View File

@ -52,6 +52,7 @@ class Attachment extends Controller
throw new ClientException(_m('No such attachment'), 404);
// @codeCoverageIgnoreEnd
} else {
$res = null;
if (Event::handle('AttachmentFileInfo', [$id, &$res]) != Event::stop) {
// If no one else claims this attachment, use the default representation
try {
@ -142,6 +143,7 @@ class Attachment extends Controller
$height = $this->int('h') ?: $default_height;
$crop = $this->bool('c') ?: $default_crop;
$sizes = null;
Event::handle('GetAllowedThumbnailSizes', [&$sizes]);
if (!in_array(['width' => $width, 'height' => $height], $sizes)) {
throw new ClientException(_m('The requested thumbnail dimensions are not allowed'), 400); // 400 Bad Request

View File

@ -56,6 +56,7 @@ class Network extends Controller
{
$notes = Note::getAllNotes($this->instance_scope);
$notes_out = null;
Event::handle('FormatNoteList', [$notes, &$notes_out]);
return [
@ -98,6 +99,7 @@ class Network extends Controller
END;
$notes = DB::sql($query, ['note' => 'App\Entity\Note'], ['target_actor_id' => $target->getId()]);
$notes_out = null;
Event::handle('FormatNoteList', [$notes, &$notes_out]);
return [
@ -110,6 +112,7 @@ END;
{
$notes = Note::getAllNotes($this->public_scope);
$notes_out = null;
Event::handle('FormatNoteList', [$notes, &$notes_out]);
return [
@ -125,6 +128,7 @@ END;
'where n.reply_to is not null and n.gsactor_id = :id ' .
'order by n.created DESC', ['id' => $actor_id]);
$notes_out = null;
Event::handle('FormatNoteList', [$notes, &$notes_out]);
return [

View File

@ -3,9 +3,16 @@
namespace App\Controller;
use App\Core\Controller;
use App\Core\DB\DB;
use App\Core\Form;
use function App\Core\I18n\_m;
use App\Entity\LocalUser;
use App\Security\EmailVerifier;
use App\Util\Exception\ClientException;
use App\Util\Exception\RedirectException;
use App\Util\Form\FormFields;
use Symfony\Component\Form\Extension\Core\Type\EmailType;
use Symfony\Component\Form\Extension\Core\Type\SubmitType;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Validator\Constraints\NotBlank;
use SymfonyCasts\Bundle\ResetPassword\Controller\ResetPasswordControllerTrait;
@ -26,7 +33,7 @@ class ResetPassword extends Controller
*/
public function requestPasswordReset(Request $request)
{
$from = Form::create([
$form = Form::create([
['email', EmailType::class, ['label' => _m('Email'), 'constraints' => [ new NotBlank(['message' => _m('Please enter an email') ]) ]]],
['password_reset_request', SubmitType::class, ['label' => _m('Submit request')]],
]);
@ -38,7 +45,7 @@ class ResetPassword extends Controller
return [
'_template' => 'reset_password/request.html.twig',
'password_reset_form' => $from->createView(),
'password_reset_form' => $form->createView(),
];
}
@ -83,7 +90,7 @@ class ResetPassword extends Controller
}
// The token is valid; allow the user to change their password.
$form = From::create([
$form = Form::create([
FormFields::repeated_password(),
['password_reset', SubmitType::class, ['label' => _m('Change password')]],
]);

View File

@ -13,7 +13,8 @@ use App\Entity\GSActor;
use App\Entity\LocalUser;
use App\Entity\Note;
use App\Security\Authenticator;
use app\Util\Common;
use App\Security\EmailVerifier;
use App\Util\Common;
use App\Util\Exception\EmailTakenException;
use App\Util\Exception\NicknameTakenException;
use App\Util\Exception\ServerException;
@ -142,7 +143,7 @@ class Security extends Controller
// generate a signed url and email it to the user
if ($_ENV['APP_ENV'] !== 'dev' && Common::config('site', 'use_email')) {
// @codeCoverageIgnoreStart
Common::sendVerificationEmail();
EmailVerifier::sendEmailConfirmation($user);
// @codeCoverageIgnoreEnd
} else {
$user->setIsEmailVerified(true);

View File

@ -43,6 +43,7 @@ use App\Entity\UserNotificationPrefs;
use App\Util\Common;
use App\Util\Exception\AuthenticationException;
use App\Util\Exception\ServerException;
use App\Util\Form\ActorArrayTransformer;
use App\Util\Form\ArrayTransformer;
use App\Util\Form\FormFields;
use App\Util\Formatting;

View File

@ -73,7 +73,7 @@ abstract class Cache
}
$class = RedisCluster::class; // true for persistent connection
$seeds = F\Map($dsns, fn ($str) => explode('://', $str)[1]);
$r = new RedisCluster(name: null, seeds: $seeds, timeout: null, read_timeout: null, persistent: true);
$r = new RedisCluster(name: null, seeds: $seeds, timeout: null, readTimeout: null, persistent: true);
// Distribute reads randomly
$r->setOption($class::OPT_SLAVE_FAILOVER, $class::FAILOVER_DISTRIBUTE);
// @codeCoverageIgnoreEnd
@ -102,7 +102,7 @@ abstract class Cache
$adapters[$pool][] = new Adapter\ApcuAdapter();
break;
case 'opcache':
$adapters[$pool][] = new Adapter\PhpArrayAdapter($rest, new FilesystemAdapter($rest . '.fallback'));
$adapters[$pool][] = new Adapter\PhpArrayAdapter($rest, new Adapter\FilesystemAdapter($rest . '.fallback'));
break;
case 'doctrine':
$adapters[$pool][] = new Adapter\PdoAdapter($dsn);

View File

@ -23,7 +23,6 @@ namespace App\Core;
use App\Core\DB\DB;
use App\Util\Exception\NotFoundException;
use App\Util\Exception\ServerException;
use App\Util\Formatting;
use DateTime;
@ -53,7 +52,7 @@ abstract class Entity
*/
public static function create(array $args, $obj = null)
{
$class = get_called_class();
$class = static::class;
$obj = $obj ?: new $class();
$date = new DateTime();
foreach (['created', 'modified'] as $prop) {

View File

@ -20,13 +20,14 @@
namespace App\Core\Modules;
use App\Util\Common;
use App\Util\Formatting;
/**
* Base class for all GNU social modules (plugins and components)
*/
abstract class Module
{
const MODULE_TYPE = 'module';
/**
* Load values from the config and set them as properties on each module object
*/
@ -54,8 +55,7 @@ abstract class Module
*/
public static function __set_state($state)
{
$class = get_called_class();
$obj = new $class();
$obj = new (static::class);
foreach ($state as $k => $v) {
$obj->{$k} = $v;
}

View File

@ -125,7 +125,7 @@ class Invitation extends Entity
'user_id' => ['type' => 'int', 'foreign key' => true, 'target' => 'LocalUser.id', 'multiplicity' => 'many to one', 'name' => 'invitation_user_id_fkey', 'not null' => true, 'description' => 'who sent the invitation'],
'address' => ['type' => 'varchar', 'length' => 191, 'not null' => true, 'description' => 'invitation sent to'],
'address_type' => ['type' => 'varchar', 'length' => 8, 'not null' => true, 'description' => 'address type ("email", "xmpp", "sms")'],
'registered_user_id' => ['type' => 'int', 'foreign key' => true, 'target' => 'LocalUser.id', 'multiplicity' => 'one to one', 'name' => 'invitation_registered_user_id_fkey', 'type' => 'int', 'not null' => false, 'description' => 'if the invitation is converted, who the new user is'],
'registered_user_id' => ['type' => 'int', 'foreign key' => true, 'target' => 'LocalUser.id', 'multiplicity' => 'one to one', 'name' => 'invitation_registered_user_id_fkey', 'not null' => false, 'description' => 'if the invitation is converted, who the new user is'],
'created' => ['type' => 'datetime', 'not null' => true, 'default' => 'CURRENT_TIMESTAMP', 'description' => 'date this record was created'],
],
'primary key' => ['code'],

View File

@ -87,7 +87,7 @@ class RelatedGroup extends Entity
// @fixme description for related_group?
'fields' => [
'group_id' => ['type' => 'int', 'foreign key' => true, 'target' => 'Group.id', 'multiplicity' => 'one to one', 'not null' => true, 'description' => 'foreign key to group'],
'related_group_id' => ['type' => 'int', 'foreign key' => true, 'target' => 'Group.id', 'multiplicity' => 'one to one', 'type' => 'int', 'not null' => true, 'description' => 'foreign key to group'],
'related_group_id' => ['type' => 'int', 'foreign key' => true, 'target' => 'Group.id', 'multiplicity' => 'one to one', 'not null' => true, 'description' => 'foreign key to group'],
'created' => ['type' => 'datetime', 'not null' => true, 'default' => 'CURRENT_TIMESTAMP', 'description' => 'date this record was created'],
],
'primary key' => ['group_id', 'related_group_id'],

View File

@ -47,35 +47,6 @@ class Kernel extends BaseKernel
public const CONFIG_EXTS = '.{php,xml,yaml,yml}';
public function __construct(string $environment, bool $debug)
{
parent::__construct($environment, $debug);
if (!defined('INSTALLDIR')) {
define('INSTALLDIR', dirname(__DIR__));
define('SRCDIR', INSTALLDIR . '/src');
define('PUBLICDIR', INSTALLDIR . '/public');
define('GNUSOCIAL_ENGINE_NAME', 'GNU social');
// MERGE Change to https://gnu.io/social/
define('GNUSOCIAL_PROJECT_URL', 'https://gnusocial.rocks/');
// MERGE Change to https://git.gnu.io/gnu/gnu-social
define('GNUSOCIAL_REPOSITORY_URL', 'https://code.undefinedhackers.net/GNUsocial/gnu-social');
// Current base version, major.minor.patch
define('GNUSOCIAL_BASE_VERSION', '3.0.0');
// 'dev', 'alpha[0-9]+', 'beta[0-9]+', 'rc[0-9]+', 'release'
define('GNUSOCIAL_LIFECYCLE', 'dev');
define('GNUSOCIAL_VERSION', GNUSOCIAL_BASE_VERSION . '-' . GNUSOCIAL_LIFECYCLE);
define('GNUSOCIAL_CODENAME', 'Big bang');
define('URL_REGEX_DOMAIN_NAME', '(?:(?!-)[A-Za-z0-9\-]{1,63}(?<!-)\.)+[A-Za-z]{2,10}');
// Work internally in UTC
date_default_timezone_set('UTC');
// Work internally with UTF-8
mb_internal_encoding('UTF-8');
}
}
/**
* Symfony framework function override responsible for registering
* bundles (similar to our modules)

View File

@ -4,6 +4,8 @@ namespace App\Security;
use App\Core\Controller;
use App\Core\DB\DB;
use function App\Core\I18n\_m;
use App\Util\Common;
use App\Util\Exception\NotFoundException;
use App\Util\Exception\RedirectException;
use Symfony\Bridge\Twig\Mime\TemplatedEmail;
@ -11,6 +13,7 @@ use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Mailer\MailerInterface;
use Symfony\Component\Mime\Address;
use Symfony\Component\Security\Core\User\UserInterface;
use SymfonyCasts\Bundle\ResetPassword\Exception\ResetPasswordExceptionInterface;
use SymfonyCasts\Bundle\ResetPassword\ResetPasswordHelperInterface;
use SymfonyCasts\Bundle\VerifyEmail\Exception\VerifyEmailExceptionInterface;
use SymfonyCasts\Bundle\VerifyEmail\VerifyEmailHelperInterface;
@ -61,7 +64,7 @@ abstract class EmailVerifier
self::send($email);
}
public function send($email)
public static function send($email)
{
return self::$mailer_helper->send($email);
}
@ -77,7 +80,7 @@ abstract class EmailVerifier
DB::flush();
}
public function processSendingPasswordResetEmail(string $emailFormData, Controller $controller)
public static function processSendingPasswordResetEmail(string $emailFormData, Controller $controller)
{
try {
$user = DB::findOneBy('local_user', ['outgoing_email' => $emailFormData]);

View File

@ -32,7 +32,7 @@ abstract class Bitmap
private static function _to(int $r, bool $instance)
{
$init = $r;
$class = get_called_class();
$class = static::class;
if ($instance) {
$obj = new $class;
} else {

View File

@ -19,6 +19,8 @@
namespace App\Util\Exception;
use function App\Core\I18n\_m;
use App\Core\Log;
use App\Core\Router\Router;
use Exception;
use Symfony\Component\HttpFoundation\RedirectResponse;

View File

@ -45,17 +45,18 @@ abstract class FormFields
*/
public static function password(array $options = []): array
{
['password', PasswordType::class, [
'label' => _m('Password'),
'label_attr' => ['class' => 'section-form-label'],
'attr' => ['placeholder' => '********'],
'required' => $options['required'] ?? true,
'mapped' => false,
'constraints' => [
new NotBlank(['message' => _m('Please enter a password')]),
new Length(['min' => Common::config('password', 'min_length'), 'minMessage' => _m(['Your password should be at least # characters'], ['count' => Common::config('password', 'min_length')]),
'max' => Common::config('password', 'max_length'), 'maxMessage' => _m(['Your password should be at most # characters'], ['count' => Common::config('password', 'max_length')]), ]),
], ],
return [
'password', PasswordType::class, [
'label' => _m('Password'),
'label_attr' => ['class' => 'section-form-label'],
'attr' => ['placeholder' => '********'],
'required' => $options['required'] ?? true,
'mapped' => false,
'constraints' => [
new NotBlank(['message' => _m('Please enter a password')]),
new Length(['min' => Common::config('password', 'min_length'), 'minMessage' => _m(['Your password should be at least # characters'], ['count' => Common::config('password', 'min_length')]),
'max' => Common::config('password', 'max_length'), 'maxMessage' => _m(['Your password should be at most # characters'], ['count' => Common::config('password', 'max_length')]), ]),
], ],
];
}
}

View File

@ -31,6 +31,7 @@ use App\Util\Exception\NicknameReservedException;
use App\Util\Exception\NicknameTakenException;
use App\Util\Exception\NicknameTooLongException;
use App\Util\Exception\NicknameTooShortException;
use App\Util\Exception\NotImplementedException;
use Functional as F;
use Normalizer;
@ -154,7 +155,7 @@ class Nickname
break;
// @codeCoverageIgnoreStart
case self::CHECK_LOCAL_GROUP:
throw new \NotImplementedException();
throw new NotImplementedException();
break;
default:
throw new \InvalidArgumentException();

View File

@ -30,7 +30,7 @@
namespace App\Util\Notification;
use App\Entity\Gsactor;
use App\Entity\GSActor;
class Notification
{

View File

@ -19,6 +19,7 @@
namespace App\Util;
use function App\Core\I18n\_m;
use App\Util\Exception\TemporaryFileException;
use Symfony\Component\Mime\MimeTypes;

View File

@ -76,6 +76,7 @@ class AttachmentTest extends GNUsocialTestCase
$test = function (string $method) {
$temp_file = new TemporaryFile();
$temp_file->write(file_get_contents(INSTALLDIR . '/tests/sample-uploads/gnu-logo.png'));
$hash = null;
Event::handle('HashFile', [$temp_file->getPathname(), &$hash]);
$attachment = DB::findOneBy('attachment', ['filehash' => $hash]);
$attachment->{$method}();
@ -118,6 +119,7 @@ class AttachmentTest extends GNUsocialTestCase
public function testMimetype()
{
$file = new \SplFileInfo(INSTALLDIR . '/tests/sample-uploads/image.jpg');
$hash = null;
Event::handle('HashFile', [$file->getPathname(), &$hash]);
$attachment = DB::findOneBy('attachment', ['filehash' => $hash]);

View File

@ -38,6 +38,7 @@ class AttachmentThumbnailTest extends GNUsocialTestCase
// Data fixture already loaded this file, but we need to get its hash to find it
$file = new \SplFileInfo(INSTALLDIR . '/tests/sample-uploads/attachment-lifecycle-target.jpg');
$hash = null;
Event::handle('HashFile', [$file->getPathname(), &$hash]);
$attachment = DB::findOneBy('attachment', ['filehash' => $hash]);
@ -73,6 +74,7 @@ class AttachmentThumbnailTest extends GNUsocialTestCase
parent::bootKernel();
$file = new \SplFileInfo(INSTALLDIR . '/tests/sample-uploads/spreadsheet.ods');
$hash = null;
Event::handle('HashFile', [$file->getPathname(), &$hash]);
$attachment = DB::findOneBy('attachment', ['filehash' => $hash]);