[TOOLS] Fix all issues found by PHPStan level 2

This commit is contained in:
Hugo Sales 2021-09-06 23:47:28 +01:00
parent 4b1780a2ee
commit 4e30e5aad9
No known key found for this signature in database
GPG Key ID: 7D0C7EAFC9D835A0
33 changed files with 114 additions and 89 deletions

View File

@ -1,7 +1,12 @@
parameters:
level: 1
level: 2
bootstrapFiles:
- config/bootstrap.php
earlyTerminatingMethodCalls:
App\Core\Log:
- unexpected_exception
- unexpected_exception
ignoreErrors:
-
message: '/Access to an undefined property App\\Util\\Bitmap::\$\w+/'
paths:
- *

View File

@ -26,7 +26,7 @@ class ActivityPub extends Plugin
* This code executes when GNU social creates the page routing, and we hook
* on this event to add our action handler for Embed.
*
* @param $r RouteLoader the router that was initialized.
* @param RouteLoader $r the router that was initialized.
*
* @return bool
*/
@ -76,4 +76,4 @@ class ActivityPub extends Plugin
)
);
}
}
}

View File

@ -50,7 +50,7 @@ class ActivityStreamsTwo extends Plugin
* This code executes when GNU social creates the page routing, and we hook
* on this event to add our action handler for Embed.
*
* @param $r RouteLoader the router that was initialized.
* @param RouteLoader $r the router that was initialized.
*
* @return bool
*/

View File

@ -2,12 +2,13 @@
namespace Plugin\ActivityStreamsTwo\Util\Model\EntityToType;
use App\Core\Entity;
use Plugin\ActivityStreamsTwo\Util\Type;
abstract class EntityToType
{
/**
* @param $entity
* @param Entity $entity
*
* @throws \Exception
*
@ -25,4 +26,4 @@ abstract class EntityToType
return Type::create($map);
}
}
}
}

View File

@ -10,7 +10,7 @@ use Plugin\ActivityStreamsTwo\Util\Type;
class NoteToType
{
/**
* @param $entity
* @param Note $note
*
* @throws \Exception
*
@ -30,4 +30,4 @@ class NoteToType
];
return Type::create(type: 'Note', attributes: $attr);
}
}
}

View File

@ -7,8 +7,10 @@ use Plugin\ActivityStreamsTwo\Util\Model\EntityToType\EntityToType;
abstract class AbstractResponse
{
/**
* @param Type $type
* @param int $status The response status code
* param Type $type // What is this `Type`
*
* @param int $status The response status code
* @param mixed $type
*
* @throws \Exception
*
@ -21,4 +23,4 @@ abstract class AbstractResponse
status: $status
);
}
}
}

View File

@ -7,8 +7,10 @@ use Symfony\Component\HttpFoundation\JsonResponse;
class TypeResponse extends JsonResponse
{
/**
* @param Type $data
* @param int $status The response status code
* param Type $data // what `Type` is this?
*
* @param int $status The response status code
* @param null|mixed $data
*
* @return JsonResponse
*/

View File

@ -137,7 +137,6 @@ abstract class AbstractObject
* Checks that property exists
*
* @param string $name
* @param bool $strict
*
* @throws Exception
*

View File

@ -27,7 +27,7 @@ abstract class AbstractActivity extends ObjectType
/**
* @var string
*/
protected string $id;
public string $id;
/**
* Describes one or more entities that either performed or are

View File

@ -30,7 +30,7 @@ class Collection extends ObjectType
/**
* @var string
*/
protected string $id;
public string $id;
/**
* A non-negative integer specifying the total number of objects

View File

@ -29,7 +29,7 @@ class CollectionPage extends Collection
/**
* @var string
*/
protected string $id;
public string $id;
/**
* Identifies the Collection to which CollectionPage objects items

View File

@ -34,7 +34,7 @@ class ObjectType extends AbstractObject
*
* @var string
*/
protected string $id;
public string $id;
/**
* @var string

View File

@ -22,7 +22,7 @@ abstract class Validator
/**
* Contains all custom validators
*
* @var array<string,string>
* @var array<string, ValidatorInterface>
*
* [ 'attributeName' => CustomValidatorClassName::class ]
*/

View File

@ -143,14 +143,14 @@ class Cover
*/
public function cover()
{
$cover = DB::find('cover', ['gsactor_id' => Common::user()->getId()]);
if ($cover == null) {
return new Response('Cover not found',Response::HTTP_NOT_FOUND);
}
$file = $cover->getFile();
if ($file == null) {
return new Response('Cover File not found',Response::HTTP_NOT_FOUND);
}
return GSFile::sendFile($cover->getFilePath(), $file->getMimetype(), $file->getTitle());
// $cover = DB::find('cover', ['gsactor_id' => Common::user()->getId()]);
// if ($cover == null) {
// return new Response('Cover not found',Response::HTTP_NOT_FOUND);
// }
// $file = $cover->getFile();
// if ($file == null) {
// return new Response('Cover File not found',Response::HTTP_NOT_FOUND);
// }
// return GSFile::sendFile($cover->getFilePath(), $file->getMimetype(), $file->getTitle());
}
}

View File

@ -113,7 +113,7 @@ class Cover extends Entity
*/
public function getAttachmentPath(): string
{
return Common::config('cover', 'dir') . $this->getAttachment()->getAttachmentName();
return Common::config('cover', 'dir') . $this->getAttachment()->getBestTitle();
}
/**
@ -129,7 +129,7 @@ class Cover extends Entity
{
// Don't go into a loop if we're deleting from Attachment
if (!$cascading) {
$attachments = $this->getAttachment()->delete($cascade = true, $attachment_flush = false, $delete_attachments_now);
$attachments = $this->getAttachment()->kill();
} else {
DB::remove(DB::getReference('cover', ['gsactor_id' => $this->gsactor_id]));
$attachment_path = $this->getAttachmentPath();

View File

@ -205,14 +205,11 @@ class Embed extends Plugin
* This code executes when GNU social creates the page routing, and we hook
* on this event to add our action handler for Embed.
*
* @param $m RouteLoader the router that was initialized.
* @param RouteLoader $m the router that was initialized.
*
* @throws Exception
*
* @return bool
*
*
*
*/
public function onAddRoute(RouteLoader $m): bool
{
@ -492,7 +489,7 @@ class Embed extends Plugin
* Event raised when GNU social polls the plugin for information about it.
* Adds this plugin's version information to $versions array
*
* @param &$versions array inherited from parent
* @param array $versions inherited from parent
*
* @throws ServerException
*

View File

@ -83,8 +83,8 @@ class Favourite extends NoteHandlerPlugin
/**
* Called from form handler
*
* @param $note Note to be favourited
* @param $data Form input
* @param Note $note to be favourited
* @param Form $data input
*
* @throws RedirectException Always thrown in order to prevent accidental form re-submit from browser
*/

View File

@ -103,7 +103,7 @@ END;
* Event raised when GNU social polls the plugin for information about it.
* Adds this plugin's version information to $versions array
*
* @param &$versions array inherited from parent
* @param array $versions inherited from parent
*
* @return bool true hook value
*/

View File

@ -230,7 +230,7 @@ class ImageEncoder extends Plugin
* Event raised when GNU social polls the plugin for information about it.
* Adds this plugin's version information to $versions array
*
* @param &$versions array inherited from parent
* @param array $versions inherited from parent
*
* @return bool true hook value
*/

View File

@ -124,6 +124,7 @@ class StoreRemoteMedia extends Plugin
}
// Have we handled it already?
/** @var AttachmentToLink */
$attachment_to_link = DB::find('attachment_to_link',
['link_id' => $link->getId()]);
@ -224,7 +225,7 @@ class StoreRemoteMedia extends Plugin
* Event raised when GNU social polls the plugin for information about it.
* Adds this plugin's version information to $versions array
*
* @param &$versions array inherited from parent
* @param array $versions inherited from parent
*
* @return bool true hook value
*/

View File

@ -17,6 +17,7 @@ use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Validator\Constraints\NotBlank;
use SymfonyCasts\Bundle\ResetPassword\Controller\ResetPasswordControllerTrait;
use SymfonyCasts\Bundle\ResetPassword\Exception\ResetPasswordExceptionInterface;
use SymfonyCasts\Bundle\ResetPassword\Model\ResetPasswordToken;
/**
* Send password reset emails to users
@ -114,4 +115,9 @@ class ResetPassword extends Controller
'resetForm' => $form->createView(),
];
}
public function setInSession(ResetPasswordToken $reset_token)
{
$this->setTokenObjectInSession($reset_token);
}
}

View File

@ -45,6 +45,7 @@ use Symfony\Component\HttpKernel\Event\ControllerEvent;
use Symfony\Component\HttpKernel\Event\ExceptionEvent;
use Symfony\Component\HttpKernel\Event\ViewEvent;
use Symfony\Component\HttpKernel\KernelEvents;
use Symfony\Component\Validator\Exception\ValidatorException;
/**
* @method int int(string $param)
@ -187,13 +188,10 @@ class Controller extends AbstractController implements EventSubscriberInterface
/**
* Get and convert GET parameters. Can be called with `int`, `bool`, `string`, etc
*
* @param string $name
*
* @throws ValidatorException
* @throws Exception
*
* @return the value or null if no paramter exists
*
* @return null|mixed the value or null if no paramter exists
*/
public function __call(string $method, array $args)
{

View File

@ -38,12 +38,16 @@ use Doctrine\Common\Collections\Criteria;
use Doctrine\Common\Collections\Expr\Expression;
use Doctrine\Common\Collections\ExpressionBuilder;
use Doctrine\ORM\EntityManagerInterface;
use Doctrine\ORM\EntityRepository;
use Doctrine\ORM\Query;
use Doctrine\ORM\Query\ResultSetMappingBuilder;
use Functional as F;
/**
* @mixin EntityManagerInterface
* @template T
*
* @method T find(string $class, array<string, mixed> $values)
*/
class DB
{
@ -163,7 +167,8 @@ class DB
{
$criteria = array_change_key_case($criteria, CASE_LOWER);
$ops = array_intersect(array_keys($criteria), self::$find_by_ops);
$repo = self::getRepository($table);
/** @var EntityRepository */
$repo = self::getRepository($table);
if (empty($ops)) {
return $repo->findBy($criteria, $orderBy, $limit, $offset);
} else {
@ -191,6 +196,7 @@ class DB
public static function count(string $table, array $criteria)
{
/** @var EntityRepository */
$repo = self::getRepository($table);
return $repo->count($criteria);
}
@ -220,11 +226,19 @@ class DB
*/
public static function __callStatic(string $name, array $args)
{
if (in_array($name, ['find', 'getReference', 'getPartialReference', 'getRepository'])
&& !str_contains($args[0], '\\')) {
$args[0] = self::$table_map[$args[0]];
}
$args[0] = self::filterTableName($name, $args);
return self::$em->{$name}(...$args);
}
public const METHODS_ACCEPTING_TABLE_NAME = ['find', 'getReference', 'getPartialReference', 'getRepository'];
public static function filterTableName(string $method, array $args): mixed
{
if (in_array($method, self::METHODS_ACCEPTING_TABLE_NAME)
&& !str_contains($args[0], '\\')) {
return self::$table_map[$args[0]];
} else {
return $args[0];
}
}
}

View File

@ -76,7 +76,7 @@ abstract class Entity
/**
* Create a new instance, but check for duplicates
*
* @return [$obj, $is_update]
* @return array [$obj, $is_update]
*/
public static function createOrUpdate(array $args, array $find_by_keys = [])
{

View File

@ -30,8 +30,9 @@ use App\Util\Exception\NoSuchFileException;
use App\Util\Exception\NotFoundException;
use App\Util\Exception\NotStoredLocallyException;
use App\Util\Exception\ServerException;
use SplFileInfo;
use App\Util\TemporaryFile;
use Symfony\Component\HttpFoundation\BinaryFileResponse;
use Symfony\Component\HttpFoundation\File\File as SymfonyFile;
use Symfony\Component\HttpFoundation\HeaderUtils;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Mime\MimeTypes;
@ -52,17 +53,13 @@ class GSFile
/**
* Perform file validation (checks and normalization), store the given file if needed and increment lives
*
* @param SplFileInfo $file
* @param string $dest_dir
* @param null|string $title
* @param bool $is_local
* @param null|int $actor_id
* @param SymfonyFile|TemporaryFile $file
*
* @throws DuplicateFoundException
*
* @return Attachment
*/
public static function sanitizeAndStoreFileAsAttachment(SplFileInfo $file): Attachment
public static function sanitizeAndStoreFileAsAttachment(TemporaryFile|SymfonyFile $file): Attachment
{
$hash = null;
Event::handle('HashFile', [$file->getPathname(), &$hash]);

View File

@ -31,7 +31,7 @@
namespace App\DependencyInjection\Compiler;
use Doctrine\Persistence\Mapping\ClassMetadata;
use Doctrine\ORM\Mapping\ClassMetadataInfo;
use Doctrine\Persistence\Mapping\Driver\StaticPHPDriver;
use Functional as F;
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
@ -88,10 +88,10 @@ class SchemaDefDriver extends StaticPHPDriver implements CompilerPassInterface
/**
* Fill in the database $metadata for $class_name
*
* @param string $class_name
* @param ClassMetadata $metadata
* @param string $class_name
* @param ClassMetadataInfo $metadata
*/
public function loadMetadataForClass($class_name, ClassMetadata $metadata)
public function loadMetadataForClass($class_name, $metadata)
{
$schema = $class_name::schemaDef();

View File

@ -34,6 +34,7 @@ use App\Util\Exception\ClientException;
use App\Util\Exception\NotFoundException;
use App\Util\Exception\NotStoredLocallyException;
use App\Util\Exception\ServerException;
use App\Util\TemporaryFile;
use DateTimeInterface;
use Symfony\Component\Mime\MimeTypes;
@ -188,14 +189,17 @@ class AttachmentThumbnail extends Entity
$event_map[$major_mime] = [];
Event::handle('FileResizerAvailable', [&$event_map, $mimetype]);
// Always prefer specific encoders
/** @var callable[] function(string $source, ?TemporaryFile &$destination, int &$width, int &$height, bool $smart_crop, ?string &$mimetype): bool */
$encoders = array_merge($event_map[$mimetype], $event_map[$major_mime]);
foreach ($encoders as $encoder) {
/** @var ?TemporaryFile */
$temp = null; // Let the EncoderPlugin create a temporary file for us
if ($encoder($attachment->getPath(), $temp, $width, $height, $crop, $mimetype)) {
$thumbnail->setAttachment($attachment);
$thumbnail->setWidth($predicted_width);
$thumbnail->setHeight($predicted_height);
$ext = '.' . MimeTypes::getDefault()->getExtensions($temp->getMimeType())[0];
$mimetype = $temp->getMimeType();
$ext = '.' . MimeTypes::getDefault()->getExtensions($mimetype)[0];
$filename = "{$predicted_width}x{$predicted_height}{$ext}-" . $attachment->getFilehash();
$thumbnail->setFilename($filename);
$thumbnail->setMimetype($mimetype);
@ -257,11 +261,11 @@ class AttachmentThumbnail extends Entity
* Values will scale _up_ to fit max values if cropping is enabled!
* With cropping disabled, the max value of each axis will be respected.
*
* @param $width int Original width
* @param $height int Original height
* @param $maxW int Resulting max width
* @param $maxH int Resulting max height
* @param $crop bool Crop to the size (not preserving aspect ratio)
* @param int $existing_width Original width
* @param int $existing_height Original height
* @param int $requested_width Resulting max width
* @param int $requested_height Resulting max height
* @param bool $crop Crop to the size (not preserving aspect ratio)
*
* @return array [predicted width, predicted height]
*/

View File

@ -256,8 +256,6 @@ class Note extends Entity implements \JsonSerializable
/**
* Whether this note is visible to the given actor
*
* @param mixed $a
*/
public function isVisibleTo(GSActor | LocalUser $a): bool
{

View File

@ -21,6 +21,7 @@ namespace App\Security;
use App\Core\DB\DB;
use function App\Core\I18n\_m;
use App\Entity\LocalUser;
use App\Entity\User;
use App\Util\Nickname;
use Exception;
@ -31,7 +32,6 @@ use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
use Symfony\Component\Security\Core\Exception\CustomUserMessageAuthenticationException;
use Symfony\Component\Security\Core\Exception\InvalidCsrfTokenException;
use Symfony\Component\Security\Core\Security;
use Symfony\Component\Security\Core\User\UserInterface;
use Symfony\Component\Security\Core\User\UserProviderInterface;
use Symfony\Component\Security\Csrf\CsrfToken;
use Symfony\Component\Security\Csrf\CsrfTokenManagerInterface;
@ -103,7 +103,11 @@ class Authenticator extends AbstractFormLoginAuthenticator
return $user;
}
public function checkCredentials($credentials, UserInterface $user)
/**
* @param LocalUser $user
* @param mixed $credentials
*/
public function checkCredentials($credentials, $user)
{
if (!$user->checkPassword($credentials['password'])) {
throw new CustomUserMessageAuthenticationException(_m('Invalid login credentials.'));

View File

@ -2,9 +2,10 @@
namespace App\Security;
use App\Core\Controller;
use App\Controller\ResetPassword;
use App\Core\DB\DB;
use function App\Core\I18n\_m;
use App\Entity\LocalUser;
use App\Util\Common;
use App\Util\Exception\NotFoundException;
use App\Util\Exception\RedirectException;
@ -12,7 +13,6 @@ use Symfony\Bridge\Twig\Mime\TemplatedEmail;
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;
@ -36,12 +36,12 @@ abstract class EmailVerifier
return self::$reset_password_helper->validateTokenAndFetchUser($token);
}
public static function removeResetRequest(string $token)
public static function removeResetRequest(string $token): void
{
return self::$reset_password_helper->removeResetRequest($token);
self::$reset_password_helper->removeResetRequest($token);
}
public static function sendEmailConfirmation(UserInterface $user): void
public static function sendEmailConfirmation(LocalUser $user): void
{
$email = (new TemplatedEmail())
->from(new Address(Common::config('site', 'email'), Common::config('site', 'nickname')))
@ -64,15 +64,15 @@ abstract class EmailVerifier
self::send($email);
}
public static function send($email)
public static function send($email): void
{
return self::$mailer_helper->send($email);
self::$mailer_helper->send($email);
}
/**
* @throws VerifyEmailExceptionInterface
*/
public function handleEmailConfirmation(Request $request, UserInterface $user): void
public function handleEmailConfirmation(Request $request, LocalUser $user): void
{
self::$verify_email_helper->validateEmailConfirmation($request->getUri(), $user->getId(), $user->getOutgoingEmail());
$user->setIsEmailVerified(true);
@ -80,7 +80,7 @@ abstract class EmailVerifier
DB::flush();
}
public static function processSendingPasswordResetEmail(string $emailFormData, Controller $controller)
public static function processSendingPasswordResetEmail(string $emailFormData, ResetPassword $controller)
{
try {
$user = DB::findOneBy('local_user', ['outgoing_email' => $emailFormData]);
@ -103,7 +103,7 @@ abstract class EmailVerifier
self::send($email);
// Store the token object in session for retrieval in check-email route.
$controller->setTokenObjectInSession($reset_token);
$controller->setInSession($reset_token);
throw new RedirectException('check_email');
}

View File

@ -84,7 +84,7 @@ abstract class HTML
}
/**
* @param $html
* @param mixed $html
*
* @return string
*/

View File

@ -22,11 +22,9 @@
namespace App\Util;
use App\Entity\LocalUser;
use App\Util\Exception\NicknameBlacklistedException;
use App\Util\Exception\NicknameEmptyException;
use App\Util\Exception\NicknameException;
use App\Util\Exception\NicknameInvalidException;
use App\Util\Exception\NicknamePathCollisionException;
use App\Util\Exception\NicknameReservedException;
use App\Util\Exception\NicknameTakenException;
use App\Util\Exception\NicknameTooLongException;
@ -171,11 +169,9 @@ class Nickname
* Normalize an input $nickname, and normalize it to its canonical form.
* The canonical form will be returned, or an exception thrown if invalid.
*
* @throws NicknameException (base class)
* @throws NicknameBlacklistedException
* @throws NicknameException (base class)
* @throws NicknameEmptyException
* @throws NicknameInvalidException
* @throws NicknamePathCollisionException
* @throws NicknameTakenException
* @throws NicknameTooLongException
* @throws NicknameTooShortException

View File

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