From 9109c61af595a7adf0b2f037751e146a5c5071d3 Mon Sep 17 00:00:00 2001 From: Hugo Sales Date: Sun, 10 Oct 2021 09:26:18 +0100 Subject: [PATCH] [TOOLS][CS-FIXER] Run new PHP CS Fixer config. Notably, adds strict_types --- components/Avatar/Avatar.php | 39 +- components/Avatar/Controller/Avatar.php | 4 +- components/Avatar/Entity/Avatar.php | 16 +- .../Avatar/Exception/NoAvatarException.php | 2 + components/Bridge/Bridge.php | 2 + components/Bridge/Entity/ForeignLink.php | 10 +- components/Bridge/Entity/ForeignService.php | 6 +- .../Bridge/Entity/ForeignSubscription.php | 4 +- components/Bridge/Entity/ForeignUser.php | 6 +- .../FreeNetwork/Entity/FreenetworkActor.php | 42 +- components/FreeNetwork/FreeNetwork.php | 4 +- components/Left/Left.php | 4 +- components/Link/Link.php | 137 +++--- components/Posting/Posting.php | 30 +- components/Right/Right.php | 4 +- components/Search/Controller/Search.php | 12 +- components/Search/Search.php | 8 +- components/Search/Util/Parser.php | 21 +- components/Tag/Controller/Tag.php | 4 +- components/Tag/Tag.php | 17 +- config/bootstrap.php | 50 ++- config/bundles.php | 2 + config/cli-config.php | 2 + config/phpstan-bootstrap.php | 2 + config/preload.php | 6 +- config/routes.php | 2 + extlib/Validate.php | 425 +++++++++--------- plugins/ActivityPub/ActivityPub.php | 43 +- plugins/ActivityPub/Controller/Inbox.php | 10 +- .../Entity/ActivitypubActivity.php | 6 +- .../ActivityPub/Entity/ActivitypubActor.php | 42 +- .../Util/Model/AS2ToEntity/AS2ToEntity.php | 11 +- .../Util/Model/AS2ToEntity/AS2ToGSActor.php | 9 +- .../Util/Model/AS2ToEntity/AS2ToNote.php | 14 +- .../Util/Model/EntityToType/EntityToType.php | 11 +- .../Util/Model/EntityToType/GSActorToType.php | 9 +- .../Util/Model/EntityToType/NoteToType.php | 11 +- .../Util/Response/AbstractResponse.php | 12 +- .../Util/Response/ActorResponse.php | 10 +- .../Util/Response/NoteResponse.php | 9 +- .../Util/Response/TypeResponse.php | 6 +- plugins/ActivityPub/Util/Type.php | 32 +- .../ActivityPub/Util/Type/AbstractObject.php | 126 ++---- .../Util/Type/Core/AbstractActivity.php | 5 +- .../ActivityPub/Util/Type/Core/Activity.php | 5 +- .../ActivityPub/Util/Type/Core/Collection.php | 10 +- .../Util/Type/Core/CollectionPage.php | 8 +- .../Util/Type/Core/IntransitiveActivity.php | 5 +- plugins/ActivityPub/Util/Type/Core/Link.php | 16 +- .../ActivityPub/Util/Type/Core/ObjectType.php | 21 +- .../Util/Type/Core/OrderedCollection.php | 5 +- .../Util/Type/Core/OrderedCollectionPage.php | 7 +- .../Util/Type/Extended/AbstractActor.php | 16 +- .../Util/Type/Extended/Activity/Accept.php | 5 +- .../Util/Type/Extended/Activity/Announce.php | 5 +- .../Util/Type/Extended/Activity/Block.php | 5 +- .../Util/Type/Extended/Activity/Create.php | 5 +- .../Util/Type/Extended/Activity/Delete.php | 5 +- .../Util/Type/Extended/Activity/Follow.php | 5 +- .../Util/Type/Extended/Activity/Ignore.php | 5 +- .../Util/Type/Extended/Activity/Join.php | 5 +- .../Util/Type/Extended/Activity/Leave.php | 5 +- .../Util/Type/Extended/Activity/Like.php | 5 +- .../Util/Type/Extended/Activity/Question.php | 5 +- .../Util/Type/Extended/Activity/Reject.php | 5 +- .../Util/Type/Extended/Activity/Remove.php | 5 +- .../Util/Type/Extended/Activity/Undo.php | 5 +- .../Util/Type/Extended/Activity/Update.php | 5 +- .../Util/Type/Extended/Actor/Application.php | 5 +- .../Util/Type/Extended/Actor/Group.php | 5 +- .../Util/Type/Extended/Actor/Organization.php | 5 +- .../Util/Type/Extended/Actor/Person.php | 5 +- .../Util/Type/Extended/Actor/Service.php | 5 +- .../Util/Type/Extended/Object/Article.php | 5 +- .../Util/Type/Extended/Object/Audio.php | 5 +- .../Util/Type/Extended/Object/Document.php | 5 +- .../Util/Type/Extended/Object/Event.php | 5 +- .../Util/Type/Extended/Object/Image.php | 5 +- .../Util/Type/Extended/Object/Mention.php | 5 +- .../Util/Type/Extended/Object/Note.php | 5 +- .../Util/Type/Extended/Object/Page.php | 5 +- .../Util/Type/Extended/Object/Place.php | 17 +- .../Util/Type/Extended/Object/Profile.php | 7 +- .../Util/Type/Extended/Object/Tombstone.php | 7 +- .../Util/Type/Extended/Object/Video.php | 5 +- .../ActivityPub/Util/Type/TypeResolver.php | 43 +- plugins/ActivityPub/Util/Type/Util.php | 210 +++------ plugins/ActivityPub/Util/Type/Validator.php | 24 +- .../Util/Type/Validator/AccuracyValidator.php | 5 +- .../Util/Type/Validator/ActorValidator.php | 32 +- .../Util/Type/Validator/AltitudeValidator.php | 11 +- .../Util/Type/Validator/AnyOfValidator.php | 11 +- .../Type/Validator/AttachmentValidator.php | 9 +- .../Type/Validator/AttributedToValidator.php | 7 +- .../Util/Type/Validator/AudienceValidator.php | 7 +- .../Util/Type/Validator/BccValidator.php | 7 +- .../Util/Type/Validator/BtoValidator.php | 7 +- .../Util/Type/Validator/CcValidator.php | 7 +- .../Util/Type/Validator/ClosedValidator.php | 13 +- .../Type/Validator/ContentMapValidator.php | 7 +- .../Util/Type/Validator/ContentValidator.php | 13 +- .../Util/Type/Validator/ContextValidator.php | 11 +- .../Util/Type/Validator/CurrentValidator.php | 7 +- .../Util/Type/Validator/DeletedValidator.php | 7 +- .../Type/Validator/DescribesValidator.php | 7 +- .../Util/Type/Validator/DurationValidator.php | 9 +- .../Util/Type/Validator/EndTimeValidator.php | 7 +- .../Type/Validator/EndpointsValidator.php | 9 +- .../Util/Type/Validator/FirstValidator.php | 2 + .../Type/Validator/FollowersValidator.php | 27 +- .../Type/Validator/FollowingValidator.php | 2 + .../Type/Validator/FormerTypeValidator.php | 9 +- .../Type/Validator/GeneratorValidator.php | 9 +- .../Util/Type/Validator/HeightValidator.php | 5 +- .../Util/Type/Validator/HrefValidator.php | 7 +- .../Util/Type/Validator/HreflangValidator.php | 5 +- .../Util/Type/Validator/IconValidator.php | 19 +- .../Util/Type/Validator/IdValidator.php | 5 +- .../Util/Type/Validator/ImageValidator.php | 2 + .../Type/Validator/InReplyToValidator.php | 17 +- .../Util/Type/Validator/InboxValidator.php | 27 +- .../Type/Validator/InstrumentValidator.php | 2 + .../Util/Type/Validator/ItemsValidator.php | 21 +- .../Util/Type/Validator/LastValidator.php | 2 + .../Util/Type/Validator/LatitudeValidator.php | 5 +- .../Util/Type/Validator/LikedValidator.php | 2 + .../Util/Type/Validator/LocationValidator.php | 2 + .../Type/Validator/LongitudeValidator.php | 5 +- .../Type/Validator/MediaTypeValidator.php | 9 +- .../Util/Type/Validator/NameMapValidator.php | 7 +- .../Util/Type/Validator/NameValidator.php | 9 +- .../Util/Type/Validator/NextValidator.php | 15 +- .../Util/Type/Validator/ObjectValidator.php | 25 +- .../Util/Type/Validator/OneOfValidator.php | 2 + .../Type/Validator/OrderedItemsValidator.php | 2 + .../Util/Type/Validator/OriginValidator.php | 15 +- .../Util/Type/Validator/OutboxValidator.php | 2 + .../Util/Type/Validator/PartOfValidator.php | 19 +- .../Validator/PreferredUsernameValidator.php | 7 +- .../Util/Type/Validator/PrevValidator.php | 2 + .../Util/Type/Validator/PreviewValidator.php | 15 +- .../Type/Validator/PublishedValidator.php | 2 + .../Util/Type/Validator/RadiusValidator.php | 5 +- .../Util/Type/Validator/RelValidator.php | 9 +- .../Util/Type/Validator/RepliesValidator.php | 15 +- .../Util/Type/Validator/ResultValidator.php | 2 + .../Util/Type/Validator/SourceValidator.php | 15 +- .../Type/Validator/StartIndexValidator.php | 5 +- .../Type/Validator/StartTimeValidator.php | 2 + .../Util/Type/Validator/StreamsValidator.php | 7 +- .../Type/Validator/SummaryMapValidator.php | 5 +- .../Util/Type/Validator/SummaryValidator.php | 9 +- .../Util/Type/Validator/TagValidator.php | 9 +- .../Util/Type/Validator/TargetValidator.php | 2 + .../Util/Type/Validator/ToValidator.php | 2 + .../Type/Validator/TotalItemsValidator.php | 5 +- .../Util/Type/Validator/TypeValidator.php | 9 +- .../Util/Type/Validator/UnitsValidator.php | 5 +- .../Util/Type/Validator/UpdatedValidator.php | 2 + .../Util/Type/Validator/UrlValidator.php | 11 +- .../Util/Type/Validator/WidthValidator.php | 2 + .../Util/Type/ValidatorInterface.php | 2 + .../ActivityPub/Util/Type/ValidatorTools.php | 81 ++-- .../AttachmentShowRelated.php | 18 +- plugins/Cover/Controller/Cover.php | 10 +- plugins/Cover/Cover.php | 10 +- plugins/Cover/Entity/Cover.php | 14 +- plugins/DeleteNote/DeleteNote.php | 15 +- plugins/Directory/Controller/Directory.php | 10 +- plugins/Directory/Directory.php | 4 +- .../EmailNotifications/EmailNotifications.php | 2 + plugins/Embed/Controller/OEmbed.php | 14 +- plugins/Embed/Embed.php | 70 +-- plugins/Embed/Entity/AttachmentEmbed.php | 12 +- plugins/Embed/Test/EmbedTest.php | 6 +- plugins/Favourite/Controller/Favourite.php | 41 +- plugins/Favourite/Entity/Favourite.php | 6 +- plugins/Favourite/Favourite.php | 20 +- plugins/FileQuota/FileQuota.php | 30 +- .../UnsupportedFileTypeException.php | 11 +- plugins/ImageEncoder/ImageEncoder.php | 75 +--- plugins/Poll/Controller/AnswerPoll.php | 9 +- plugins/Poll/Controller/NewPoll.php | 13 +- plugins/Poll/Entity/Poll.php | 23 +- plugins/Poll/Entity/PollResponse.php | 19 +- plugins/Poll/Poll.php | 22 +- .../ProfileColor/Controller/ProfileColor.php | 29 +- plugins/ProfileColor/Entity/ProfileColor.php | 16 +- plugins/ProfileColor/ProfileColor.php | 18 +- plugins/Repeat/Repeat.php | 11 +- plugins/Reply/Controller/Reply.php | 6 +- plugins/Reply/Reply.php | 4 +- plugins/StoreRemoteMedia/StoreRemoteMedia.php | 37 +- plugins/TreeNotes/TreeNotes.php | 6 +- plugins/VideoEncoder/VideoEncoder.php | 80 +--- .../XMPPNotifications/XMPPNotifications.php | 2 + public/index.php | 9 +- scripts/clean_file_table.php | 36 +- scripts/clean_thumbnails.php | 46 +- src/CacheKernel.php | 2 + src/Command/ListEventsCommand.php | 29 +- src/Controller/Actor.php | 2 + src/Controller/AdminPanel.php | 18 +- src/Controller/Attachment.php | 39 +- src/Controller/Network.php | 78 ++-- src/Controller/Note.php | 2 + src/Controller/ResetPassword.php | 6 +- src/Controller/Security.php | 10 +- src/Controller/Subscribers.php | 2 + src/Controller/Subscriptions.php | 2 + src/Controller/TemplateController.php | 2 + src/Controller/UserPanel.php | 24 +- src/Core/Cache.php | 48 +- src/Core/DB/DB.php | 22 +- src/Core/DB/UpdateListener.php | 4 +- src/Core/Entity.php | 27 +- src/Core/Event.php | 29 +- src/Core/Form.php | 21 +- src/Core/GNUsocial.php | 58 ++- src/Core/GSFile.php | 44 +- src/Core/HTTPClient.php | 6 +- src/Core/I18n/I18n.php | 53 ++- src/Core/I18n/TransExtractor.php | 71 ++- src/Core/Log.php | 11 +- src/Core/ModuleManager.php | 50 ++- src/Core/Modules/Component.php | 4 +- src/Core/Modules/Module.php | 6 +- src/Core/Modules/NoteHandlerPlugin.php | 14 +- src/Core/Modules/Plugin.php | 4 +- src/Core/Queue/Message.php | 4 +- src/Core/Queue/MessageHandler.php | 2 + src/Core/Queue/MessageHigh.php | 2 + src/Core/Queue/MessageLow.php | 2 + src/Core/Queue/Queue.php | 6 +- src/Core/Router/RouteLoader.php | 20 +- src/Core/Router/Router.php | 14 +- src/Core/Security.php | 5 +- src/Core/UserRoles.php | 2 + src/Core/VisibilityScope.php | 2 + src/DataFixtures/CoreFixtures.php | 2 + src/DataFixtures/MediaFixtures.php | 28 +- .../Compiler/ModuleManagerPass.php | 2 + .../Compiler/SchemaDefDriver.php | 35 +- src/Kernel.php | 4 +- ...DynamicStaticMethodReturnTypeExtension.php | 8 +- src/PHPStan/GNUsocialProvider.php | 7 +- .../ResetPasswordRequestRepository.php | 5 +- src/Routes/Actor.php | 4 +- src/Routes/Attachments.php | 10 +- src/Routes/Main.php | 4 +- src/Routes/Note.php | 4 +- src/Routes/Subscribers.php | 4 +- src/Routes/Subscriptions.php | 4 +- src/Security/Authenticator.php | 11 +- src/Security/EmailVerifier.php | 28 +- src/Twig/Extension.php | 4 +- src/Twig/Runtime.php | 10 +- src/Util/Bitmap.php | 7 +- src/Util/Common.php | 37 +- .../Exception/AuthenticationException.php | 2 + src/Util/Exception/ClientException.php | 4 +- src/Util/Exception/ConfigurationException.php | 2 + .../Exception/DuplicateFoundException.php | 2 + src/Util/Exception/EmailException.php | 4 +- src/Util/Exception/EmailNotFoundException.php | 7 +- src/Util/Exception/EmailTakenException.php | 2 + src/Util/Exception/InvalidFormException.php | 2 + src/Util/Exception/NicknameEmptyException.php | 2 + src/Util/Exception/NicknameException.php | 4 +- .../Exception/NicknameInvalidException.php | 2 + .../Exception/NicknameNotAllowedException.php | 2 + .../Exception/NicknameNotFoundException.php | 9 +- src/Util/Exception/NicknameTakenException.php | 2 + .../Exception/NicknameTooLongException.php | 2 + src/Util/Exception/NoLoggedInUser.php | 2 + src/Util/Exception/NoSuchFileException.php | 2 + src/Util/Exception/NoSuchNoteException.php | 2 + src/Util/Exception/NotFoundException.php | 2 + .../Exception/NotImplementedException.php | 2 + .../Exception/NotStoredLocallyException.php | 2 + src/Util/Exception/RedirectException.php | 4 +- src/Util/Exception/ServerException.php | 4 +- src/Util/Exception/TemporaryFileException.php | 6 +- src/Util/Form/ActorArrayTransformer.php | 26 +- src/Util/Form/ArrayTransformer.php | 20 +- src/Util/Form/FormFields.php | 6 +- src/Util/Formatting.php | 134 +++--- src/Util/GNUsocialTestCase.php | 7 +- src/Util/HTML.php | 40 +- src/Util/Nickname.php | 29 +- src/Util/Notification/AbstractTransport.php | 7 +- src/Util/Notification/Notification.php | 2 + src/Util/TemporaryFile.php | 38 +- tests/Controller/AdminTest.php | 17 +- tests/Controller/AttachmentTest.php | 2 + tests/Controller/NetworkTest.php | 10 +- tests/Controller/SecurityTest.php | 2 + tests/Controller/UserPanelTest.php | 2 + tests/Core/CacheTest.php | 17 +- tests/Core/ControllerTest.php | 2 + tests/Core/DB/DBTest.php | 10 +- tests/Core/DB/UpdateListenerTest.php | 2 + tests/Core/EntityTest.php | 8 +- tests/Core/EventTest.php | 6 +- tests/Core/FormTest.php | 12 +- tests/Core/GSFileTest.php | 2 + tests/Core/I18n/I18nTest.php | 49 +- tests/Core/RouterTest.php | 5 +- tests/Entity/ActorTest.php | 2 + tests/Entity/AttachmentTest.php | 19 +- tests/Entity/AttachmentThumbnailTest.php | 7 +- tests/Entity/GroupTest.php | 2 + tests/Entity/LinkTest.php | 7 +- tests/Entity/LocalUserTest.php | 9 +- tests/Entity/NoteTest.php | 2 + tests/Entity/PollTest.php | 4 +- tests/Twig/ExtensionTest.php | 4 +- tests/Util/BitmapTest.php | 2 + tests/Util/CommonTest.php | 40 +- tests/Util/Form/ActorArrayTransformerTest.php | 2 + tests/Util/Form/ArrayTransformerTest.php | 2 + tests/Util/FormattingTest.php | 7 +- tests/Util/HTMLTest.php | 5 +- tests/Util/NicknameTest.php | 6 +- tests/Util/Notification/NotificationTest.php | 2 + tests/Util/TemporaryFileTest.php | 6 +- tests/bootstrap.php | 10 +- 327 files changed, 2246 insertions(+), 2616 deletions(-) diff --git a/components/Avatar/Avatar.php b/components/Avatar/Avatar.php index cf8bf54a18..37d887527a 100644 --- a/components/Avatar/Avatar.php +++ b/components/Avatar/Avatar.php @@ -1,5 +1,7 @@ $actor_id]); - })); + return DB::dql( + 'select a from Component\Avatar\Entity\Avatar a ' + . 'where a.actor_id = :actor_id', + ['actor_id' => $actor_id], + ); + }, + ), + ); } /** @@ -112,14 +118,17 @@ class Avatar extends Component */ public static function getAvatarFileInfo(int $actor_id, string $size = 'full'): array { - $res = Cache::get("avatar-file-info-{$actor_id}-{$size}", + $res = Cache::get( + "avatar-file-info-{$actor_id}-{$size}", function () use ($actor_id) { - return DB::dql('select f.id, f.filename, a.title, f.mimetype ' . - 'from App\Entity\Attachment f ' . - 'join Component\Avatar\Entity\Avatar a with f.id = a.attachment_id ' . - 'where a.actor_id = :actor_id', - ['actor_id' => $actor_id]); - } + return DB::dql( + 'select f.id, f.filename, a.title, f.mimetype ' + . 'from App\Entity\Attachment f ' + . 'join Component\Avatar\Entity\Avatar a with f.id = a.attachment_id ' + . 'where a.actor_id = :actor_id', + ['actor_id' => $actor_id], + ); + }, ); if ($res === []) { // Avatar not found $filepath = INSTALLDIR . '/public/assets/default-avatar.svg'; diff --git a/components/Avatar/Controller/Avatar.php b/components/Avatar/Controller/Avatar.php index 0f1e9e2fc8..d877eae404 100644 --- a/components/Avatar/Controller/Avatar.php +++ b/components/Avatar/Controller/Avatar.php @@ -1,5 +1,7 @@ 'gs-avatar']); diff --git a/components/Avatar/Entity/Avatar.php b/components/Avatar/Entity/Avatar.php index 2aa15ef586..03cf9a010f 100644 --- a/components/Avatar/Entity/Avatar.php +++ b/components/Avatar/Entity/Avatar.php @@ -1,5 +1,7 @@ attachment_id; } - /** - * @return null|string - */ public function getTitle(): ?string { return $this->title; } - /** - * @param null|string $title - */ public function setTitle(?string $title): void { $this->title = $title; @@ -121,14 +117,12 @@ class Avatar extends Entity public function getUrl(string $size = 'full', int $type = Router::ABSOLUTE_PATH): string { $actor_id = $this->getActorId(); - return Cache::get("avatar-url-{$actor_id}-{$size}-{$type}", function () use ($actor_id, $size, $type) { - return Router::url('avatar_actor', ['actor_id' => $actor_id, 'size' => $size], $type); - }); + return Cache::get("avatar-url-{$actor_id}-{$size}-{$type}", fn () => Router::url('avatar_actor', ['actor_id' => $actor_id, 'size' => $size], $type)); } public function getAttachment(): Attachment { - $this->attachment = $this->attachment ?? DB::findOneBy('attachment', ['id' => $this->attachment_id]); + $this->attachment ??= DB::findOneBy('attachment', ['id' => $this->attachment_id]); return $this->attachment; } @@ -144,8 +138,6 @@ class Avatar extends Entity /** * Delete this avatar and kill corresponding attachment - * - * @return bool */ public function delete(): bool { diff --git a/components/Avatar/Exception/NoAvatarException.php b/components/Avatar/Exception/NoAvatarException.php index a065de364a..e02490c28d 100644 --- a/components/Avatar/Exception/NoAvatarException.php +++ b/components/Avatar/Exception/NoAvatarException.php @@ -1,5 +1,7 @@ actor_uri; } - /** - * @param string $actor_uri - */ public function setActorUri(string $actor_uri): void { $this->actor_uri = $actor_uri; } - /** - * @return string - */ public function getSource(): string { return $this->source; } - /** - * @param string $source - */ public function setSource(string $source): void { $this->source = $source; } - /** - * @return int - */ public function getActorId(): int { return $this->actor_id; } - /** - * @param int $actor_id - */ public function setActorId(int $actor_id): void { $this->actor_id = $actor_id; } - /** - * @return bool - */ public function isIsLocal(): bool { return $this->is_local; } - /** - * @param bool $is_local - */ public function setIsLocal(bool $is_local): void { $this->is_local = $is_local; } - /** - * @return DateTimeInterface - */ public function getCreated(): DateTimeInterface { return $this->created; } - /** - * @param DateTimeInterface $created - */ public function setCreated(DateTimeInterface $created): void { $this->created = $created; } - /** - * @return DateTimeInterface - */ public function getModified(): DateTimeInterface { return $this->modified; } - /** - * @param DateTimeInterface $modified - */ public function setModified(DateTimeInterface $modified): void { $this->modified = $modified; diff --git a/components/FreeNetwork/FreeNetwork.php b/components/FreeNetwork/FreeNetwork.php index bb6689f599..77e951d7f0 100644 --- a/components/FreeNetwork/FreeNetwork.php +++ b/components/FreeNetwork/FreeNetwork.php @@ -1,5 +1,7 @@ \(\)\[\]\{\}\\\'\\\";]+)(?![\@\!\#])' . - '(' . - '(?:' . - '(?:' . //Known protocols - '(?:' . - '(?:(?:' . implode('|', $this->URLSchemes(self::URL_SCHEME_COLON_DOUBLE_SLASH)) . ')://)' . - '|' . - '(?:(?:' . implode('|', $this->URLSchemes(self::URL_SCHEME_SINGLE_COLON)) . '):)' . - ')' . - '(?:[\pN\pL\-\_\+\%\~]+(?::[\pN\pL\-\_\+\%\~]+)?\@)?' . //user:pass@ - '(?:' . - '(?:' . - '\[[\pN\pL\-\_\:\.]+(?URLSchemes(self::URL_SCHEME_COLON_COORDINATES)) . '):' . + return '#' + . '(?:^|[\s\<\>\(\)\[\]\{\}\\\'\\\";]+)(?![\@\!\#])' + . '(' + . '(?:' + . '(?:' //Known protocols + . '(?:' + . '(?:(?:' . implode('|', $this->URLSchemes(self::URL_SCHEME_COLON_DOUBLE_SLASH)) . ')://)' + . '|' + . '(?:(?:' . implode('|', $this->URLSchemes(self::URL_SCHEME_SINGLE_COLON)) . '):)' + . ')' + . '(?:[\pN\pL\-\_\+\%\~]+(?::[\pN\pL\-\_\+\%\~]+)?\@)?' //user:pass@ + . '(?:' + . '(?:' + . '\[[\pN\pL\-\_\:\.]+(?URLSchemes(self::URL_SCHEME_COLON_COORDINATES)) . '):' // There's an order that must be followed here too, if ;crs= is used, it must precede ;u= // Also 'crsp' (;crs=$crsp) must match $geouri_labeltext_regex // Also 'uval' (;u=$uval) must be a pnum: \-?[0-9]+ - '(?:' . - '(?:[0-9]+(?:\.[0-9]+)?(?:\,[0-9]+(?:\.[0-9]+)?){1,2})' . // 1(.23)?(,4(.56)){1,2} - '(?:\;(?:[' . $geouri_labeltext_regex . ']+)(?:\=[' . $geouri_paramchar_regex . ']+)*)*' . - ')' . - ')' . + . '(?:' + . '(?:[0-9]+(?:\.[0-9]+)?(?:\,[0-9]+(?:\.[0-9]+)?){1,2})' // 1(.23)?(,4(.56)){1,2} + . '(?:\;(?:[' . $geouri_labeltext_regex . ']+)(?:\=[' . $geouri_paramchar_regex . ']+)*)*' + . ')' + . ')' // URLs without domain name, like magnet:?xt=... - '|(?:(?:' . implode('|', $this->URLSchemes(self::URL_SCHEME_NO_DOMAIN)) . '):(?=\?))' . // zero-length lookahead requires ? after : - (Common::config('linkify', 'ipv4') // Convert IPv4 addresses to hyperlinks + . '|(?:(?:' . implode('|', $this->URLSchemes(self::URL_SCHEME_NO_DOMAIN)) . '):(?=\?))' // zero-length lookahead requires ? after : + . (Common::config('linkify', 'ipv4') // Convert IPv4 addresses to hyperlinks ? '|(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)' - : '') . - (Common::config('linkify', 'ipv6') // Convert IPv6 addresses to hyperlinks - ? '|(?:' . //IPv6 - '\[?(?:(?:(?:[0-9A-Fa-f]{1,4}:){7}(?:(?:[0-9A-Fa-f]{1,4})|:))|(?:(?:[0-9A-Fa-f]{1,4}:){6}(?::|(?:(?:25[0-5]|2[0-4]\d|[01]?\d{1,2})(?:\.(?:25[0-5]|2[0-4]\d|[01]?\d{1,2})){3})|(?::[0-9A-Fa-f]{1,4})))|(?:(?:[0-9A-Fa-f]{1,4}:){5}(?:(?::(?:(?:25[0-5]|2[0-4]\d|[01]?\d{1,2})(?:\.(?:25[0-5]|2[0-4]\d|[01]?\d{1,2})){3})?)|(?:(?::[0-9A-Fa-f]{1,4}){1,2})))|(?:(?:[0-9A-Fa-f]{1,4}:){4}(?::[0-9A-Fa-f]{1,4}){0,1}(?:(?::(?:(?:25[0-5]|2[0-4]\d|[01]?\d{1,2})(?:\.(?:25[0-5]|2[0-4]\d|[01]?\d{1,2})){3})?)|(?:(?::[0-9A-Fa-f]{1,4}){1,2})))|(?:(?:[0-9A-Fa-f]{1,4}:){3}(?::[0-9A-Fa-f]{1,4}){0,2}(?:(?::(?:(?:25[0-5]|2[0-4]\d|[01]?\d{1,2})(?:\.(?:25[0-5]|2[0-4]\d|[01]?\d{1,2})){3})?)|(?:(?::[0-9A-Fa-f]{1,4}){1,2})))|(?:(?:[0-9A-Fa-f]{1,4}:){2}(?::[0-9A-Fa-f]{1,4}){0,3}(?:(?::(?:(?:25[0-5]|2[0-4]\d|[01]?\d{1,2})(?:\.(?:25[0-5]|2[0-4]\d|[01]?\d{1,2})){3})?)|(?:(?::[0-9A-Fa-f]{1,4}){1,2})))|(?:(?:[0-9A-Fa-f]{1,4}:)(?::[0-9A-Fa-f]{1,4}){0,4}(?:(?::(?:(?:25[0-5]|2[0-4]\d|[01]?\d{1,2})(?:\.(?:25[0-5]|2[0-4]\d|[01]?\d{1,2})){3})?)|(?:(?::[0-9A-Fa-f]{1,4}){1,2})))|(?::(?::[0-9A-Fa-f]{1,4}){0,5}(?:(?::(?:(?:25[0-5]|2[0-4]\d|[01]?\d{1,2})(?:\.(?:25[0-5]|2[0-4]\d|[01]?\d{1,2})){3})?)|(?:(?::[0-9A-Fa-f]{1,4}){1,2})))|(?:(?:(?:25[0-5]|2[0-4]\d|[01]?\d{1,2})(?:\.(?:25[0-5]|2[0-4]\d|[01]?\d{1,2})){3})))\]?(? self::URL_SCHEME_COLON_COORDINATES, ]; - return array_keys(array_filter($schemes, fn ($scheme) => is_null($filter) || ($scheme & $filter))); + return array_keys(array_filter($schemes, fn ($scheme) => \is_null($filter) || ($scheme & $filter))); } /** * Find links in the given text and pass them to the given callback function. - * - * @param string $text */ public function replaceURLs(string $text): string { @@ -180,16 +180,13 @@ class Link extends Component * Intermediate callback for `replaceURLs()`, which helps resolve some * ambiguous link forms before passing on to the final callback. * - * @param array $matches * @param callable(string $text): string $callback: return replacement text - * - * @return string */ private function callbackHelper(array $matches, callable $callback): string { $url = $matches[1]; - $left = strpos($matches[0], $url); - $right = $left + strlen($url); + $left = mb_strpos($matches[0], $url); + $right = $left + mb_strlen($url); $groupSymbolSets = [ [ @@ -214,23 +211,23 @@ class Link extends Component do { $original_url = $url; foreach ($groupSymbolSets as $groupSymbolSet) { - if (substr($url, -1) == $groupSymbolSet['right']) { - $group_left_count = substr_count($url, $groupSymbolSet['left']); - $group_right_count = substr_count($url, $groupSymbolSet['right']); + if (mb_substr($url, -1) == $groupSymbolSet['right']) { + $group_left_count = mb_substr_count($url, $groupSymbolSet['left']); + $group_right_count = mb_substr_count($url, $groupSymbolSet['right']); if ($group_left_count < $group_right_count) { --$right; - $url = substr($url, 0, -1); + $url = mb_substr($url, 0, -1); } } } - if (in_array(substr($url, -1), $cannotEndWith)) { + if (\in_array(mb_substr($url, -1), $cannotEndWith)) { --$right; - $url = substr($url, 0, -1); + $url = mb_substr($url, 0, -1); } } while ($original_url != $url); $result = $callback($url); - return substr($matches[0], 0, $left) . $result . substr($matches[0], $right); + return mb_substr($matches[0], 0, $left) . $result . mb_substr($matches[0], $right); } /** @@ -242,7 +239,7 @@ class Link extends Component // functions $url = htmlspecialchars_decode($url); - if (strpos($url, '@') !== false && strpos($url, ':') === false && ($email = filter_var($url, FILTER_VALIDATE_EMAIL)) !== false) { + if (str_contains($url, '@') && !str_contains($url, ':') && ($email = filter_var($url, \FILTER_VALIDATE_EMAIL)) !== false) { //url is an email address without the mailto: protocol $url = "mailto:{$email}"; } diff --git a/components/Posting/Posting.php b/components/Posting/Posting.php index 25dca8a36b..033f34f04f 100644 --- a/components/Posting/Posting.php +++ b/components/Posting/Posting.php @@ -1,5 +1,7 @@ getId(); $to_tags = []; - $tags = Cache::get("actor-circle-{$actor_id}", - fn () => DB::dql('select c.tag from App\Entity\ActorCircle c where c.tagger = :tagger', ['tagger' => $actor_id])); + $tags = Cache::get( + "actor-circle-{$actor_id}", + fn () => DB::dql('select c.tag from App\Entity\ActorCircle c where c.tagger = :tagger', ['tagger' => $actor_id]), + ); foreach ($tags as $t) { $t = $t['tag']; $to_tags[$t] = $t; @@ -87,7 +91,7 @@ class Posting extends Component ['content', TextareaType::class, ['label' => _m('Content:'), 'data' => $initial_content, 'attr' => ['placeholder' => _m($placeholder)]]], ['attachments', FileType::class, ['label' => _m('Attachments:'), 'data' => null, 'multiple' => true, 'required' => false]], ]; - if (count($available_content_types) > 1) { + if (\count($available_content_types) > 1) { $form_params[] = ['content_type', ChoiceType::class, [ 'label' => _m('Text format:'), 'multiple' => false, 'expanded' => false, @@ -121,13 +125,6 @@ class Posting extends Component * $actor_id, possibly as a reply to note $reply_to and with flag * $is_local. Sanitizes $content and $attachments * - * @param Actor $actor - * @param string $content - * @param string $content_type - * @param array $attachments - * @param null|Note $reply_to - * @param null|Note $repeat_of - * * @throws ClientException * @throws ServerException */ @@ -149,8 +146,8 @@ class Posting extends Component $filesize = $f->getSize(); $max_file_size = Common::config('attachments', 'file_quota'); if ($max_file_size < $filesize) { - throw new ClientException(_m('No file may be larger than {quota} bytes and the file you sent was {size} bytes. ' . - 'Try to upload a smaller version.', ['quota' => $max_file_size, 'size' => $filesize])); + throw new ClientException(_m('No file may be larger than {quota} bytes and the file you sent was {size} bytes. ' + . 'Try to upload a smaller version.', ['quota' => $max_file_size, 'size' => $filesize], )); } Event::handle('EnforceUserFileQuota', [$filesize, $actor->getId()]); $processed_attachments[] = [GSFile::storeFileAsAttachment($f), $f->getClientOriginalName()]; @@ -193,11 +190,6 @@ class Posting extends Component * Get a unique representation of a file on disk * * This can be used in the future to deduplicate images by visual content - * - * @param string $filename - * @param null|string $out_hash - * - * @return bool */ public function onHashFile(string $filename, ?string &$out_hash): bool { @@ -207,10 +199,6 @@ class Posting extends Component /** * Fill the list with allowed sizes for an attachment, to prevent potential DoS'ing by requesting thousands of different thumbnail sizes - * - * @param null|array $sizes - * - * @return bool */ public function onGetAllowedThumbnailSizes(?array &$sizes): bool { diff --git a/components/Right/Right.php b/components/Right/Right.php index fbc505fceb..75fd92edc0 100644 --- a/components/Right/Right.php +++ b/components/Right/Right.php @@ -1,5 +1,7 @@ select('actor')->from('App\Entity\Actor', 'actor'); Event::handle('SeachQueryAddJoins', [&$note_qb, &$actor_qb]); $notes = $actors = []; - if (!is_null($note_criteria)) { + if (!\is_null($note_criteria)) { $note_qb->addCriteria($note_criteria); $notes = $note_qb->getQuery()->execute(); - } else { - if (!is_null($actor_criteria)) { - $actor_qb->addCriteria($actor_criteria); - $actors = $actor_qb->getQuery()->execute(); - } + } elseif (!\is_null($actor_criteria)) { + $actor_qb->addCriteria($actor_criteria); + $actors = $actor_qb->getQuery()->execute(); } return [ diff --git a/components/Search/Search.php b/components/Search/Search.php index dec35b3ae0..0c15ca6df0 100644 --- a/components/Search/Search.php +++ b/components/Search/Search.php @@ -1,5 +1,7 @@ ['placeholder' => _m('Search tags...')] + 'attr' => ['placeholder' => _m('Search tags...')], ]], [$form_name = 'submit_search', SubmitType::class, [ @@ -74,7 +76,7 @@ class Search extends Component * * @param array $styles stylesheets path * - * @return bool hook value; true means continue processing, false means stop. + * @return bool hook value; true means continue processing, false means stop */ public function onEndShowStyles(array &$styles, string $route): bool { diff --git a/components/Search/Util/Parser.php b/components/Search/Util/Parser.php index 1edaa8dd33..88a35decbd 100644 --- a/components/Search/Util/Parser.php +++ b/components/Search/Util/Parser.php @@ -1,5 +1,7 @@ $canonical], actor: $user, - page: $page + page: $page, ); return [ diff --git a/components/Tag/Tag.php b/components/Tag/Tag.php index 86ced208f8..72beba2258 100644 --- a/components/Tag/Tag.php +++ b/components/Tag/Tag.php @@ -1,5 +1,7 @@ connect('tag', '/tag/{tag<' . self::TAG_SLUG_REGEX . '>}' , [Controller\Tag::class, 'tag']); + $r->connect('tag', '/tag/{tag<' . self::TAG_SLUG_REGEX . '>}', [Controller\Tag::class, 'tag']); return Event::next; } @@ -60,7 +62,7 @@ class Tag extends Component { $matched_tags = []; $processed_tags = false; - preg_match_all(self::TAG_REGEX, $content, $matched_tags, PREG_SET_ORDER); + preg_match_all(self::TAG_REGEX, $content, $matched_tags, \PREG_SET_ORDER); foreach ($matched_tags as $match) { $tag = $match[2]; $canonical_tag = self::canonicalTag($tag); @@ -87,16 +89,13 @@ class Tag extends Component public static function canonicalTag(string $tag): string { - return substr(Formatting::slugify($tag), 0, self::MAX_TAG_LENGTH); + return mb_substr(Formatting::slugify($tag), 0, self::MAX_TAG_LENGTH); } /** * Populate $note_expr with an expression to match a tag, if the term looks like a tag * * $term /^(note|tag|people|actor)/ means we want to match only either a note or an actor - * - * @param mixed $note_expr - * @param mixed $actor_expr */ public function onSearchCreateExpression(ExpressionBuilder $eb, string $term, &$note_expr, &$actor_expr) { diff --git a/config/bootstrap.php b/config/bootstrap.php index 9b49a9f865..738268a615 100644 --- a/config/bootstrap.php +++ b/config/bootstrap.php @@ -1,17 +1,19 @@ =1.2) -if (\is_array($env = @include dirname(__DIR__) . '/.env.local.php') && (!isset($env['APP_ENV']) || ($_SERVER['APP_ENV'] ?? $_ENV['APP_ENV'] ?? $env['APP_ENV']) === $env['APP_ENV'])) { +if (\is_array($env = @include \dirname(__DIR__) . '/.env.local.php') && (!isset($env['APP_ENV']) || ($_SERVER['APP_ENV'] ?? $_ENV['APP_ENV'] ?? $env['APP_ENV']) === $env['APP_ENV'])) { foreach ($env as $k => $v) { - $_ENV[$k] = $_ENV[$k] ?? (isset($_SERVER[$k]) && 0 !== strpos($k, 'HTTP_') ? $_SERVER[$k] : $v); + $_ENV[$k] = $_ENV[$k] ?? (isset($_SERVER[$k]) && !str_starts_with($k, 'HTTP_') ? $_SERVER[$k] : $v); } -} elseif (!\class_exists(Dotenv::class)) { +} elseif (!class_exists(Dotenv::class)) { throw new RuntimeException('Please run "composer require symfony/dotenv" to load the ".env" files configuring the application.'); } else { // load all the .env files @@ -19,38 +21,38 @@ if (\is_array($env = @include dirname(__DIR__) . '/.env.local.php') && (!isset($ } $_SERVER += $_ENV; -$_SERVER['APP_ENV'] = $_ENV['APP_ENV'] = ($_SERVER['APP_ENV'] ?? $_ENV['APP_ENV'] ?? null) ?: 'dev'; -$_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'; +$_SERVER['APP_ENV'] = $_ENV['APP_ENV'] = ($_SERVER['APP_ENV'] ?? $_ENV['APP_ENV'] ?? null) ?: 'dev'; +$_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'); +\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/'); -define('GNUSOCIAL_ENGINE_URL', GNUSOCIAL_PROJECT_URL); +\define('GNUSOCIAL_PROJECT_URL', 'https://gnusocial.rocks/'); +\define('GNUSOCIAL_ENGINE_URL', GNUSOCIAL_PROJECT_URL); // MERGE Change to https://git.gnu.io/gnu/gnu-social -define('GNUSOCIAL_REPOSITORY_URL', 'https://code.undefinedhackers.net/GNUsocial/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'); +\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('GNUSOCIAL_LIFECYCLE', 'dev'); +\define('GNUSOCIAL_VERSION', GNUSOCIAL_BASE_VERSION . '-' . GNUSOCIAL_LIFECYCLE); +\define('GNUSOCIAL_CODENAME', 'Big bang'); -define('MODULE_CACHE_FILE', INSTALLDIR . '/var/cache/module_manager.php'); +\define('MODULE_CACHE_FILE', INSTALLDIR . '/var/cache/module_manager.php'); /** * StatusNet had this string as valid path characters: '\pN\pL\,\!\(\)\.\:\-\_\+\/\=\&\;\%\~\*\$\'\@' * Some of those characters can be troublesome when auto-linking plain text. Such as "http://some.com/)" * URL encoding should be used whenever a weird character is used, the following strings are not definitive. */ -define('URL_REGEX_VALID_PATH_CHARS', '\pN\pL\,\!\.\:\-\_\+\/\@\=\;\%\~\*\(\)'); -define('URL_REGEX_VALID_QSTRING_CHARS', URL_REGEX_VALID_PATH_CHARS . '\&'); -define('URL_REGEX_VALID_FRAGMENT_CHARS', URL_REGEX_VALID_QSTRING_CHARS . '\?\#'); -define('URL_REGEX_EXCLUDED_END_CHARS', '\?\.\,\!\#\:\''); // don't include these if they are directly after a URL -define('URL_REGEX_DOMAIN_NAME', '(?:(?!-)[A-Za-z0-9\-]{1,63}(? ['all' => true], Symfony\Bundle\TwigBundle\TwigBundle::class => ['all' => true], diff --git a/config/cli-config.php b/config/cli-config.php index 45856e1cf1..383df51637 100644 --- a/config/cli-config.php +++ b/config/cli-config.php @@ -1,5 +1,7 @@ * @author Pierre-Alain Joye * @author Amir Mohammad Saied * @copyright 1997-2006 Pierre-Alain Joye,Tomas V.V.Cox,Amir Mohammad Saied * @license http://www.opensource.org/licenses/bsd-license.php New BSD License + * * @version CVS: $Id$ - * @link http://pear.php.net/package/Validate + * + * @see http://pear.php.net/package/Validate */ // {{{ Constants /** * Methods for common data validations */ -define('VALIDATE_NUM', '0-9'); -define('VALIDATE_SPACE', '\s'); -define('VALIDATE_ALPHA_LOWER', 'a-z'); -define('VALIDATE_ALPHA_UPPER', 'A-Z'); -define('VALIDATE_ALPHA', VALIDATE_ALPHA_LOWER . VALIDATE_ALPHA_UPPER); -define('VALIDATE_EALPHA_LOWER', VALIDATE_ALPHA_LOWER . 'áéíóúýàèìòùäëïöüÿâêîôûãñõ¨åæç½ðøþß'); -define('VALIDATE_EALPHA_UPPER', VALIDATE_ALPHA_UPPER . 'ÁÉÍÓÚÝÀÈÌÒÙÄËÏÖܾÂÊÎÔÛÃÑÕ¦ÅÆǼÐØÞ'); -define('VALIDATE_EALPHA', VALIDATE_EALPHA_LOWER . VALIDATE_EALPHA_UPPER); -define('VALIDATE_PUNCTUATION', VALIDATE_SPACE . '\.,;\:&"\'\?\!\(\)'); -define('VALIDATE_NAME', VALIDATE_EALPHA . VALIDATE_SPACE . "'" . '\-'); -define('VALIDATE_STREET', VALIDATE_NUM . VALIDATE_NAME . "/\\ºª\."); +\define('VALIDATE_NUM', '0-9'); +\define('VALIDATE_SPACE', '\s'); +\define('VALIDATE_ALPHA_LOWER', 'a-z'); +\define('VALIDATE_ALPHA_UPPER', 'A-Z'); +\define('VALIDATE_ALPHA', VALIDATE_ALPHA_LOWER . VALIDATE_ALPHA_UPPER); +\define('VALIDATE_EALPHA_LOWER', VALIDATE_ALPHA_LOWER . 'áéíóúýàèìòùäëïöüÿâêîôûãñõ¨åæç½ðøþß'); +\define('VALIDATE_EALPHA_UPPER', VALIDATE_ALPHA_UPPER . 'ÁÉÍÓÚÝÀÈÌÒÙÄËÏÖܾÂÊÎÔÛÃÑÕ¦ÅÆǼÐØÞ'); +\define('VALIDATE_EALPHA', VALIDATE_EALPHA_LOWER . VALIDATE_EALPHA_UPPER); +\define('VALIDATE_PUNCTUATION', VALIDATE_SPACE . '\.,;\:&"\'\?\!\(\)'); +\define('VALIDATE_NAME', VALIDATE_EALPHA . VALIDATE_SPACE . "'" . '\-'); +\define('VALIDATE_STREET', VALIDATE_NUM . VALIDATE_NAME . '/\\ºª\\.'); -define('VALIDATE_ITLD_EMAILS', 1); -define('VALIDATE_GTLD_EMAILS', 2); -define('VALIDATE_CCTLD_EMAILS', 4); -define('VALIDATE_ALL_EMAILS', 8); +\define('VALIDATE_ITLD_EMAILS', 1); +\define('VALIDATE_GTLD_EMAILS', 2); +\define('VALIDATE_CCTLD_EMAILS', 4); +\define('VALIDATE_ALL_EMAILS', 8); // }}} /** @@ -71,14 +76,17 @@ define('VALIDATE_ALL_EMAILS', 8); * * @category Validate * @package Validate + * * @author Tomas V.V.Cox * @author Pierre-Alain Joye * @author Amir Mohammad Saied * @author Diogo Cordeiro * @copyright 1997-2006 Pierre-Alain Joye,Tomas V.V.Cox,Amir Mohammad Saied * @license http://www.opensource.org/licenses/bsd-license.php New BSD License + * * @version Release: @package_version@ - * @link http://pear.php.net/package/Validate + * + * @see http://pear.php.net/package/Validate */ class Validate { @@ -91,7 +99,7 @@ class Validate * * @var array $itld (International top-level domains) */ - protected static $itld = [ + protected static array $itld = [ 'arpa', 'root', ]; @@ -104,7 +112,7 @@ class Validate * * @var array $gtld (Generic top-level domains) */ - protected static $gtld = [ + protected static array $gtld = [ 'aero', 'biz', 'cat', @@ -137,7 +145,7 @@ class Validate * * @var array $cctld (Country Code Top-Level Domain) */ - protected static $cctld = [ + protected static array $cctld = [ 'ac', 'ad', 'ae', 'af', 'ag', 'ai', 'al', 'am', 'an', @@ -210,10 +218,9 @@ class Validate * * @param string $uri tag URI to validate * - * @return bool true if valid tag URI, false if not - * - * @access private * @throws Exception + * + * @return bool true if valid tag URI, false if not */ private static function uriRFC4151(string $uri): bool { @@ -221,15 +228,15 @@ class Validate if (preg_match( '/^tag:(?.*),(?\d{4}-?\d{0,2}-?\d{0,2}):(?.*)(.*:)*$/', $uri, - $matches + $matches, )) { - $date = $matches['date']; + $date = $matches['date']; $date6 = strtotime($date); - if ((strlen($date) == 4) && $date <= date('Y')) { + if ((mb_strlen($date) == 4) && $date <= date('Y')) { $datevalid = true; - } elseif ((strlen($date) == 7) && ($date6 < strtotime("now"))) { + } elseif ((mb_strlen($date) == 7) && ($date6 < strtotime('now'))) { $datevalid = true; - } elseif ((strlen($date) == 10) && ($date6 < strtotime("now"))) { + } elseif ((mb_strlen($date) == 10) && ($date6 < strtotime('now'))) { $datevalid = true; } if (self::email($matches['name'])) { @@ -246,28 +253,28 @@ class Validate /** * Validate a number * - * @param string $number Number to validate - * @param array $options array where: - * 'decimal' is the decimal char or false when decimal - * not allowed. - * i.e. ',.' to allow both ',' and '.' - * 'dec_prec' Number of allowed decimals - * 'min' minimum value - * 'max' maximum value + * @param string $number Number to validate + * @param array $options array where: + * 'decimal' is the decimal char or false when decimal + * not allowed. + * i.e. ',.' to allow both ',' and '.' + * 'dec_prec' Number of allowed decimals + * 'min' minimum value + * 'max' maximum value * * @return bool true if valid number, false if not */ - public static function number($number, array $options = []): bool + public static function number(string $number, array $options = []): bool { $decimal = $dec_prec = $min = $max = null; - if (is_array($options)) { + if (\is_array($options)) { extract($options); } - $dec_prec = $dec_prec ? "{1,$dec_prec}" : '+'; - $dec_regex = $decimal ? "[$decimal][0-9]$dec_prec" : ''; + $dec_prec = $dec_prec ? "{1,{$dec_prec}}" : '+'; + $dec_regex = $decimal ? "[{$decimal}][0-9]{$dec_prec}" : ''; - if (!preg_match("|^[-+]?\s*[0-9]+($dec_regex)?\$|", $number)) { + if (!preg_match("|^[-+]?\\s*[0-9]+({$dec_regex})?\$|", $number)) { return false; } @@ -275,15 +282,12 @@ class Validate $number = strtr($number, $decimal, '.'); } - $number = (float)str_replace(' ', '', $number); + $number = (float) str_replace(' ', '', $number); if ($min !== null && $min > $number) { return false; } - if ($max !== null && $max < $number) { - return false; - } - return true; + return !($max !== null && $max < $number); } /** @@ -291,29 +295,28 @@ class Validate * * @param string $string string to be converted * - * @return string converted string + * @return string converted string */ private static function stringToUtf7(string $string): string { $return = ''; - $utf7 = [ + $utf7 = [ 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '0', '1', '2', - '3', '4', '5', '6', '7', '8', '9', '+', ',' + '3', '4', '5', '6', '7', '8', '9', '+', ',', ]; - $state = 0; if (!empty($string)) { $i = 0; - while ($i <= strlen($string)) { - $char = substr($string, $i, 1); + while ($i <= mb_strlen($string)) { + $char = mb_substr($string, $i, 1); if ($state == 0) { - if ((ord($char) >= 0x7F) || (ord($char) <= 0x1F)) { + if ((\ord($char) >= 0x7F) || (\ord($char) <= 0x1F)) { if ($char) { $return .= '&'; } @@ -323,13 +326,13 @@ class Validate } else { $return .= $char; } - } elseif (($i == strlen($string) || - !((ord($char) >= 0x7F)) || (ord($char) <= 0x1F))) { + } elseif (($i == mb_strlen($string) + || !((\ord($char) >= 0x7F)) || (\ord($char) <= 0x1F))) { if ($state != 1) { - if (ord($char) > 64) { + if (\ord($char) > 64) { $return .= ''; } else { - $return .= $utf7[ord($char)]; + $return .= $utf7[\ord($char)]; } } $return .= '-'; @@ -337,23 +340,23 @@ class Validate } else { switch ($state) { case 1: - $return .= $utf7[ord($char) >> 2]; - $residue = (ord($char) & 0x03) << 4; - $state = 2; + $return .= $utf7[\ord($char) >> 2]; + $residue = (\ord($char) & 0x03) << 4; + $state = 2; break; case 2: - $return .= $utf7[$residue | (ord($char) >> 4)]; - $residue = (ord($char) & 0x0F) << 2; - $state = 3; + $return .= $utf7[$residue | (\ord($char) >> 4)]; + $residue = (\ord($char) & 0x0F) << 2; + $state = 3; break; case 3: - $return .= $utf7[$residue | (ord($char) >> 6)]; - $return .= $utf7[ord($char) & 0x3F]; + $return .= $utf7[$residue | (\ord($char) >> 6)]; + $return .= $utf7[\ord($char) & 0x3F]; $state = 1; break; } } - $i++; + ++$i; } return $return; } @@ -363,15 +366,15 @@ class Validate /** * Validate an email according to full RFC822 (inclusive human readable part) * - * @param string $email email to validate, + * @param string $email email to validate, * will return the address for optional dns validation - * @param array $options email() options + * @param array $options email() options * * @return bool true if valid email, false if not */ private static function emailRFC822(string &$email, array &$options): bool { - static $address = null; + static $address = null; static $uncomment = null; if (!$address) { // atom = 1* @@ -416,9 +419,9 @@ class Validate // / group ; named list $address = '/^\s*(?:' . $mailbox . '|' . $group . ')$/'; - $uncomment = - '/((?:(?:\\\\"|[^("])*(?:' . $quoted_string . - ')?)*)((? $keys) { - if (in_array($emailEnding, $keys)) { + if (\in_array($emailEnding, $keys)) { return true; } } @@ -511,18 +514,19 @@ class Validate * 'VALIDATE_CCTLD_EMAILS' => 'true', * 'VALIDATE_ITLD_EMAILS' => 'true', * ]; - * - * @return bool true if valid email, false if not + * @param null|mixed $options * * @throws Exception + * + * @return bool true if valid email, false if not */ public static function email(string $email, $options = null): bool { $check_domain = false; - $use_rfc822 = false; - if (is_bool($options)) { + $use_rfc822 = false; + if (\is_bool($options)) { $check_domain = $options; - } elseif (is_array($options)) { + } elseif (\is_array($options)) { extract($options); } @@ -538,20 +542,20 @@ class Validate } if ($hasIDNA === true) { - if (strpos($email, '@') !== false) { + if (str_contains($email, '@')) { $tmpEmail = explode('@', $email); - $domain = array_pop($tmpEmail); + $domain = array_pop($tmpEmail); // Check if the domain contains characters > 127 which means // it's an idn domain name. $chars = count_chars($domain, 1); if (!empty($chars) && max(array_keys($chars)) > 127) { - $idna =& Net_IDNA2::singleton(); + $idna = &Net_IDNA2::singleton(); $domain = $idna->encode($domain); } - array_push($tmpEmail, $domain); - $email = implode('@', $tmpEmail); + $tmpEmail[] = $domain; + $email = implode('@', $tmpEmail); } } @@ -580,14 +584,11 @@ class Validate $&xi'; //checks if exists the domain (MX or A) - if ($use_rfc822 ? self::emailRFC822($email, $options) : - preg_match($regex, $email)) { - if ($check_domain && function_exists('checkdnsrr')) { + if ($use_rfc822 ? self::emailRFC822($email, $options) + : preg_match($regex, $email)) { + if ($check_domain && \function_exists('checkdnsrr')) { $domain = preg_replace('/[^-a-z.0-9]/i', '', array_pop(explode('@', $email))); - if (checkdnsrr($domain, 'MX') || checkdnsrr($domain, 'A')) { - return true; - } - return false; + return (bool) (checkdnsrr($domain, 'MX') || checkdnsrr($domain, 'A')); } return true; } @@ -597,38 +598,34 @@ class Validate /** * Validate a string using the given format 'format' * - * @param string $string String to validate + * @param string $string String to validate * @param array|string $options Options array where: - * 'format' is the format of the string + * 'format' is the format of the string * Ex:VALIDATE_NUM . VALIDATE_ALPHA (see constants) - * 'min_length' minimum length - * 'max_length' maximum length + * 'min_length' minimum length + * 'max_length' maximum length * * @return bool true if valid string, false if not */ public static function string(string $string, $options): bool { - $format = null; + $format = null; $min_length = 0; $max_length = 0; - if (is_array($options)) { + if (\is_array($options)) { extract($options); } - if ($format && !preg_match("|^[$format]*\$|s", $string)) { + if ($format && !preg_match("|^[{$format}]*\$|s", $string)) { return false; } - if ($min_length && strlen($string) < $min_length) { + if ($min_length && mb_strlen($string) < $min_length) { return false; } - if ($max_length && strlen($string) > $max_length) { - return false; - } - - return true; + return !($max_length && mb_strlen($string) > $max_length); } /** @@ -651,35 +648,35 @@ class Validate * the characters ';/?:@$,' will not be accepted in the query part * if not urlencoded, refer to the option "strict'" * - * @param string $url URI to validate - * @param array|null $options Options used by the validation method. - * key => type - * 'domain_check' => boolean - * Whether to check the DNS entry or not - * 'allowed_schemes' => array, list of protocols - * List of allowed schemes ('http', - * 'ssh+svn', 'mms') - * 'strict' => string the refused chars - * in query and fragment parts - * default: ';/?:@$,' - * empty: accept all rfc2396 foreseen chars - * - * @return bool true if valid uri, false if not + * @param string $url URI to validate + * @param null|array $options Options used by the validation method. + * key => type + * 'domain_check' => boolean + * Whether to check the DNS entry or not + * 'allowed_schemes' => array, list of protocols + * List of allowed schemes ('http', + * 'ssh+svn', 'mms') + * 'strict' => string the refused chars + * in query and fragment parts + * default: ';/?:@$,' + * empty: accept all rfc2396 foreseen chars * * @throws Exception + * + * @return bool true if valid uri, false if not */ public static function uri(string $url, ?array $options = null): bool { - $strict = ';/?:@$,'; - $domain_check = false; + $strict = ';/?:@$,'; + $domain_check = false; $allowed_schemes = null; - if (is_array($options)) { + if (\is_array($options)) { extract($options); } - if (is_array($allowed_schemes) && - in_array("tag", $allowed_schemes) + if (\is_array($allowed_schemes) + && \in_array('tag', $allowed_schemes) ) { - if (strpos($url, "tag:") === 0) { + if (str_starts_with($url, 'tag:')) { return self::uriRFC4151($url); } } @@ -696,12 +693,12 @@ class Validate (?:\#((?:%[0-9a-f]{2}|[-a-z0-9_.!~*\'();/?:@\&=+$,])*))? # 8. fragment $&xi', $url, - $matches + $matches, )) { - $scheme = isset($matches[1]) ? $matches[1] : ''; - $authority = isset($matches[3]) ? $matches[3] : ''; - if (is_array($allowed_schemes) && - !in_array($scheme, $allowed_schemes) + $scheme = $matches[1] ?? ''; + $authority = $matches[3] ?? ''; + if (\is_array($allowed_schemes) + && !\in_array($scheme, $allowed_schemes) ) { return false; } @@ -712,7 +709,7 @@ class Validate return false; } } - } elseif ($domain_check && function_exists('checkdnsrr')) { + } elseif ($domain_check && \function_exists('checkdnsrr')) { if (!checkdnsrr($authority, 'A')) { return false; } @@ -732,65 +729,63 @@ class Validate /** * Substr * - * @param string &$date Date - * @param string $num Length - * @param string|false $opt Unknown - * - * @return string + * @param string &$date Date + * @param string $num Length + * @param false|string $opt Unknown */ private static function substr( string &$date, string $num, - $opt = false + $opt = false, ): string { if ( $opt - && strlen($date) >= $opt + && mb_strlen($date) >= $opt && preg_match('/^[0-9]{' . $opt . '}/', $date, $m) ) { $ret = $m[0]; } else { - $ret = substr($date, 0, $num); + $ret = mb_substr($date, 0, $num); } - $date = substr($date, strlen($ret)); + $date = mb_substr($date, mb_strlen($ret)); return $ret; } protected static function modf($val, $div) { - if (function_exists('bcmod')) { + if (\function_exists('bcmod')) { return bcmod($val, $div); - } elseif (function_exists('fmod')) { + } elseif (\function_exists('fmod')) { return fmod($val, $div); } $r = $val / $div; - $i = intval($r); - return intval($val - $i * $div + .1); + $i = (int) $r; + return (int) ($val - $i * $div + .1); } /** * Calculates sum of product of number digits with weights * - * @param string $number number string - * @param array $weights reference to array of weights + * @param string $number number string + * @param array $weights reference to array of weights * * @return int returns product of number digits with weights */ protected static function multWeights( string $number, - array &$weights + array &$weights, ): int { - if (!is_array($weights)) { + if (!\is_array($weights)) { return -1; } $sum = 0; - $count = min(count($weights), strlen($number)); + $count = min(\count($weights), mb_strlen($number)); if ($count == 0) { // empty string or weights array return -1; } for ($i = 0; $i < $count; ++$i) { - $sum += intval(substr($number, $i, 1)) * $weights[$i]; + $sum += (int) (mb_substr($number, $i, 1)) * $weights[$i]; } return $sum; @@ -799,20 +794,20 @@ class Validate /** * Calculates control digit for a given number * - * @param string $number number string - * @param array $weights reference to array of weights - * @param int $modulo (optionsl) number - * @param int $subtract (optional) number - * @param bool $allow_high (optional) true if function can return number higher than 10 + * @param string $number number string + * @param array $weights reference to array of weights + * @param int $modulo (optionsl) number + * @param int $subtract (optional) number + * @param bool $allow_high (optional) true if function can return number higher than 10 * - * @return int -1 calculated control number is returned + * @return int -1 calculated control number is returned */ protected static function getControlNumber( string $number, array &$weights, int $modulo = 10, int $subtract = 0, - bool $allow_high = false + bool $allow_high = false, ): int { // calc sum $sum = self::multWeights($number, $weights); @@ -833,30 +828,29 @@ class Validate /** * Validates a number * - * @param string $number number to validate - * @param array $weights reference to array of weights - * @param int $modulo (optional) number - * @param int $subtract (optional) number + * @param string $number number to validate + * @param array $weights reference to array of weights + * @param int $modulo (optional) number + * @param int $subtract (optional) number * - * @return bool true if valid, false if not + * @return bool true if valid, false if not */ protected static function checkControlNumber( string $number, array &$weights, int $modulo = 10, - int $subtract = 0 - ): bool - { - if (strlen($number) < count($weights)) { + int $subtract = 0, + ): bool { + if (mb_strlen($number) < \count($weights)) { return false; } - $target_digit = substr($number, count($weights), 1); + $target_digit = mb_substr($number, \count($weights), 1); $control_digit = self::getControlNumber( $number, $weights, $modulo, $subtract, - ($modulo > 10) + ($modulo > 10), ); if ($control_digit == -1) { @@ -865,10 +859,7 @@ class Validate if ($target_digit === 'X' && $control_digit == 10) { return true; } - if ($control_digit != $target_digit) { - return false; - } - return true; + return !($control_digit != $target_digit); } /** @@ -876,22 +867,22 @@ class Validate * assoc array in the form $var_name => $value. * Can be used on any of Validate subpackages * - * @param array $data Ex: ['name' => 'toto', 'email' => 'toto@thing.info']; + * @param array $data Ex: ['name' => 'toto', 'email' => 'toto@thing.info']; * @param array $val_type Contains the validation type and all parameters used in. - * 'val_type' is not optional - * others validations properties must have the same name as the function - * parameters. - * Ex: ['toto' => ['type'=>'string','format'='toto@thing.info','min_length'=>5]]; - * @param bool $remove if set, the elements not listed in data will be removed + * 'val_type' is not optional + * others validations properties must have the same name as the function + * parameters. + * Ex: ['toto' => ['type'=>'string','format'='toto@thing.info','min_length'=>5]]; + * @param bool $remove if set, the elements not listed in data will be removed * - * @return array value name => true|false the value name comes from the data key + * @return array value name => true|false the value name comes from the data key */ public static function multiple( array &$data, array &$val_type, - bool $remove = false + bool $remove = false, ): array { - $keys = array_keys($data); + $keys = array_keys($data); $valid = []; foreach ($keys as $var_name) { @@ -901,45 +892,45 @@ class Validate } continue; } - $opt = $val_type[$var_name]; - $methods = get_class_methods('Validate'); + $opt = $val_type[$var_name]; + $methods = get_class_methods('Validate'); $val2check = $data[$var_name]; // core validation method - if (in_array(strtolower($opt['type']), $methods)) { + if (\in_array(mb_strtolower($opt['type']), $methods)) { //$opt[$opt['type']] = $data[$var_name]; $method = $opt['type']; unset($opt['type']); - if (sizeof($opt) == 1 && is_array(reset($opt))) { + if (sizeof($opt) == 1 && \is_array(reset($opt))) { $opt = array_pop($opt); } - $valid[$var_name] = call_user_func(['Validate', $method], $val2check, $opt); + $valid[$var_name] = \call_user_func(['Validate', $method], $val2check, $opt); /** * external validation method in the form: * "" * Ex: us_ssn will include class Validate/US.php and call method ssn() */ - } elseif (strpos($opt['type'], '_') !== false) { + } elseif (str_contains($opt['type'], '_')) { $validateType = explode('_', $opt['type']); - $method = array_pop($validateType); - $class = implode('_', $validateType); - $classPath = str_replace('_', DIRECTORY_SEPARATOR, $class); - $class = 'Validate_' . $class; + $method = array_pop($validateType); + $class = implode('_', $validateType); + $classPath = str_replace('_', \DIRECTORY_SEPARATOR, $class); + $class = 'Validate_' . $class; if (self::includePathFileExists("Validate/{$classPath}.php")) { include_once "Validate/{$classPath}.php"; } else { - trigger_error("$class isn't installed or you may have some permission issues", E_USER_ERROR); + trigger_error("{$class} isn't installed or you may have some permission issues", \E_USER_ERROR); } - $ce = substr(phpversion(), 0, 1) > 4 ? - class_exists($class, false) : class_exists($class); - if (!$ce || - !in_array($method, get_class_methods($class)) + $ce = mb_substr(phpversion(), 0, 1) > 4 + ? class_exists($class, false) : class_exists($class); + if (!$ce + || !\in_array($method, get_class_methods($class)) ) { trigger_error( - "Invalid validation type $class::$method", - E_USER_WARNING + "Invalid validation type {$class}::{$method}", + \E_USER_WARNING, ); continue; } @@ -947,15 +938,15 @@ class Validate if (sizeof($opt) == 1) { $opt = array_pop($opt); } - $valid[$var_name] = call_user_func( - array($class, $method), + $valid[$var_name] = \call_user_func( + [$class, $method], $data[$var_name], - $opt + $opt, ); } else { trigger_error( "Invalid validation type {$opt['type']}", - E_USER_WARNING + \E_USER_WARNING, ); } } @@ -971,11 +962,11 @@ class Validate */ private static function includePathFileExists(string $filename): bool { - $paths = explode(":", ini_get("include_path")); + $paths = explode(':', ini_get('include_path')); $result = false; foreach ($paths as $val) { - $result = file_exists($val . "/" . $filename); + $result = file_exists($val . '/' . $filename); if ($result) { break; } diff --git a/plugins/ActivityPub/ActivityPub.php b/plugins/ActivityPub/ActivityPub.php index d5670e596b..b370767de3 100644 --- a/plugins/ActivityPub/ActivityPub.php +++ b/plugins/ActivityPub/ActivityPub.php @@ -1,5 +1,7 @@ }/inbox.json', [Inbox::class, 'handle'], - options: ['accept' => self::$accept_headers] + options: ['accept' => self::$accept_headers], ); $r->connect( 'activitypub_actor_outbox', '/actor/{gsactor_id<\d+>}/outbox.json', [Inbox::class, 'handle'], - options: ['accept' => self::$accept_headers] + options: ['accept' => self::$accept_headers], ); $r->connect( 'activitypub_inbox', '/inbox.json', [Inbox::class, 'handle'], - options: ['accept' => self::$accept_headers] + options: ['accept' => self::$accept_headers], ); return Event::next; } @@ -53,23 +53,19 @@ class ActivityPub extends Plugin /** * Validate HTTP Accept headers * - * @param null|array|string $accept - * @param bool $strict Strict mode + * @param bool $strict Strict mode * * @throws Exception when strict mode enabled - * - * @return bool - * */ public static function validateAcceptHeader(array|string|null $accept, bool $strict): bool { - if (is_string($accept) - && in_array($accept, self::$accept_headers) + if (\is_string($accept) + && \in_array($accept, self::$accept_headers) ) { return true; - } elseif (is_array($accept) - && count( - array_intersect($accept, self::$accept_headers) + } elseif (\is_array($accept) + && \count( + array_intersect($accept, self::$accept_headers), ) > 0 ) { return true; @@ -82,8 +78,8 @@ class ActivityPub extends Plugin throw new Exception( sprintf( "HTTP Accept header error. Given: '%s'", - $accept - ) + $accept, + ), ); } @@ -95,20 +91,11 @@ class ActivityPub extends Plugin ]; /** - * @param string $route - * @param array $accept_header - * @param array $vars - * @param null|TypeResponse $response - * * @throws Exception - * - * @return bool - * - * */ public function onControllerResponseInFormat(string $route, array $accept_header, array $vars, ?TypeResponse &$response = null): bool { - if (count(array_intersect(self::$accept_headers, $accept_header)) === 0) { + if (\count(array_intersect(self::$accept_headers, $accept_header)) === 0) { return Event::next; } switch ($route) { diff --git a/plugins/ActivityPub/Controller/Inbox.php b/plugins/ActivityPub/Controller/Inbox.php index 2c2c33fbec..866d65514c 100644 --- a/plugins/ActivityPub/Controller/Inbox.php +++ b/plugins/ActivityPub/Controller/Inbox.php @@ -1,5 +1,7 @@ $gsactor_id]); - if (is_null($user)) { + if (\is_null($user)) { throw new ClientException(_m('No such actor.'), 404); } } @@ -48,14 +50,14 @@ class Inbox extends Controller // Check accept header ActivityPub::validateAcceptHeader( $this->request->headers->get('accept'), - true + true, ); // TODO: Check if Actor can post // Get content $payload = Util::decodeJson( - (string) $this->request->getContent() + (string) $this->request->getContent(), ); // Cast as an ActivityStreams type diff --git a/plugins/ActivityPub/Entity/ActivitypubActivity.php b/plugins/ActivityPub/Entity/ActivitypubActivity.php index 9f8473fb38..6449bc5265 100644 --- a/plugins/ActivityPub/Entity/ActivitypubActivity.php +++ b/plugins/ActivityPub/Entity/ActivitypubActivity.php @@ -1,5 +1,7 @@ uri; } - /** - * @param string $uri - */ public function setUri(string $uri): void { $this->uri = $uri; } - /** - * @return int - */ public function getActorId(): int { return $this->actor_id; } - /** - * @param int $actor_id - */ public function setActorId(int $actor_id): void { $this->actor_id = $actor_id; } - /** - * @return string - */ public function getInboxUri(): string { return $this->inbox_uri; } - /** - * @param string $inbox_uri - */ public function setInboxUri(string $inbox_uri): void { $this->inbox_uri = $inbox_uri; } - /** - * @return string - */ public function getInboxSharedUri(): string { return $this->inbox_shared_uri; } - /** - * @param string $inbox_shared_uri - */ public function setInboxSharedUri(string $inbox_shared_uri): void { $this->inbox_shared_uri = $inbox_shared_uri; } - /** - * @return DateTimeInterface - */ public function getCreated(): DateTimeInterface { return $this->created; } - /** - * @param DateTimeInterface $created - */ public function setCreated(DateTimeInterface $created): void { $this->created = $created; } - /** - * @return DateTimeInterface - */ public function getModified(): DateTimeInterface { return $this->modified; } - /** - * @param DateTimeInterface $modified - */ public function setModified(DateTimeInterface $modified): void { $this->modified = $modified; diff --git a/plugins/ActivityPub/Util/Model/AS2ToEntity/AS2ToEntity.php b/plugins/ActivityPub/Util/Model/AS2ToEntity/AS2ToEntity.php index fd681eee46..abca284609 100644 --- a/plugins/ActivityPub/Util/Model/AS2ToEntity/AS2ToEntity.php +++ b/plugins/ActivityPub/Util/Model/AS2ToEntity/AS2ToEntity.php @@ -1,5 +1,7 @@ new DateTime($object['published'] ?? 'now'), 'content' => $object['content'] ?? null, 'content_type' => 'text/html', - 'url' => array_key_exists('url', $object) ? $object['url'] : $object['id'], + 'url' => \array_key_exists('url', $object) ? $object['url'] : $object['id'], 'actor_id' => $actor_id, 'modified' => new DateTime(), 'source' => $source, @@ -49,4 +47,4 @@ abstract class AS2ToNote } return $obj; } -} \ No newline at end of file +} diff --git a/plugins/ActivityPub/Util/Model/EntityToType/EntityToType.php b/plugins/ActivityPub/Util/Model/EntityToType/EntityToType.php index 03345f61d9..f2c6e0ef0d 100644 --- a/plugins/ActivityPub/Util/Model/EntityToType/EntityToType.php +++ b/plugins/ActivityPub/Util/Model/EntityToType/EntityToType.php @@ -1,20 +1,19 @@ 'ActivityPub', 'actor_id' => $gsactor->getId(), 'actor_uri' => &$attributedTo]); diff --git a/plugins/ActivityPub/Util/Model/EntityToType/NoteToType.php b/plugins/ActivityPub/Util/Model/EntityToType/NoteToType.php index b6508ce65a..9a6e817704 100644 --- a/plugins/ActivityPub/Util/Model/EntityToType/NoteToType.php +++ b/plugins/ActivityPub/Util/Model/EntityToType/NoteToType.php @@ -1,23 +1,22 @@ 'ActivityPub', 'actor_id' => $note->getActorId(), 'actor_uri' => &$attributedTo]); diff --git a/plugins/ActivityPub/Util/Response/AbstractResponse.php b/plugins/ActivityPub/Util/Response/AbstractResponse.php index 6256332f29..b3c9f18913 100644 --- a/plugins/ActivityPub/Util/Response/AbstractResponse.php +++ b/plugins/ActivityPub/Util/Response/AbstractResponse.php @@ -1,7 +1,10 @@ getLocalUser(); // This throws exception if not a local user, which is intended return new TypeResponse(data: GSActorToType::translate($gsactor), status: $status); } -} \ No newline at end of file +} diff --git a/plugins/ActivityPub/Util/Response/NoteResponse.php b/plugins/ActivityPub/Util/Response/NoteResponse.php index beb5a9a535..98d739265a 100644 --- a/plugins/ActivityPub/Util/Response/NoteResponse.php +++ b/plugins/ActivityPub/Util/Response/NoteResponse.php @@ -1,5 +1,7 @@ $id]); return new TypeResponse(data: NoteToType::translate($note), status: $status); } -} \ No newline at end of file +} diff --git a/plugins/ActivityPub/Util/Response/TypeResponse.php b/plugins/ActivityPub/Util/Response/TypeResponse.php index 3219654182..f9c52af1aa 100644 --- a/plugins/ActivityPub/Util/Response/TypeResponse.php +++ b/plugins/ActivityPub/Util/Response/TypeResponse.php @@ -1,5 +1,7 @@ toJson() : null, + data: !\is_null($data) ? $data->toJson() : null, status: $status, headers: ['content-type' => 'application/ld+json; profile="https://www.w3.org/ns/activitystreams"'], - json: true + json: true, ); } } diff --git a/plugins/ActivityPub/Util/Type.php b/plugins/ActivityPub/Util/Type.php index 32cdcf0f81..1231f2d5ec 100644 --- a/plugins/ActivityPub/Util/Type.php +++ b/plugins/ActivityPub/Util/Type.php @@ -1,5 +1,7 @@ $attributes * * @throws Exception - * - * @return mixed */ - public static function create($type, array $attributes = []) + public static function create($type, array $attributes = []): mixed { - if (!is_string($type) && !is_array($type)) { + if (!\is_string($type) && !\is_array($type)) { throw new Exception( 'Type parameter must be a string or an array. Given=' - . gettype($type) + . \gettype($type), ); } - if (is_array($type)) { + if (\is_array($type)) { if (!isset($type['type'])) { throw new Exception( - "Type parameter must have a 'type' key" + "Type parameter must have a 'type' key", ); } @@ -65,17 +65,17 @@ abstract class Type } try { - $class = is_array($type) + $class = \is_array($type) ? TypeResolver::getClass($type['type']) : TypeResolver::getClass($type); } catch (Exception $exception) { - $message = json_encode($attributes, JSON_PRETTY_PRINT); + $message = json_encode($attributes, \JSON_PRETTY_PRINT); throw new Exception( - $exception->getMessage() . "\n{$message}" + $exception->getMessage() . "\n{$message}", ); } - if (is_string($class)) { + if (\is_string($class)) { $class = new $class(); } @@ -97,8 +97,8 @@ abstract class Type { $data = json_decode($json, true); - if (json_last_error() === JSON_ERROR_NONE - && is_array($data) + if (json_last_error() === \JSON_ERROR_NONE + && \is_array($data) ) { return self::create($data); } @@ -106,8 +106,8 @@ abstract class Type throw new Exception( sprintf( "An error occurred during the JSON decoding.\n '%s'", - $json - ) + $json, + ), ); } @@ -115,7 +115,7 @@ abstract class Type * Add a custom validator for an attribute. * It checks that it implements Validator\Interface * - * @param string $name An attribute name to validate. + * @param string $name an attribute name to validate * @param string $class A validator class name */ public static function addValidator(string $name, string $class): void diff --git a/plugins/ActivityPub/Util/Type/AbstractObject.php b/plugins/ActivityPub/Util/Type/AbstractObject.php index 8dede2262a..2aae04da48 100644 --- a/plugins/ActivityPub/Util/Type/AbstractObject.php +++ b/plugins/ActivityPub/Util/Type/AbstractObject.php @@ -1,5 +1,7 @@ {$name})) { - if (!array_key_exists($name, $this->_props)) { + if (!\array_key_exists($name, $this->_props)) { $this->_props[$name] = $this->{$name}; } return true; } - if (array_key_exists($name, $this->_props)) { + if (\array_key_exists($name, $this->_props)) { return true; } $reflect = new ReflectionClass(Type::create($this->type)); - $allowed_props = $reflect->getProperties(\ReflectionProperty::IS_PUBLIC | \ReflectionProperty::IS_PROTECTED); + $allowed_props = $reflect->getProperties(ReflectionProperty::IS_PUBLIC | ReflectionProperty::IS_PROTECTED); $allowed = []; foreach ($allowed_props as $prop) { $allowed[] = $prop->getName(); } - if (!in_array($name, $allowed)) { + if (!\in_array($name, $allowed)) { sort($allowed); throw new Exception( sprintf( - 'Property "%s" is not defined. Type="%s", ' . - 'Class="%s"' . PHP_EOL . 'Allowed properties: %s', + 'Property "%s" is not defined. Type="%s", ' + . 'Class="%s"' . \PHP_EOL . 'Allowed properties: %s', $name, $this->get('type'), static::class, - implode(', ', $allowed) - ) + implode(', ', $allowed), + ), ); } else { return false; @@ -181,8 +166,6 @@ abstract class AbstractObject /** * Get a list of all properties names - * - * @return array */ public function getProperties(): array { @@ -193,11 +176,11 @@ abstract class AbstractObject array_keys( array_diff_key( get_object_vars($this), - ['_props' => '1'] - ) - ) - ) - ) + ['_props' => '1'], + ), + ), + ), + ), ); } @@ -211,11 +194,9 @@ abstract class AbstractObject $keys = array_keys( array_filter( get_object_vars($this), - static function ($value, $key): bool { - return !is_null($value) && $key !== '_props'; - }, - ARRAY_FILTER_USE_BOTH - ) + static fn ($value, $key): bool => !\is_null($value) && $key !== '_props', + \ARRAY_FILTER_USE_BOTH, + ), ); $stack = []; @@ -224,17 +205,17 @@ abstract class AbstractObject foreach ($keys as $key) { if ($this->{$key} instanceof self) { $stack[$key] = $this->{$key}->toArray(); - } elseif (!is_array($this->{$key})) { + } elseif (!\is_array($this->{$key})) { $stack[$key] = $this->{$key}; - } elseif (is_array($this->{$key})) { - if (is_int(key($this->{$key}))) { + } elseif (\is_array($this->{$key})) { + if (\is_int(key($this->{$key}))) { $stack[$key] = array_map( static function ($value) { return $value instanceof self ? $value->toArray() : $value; }, - $this->{$key} + $this->{$key}, ); } else { $stack[$key] = $this->{$key}; @@ -244,23 +225,23 @@ abstract class AbstractObject // _props foreach ($this->_props as $key => $value) { - if (is_null($value)) { + if (\is_null($value)) { continue; } if ($value instanceof self) { $stack[$key] = $value->toArray(); - } elseif (!is_array($value)) { + } elseif (!\is_array($value)) { $stack[$key] = $value; } else { - if (is_int(key($value))) { + if (\is_int(key($value))) { $stack[$key] = array_map( static function ($value) { return $value instanceof self ? $value->toArray() : $value; }, - $value + $value, ); } else { $stack[$key] = $value; @@ -275,14 +256,12 @@ abstract class AbstractObject * Get a JSON * * @param null|int $options PHP JSON options - * - * @return string */ public function toJson(?int $options = null): string { return json_encode( $this->toArray(), - (int) $options + (int) $options, ); } @@ -297,15 +276,14 @@ abstract class AbstractObject { return Type::create( $this->type, - $this->toArray() + $this->toArray(), ); } /** * Extend current type properties * - * @param string $property - * @param mixed $default + * @param mixed $default * * @throws Exception */ @@ -315,7 +293,7 @@ abstract class AbstractObject return; } - if (!array_key_exists($property, $this->_props)) { + if (!\array_key_exists($property, $this->_props)) { $this->_props[$property] = $default; } } @@ -326,15 +304,12 @@ abstract class AbstractObject public function __isset(string $name): bool { return property_exists($this, $name) - || array_key_exists($name, $this->_props); + || \array_key_exists($name, $this->_props); } /** * Magical setter method * - * @param string $name - * @param mixed $value - * * @throws Exception */ public function __set(string $name, mixed $value): void @@ -345,11 +320,7 @@ abstract class AbstractObject /** * Magical getter method * - * @param string $name - * * @throws Exception - * - * @return mixed */ public function __get(string $name): mixed { @@ -359,32 +330,27 @@ abstract class AbstractObject /** * Overloading methods * - * @param string $name - * @param null|array $arguments - * * @throws Exception - * - * @return mixed */ - public function __call(string $name, ?array $arguments = []) + public function __call(string $name, ?array $arguments = []): mixed { // Getters if (str_starts_with($name, 'get')) { - $attr = lcfirst(substr($name, 3)); + $attr = lcfirst(mb_substr($name, 3)); return $this->get($attr); } // Setters if (str_starts_with($name, 'set')) { - if (count($arguments) === 1) { - $attr = lcfirst(substr($name, 3)); + if (\count($arguments) === 1) { + $attr = lcfirst(mb_substr($name, 3)); return $this->set($attr, $arguments[0]); } else { throw new Exception( sprintf( 'Expected exactly one argument for method "%s()"', - $name - ) + $name, + ), ); } } @@ -392,8 +358,8 @@ abstract class AbstractObject throw new Exception( sprintf( 'Method "%s" is not defined', - $name - ) + $name, + ), ); } } diff --git a/plugins/ActivityPub/Util/Type/Core/AbstractActivity.php b/plugins/ActivityPub/Util/Type/Core/AbstractActivity.php index 786930b644..64aa241296 100644 --- a/plugins/ActivityPub/Util/Type/Core/AbstractActivity.php +++ b/plugins/ActivityPub/Util/Type/Core/AbstractActivity.php @@ -1,5 +1,7 @@ type) - || !is_string($item->type) + || !\is_string($item->type) ) { return false; } - return match (strtolower($poolname)) { + return match (mb_strtolower($poolname)) { 'all' => self::exists($item->type), - 'actor' => in_array($item->type, self::$actorTypes), + 'actor' => \in_array($item->type, self::$actorTypes), default => false, }; } /** * Verify that a type exists - * - * @param string $name - * - * @return bool */ public static function exists(string $name): bool { - return in_array( + return \in_array( $name, array_merge( self::$coreTypes, self::$activityTypes, self::$actorTypes, - self::$objectTypes - ) + self::$objectTypes, + ), ); } } diff --git a/plugins/ActivityPub/Util/Type/Util.php b/plugins/ActivityPub/Util/Type/Util.php index bfc9af2ff6..282a256025 100644 --- a/plugins/ActivityPub/Util/Type/Util.php +++ b/plugins/ActivityPub/Util/Type/Util.php @@ -1,5 +1,7 @@ = 0; } /** * Validate a non negative number. - * - * @param float|int $value - * - * @return bool */ public static function validateNonNegativeNumber(float|int $value): bool { @@ -151,15 +126,11 @@ abstract class Util /** * Validate units format. - * - * @param string $value - * - * @return bool */ public static function validateUnits(string $value): bool { - if (is_string($value)) { - if (in_array($value, self::$units) + if (\is_string($value)) { + if (\in_array($value, self::$units) || self::validateUrl($value) ) { return true; @@ -172,16 +143,12 @@ abstract class Util /** * Validate an Object type * - * @param object $item - * * @throws Exception - * - * @return bool */ public static function validateObject(object $item): bool { return self::hasProperties($item, ['type']) - && is_string($item->type) + && \is_string($item->type) && $item->type === 'Object'; } @@ -194,9 +161,9 @@ abstract class Util { $json = json_decode($value, true); - if (json_last_error() !== JSON_ERROR_NONE) { + if (json_last_error() !== \JSON_ERROR_NONE) { throw new Exception( - 'JSON decoding failed for string: ' . $value + 'JSON decoding failed for string: ' . $value, ); } @@ -206,19 +173,15 @@ abstract class Util /** * Checks that all properties exist for a stdClass * - * @param object $item - * @param array $properties - * @param bool $strict If true throws an \Exception, - * otherwise, returns false + * @param bool $strict If true throws an \Exception, + * otherwise, returns false * * @throws Exception if a property is not set - * - * @return bool */ public static function hasProperties( object $item, array $properties, - bool $strict = false + bool $strict = false, ): bool { foreach ($properties as $property) { if (!property_exists($item, $property)) { @@ -227,8 +190,8 @@ abstract class Util sprintf( 'Attribute "%s" MUST be set for item: %s', $property, - print_r($item, true) - ) + print_r($item, true), + ), ); } @@ -242,11 +205,7 @@ abstract class Util /** * Validate a reference with a Link or an Object with a URL * - * @param object $item - * * @throws Exception - * - * @return bool */ public static function isLinkOrUrlObject(object $item): bool { @@ -266,19 +225,15 @@ abstract class Util /** * Validate a reference as Link * - * @param array|object $item - * * @throws Exception - * - * @return bool */ public static function validateLink(object|array $item): bool { - if (is_array($item)) { + if (\is_array($item)) { $item = (object) $item; } - if (!is_object($item)) { + if (!\is_object($item)) { return false; } @@ -298,15 +253,13 @@ abstract class Util /** * Validate a datetime - * - * @param mixed $value */ public static function validateDatetime($value): bool { - if (!is_string($value) + if (!\is_string($value) || !preg_match( '/^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2})(.*)$/', - $value + $value, ) ) { return false; @@ -323,22 +276,18 @@ abstract class Util /** * Check that container class is a subclass of a given class * - * @param object $container - * @param array|string $classes - * @param bool $strict If true, throws an exception + * @param bool $strict If true, throws an exception * * @throws Exception - * - * @return bool */ public static function subclassOf(object $container, array|string $classes, bool $strict = false): bool { - if (!is_array($classes)) { + if (!\is_array($classes)) { $classes = [$classes]; } foreach ($classes as $class) { - if (get_class($container) === $class + if (\get_class($container) === $class || is_subclass_of($container, $class) ) { return true; @@ -349,9 +298,9 @@ abstract class Util throw new Exception( sprintf( 'Class "%s" MUST be a subclass of "%s"', - get_class($container), - implode(', ', $classes) - ) + \get_class($container), + implode(', ', $classes), + ), ); } @@ -362,12 +311,6 @@ abstract class Util * Checks that a numeric value is part of a range. * If a minimal value is null, value has to be inferior to max value * If a maximum value is null, value has to be superior to min value - * - * @param float|int $value - * @param null|float|int $min - * @param null|float|int $max - * - * @return bool */ public static function between(float|int $value, float|int|null $min, float|int|null $max): bool { @@ -376,10 +319,10 @@ abstract class Util } return match (true) { - is_null($min) && is_null($max) => false, - is_null($min) => $value <= $max, - is_null($max) => $value >= $min, - default => $value >= $min + \is_null($min) && \is_null($max) => false, + \is_null($min) => $value <= $max, + \is_null($max) => $value >= $min, + default => $value >= $min && $value <= $max, }; } @@ -387,12 +330,9 @@ abstract class Util /** * Check that a given string is a valid XML Schema xsd:duration * - * @param string $duration - * @param bool $strict If true, throws an exception + * @param bool $strict If true, throws an exception * * @throws Exception - * - * @return bool */ public static function isDuration(string $duration, bool $strict = false): bool { @@ -404,8 +344,8 @@ abstract class Util throw new Exception( sprintf( 'Duration "%s" MUST respect xsd:duration', - $duration - ) + $duration, + ), ); } } @@ -415,10 +355,6 @@ abstract class Util /** * Checks that it's an object type - * - * @param object $item - * - * @return bool */ public static function isObjectType(object $item): bool { @@ -427,10 +363,6 @@ abstract class Util /** * Checks that it's an actor type - * - * @param object $item - * - * @return bool */ public static function isActorType(object $item): bool { @@ -440,84 +372,62 @@ abstract class Util /** * Validate an object type with type attribute * - * @param object $item * @param string $type An expected type - * - * @return bool */ public static function isType(object $item, string $type): bool { // Validate that container is a certain type - if (!is_object($item)) { + if (!\is_object($item)) { return false; } - if (property_exists($item, 'type') - && is_string($item->type) + return (bool) ( + property_exists($item, 'type') + && \is_string($item->type) && $item->type === $type - ) { - return true; - } - - return false; + ); } /** * Validate a BCP 47 language value - * - * @param string $value - * - * @return bool */ public static function validateBcp47(string $value): bool { - return is_string($value) + return \is_string($value) && preg_match( '/^(((en-GB-oed|i-ami|i-bnn|i-default|i-enochian|i-hak|i-klingon|i-lux|i-mingo|i-navajo|i-pwn|i-tao|i-tay|i-tsu|sgn-BE-FR|sgn-BE-NL|sgn-CH-DE)|(art-lojban|cel-gaulish|no-bok|no-nyn|zh-guoyu|zh-hakka|zh-min|zh-min-nan|zh-xiang))|((([A-Za-z]{2,3}(-([A-Za-z]{3}(-[A-Za-z]{3}){0,2}))?)|[A-Za-z]{4}|[A-Za-z]{5,8})(-([A-Za-z]{4}))?(-([A-Za-z]{2}|[0-9]{3}))?(-([A-Za-z0-9]{5,8}|[0-9][A-Za-z0-9]{3}))*(-([0-9A-WY-Za-wy-z](-[A-Za-z0-9]{2,8})+))*(-(x(-[A-Za-z0-9]{1,8})+))?)|(x(-[A-Za-z0-9]{1,8})+))$/', - $value + $value, ); } /** * Validate a plain text value - * - * @param string $value - * - * @return bool */ public static function validatePlainText(string $value): bool { - return is_string($value) + return \is_string($value) && preg_match( '/^([^<]+)$/', - $value + $value, ); } /** * Validate mediaType format - * - * @param string $value - * - * @return bool */ public static function validateMediaType(string $value): bool { - return is_string($value) + return \is_string($value) && preg_match( '#^(([\w]+[\w\-]+[\w+])/(([\w]+[\w\-\.\+]+[\w]+)|(\*));?)+$#', - $value + $value, ); } /** * Validate a Collection type * - * @param object $item - * * @throws Exception - * - * @return bool */ public static function validateCollection(object $item): bool { @@ -525,14 +435,14 @@ abstract class Util return false; } - if (!is_object($item)) { + if (!\is_object($item)) { $item = (object) $item; } self::hasProperties( $item, [/*totalItems', 'current', 'first', 'last', */ 'items'], - true + true, ); return true; @@ -541,11 +451,7 @@ abstract class Util /** * Validate a CollectionPage type * - * @param object $item - * * @throws Exception - * - * @return bool */ public static function validateCollectionPage(object $item): bool { @@ -558,7 +464,7 @@ abstract class Util self::hasProperties( $item, ['partOf'/*, 'next', 'prev'*/], - true + true, ); return true; diff --git a/plugins/ActivityPub/Util/Type/Validator.php b/plugins/ActivityPub/Util/Type/Validator.php index ac776d0c85..1ed41ef9aa 100644 --- a/plugins/ActivityPub/Util/Type/Validator.php +++ b/plugins/ActivityPub/Util/Type/Validator.php @@ -1,5 +1,7 @@ validate( $value, - $container + $container, ); } // Try to load a default validator $validatorName = sprintf( '\Plugin\ActivityPub\Util\Type\Validator\%sValidator', - ucfirst($name) + ucfirst($name), ); if (class_exists($validatorName)) { @@ -75,7 +73,7 @@ abstract class Validator * Add a new validator in the pool. * It checks that it implements Validator\Interface * - * @param string $name An attribute name to validate. + * @param string $name an attribute name to validate * @param object|string $class A validator class name * * @throws Exception if validator class does not implement @@ -89,9 +87,9 @@ abstract class Validator throw new Exception( sprintf( 'Validator "%s" MUST implement "%s" interface', - get_class($validator), - ValidatorInterface::class - ) + \get_class($validator), + ValidatorInterface::class, + ), ); } diff --git a/plugins/ActivityPub/Util/Type/Validator/AccuracyValidator.php b/plugins/ActivityPub/Util/Type/Validator/AccuracyValidator.php index 3a592f2460..df3b645cfb 100644 --- a/plugins/ActivityPub/Util/Type/Validator/AccuracyValidator.php +++ b/plugins/ActivityPub/Util/Type/Validator/AccuracyValidator.php @@ -1,5 +1,7 @@ validateObjectCollection($value); } // Must be an object - if (!is_object($value)) { + if (!\is_object($value)) { return false; } @@ -62,25 +61,22 @@ class ActorValidator implements ValidatorInterface /** * Validate an Actor object type * - * @param array|object $item - * * @throws Exception - * - * @return bool */ protected function validateObject(object|array $item): bool { - if (is_array($item)) { + if (\is_array($item)) { $item = Util::arrayToType($item); } Util::subclassOf( - $item, [ + $item, + [ AbstractActor::class, Link::class, Collection::class, ], - true + true, ); return true; @@ -98,19 +94,19 @@ class ActorValidator implements ValidatorInterface protected function validateObjectCollection(array $collection): bool { foreach ($collection as $item) { - if (is_array($item) && $this->validateObject($item)) { + if (\is_array($item) && $this->validateObject($item)) { continue; } - if (is_object($item) && $this->validateObject($item)) { + if (\is_object($item) && $this->validateObject($item)) { continue; } - if (is_string($item) && Util::validateUrl($item)) { + if (\is_string($item) && Util::validateUrl($item)) { continue; } return false; } - return count($collection) > 0; + return \count($collection) > 0; } } diff --git a/plugins/ActivityPub/Util/Type/Validator/AltitudeValidator.php b/plugins/ActivityPub/Util/Type/Validator/AltitudeValidator.php index 878a01106b..cc106c15e0 100644 --- a/plugins/ActivityPub/Util/Type/Validator/AltitudeValidator.php +++ b/plugins/ActivityPub/Util/Type/Validator/AltitudeValidator.php @@ -1,5 +1,7 @@ validateObjectCollection( $value, - $this->getQuestionAnswerValidator() + $this->getQuestionAnswerValidator(), ); } } diff --git a/plugins/ActivityPub/Util/Type/Validator/AttachmentValidator.php b/plugins/ActivityPub/Util/Type/Validator/AttachmentValidator.php index 1b14ca6a60..1f104d577e 100644 --- a/plugins/ActivityPub/Util/Type/Validator/AttachmentValidator.php +++ b/plugins/ActivityPub/Util/Type/Validator/AttachmentValidator.php @@ -1,5 +1,7 @@ validateListOrObject( $value, $container, - $this->getAttachmentValidator() + $this->getAttachmentValidator(), ); } } diff --git a/plugins/ActivityPub/Util/Type/Validator/AttributedToValidator.php b/plugins/ActivityPub/Util/Type/Validator/AttributedToValidator.php index a9b16c94ac..8f8055193e 100644 --- a/plugins/ActivityPub/Util/Type/Validator/AttributedToValidator.php +++ b/plugins/ActivityPub/Util/Type/Validator/AttributedToValidator.php @@ -1,5 +1,7 @@ validateListOrObject( $value, $container, - $this->getCollectionActorsValidator() + $this->getCollectionActorsValidator(), ); } } diff --git a/plugins/ActivityPub/Util/Type/Validator/AudienceValidator.php b/plugins/ActivityPub/Util/Type/Validator/AudienceValidator.php index 076d1b220b..ebd310fbbe 100644 --- a/plugins/ActivityPub/Util/Type/Validator/AudienceValidator.php +++ b/plugins/ActivityPub/Util/Type/Validator/AudienceValidator.php @@ -1,5 +1,7 @@ validateListOrObject( $value, $container, - $this->getLinkOrNamedObjectValidator() + $this->getLinkOrNamedObjectValidator(), ); } } diff --git a/plugins/ActivityPub/Util/Type/Validator/BccValidator.php b/plugins/ActivityPub/Util/Type/Validator/BccValidator.php index 00baa81873..8accd0a28a 100644 --- a/plugins/ActivityPub/Util/Type/Validator/BccValidator.php +++ b/plugins/ActivityPub/Util/Type/Validator/BccValidator.php @@ -1,5 +1,7 @@ validateListOrObject( $value, $container, - $this->getLinkOrUrlObjectValidator() + $this->getLinkOrUrlObjectValidator(), ); } } diff --git a/plugins/ActivityPub/Util/Type/Validator/BtoValidator.php b/plugins/ActivityPub/Util/Type/Validator/BtoValidator.php index 8b61bca465..48eeee57a6 100644 --- a/plugins/ActivityPub/Util/Type/Validator/BtoValidator.php +++ b/plugins/ActivityPub/Util/Type/Validator/BtoValidator.php @@ -1,5 +1,7 @@ validateListOrObject( $value, $container, - $this->getLinkOrUrlObjectValidator() + $this->getLinkOrUrlObjectValidator(), ); } } diff --git a/plugins/ActivityPub/Util/Type/Validator/CcValidator.php b/plugins/ActivityPub/Util/Type/Validator/CcValidator.php index d50e1729d7..dd2a1628a5 100644 --- a/plugins/ActivityPub/Util/Type/Validator/CcValidator.php +++ b/plugins/ActivityPub/Util/Type/Validator/CcValidator.php @@ -1,5 +1,7 @@ validateListOrObject( $value, $container, - $this->getLinkOrUrlObjectValidator() + $this->getLinkOrUrlObjectValidator(), ); } } diff --git a/plugins/ActivityPub/Util/Type/Validator/ClosedValidator.php b/plugins/ActivityPub/Util/Type/Validator/ClosedValidator.php index dcb68c08e9..528edfc3bc 100644 --- a/plugins/ActivityPub/Util/Type/Validator/ClosedValidator.php +++ b/plugins/ActivityPub/Util/Type/Validator/ClosedValidator.php @@ -1,5 +1,7 @@ validateObject($value); + return \is_array($value) && $this->validateObject($value); } /** diff --git a/plugins/ActivityPub/Util/Type/Validator/FirstValidator.php b/plugins/ActivityPub/Util/Type/Validator/FirstValidator.php index 726f19ca6f..f67b4668a6 100644 --- a/plugins/ActivityPub/Util/Type/Validator/FirstValidator.php +++ b/plugins/ActivityPub/Util/Type/Validator/FirstValidator.php @@ -1,5 +1,7 @@ validateObject($value); + return \is_object($value) && $this->validateObject($value); } /** * Validate that it is an OrderedCollection or a Collection * - * @param object $collection - * * @throws Exception * @throws Exception - * - * @return bool */ protected function validateObject(object $collection): bool { return Util::subclassOf( - $collection, - OrderedCollection::class - ) || Util::subclassOf( - $collection, - Collection::class - ); + $collection, + OrderedCollection::class, + ) || Util::subclassOf( + $collection, + Collection::class, + ); } } diff --git a/plugins/ActivityPub/Util/Type/Validator/FollowingValidator.php b/plugins/ActivityPub/Util/Type/Validator/FollowingValidator.php index 12c339a25c..9c7c39c808 100644 --- a/plugins/ActivityPub/Util/Type/Validator/FollowingValidator.php +++ b/plugins/ActivityPub/Util/Type/Validator/FollowingValidator.php @@ -1,5 +1,7 @@ validateObject($value); + return \is_object($value) && $this->validateObject($value); } /** * Validate that it is an OrderedCollection * - * @param object $collection - * * @throws Exception - * - * @return bool */ protected function validateObject(object $collection): bool { return Util::subclassOf( - $collection, - OrderedCollection::class - ) || Util::subclassOf( - $collection, - OrderedCollectionPage::class - ); + $collection, + OrderedCollection::class, + ) || Util::subclassOf( + $collection, + OrderedCollectionPage::class, + ); } } diff --git a/plugins/ActivityPub/Util/Type/Validator/InstrumentValidator.php b/plugins/ActivityPub/Util/Type/Validator/InstrumentValidator.php index 4680c06216..7b82ed08c4 100644 --- a/plugins/ActivityPub/Util/Type/Validator/InstrumentValidator.php +++ b/plugins/ActivityPub/Util/Type/Validator/InstrumentValidator.php @@ -1,5 +1,7 @@ validateObjectCollection( $value, - $this->getCollectionItemsValidator() + $this->getCollectionItemsValidator(), ); } } diff --git a/plugins/ActivityPub/Util/Type/Validator/LastValidator.php b/plugins/ActivityPub/Util/Type/Validator/LastValidator.php index 15ae6e758a..575f10c9b6 100644 --- a/plugins/ActivityPub/Util/Type/Validator/LastValidator.php +++ b/plugins/ActivityPub/Util/Type/Validator/LastValidator.php @@ -1,5 +1,7 @@ 0; + return \count($value) > 0; } return false; diff --git a/plugins/ActivityPub/Util/Type/Validator/OneOfValidator.php b/plugins/ActivityPub/Util/Type/Validator/OneOfValidator.php index fa2e0942a0..16c1b30d56 100644 --- a/plugins/ActivityPub/Util/Type/Validator/OneOfValidator.php +++ b/plugins/ActivityPub/Util/Type/Validator/OneOfValidator.php @@ -1,5 +1,7 @@ validateString( - $value + $value, ); } } diff --git a/plugins/ActivityPub/Util/Type/Validator/PrevValidator.php b/plugins/ActivityPub/Util/Type/Validator/PrevValidator.php index b63a307886..a126607073 100644 --- a/plugins/ActivityPub/Util/Type/Validator/PrevValidator.php +++ b/plugins/ActivityPub/Util/Type/Validator/PrevValidator.php @@ -1,5 +1,7 @@ $item) { - if (!is_int($key) + if (!\is_int($key) || !Util::validateRel($item)) { return false; } diff --git a/plugins/ActivityPub/Util/Type/Validator/RepliesValidator.php b/plugins/ActivityPub/Util/Type/Validator/RepliesValidator.php index 2994e88c47..59813a7fc0 100644 --- a/plugins/ActivityPub/Util/Type/Validator/RepliesValidator.php +++ b/plugins/ActivityPub/Util/Type/Validator/RepliesValidator.php @@ -1,5 +1,7 @@ validateObjectCollection( $value, - $this->getCollectionItemsValidator() + $this->getCollectionItemsValidator(), ); } } diff --git a/plugins/ActivityPub/Util/Type/Validator/TargetValidator.php b/plugins/ActivityPub/Util/Type/Validator/TargetValidator.php index 8132c309a8..e1440881fb 100644 --- a/plugins/ActivityPub/Util/Type/Validator/TargetValidator.php +++ b/plugins/ActivityPub/Util/Type/Validator/TargetValidator.php @@ -1,5 +1,7 @@ validateString( - $value + $value, ); } } diff --git a/plugins/ActivityPub/Util/Type/Validator/UnitsValidator.php b/plugins/ActivityPub/Util/Type/Validator/UnitsValidator.php index 0aec0ad08e..359e92ae08 100644 --- a/plugins/ActivityPub/Util/Type/Validator/UnitsValidator.php +++ b/plugins/ActivityPub/Util/Type/Validator/UnitsValidator.php @@ -1,5 +1,7 @@ $item) { if (!$this->validateUrlOrLink($item)) { return false; @@ -55,11 +54,7 @@ class UrlValidator implements ValidatorInterface /** * Validate that a value is a Link or a URL * - * @param Link|string $value - * * @throws Exception - * - * @return bool */ protected function validateUrlOrLink(Link|string $value): bool { diff --git a/plugins/ActivityPub/Util/Type/Validator/WidthValidator.php b/plugins/ActivityPub/Util/Type/Validator/WidthValidator.php index 095e0fe3ac..db7aa3a0a9 100644 --- a/plugins/ActivityPub/Util/Type/Validator/WidthValidator.php +++ b/plugins/ActivityPub/Util/Type/Validator/WidthValidator.php @@ -1,5 +1,7 @@ validateObjectCollection($value, $callback); } $value = Util::arrayToType($value); } - if (!is_object($value)) { + if (!\is_object($value)) { return false; } @@ -99,10 +95,7 @@ abstract class ValidatorTools implements ValidatorInterface /** * Validate a list of Collection * - * @param array $collection - * @param callable $callback A dedicated validator - * - * @return bool + * @param callable $callback A dedicated validator */ protected function validateObjectCollection(array $collection, callable $callback): bool { @@ -120,20 +113,16 @@ abstract class ValidatorTools implements ValidatorInterface /** * Validate that a value is a string * - * @param string $value - * * @throws Exception - * - * @return bool */ protected function validateString(string $value): bool { - if (!is_string($value) || strlen($value) < 1) { + if (!\is_string($value) || $value === '') { throw new Exception( sprintf( 'Value must be a non-empty string. Given: "%s"', - print_r($value, true) - ) + print_r($value, true), + ), ); } @@ -150,15 +139,15 @@ abstract class ValidatorTools implements ValidatorInterface return /** The implementation lambda */ static function ($item): bool { - if (is_string($item)) { + if (\is_string($item)) { return Util::validateUrl($item); } - if (is_array($item)) { + if (\is_array($item)) { $item = Util::arrayToType($item); } - if (is_object($item)) { + if (\is_object($item)) { Util::hasProperties($item, ['type'], true); // Validate Link type @@ -169,7 +158,7 @@ abstract class ValidatorTools implements ValidatorInterface // Validate Object type Util::hasProperties($item, ['name'], true); - return is_string($item->name); + return \is_string($item->name); } return false; @@ -186,20 +175,16 @@ abstract class ValidatorTools implements ValidatorInterface return /** The implementation lambda */ static function ($item): bool { - if (is_array($item)) { + if (\is_array($item)) { $item = Util::arrayToType($item); } - if (is_object($item) + if (\is_object($item) && Util::isLinkOrUrlObject($item)) { return true; } - if (Util::validateUrl($item)) { - return true; - } - - return false; + return (bool) (Util::validateUrl($item)); }; } @@ -214,11 +199,11 @@ abstract class ValidatorTools implements ValidatorInterface return /** The implementation lambda */ static function ($item): bool { - if (is_array($item)) { + if (\is_array($item)) { $item = Util::arrayToType($item); } - if (is_object($item)) { + if (\is_object($item)) { if (Util::isLinkOrUrlObject($item)) { return true; } @@ -226,11 +211,7 @@ abstract class ValidatorTools implements ValidatorInterface return $item instanceof ObjectType; } - if (Util::validateUrl($item)) { - return true; - } - - return false; + return (bool) (Util::validateUrl($item)); }; } @@ -242,11 +223,11 @@ abstract class ValidatorTools implements ValidatorInterface return /** The implementation lambda */ static function ($item): bool { - if (is_array($item)) { + if (\is_array($item)) { $item = Util::arrayToType($item); } - if (!is_object($item)) { + if (!\is_object($item)) { return false; } @@ -265,15 +246,15 @@ abstract class ValidatorTools implements ValidatorInterface return /** The implementation lambda */ static function ($item): bool { - if (is_string($item)) { + if (\is_string($item)) { return Util::validateUrl($item); } - if (is_array($item)) { + if (\is_array($item)) { $item = Util::arrayToType($item); } - if (!is_object($item)) { + if (!\is_object($item)) { return false; } @@ -289,20 +270,20 @@ abstract class ValidatorTools implements ValidatorInterface return /** The implementation lambda */ static function ($item): bool { - if (is_string($item)) { + if (\is_string($item)) { return Util::validateUrl($item); } - if (is_array($item)) { + if (\is_array($item)) { $item = Util::arrayToType($item); } - if (!is_object($item)) { + if (!\is_object($item)) { return false; } // id must be filled if ($item instanceof AbstractActor) { - return !is_null($item->id); + return !\is_null($item->id); } return Util::validateLink($item); diff --git a/plugins/AttachmentShowRelated/AttachmentShowRelated.php b/plugins/AttachmentShowRelated/AttachmentShowRelated.php index b655032272..533fbe342b 100644 --- a/plugins/AttachmentShowRelated/AttachmentShowRelated.php +++ b/plugins/AttachmentShowRelated/AttachmentShowRelated.php @@ -1,5 +1,7 @@ $vars['vars']['attachment_id']]); - $related_tags = DB::dql('select distinct t.tag ' . - 'from attachment_to_note an join note_tag t with an.note_id = t.note_id ' . - 'where an.attachment_id = :attachment_id', ['attachment_id' => $vars['vars']['attachment_id']]); + $related_notes = DB::dql('select n from attachment_to_note an ' + . 'join note n with n.id = an.note_id ' + . 'where an.attachment_id = :attachment_id', ['attachment_id' => $vars['vars']['attachment_id']], ); + $related_tags = DB::dql('select distinct t.tag ' + . 'from attachment_to_note an join note_tag t with an.note_id = t.note_id ' + . 'where an.attachment_id = :attachment_id', ['attachment_id' => $vars['vars']['attachment_id']], ); $res[] = Formatting::twigRenderFile('attachmentShowRelated/attachmentRelatedNotes.html.twig', ['related_notes' => $related_notes, 'have_user' => Common::user() !== null]); $res[] = Formatting::twigRenderFile('attachmentShowRelated/attachmentRelatedTags.html.twig', ['related_tags' => $related_tags]); } @@ -49,7 +51,7 @@ class AttachmentShowRelated extends Plugin * * @param array $styles stylesheets path * - * @return bool hook value; true means continue processing, false means stop. + * @return bool hook value; true means continue processing, false means stop */ public function onEndShowStyles(array &$styles, string $path): bool { @@ -58,4 +60,4 @@ class AttachmentShowRelated extends Plugin } return Event::next; } -} \ No newline at end of file +} diff --git a/plugins/Cover/Controller/Cover.php b/plugins/Cover/Controller/Cover.php index 5e7ba28343..764eccaca8 100644 --- a/plugins/Cover/Controller/Cover.php +++ b/plugins/Cover/Controller/Cover.php @@ -1,5 +1,7 @@ getId(); @@ -93,7 +93,7 @@ class Cover throw new ClientException('Invalid form'); } - if (explode('/',$sfile->getMimeType())[0] != 'image') { + if (explode('/', $sfile->getMimeType())[0] != 'image') { throw new ServerException('Invalid file type'); } $file = GSFile::storeFileAsAttachment($sfile); @@ -141,7 +141,7 @@ class Cover * * @return mixed cover file */ - public function cover() + public function cover(): mixed { // $cover = DB::find('cover', ['actor_id' => Common::user()->getId()]); // if ($cover == null) { diff --git a/plugins/Cover/Cover.php b/plugins/Cover/Cover.php index c343dc3355..6af41c6b6a 100644 --- a/plugins/Cover/Cover.php +++ b/plugins/Cover/Cover.php @@ -1,4 +1,6 @@ getId(); + $user_id = $user->getId(); $note_actor_id = $note->getActor()->getId(); if ($user_id !== $note_actor_id) { return Event::next; } - $note_id = $note->getId(); + $note_id = $note->getId(); $form_delete = Form::create([ ['submit_delete', SubmitType::class, [ @@ -78,7 +80,11 @@ class DeleteNote extends NoteHandlerPlugin // Handle form $ret = self::noteActionHandle( - $request, $form_delete, $note, "delete-{$note_id}", function ($note, $note_id) { + $request, + $form_delete, + $note, + "delete-{$note_id}", + function ($note, $note_id) { DB::remove(DB::findOneBy('note', ['id' => $note_id])); DB::flush(); @@ -86,7 +92,8 @@ class DeleteNote extends NoteHandlerPlugin throw new RedirectException(); return Event::stop; - }); + }, + ); if ($ret !== null) { return $ret; diff --git a/plugins/Directory/Controller/Directory.php b/plugins/Directory/Controller/Directory.php index e93184effe..afa2a3025e 100644 --- a/plugins/Directory/Controller/Directory.php +++ b/plugins/Directory/Controller/Directory.php @@ -1,5 +1,7 @@ 'directory/actors.html.twig', 'actors' => DB::dql('select g from App\Entity\Actor g order by g.nickname ASC')]; } @@ -41,11 +41,9 @@ class Directory /** * groups stream * - * @param Request $request - * * @return array template */ - public function groups(Request $request) + public function groups(Request $request): array { return ['_template' => 'directory/groups.html.twig', 'groups' => DB::dql('select g from App\Entity\Group g order by g.nickname ASC')]; } diff --git a/plugins/Directory/Directory.php b/plugins/Directory/Directory.php index 52cb16c871..3e944f9e51 100644 --- a/plugins/Directory/Directory.php +++ b/plugins/Directory/Directory.php @@ -1,5 +1,7 @@ null, }; - if (is_null($url)) { + if (\is_null($url)) { foreach (['xml', 'json'] as $format) { $result[] = [ 'link' => [ @@ -150,18 +150,15 @@ class Embed extends Plugin /** * Show this attachment enhanced with the corresponding Embed data, if available - * - * @param array $vars - * @param array $res - * - * @return bool */ public function onViewLink(array $vars, array &$res): bool { $link = $vars['link']; try { - $embed = Cache::get('attachment-embed-' . $link->getId(), - fn () => DB::findOneBy('attachment_embed', ['link_id' => $link->getId()])); + $embed = Cache::get( + 'attachment-embed-' . $link->getId(), + fn () => DB::findOneBy('attachment_embed', ['link_id' => $link->getId()]), + ); } catch (DuplicateFoundException $e) { Log::warning($e); return Event::next; @@ -172,8 +169,10 @@ class Embed extends Plugin $attributes = $embed->getImageHTMLAttributes(); - $res[] = Formatting::twigRenderFile('embed/embedView.html.twig', - ['embed' => $embed, 'attributes' => $attributes, 'link' => $link]); + $res[] = Formatting::twigRenderFile( + 'embed/embedView.html.twig', + ['embed' => $embed, 'attributes' => $attributes, 'link' => $link], + ); return Event::stop; } @@ -181,14 +180,7 @@ class Embed extends Plugin /** * Save embedding information for an Attachment, if applicable. * - * @param Link $link - * @param Note $note - * * @throws DuplicateFoundException - * - * @return bool - * - * */ public function onNewLinkFromNote(Link $link, Note $note): bool { @@ -200,19 +192,19 @@ class Embed extends Plugin // Ignore if already handled $attachment_embed = DB::find('attachment_embed', ['link_id' => $link->getId()]); - if (!is_null($attachment_embed)) { + if (!\is_null($attachment_embed)) { return Event::next; } // If an attachment already exist, do not create an Embed for it. Some other plugin must have done things $attachment_to_link = DB::find('attachment_to_link', ['link_id' => $link->getId()]); - if (!is_null($attachment_to_link)) { + if (!\is_null($attachment_to_link)) { $attachment_id = $attachment_to_link->getAttachmentId(); try { $attachment = DB::findOneBy('attachment', ['id' => $attachment_id]); $attachment->livesIncrementAndGet(); return Event::next; - } catch (DuplicateFoundException | NotFoundException $e) { + } catch (DuplicateFoundException|NotFoundException $e) { Log::error($e); } } @@ -247,8 +239,6 @@ class Embed extends Plugin } /** - * @param string $url - * * @return bool true if allowed by the lists, false otherwise */ private function allowedLink(string $url): bool @@ -258,7 +248,7 @@ class Embed extends Plugin if ($this->check_whitelist) { $passed_whitelist = false; // don't trust be default - $host = parse_url($url, PHP_URL_HOST); + $host = parse_url($url, \PHP_URL_HOST); foreach ($this->domain_whitelist as $regex => $provider) { if (preg_match("/{$regex}/", $host)) { $passed_whitelist = true; // we trust this source @@ -268,7 +258,7 @@ class Embed extends Plugin if ($this->check_blacklist) { // assume it passed by default - $host = parse_url($url, PHP_URL_HOST); + $host = parse_url($url, \PHP_URL_HOST); foreach ($this->domain_blacklist as $regex => $provider) { if (preg_match("/{$regex}/", $host)) { $passed_blacklist = false; // we blocked this source @@ -286,10 +276,6 @@ class Embed extends Plugin * know they exist but autodiscovery data isn't available. * * Throws exceptions on failure. - * - * @param string $url - * - * @return array */ private function getEmbedLibMetadata(string $url): array { @@ -305,7 +291,7 @@ class Embed extends Plugin $root_url = "{$root_url['scheme']}://{$root_url['host']}"; $metadata['provider_url'] = (string) ($info->providerUrl != '' ? $info->providerUrl : $root_url); - if (!is_null($info->image)) { + if (!\is_null($info->image)) { $thumbnail_url = (string) $info->image; } else { $thumbnail_url = (string) $info->favicon; @@ -318,10 +304,6 @@ class Embed extends Plugin /** * Normalize fetched info. - * - * @param array $metadata - * - * @return array */ private static function normalizeEmbedLibMetadata(array $metadata): array { @@ -350,8 +332,6 @@ class Embed extends Plugin * - downloads the thumbnail, returns a string if successful. * * @param string $url URL to the remote thumbnail - * - * @return null|bool|string */ private function downloadThumbnail(string $url): bool|string|null { @@ -370,7 +350,7 @@ class Embed extends Plugin // Validate if the URL really does point to a remote image $head = HTTPClient::head($url); $headers = $head->getHeaders(); - $headers = array_change_key_case($headers, CASE_LOWER); + $headers = array_change_key_case($headers, \CASE_LOWER); if (empty($headers['content-type']) || GSFile::mimetypeMajor($headers['content-type'][0]) !== 'image') { Log::debug("URL ({$url}) doesn't point to an image (content-type: " . (!empty($headers['content-type'][0]) ? $headers['content-type'][0] : 'not available') . ') in Embed->downloadThumbnail.'); return null; @@ -409,17 +389,15 @@ class Embed extends Plugin * @throws ServerException * * @return bool true hook value - * */ public function onPluginVersion(array &$versions): bool { $versions[] = [ - 'name' => 'Embed', - 'version' => $this->version(), - 'author' => 'Mikael Nordfeldth, Hugo Sales, Diogo Peralta Cordeiro', - 'homepage' => GNUSOCIAL_PROJECT_URL, - 'description' => // TRANS: Plugin description. - _m('Plugin for using and representing oEmbed, OpenGraph and other data.'), + 'name' => 'Embed', + 'version' => $this->version(), + 'author' => 'Mikael Nordfeldth, Hugo Sales, Diogo Peralta Cordeiro', + 'homepage' => GNUSOCIAL_PROJECT_URL, + 'description', // TRANS: Plugin description. => _m('Plugin for using and representing oEmbed, OpenGraph and other data.'), ]; return Event::next; } diff --git a/plugins/Embed/Entity/AttachmentEmbed.php b/plugins/Embed/Entity/AttachmentEmbed.php index af9f3fb19d..84a44607a5 100644 --- a/plugins/Embed/Entity/AttachmentEmbed.php +++ b/plugins/Embed/Entity/AttachmentEmbed.php @@ -1,4 +1,6 @@ link_id; } - /** - * @return int - */ public function getAttachmentId(): int { return $this->attachment_id; } - /** - * @param int $attachment_id - */ public function setAttachmentId(int $attachment_id): void { $this->attachment_id = $attachment_id; @@ -187,7 +183,7 @@ class AttachmentEmbed extends Entity $attr = ['class' => 'u-photo embed']; $attachment = DB::find('attachment', ['id' => $this->getAttachmentId()]); $thumbnail = $attachment->getThumbnail('medium'); - if (is_null($attachment) || is_null($attachment->getWidth()) || is_null($attachment->getHeight())) { + if (\is_null($attachment) || \is_null($attachment->getWidth()) || \is_null($attachment->getHeight())) { $attr['has_attachment'] = false; } else { $attr['has_attachment'] = true; diff --git a/plugins/Embed/Test/EmbedTest.php b/plugins/Embed/Test/EmbedTest.php index 107990c44c..b2d1ec359f 100644 --- a/plugins/Embed/Test/EmbedTest.php +++ b/plugins/Embed/Test/EmbedTest.php @@ -1,5 +1,7 @@ $id] + 'select n from App\Entity\Note n, Plugin\Favourite\Entity\Favourite f ' + . 'where n.id = f.note_id ' + . 'and f.actor_id = :id ' + . 'order by f.created DESC', + ['id' => $id], ); $notes_out = null; Event::handle('FormatNoteList', [$notes, &$notes_out]); return [ - '_template' => 'network/feed.html.twig', - 'notes' => $notes_out, - 'page_title' => 'Favourites timeline.', + '_template' => 'network/feed.html.twig', + 'notes' => $notes_out, + 'page_title' => 'Favourites timeline.', ]; } public function favouritesByActorNickname(Request $request, string $nickname) @@ -55,29 +57,28 @@ class Favourite /** * Reverse favourites stream * - * @param Request $request - * * @throws \App\Util\Exception\NoLoggedInUser user not logged in * * @return array template */ - public function reverseFavouritesByActorId(Request $request, int $id) + public function reverseFavouritesByActorId(Request $request, int $id): array { - $notes = DB::dql('select n from App\Entity\Note n, Plugin\Favourite\Entity\Favourite f ' . - 'where n.id = f.note_id ' . - 'and f.actor_id != :id ' . - 'and n.actor_id = :id ' . - 'order by f.created DESC' , - ['id' => $id] + $notes = DB::dql( + 'select n from App\Entity\Note n, Plugin\Favourite\Entity\Favourite f ' + . 'where n.id = f.note_id ' + . 'and f.actor_id != :id ' + . 'and n.actor_id = :id ' + . 'order by f.created DESC', + ['id' => $id], ); $notes_out = null; Event::handle('FormatNoteList', [$notes, &$notes_out]); return [ - '_template' => 'network/feed.html.twig', - 'notes' => $notes, - 'page_title' => 'Reverse favourites timeline.', + '_template' => 'network/feed.html.twig', + 'notes' => $notes, + 'page_title' => 'Reverse favourites timeline.', ]; } public function reverseFavouritesByActorNickname(Request $request, string $nickname) diff --git a/plugins/Favourite/Entity/Favourite.php b/plugins/Favourite/Entity/Favourite.php index 8579a20bb7..b6f581264a 100644 --- a/plugins/Favourite/Entity/Favourite.php +++ b/plugins/Favourite/Entity/Favourite.php @@ -1,5 +1,7 @@ getId()}", + $request, + $form_fav, + $note, + "favourite-{$note->getId()}", /** * Called from form handler * @@ -88,7 +89,7 @@ class Favourite extends NoteHandlerPlugin * * @throws RedirectException Always thrown in order to prevent accidental form re-submit from browser */ - function ($note, $data) use ($opts) { + function (Note $note, Form $data) use ($opts) { $favourite_note = DB::find('favourite', $opts); if ($data["favourite-{$note->getId()}"] === '0' && $favourite_note === null) { DB::persist(Entity\Favourite::create($opts)); @@ -104,7 +105,8 @@ class Favourite extends NoteHandlerPlugin throw new RedirectException(); return Event::stop; - }); + }, + ); if ($ret !== null) { return $ret; @@ -125,7 +127,7 @@ class Favourite extends NoteHandlerPlugin { $r->connect(id: 'actor_favourites_id', uri_path: '/actor/{id<\d+>}/favourites', target: [Controller\Favourite::class, 'favouritesByActorId']); $r->connect(id: 'actor_reverse_favourites_id', uri_path: '/actor/{id<\d+>}/reverse_favourites', target: [Controller\Favourite::class, 'reverseFavouritesByActorId']); - $r->connect(id:'actor_favourites_nickname', uri_path: '/@{nickname<' . Nickname::DISPLAY_FMT . '>}/favourites', target: [Controller\Favourite::class, 'favouritesByActorNickname']); + $r->connect(id: 'actor_favourites_nickname', uri_path: '/@{nickname<' . Nickname::DISPLAY_FMT . '>}/favourites', target: [Controller\Favourite::class, 'favouritesByActorNickname']); $r->connect(id: 'actor_reverse_favourites_nickname', uri_path: '/@{nickname<' . Nickname::DISPLAY_FMT . '>}/reverse_favourites', target: [Controller\Favourite::class, 'reverseFavouritesByActorNickname']); return Event::next; } diff --git a/plugins/FileQuota/FileQuota.php b/plugins/FileQuota/FileQuota.php index 93115ce9e2..ba4c4f64eb 100644 --- a/plugins/FileQuota/FileQuota.php +++ b/plugins/FileQuota/FileQuota.php @@ -1,5 +1,7 @@ 'FileQuota', - 'version' => $this->version(), - 'author' => 'Hugo Sales', - 'homepage' => GNUSOCIAL_PROJECT_URL, - 'description' => // TRANS: Plugin description. - _m('Plugin to manage user quotas.'), + 'name' => 'FileQuota', + 'version' => $this->version(), + 'author' => 'Hugo Sales', + 'homepage' => GNUSOCIAL_PROJECT_URL, + 'description', // TRANS: Plugin description. => _m('Plugin to manage user quotas.'), ]; return Event::next; } diff --git a/plugins/ImageEncoder/Exception/UnsupportedFileTypeException.php b/plugins/ImageEncoder/Exception/UnsupportedFileTypeException.php index 97f9d6c089..12d8cba749 100644 --- a/plugins/ImageEncoder/Exception/UnsupportedFileTypeException.php +++ b/plugins/ImageEncoder/Exception/UnsupportedFileTypeException.php @@ -1,5 +1,7 @@ getFilename(), mimetype: $original_mimetype, ext: $extension, - force: false + force: false, ) ?? $extension; // TemporaryFile handles deleting the file if some error occurs @@ -172,10 +154,12 @@ class ImageEncoder extends Plugin } $width = $image->width; $height = $image->height; - $image = $image->crop(left: 0, - top: 0, - width: $width, - height: $height); + $image = $image->crop( + left: 0, + top: 0, + width: $width, + height: $height, + ); $image->writeToFile($temp->getRealPath()); // Replace original file with the sanitized one @@ -190,22 +174,19 @@ class ImageEncoder extends Plugin /** * Generates the view for attachments of type Image - * - * @param array $vars - * @param array $res - * - * @return bool */ public function onViewAttachment(array $vars, array &$res): bool { if ($vars['attachment']->getMimetypeMajor() !== 'image') { return Event::next; } - $res[] = Formatting::twigRenderFile('imageEncoder/imageEncoderView.html.twig', + $res[] = Formatting::twigRenderFile( + 'imageEncoder/imageEncoderView.html.twig', [ 'attachment' => $vars['attachment'], 'note' => $vars['note'], - ]); + ], + ); return Event::stop; } @@ -218,19 +199,8 @@ class ImageEncoder extends Plugin * enable the handling of bigger images, which can cause a peak of memory consumption, while * encoding * - * @param string $source - * @param null|TemporaryFile $destination - * @param int $width - * @param int $height - * @param bool $smart_crop - * @param null|string $mimetype - * - * @throws Vips\Exception * @throws TemporaryFileException - * - * @return bool - * - * + * @throws Vips\Exception */ public function resizeImagePath(string $source, ?TemporaryFile &$destination, int &$width, int &$height, bool $smart_crop, ?string &$mimetype): bool { @@ -244,12 +214,12 @@ class ImageEncoder extends Plugin $image = $image->smartcrop($width, $height, [Vips\Interesting::ATTENTION]); } } catch (Exception $e) { - Log::error(__METHOD__ . ' encountered exception: ' . get_class($e)); + Log::error(__METHOD__ . ' encountered exception: ' . \get_class($e)); // TRANS: Exception thrown when trying to resize an unknown file type. throw new Exception(_m('Unknown file type')); } - if (is_null($destination)) { + if (\is_null($destination)) { // IMPORTANT: We have to specify the extension for the temporary file // in order to have a format conversion $ext = '.' . Common::config('thumbnail', 'extension'); @@ -282,12 +252,11 @@ class ImageEncoder extends Plugin public function onPluginVersion(array &$versions): bool { $versions[] = [ - 'name' => 'ImageEncoder', - 'version' => $this->version(), - 'author' => 'Hugo Sales, Diogo Peralta Cordeiro', - 'homepage' => GNUSOCIAL_PROJECT_URL, - 'description' => // TRANS: Plugin description. - _m('Use VIPS for some additional image support.'), + 'name' => 'ImageEncoder', + 'version' => $this->version(), + 'author' => 'Hugo Sales, Diogo Peralta Cordeiro', + 'homepage' => GNUSOCIAL_PROJECT_URL, + 'description', // TRANS: Plugin description. => _m('Use VIPS for some additional image support.'), ]; return Event::next; } diff --git a/plugins/Poll/Controller/AnswerPoll.php b/plugins/Poll/Controller/AnswerPoll.php index c859abb66a..faaab3b544 100644 --- a/plugins/Poll/Controller/AnswerPoll.php +++ b/plugins/Poll/Controller/AnswerPoll.php @@ -1,5 +1,7 @@ _m('Visibility:'), 'expanded' => true, 'choices' => [_m('Public') => 'public', _m('Instance') => 'instance', _m('Private') => 'private']]]; $opts[] = ['Question', TextType::class, ['label' => _m(('Question'))]]; @@ -91,7 +92,7 @@ class NewPoll Security::sanitize($opt[$i - 1] = $data['Option_' . $i]); } - $options = implode("\n",$opt); + $options = implode("\n", $opt); $poll = Poll::create(['actor_id' => $user->getId(), 'question' => $question, 'options' => $options, 'note_id' => $note->getId()]); DB::persist($poll); DB::flush(); diff --git a/plugins/Poll/Entity/Poll.php b/plugins/Poll/Entity/Poll.php index 7a4eecc974..b1f0ef01a9 100644 --- a/plugins/Poll/Entity/Poll.php +++ b/plugins/Poll/Entity/Poll.php @@ -1,5 +1,7 @@ count($this->getOptionsArr())) { - return false; - } - return true; + return !($selection < 1 || $selection > \count($this->getOptionsArr())); } /** @@ -200,10 +197,12 @@ class Poll extends Entity { $responses = []; $options = $this->getOptionsArr(); - for ($i = 0; $i < count($options); ++$i) { - $responses[$options[$i]] = DB::dql('select count(pr) from App\Entity\PollResponse pr ' . - 'where pr.poll_id = :id and pr.selection = :selection', - ['id' => $this->id, 'selection' => $i + 1])[0][1]; + for ($i = 0; $i < \count($options); ++$i) { + $responses[$options[$i]] = DB::dql( + 'select count(pr) from App\Entity\PollResponse pr ' + . 'where pr.poll_id = :id and pr.selection = :selection', + ['id' => $this->id, 'selection' => $i + 1], + )[0][1]; } return $responses; diff --git a/plugins/Poll/Entity/PollResponse.php b/plugins/Poll/Entity/PollResponse.php index dfce833741..29c1735ab9 100644 --- a/plugins/Poll/Entity/PollResponse.php +++ b/plugins/Poll/Entity/PollResponse.php @@ -1,5 +1,7 @@ 'pollresponse', @@ -166,16 +168,15 @@ class PollResponse extends Entity /** * Checks if a user already responded to the poll * - * @param int $pollId * @param int $actorId user - * - * @return bool */ public static function exits(int $pollId, int $actorId): bool { - $res = DB::dql('select pr from App\Entity\PollResponse pr + $res = DB::dql( + 'select pr from App\Entity\PollResponse pr where pr.poll_id = :pollId and pr.actor_id = :actorId', - ['pollId' => $pollId, 'actorId' => $actorId]); - return count($res) != 0; + ['pollId' => $pollId, 'actorId' => $actorId], + ); + return \count($res) != 0; } } diff --git a/plugins/Poll/Poll.php b/plugins/Poll/Poll.php index 2a17861fb3..8ec30771d7 100644 --- a/plugins/Poll/Poll.php +++ b/plugins/Poll/Poll.php @@ -1,4 +1,6 @@ getId(), Common::ensureLoggedIn()->getId())) { $opts = $poll->getOptionsArr(); $options = []; - for ($i = 1; $i <= count($opts); ++$i) { + for ($i = 1; $i <= \count($opts); ++$i) { $options[$opts[$i - 1]] = $i; } $formOptions = [ diff --git a/plugins/ProfileColor/Controller/ProfileColor.php b/plugins/ProfileColor/Controller/ProfileColor.php index ec66352a78..3c2b642c58 100644 --- a/plugins/ProfileColor/Controller/ProfileColor.php +++ b/plugins/ProfileColor/Controller/ProfileColor.php @@ -1,5 +1,7 @@ getId(); + $actor = Common::actor(); + $actor_id = $actor->getId(); $current_profile_color = DB::find('profile_color', ['actor_id' => $actor_id]); $form = Form::create([ ['background_color', ColorType::class, [ 'html5' => true, - 'data' => $current_profile_color ? $current_profile_color->getBackground() : "#000000", + 'data' => $current_profile_color ? $current_profile_color->getBackground() : '#000000', 'label' => _m('Profile background color'), - 'help' => _m('Choose your Profile background color')] + 'help' => _m('Choose your Profile background color'), ], ], ['foreground_color', ColorType::class, [ 'html5' => true, - 'data' => $current_profile_color ? $current_profile_color->getColor() : "#000000", + 'data' => $current_profile_color ? $current_profile_color->getColor() : '#000000', 'label' => _m('Profile foreground color'), - 'help' => _m('Choose your Profile foreground color')] + 'help' => _m('Choose your Profile foreground color'), ], ], ['hidden', HiddenType::class, []], ['save_profile_color', SubmitType::class, ['label' => _m('Submit')]], @@ -83,14 +81,13 @@ class ProfileColor $form->handleRequest($request); if ($form->isSubmitted() && $form->isValid()) { - if ($current_profile_color !== null) { DB::remove($current_profile_color); DB::flush(); } - $data = $form->getData(); - $current_profile_color = Entity\ProfileColor::create(['actor_id' => $actor_id, 'color' => $data['foreground_color'], 'background' => $data['background_color']]); + $data = $form->getData(); + $current_profile_color = Entity\ProfileColor::create(['actor_id' => $actor_id, 'color' => $data['foreground_color'], 'background' => $data['background_color']]); DB::persist($current_profile_color); DB::flush(); diff --git a/plugins/ProfileColor/Entity/ProfileColor.php b/plugins/ProfileColor/Entity/ProfileColor.php index 2079731228..dd6edeefa8 100644 --- a/plugins/ProfileColor/Entity/ProfileColor.php +++ b/plugins/ProfileColor/Entity/ProfileColor.php @@ -1,5 +1,7 @@ 'profile_color', 'fields' => [ - 'actor_id' => ['type' => 'int', 'foreign key' => true, 'target' => 'Actor.id', 'multiplicity' => 'one to one', 'not null' => true, 'description' => 'foreign key to actor table'], - 'background' => ['type' => 'text', 'description' => 'color hex code'], - 'color' => ['type' => 'text', 'description' => 'color hex code'], - 'created' => ['type' => 'datetime', 'not null' => true, 'description' => 'date this record was created', 'default' => 'CURRENT_TIMESTAMP'], - 'modified' => ['type' => 'timestamp', 'not null' => true, 'description' => 'date this record was modified', 'default' => 'CURRENT_TIMESTAMP'], + 'actor_id' => ['type' => 'int', 'foreign key' => true, 'target' => 'Actor.id', 'multiplicity' => 'one to one', 'not null' => true, 'description' => 'foreign key to actor table'], + 'background' => ['type' => 'text', 'description' => 'color hex code'], + 'color' => ['type' => 'text', 'description' => 'color hex code'], + 'created' => ['type' => 'datetime', 'not null' => true, 'description' => 'date this record was created', 'default' => 'CURRENT_TIMESTAMP'], + 'modified' => ['type' => 'timestamp', 'not null' => true, 'description' => 'date this record was modified', 'default' => 'CURRENT_TIMESTAMP'], ], 'primary key' => ['actor_id'], ]; diff --git a/plugins/ProfileColor/ProfileColor.php b/plugins/ProfileColor/ProfileColor.php index d57802b3af..c0f022f9a6 100644 --- a/plugins/ProfileColor/ProfileColor.php +++ b/plugins/ProfileColor/ProfileColor.php @@ -1,4 +1,6 @@ $actor_id])[0]; + $color = DB::findBy('profile_color', ['actor_id' => $actor_id])[0]; if ($color !== null) { $color = $color->getColor(); $res[] = Formatting::twigRenderFile('/profileColor/profileColorView.html.twig', ['profile_color' => $profile_color_tab, 'actor' => $actor_id]); diff --git a/plugins/Repeat/Repeat.php b/plugins/Repeat/Repeat.php index 76e6a26ddd..bc4e877be5 100644 --- a/plugins/Repeat/Repeat.php +++ b/plugins/Repeat/Repeat.php @@ -1,5 +1,7 @@ getId()}", function ($note, $data, $user) { + $request, + $form_repeat, + $note, + "repeat-{$note->getId()}", + function ($note, $data, $user) { if ($data["repeat-{$note->getId()}"] === '0') { DB::persist(Note::create([ 'actor_id' => $user->getId(), @@ -80,7 +86,8 @@ class Repeat extends NoteHandlerPlugin throw new RedirectException(); return Event::stop; - }); + }, + ); if ($ret !== null) { return $ret; diff --git a/plugins/Reply/Controller/Reply.php b/plugins/Reply/Controller/Reply.php index 9354a5458b..c214b32405 100644 --- a/plugins/Reply/Controller/Reply.php +++ b/plugins/Reply/Controller/Reply.php @@ -1,4 +1,6 @@ string('return_to'); - if (!is_null($return)) { + if (!\is_null($return)) { // Prevent open redirect if (Router::isAbsolute($return)) { Log::warning("Actor {$actor_id} attempted to reply to a note and then get redirected to another host, or the URL was invalid ({$return})"); diff --git a/plugins/Reply/Reply.php b/plugins/Reply/Reply.php index ddde386556..19c24a8606 100644 --- a/plugins/Reply/Reply.php +++ b/plugins/Reply/Reply.php @@ -1,5 +1,7 @@ $link->getId()]); + $attachment_to_link = DB::find( + 'attachment_to_link', + ['link_id' => $link->getId()], + ); // If it was handled already - if (!is_null($attachment_to_link)) { + if (!\is_null($attachment_to_link)) { // Relate the note with the existing attachment DB::persist(AttachmentToNote::create([ 'attachment_id' => $attachment_to_link->getAttachmentId(), @@ -179,7 +177,7 @@ class StoreRemoteMedia extends Plugin $thumbnail = AttachmentThumbnail::getOrCreate( attachment: $attachment, size: 'medium', - crop: $this->getSmartCrop() + crop: $this->getSmartCrop(), ); $attachment->deleteStorage(); } @@ -189,8 +187,6 @@ class StoreRemoteMedia extends Plugin } /** - * @param string $url - * * @return bool true if allowed by the lists, false otherwise */ private function allowedLink(string $url): bool @@ -200,7 +196,7 @@ class StoreRemoteMedia extends Plugin if ($this->check_whitelist) { $passed_whitelist = false; // don't trust be default - $host = parse_url($url, PHP_URL_HOST); + $host = parse_url($url, \PHP_URL_HOST); foreach ($this->domain_whitelist as $regex => $provider) { if (preg_match("/{$regex}/", $host)) { $passed_whitelist = true; // we trust this source @@ -210,7 +206,7 @@ class StoreRemoteMedia extends Plugin if ($this->check_blacklist) { // assume it passed by default - $host = parse_url($url, PHP_URL_HOST); + $host = parse_url($url, \PHP_URL_HOST); foreach ($this->domain_blacklist as $regex => $provider) { if (preg_match("/{$regex}/", $host)) { $passed_blacklist = false; // we blocked this source @@ -232,12 +228,11 @@ class StoreRemoteMedia extends Plugin public function onPluginVersion(array &$versions): bool { $versions[] = [ - 'name' => 'StoreRemoteMedia', - 'version' => $this->version(), - 'author' => 'Mikael Nordfeldth, Diogo Peralta Cordeiro', - 'homepage' => GNUSOCIAL_PROJECT_URL, - 'description' => // TRANS: Plugin description. - _m('Plugin for downloading remotely attached files to local server.'), + 'name' => 'StoreRemoteMedia', + 'version' => $this->version(), + 'author' => 'Mikael Nordfeldth, Diogo Peralta Cordeiro', + 'homepage' => GNUSOCIAL_PROJECT_URL, + 'description', // TRANS: Plugin description. => _m('Plugin for downloading remotely attached files to local server.'), ]; return Event::next; } diff --git a/plugins/TreeNotes/TreeNotes.php b/plugins/TreeNotes/TreeNotes.php index 249a36b1d7..354b3fa106 100644 --- a/plugins/TreeNotes/TreeNotes.php +++ b/plugins/TreeNotes/TreeNotes.php @@ -1,5 +1,7 @@ getReplyTo() == null; }); + $roots = array_filter($notes_in, fn (Note $note) => $note->getReplyTo() == null); $notes_out = $this->build_tree($roots, $notes_in); } @@ -44,7 +46,7 @@ class TreeNotes extends Plugin private function build_subtree(Note $parent, array $notes) { - $children = array_filter($notes, function (Note $n) use ($parent) { return $parent->getId() == $n->getReplyTo(); }); + $children = array_filter($notes, fn (Note $n) => $parent->getId() == $n->getReplyTo()); return ['note' => $parent, 'replies' => $this->build_tree($children, $notes)]; } } diff --git a/plugins/VideoEncoder/VideoEncoder.php b/plugins/VideoEncoder/VideoEncoder.php index b41bef9916..80c200e1b4 100644 --- a/plugins/VideoEncoder/VideoEncoder.php +++ b/plugins/VideoEncoder/VideoEncoder.php @@ -1,4 +1,6 @@ streams($file->getRealPath()) // extracts streams informations - ->videos() // filters video streams - ->first(); // returns the first video stream + ->videos() // filters video streams + ->first(); // returns the first video stream $width = $metadata->get('width'); $height = $metadata->get('height'); @@ -141,17 +121,7 @@ class VideoEncoder extends Plugin /** * Resizes GIF files. * - * @param string $source - * @param null|TemporaryFile $destination - * @param int $width - * @param int $height - * @param bool $smart_crop - * @param null|string $mimetype - * * @throws TemporaryFileException - * - * @return bool - * */ public function resizeVideoPath(string $source, ?TemporaryFile &$destination, int &$width, int &$height, bool $smart_crop, ?string &$mimetype): bool { @@ -168,19 +138,16 @@ class VideoEncoder extends Plugin /** * Generates the view for attachments of type Video - * - * @param array $vars - * @param array $res - * - * @return bool */ public function onViewAttachment(array $vars, array &$res): bool { - $res[] = Formatting::twigRenderFile('videoEncoder/videoEncoderView.html.twig', + $res[] = Formatting::twigRenderFile( + 'videoEncoder/videoEncoderView.html.twig', [ 'attachment' => $vars['attachment'], 'note' => $vars['note'], - ]); + ], + ); return Event::stop; } @@ -188,12 +155,8 @@ class VideoEncoder extends Plugin * Animated GIF test, courtesy of frank at huddler dot com et al: * http://php.net/manual/en/function.imagecreatefromgif.php#104473 * Modified so avoid landing inside of a header (and thus not matching our regexp). - * - * @param string $filepath - * - * @return bool */ - public function isAnimatedGif(string $filepath) + public function isAnimatedGif(string $filepath): bool { if (!($fh = @fopen($filepath, 'rb'))) { return false; @@ -215,7 +178,7 @@ class VideoEncoder extends Plugin // rewind in case we ended up in the middle of the header, but avoid // infinite loop (i.e. don't rewind if we're already in the end). if (!feof($fh) && ftell($fh) >= 9) { - fseek($fh, -9, SEEK_CUR); + fseek($fh, -9, \SEEK_CUR); } } @@ -229,16 +192,7 @@ class VideoEncoder extends Plugin * @see http://blog.pkh.me/p/21-high-quality-gif-with-ffmpeg.html * @see https://github.com/PHP-FFMpeg/PHP-FFMpeg/pull/592 * - * @param string $source - * @param null|TemporaryFile $destination - * @param int $width - * @param int $height - * @param bool $smart_crop - * @param null|string $mimetype - * * @throws TemporaryFileException - * - * @return bool */ public function resizeImageFileAnimatedGif(string $source, ?TemporaryFile &$destination, int &$width, int &$height, bool $smart_crop, ?string &$mimetype): bool { @@ -251,7 +205,7 @@ class VideoEncoder extends Plugin // FFmpeg can't edit existing files in place, // generate temporary output file to avoid that - $destination = $destination ?? new TemporaryFile(['prefix' => 'video']); + $destination ??= new TemporaryFile(['prefix' => 'video']); // Generate palette file. FFmpeg explicitly needs to be told the // extension for PNG files outputs @@ -315,11 +269,6 @@ class VideoEncoder extends Plugin * Courtesy of tomas at slax dot org: * * @see https://www.php.net/manual/en/function.tempnam.php#98232 - * - * @param string $dir - * @param string $suffix - * - * @return string */ private function tempnam_sfx(string $dir, string $suffix): string { @@ -333,11 +282,7 @@ class VideoEncoder extends Plugin } /** - * @param array $versions - * * @throws ServerException - * - * @return bool */ public function onPluginVersion(array &$versions): bool { @@ -345,8 +290,7 @@ class VideoEncoder extends Plugin 'version' => self::version(), 'author' => 'Bruno Casteleiro, Diogo Peralta Cordeiro', 'homepage' => 'https://notabug.org/diogo/gnu-social/src/nightly/plugins/FFmpeg', - 'rawdescription' => // TRANS: Plugin description. - _m('Use PHP-FFMpeg for some more video support.'), + 'rawdescription', // TRANS: Plugin description. => _m('Use PHP-FFMpeg for some more video support.'), ]; return Event::next; } diff --git a/plugins/XMPPNotifications/XMPPNotifications.php b/plugins/XMPPNotifications/XMPPNotifications.php index 4ea5029630..cc7a0c890d 100644 --- a/plugins/XMPPNotifications/XMPPNotifications.php +++ b/plugins/XMPPNotifications/XMPPNotifications.php @@ -1,5 +1,7 @@ . */ -define('INSTALLDIR', dirname(__DIR__)); -define('PUBLICDIR', INSTALLDIR . DIRECTORY_SEPARATOR . 'public'); +\define('INSTALLDIR', \dirname(__DIR__)); +\define('PUBLICDIR', INSTALLDIR . \DIRECTORY_SEPARATOR . 'public'); $shortoptions = 'y'; -$longoptions = array('yes'); +$longoptions = ['yes']; -$helptext = <<whereAdd('filename IS NOT NULL'); @@ -53,11 +53,11 @@ if ($file->find()) { while ($file->fetch()) { try { $file->getPath(); - print '.'; + echo '.'; } catch (FileNotFoundException $e) { $file->delete(); - print 'x'; + echo 'x'; } } } -print "\nDONE.\n"; +echo "\nDONE.\n"; diff --git a/scripts/clean_thumbnails.php b/scripts/clean_thumbnails.php index 5a3dbf82d4..c31453550e 100755 --- a/scripts/clean_thumbnails.php +++ b/scripts/clean_thumbnails.php @@ -18,45 +18,45 @@ * along with this program. If not, see . */ -define('INSTALLDIR', dirname(__DIR__)); -define('PUBLICDIR', INSTALLDIR . DIRECTORY_SEPARATOR . 'public'); +\define('INSTALLDIR', \dirname(__DIR__)); +\define('PUBLICDIR', INSTALLDIR . \DIRECTORY_SEPARATOR . 'public'); $shortoptions = 'y::a::f'; -$longoptions = ['yes', 'all', 'force']; +$longoptions = ['yes', 'all', 'force']; -$helptext = <<find(); while ($thumbs->fetch()) { try { - $file = $thumbs->getFile(); + $file = $thumbs->getFile(); $is_local = $file->isLocal(); if ($is_local || !$only_local) { // only delete if we can regenerate it @@ -69,12 +69,12 @@ while ($thumbs->fetch()) { } } $thumbs->delete(); - print '.'; + echo '.'; } } catch (NoResultException $e) { // No File object for thumbnail, let's delete the thumbnail entry $thumbs->delete(); - print 'x'; + echo 'x'; } } -print "\nDONE.\n"; +echo "\nDONE.\n"; diff --git a/src/CacheKernel.php b/src/CacheKernel.php index 792790e530..0979ad1b8b 100644 --- a/src/CacheKernel.php +++ b/src/CacheKernel.php @@ -1,5 +1,7 @@ setDefinition([new InputArgument('pattern', InputArgument::OPTIONAL, 'An event pattern to look for')]) - ->setDescription('Search for an event') - ->setHelp(<<<'EOF' -The %command.name% command displays GNU social event listeners: + ->setDescription('Search for an event') + ->setHelp( + <<<'EOF' + The %command.name% command displays GNU social event listeners: - php %command.full_name% + php %command.full_name% -To get specific listeners for an event, specify its name: + To get specific listeners for an event, specify its name: - php %command.full_name% kernel.request -EOF - ); + php %command.full_name% kernel.request + EOF, + ); } /** @@ -81,10 +84,10 @@ EOF { $patterm = $input->getArgument('pattern') ?? 'GNUsocial.*'; $listeners = $this->dispatcher->getListeners(); - $listeners = F\select($listeners, - function ($_, $key, $__) use ($patterm) { - return preg_match('/' . $patterm . '/', $key); - }); + $listeners = F\select( + $listeners, + fn ($_, $key, $__) => preg_match('/' . $patterm . '/', $key), + ); ksort($listeners); foreach ($listeners as $event => $listener) { @@ -93,7 +96,7 @@ EOF foreach ($listener as $c) { $r = new ReflectionFunction($c); $m = $r->getStaticVariables()['handler']; - $output->writeln("\t" . get_class($m[0]) . '::' . $m[1]); + $output->writeln("\t" . \get_class($m[0]) . '::' . $m[1]); } $output->writeln(''); } diff --git a/src/Controller/Actor.php b/src/Controller/Actor.php index 5731ab6e6c..4a2b116b8a 100644 --- a/src/Controller/Actor.php +++ b/src/Controller/Actor.php @@ -1,5 +1,7 @@ handleRequest($request); if ($form->isSubmitted()) { $data = $form->getData(); - if ($form->isValid() && array_key_exists('setting', $data)) { + if ($form->isValid() && \array_key_exists('setting', $data)) { [$section, $setting] = explode(':', $data['setting']); if (!isset($defaults[$section]) && !isset($defaults[$section][$setting])) { // @codeCoverageIgnoreStart @@ -81,13 +83,13 @@ class AdminPanel extends Controller $value = null; foreach ([ - 'int' => FILTER_VALIDATE_INT, - 'bool' => FILTER_VALIDATE_BOOL, - 'string' => [fn ($v) => strstr($v, ',') === false, fn ($v) => $v], - 'array' => [fn ($v) => strstr($v, ',') !== false, function ($v) { Formatting::toArray($v, $v); return $v; }], + 'int' => \FILTER_VALIDATE_INT, + 'bool' => \FILTER_VALIDATE_BOOL, + 'string' => [fn ($v) => mb_strstr($v, ',') === false, fn ($v) => $v], + 'array' => [fn ($v) => mb_strstr($v, ',') !== false, function ($v) { Formatting::toArray($v, $v); return $v; }], ] as $type => $validator) { - if (!is_array($validator)) { - $value = filter_var($data['value'], $validator, FILTER_NULL_ON_FAILURE); + if (!\is_array($validator)) { + $value = filter_var($data['value'], $validator, \FILTER_NULL_ON_FAILURE); if ($value !== null) { break; } @@ -102,7 +104,7 @@ class AdminPanel extends Controller $default = $defaults[$section][$setting]; // Sanity check - if (gettype($default) === gettype($value)) { + if (\gettype($default) === \gettype($value)) { $old_value = Common::config($section, $setting); Common::setConfig($section, $setting, $value); return [ diff --git a/src/Controller/Attachment.php b/src/Controller/Attachment.php index 253d3c4ff0..d12fa3c7ed 100644 --- a/src/Controller/Attachment.php +++ b/src/Controller/Attachment.php @@ -1,5 +1,7 @@ attachment($id, fn (array $res) => GSFile::sendFile( - $res['filepath'], $res['mimetype'], - GSFile::ensureFilenameWithProperExtension($res['filename'], $res['mimetype']) ?? $res['filename'], - HeaderUtils::DISPOSITION_INLINE - ) + return $this->attachment( + $id, + fn (array $res) => GSFile::sendFile( + $res['filepath'], + $res['mimetype'], + GSFile::ensureFilenameWithProperExtension($res['filename'], $res['mimetype']) ?? $res['filename'], + HeaderUtils::DISPOSITION_INLINE, + ), ); } public function attachment_download(Request $request, int $id) { - return $this->attachment($id, fn (array $res) => GSFile::sendFile( - $res['filepath'], $res['mimetype'], - GSFile::ensureFilenameWithProperExtension($res['filename'], $res['mimetype']) ?? $res['filename'], - HeaderUtils::DISPOSITION_ATTACHMENT - ) + return $this->attachment( + $id, + fn (array $res) => GSFile::sendFile( + $res['filepath'], + $res['mimetype'], + GSFile::ensureFilenameWithProperExtension($res['filename'], $res['mimetype']) ?? $res['filename'], + HeaderUtils::DISPOSITION_ATTACHMENT, + ), ); } /** * Controller to produce a thumbnail for a given attachment id * - * @param Request $request - * @param int $id Attachment ID + * @param int $id Attachment ID * + * @throws \App\Util\Exception\DuplicateFoundException * @throws ClientException * @throws NotFoundException * @throws ServerException - * @throws \App\Util\Exception\DuplicateFoundException - * - * @return Response */ public function attachment_thumbnail(Request $request, int $id, string $size = 'small'): Response { @@ -139,7 +144,7 @@ class Attachment extends Controller $crop = Common::config('thumbnail', 'smart_crop'); $thumbnail = AttachmentThumbnail::getOrCreate(attachment: $attachment, size: $size, crop: $crop); - if (is_null($thumbnail)) { + if (\is_null($thumbnail)) { throw new ClientException(_m('Can not generate thumbnail for attachment with id={id}', ['id' => $attachment->getId()])); } diff --git a/src/Controller/Network.php b/src/Controller/Network.php index 9b0282cdf7..a6deb9ecf9 100644 --- a/src/Controller/Network.php +++ b/src/Controller/Network.php @@ -1,5 +1,7 @@ 'network/feed.html.twig', - 'notes' => $notes_out, - 'page_title' => 'Public timeline', + '_template' => 'network/feed.html.twig', + 'notes' => $notes_out, + 'page_title' => 'Public timeline', ]; } @@ -75,38 +77,38 @@ class Network extends Controller } $query = << {$this->message_scope} - order by note.modified DESC -END; + -- Select notes from: + select note.* from note left join -- left join ensures all returned notes' ids are not null + ( + -- Followed by target + select n.id from note n inner join follow f on n.actor_id = f.followed + where f.follower = :target_actor_id + union all + -- Replies to notes by target + select n.id from note n inner join note nr on nr.id = nr.reply_to + union all + -- Notifications to target + select a.activity_id from notification a inner join note n on a.activity_id = n.id + union all + -- Notes in groups target follows + select gi.activity_id from group_inbox gi inner join group_member gm on gi.group_id = gm.group_id + where gm.actor_id = :target_actor_id + ) + as s on s.id = note.id + where + -- Remove direct messages + note.scope <> {$this->message_scope} + order by note.modified DESC + END; $notes = DB::sql($query, ['note' => 'App\Entity\Note'], ['target_actor_id' => $target->getId()]); $notes_out = null; Event::handle('FormatNoteList', [$notes, &$notes_out]); return [ - '_template' => 'network/feed.html.twig', - 'notes' => $notes_out, - 'page_title' => 'Home timeline', + '_template' => 'network/feed.html.twig', + 'notes' => $notes_out, + 'page_title' => 'Home timeline', ]; } @@ -118,26 +120,26 @@ END; Event::handle('FormatNoteList', [$notes, &$notes_out]); return [ - '_template' => 'network/feed.html.twig', - 'notes' => $notes_out, - 'page_title' => 'Network timeline', + '_template' => 'network/feed.html.twig', + 'notes' => $notes_out, + 'page_title' => 'Network timeline', ]; } public function replies(Request $request) { $actor_id = Common::ensureLoggedIn()->getId(); - $notes = DB::dql('select n from App\Entity\Note n ' . - 'where n.reply_to is not null and n.actor_id = :id ' . - 'order by n.created DESC', ['id' => $actor_id]); + $notes = DB::dql('select n from App\Entity\Note n ' + . 'where n.reply_to is not null and n.actor_id = :id ' + . 'order by n.created DESC', ['id' => $actor_id], ); $notes_out = null; Event::handle('FormatNoteList', [$notes, &$notes_out]); return [ - '_template' => 'network/feed.html.twig', - 'notes' => $notes_out, - 'page_title' => 'Replies timeline', + '_template' => 'network/feed.html.twig', + 'notes' => $notes_out, + 'page_title' => 'Replies timeline', ]; } } diff --git a/src/Controller/Note.php b/src/Controller/Note.php index 2bc92574c7..44ba5bb41a 100644 --- a/src/Controller/Note.php +++ b/src/Controller/Note.php @@ -1,5 +1,7 @@ _m('Email'), 'constraints' => [ new NotBlank(['message' => _m('Please enter an email') ]) ]]], + ['email', EmailType::class, ['label' => _m('Email'), 'constraints' => [new NotBlank(['message' => _m('Please enter an email')])]]], ['password_reset_request', SubmitType::class, ['label' => _m('Submit request')]], ]); @@ -69,7 +71,7 @@ class ResetPassword extends Controller /** * Validates and process the reset URL that the user clicked in their email. */ - public function reset(Request $request, string $token = null) + public function reset(Request $request, ?string $token = null) { if ($token) { // We store the token in session and remove it from the URL, to avoid the URL being diff --git a/src/Controller/Security.php b/src/Controller/Security.php index 7c17912b78..e91482da7d 100644 --- a/src/Controller/Security.php +++ b/src/Controller/Security.php @@ -1,5 +1,7 @@ _m('Email'), 'help' => _m('Desired email for this account (e.g., john@provider.com)'), - 'constraints' => [ new NotBlank(['message' => _m('Please enter an email') ])], + 'constraints' => [new NotBlank(['message' => _m('Please enter an email')])], 'block_name' => 'email', 'label_attr' => ['class' => 'section-form-label'], 'invalid_message' => _m('Email not valid. Please provide a valid email.'), @@ -145,7 +147,7 @@ class Security extends Controller $actor, $user, // Self follow - fn (int $id) => DB::persist(Follow::create(['follower' => $id, 'followed' => $id])) + fn (int $id) => DB::persist(Follow::create(['follower' => $id, 'followed' => $id])), ); DB::flush(); // @codeCoverageIgnoreStart @@ -170,7 +172,7 @@ class Security extends Controller $user, $request, $authenticator, - 'main' // firewall name in security.yaml + 'main', // firewall name in security.yaml ); } diff --git a/src/Controller/Subscribers.php b/src/Controller/Subscribers.php index 7512287bfd..65e892c570 100644 --- a/src/Controller/Subscribers.php +++ b/src/Controller/Subscribers.php @@ -1,5 +1,7 @@ account($request); $personal_form = $this->personal_info($request); @@ -106,9 +104,7 @@ class UserPanel extends AbstractController $extra_step = function ($data, $extra_args) use ($user) { $user->setNickname($data['nickname']); }; - $form = Form::handle($form_definition, $request, $actor, $extra, $extra_step, [['self_tags' => $extra['self_tags']]]); - - return $form; + return Form::handle($form_definition, $request, $actor, $extra, $extra_step, [['self_tags' => $extra['self_tags']]]); } /** @@ -132,7 +128,7 @@ class UserPanel extends AbstractController if ($form->isSubmitted() && $form->isValid()) { $data = $form->getData(); - if (!is_null($data['old_password'])) { + if (!\is_null($data['old_password'])) { $data['password'] = $form->get('password')->getData(); if (!($user->changePassword($data['old_password'], $data['password']))) { throw new AuthenticationException(_m('The provided password is incorrect')); @@ -166,7 +162,7 @@ class UserPanel extends AbstractController foreach ($columns as $name => $col) { $type = $col->getType(); $val = $type->convertToPHPValue($col->getDefault(), $platform); - $type_str = lcfirst(substr((string) $type, 1)); + $type_str = lcfirst(mb_substr((string) $type, 1)); $label = str_replace('_', ' ', ucfirst($name)); $labels = [ @@ -223,14 +219,14 @@ class UserPanel extends AbstractController try { [$ent, $is_update] = UserNotificationPrefs::createOrUpdate( array_merge(['user_id' => $user->getId(), 'transport' => $transport_name], $data), - find_by_keys: ['user_id', 'transport'] + find_by_keys: ['user_id', 'transport'], ); if (!$is_update) { DB::persist($ent); } DB::flush(); // @codeCoverageIgnoreStart - } catch (\Exception $e) { + } catch (Exception $e) { // Somehow, the exception doesn't bubble up in phpunit dd($data, $e); // @codeCoverageIgnoreEnd @@ -238,9 +234,7 @@ class UserPanel extends AbstractController } } - $tabbed_forms = F\map($tabbed_forms, function ($f) { - return $f->createView(); - }); + $tabbed_forms = F\map($tabbed_forms, fn ($f) => $f->createView()); return $tabbed_forms; } } diff --git a/src/Core/Cache.php b/src/Core/Cache.php index 8d2b67cb9f..dba4438d2c 100644 --- a/src/Core/Cache.php +++ b/src/Core/Cache.php @@ -1,5 +1,7 @@ pconnect($rest); @@ -122,7 +125,7 @@ abstract class Cache unset(self::$redis[$pool]); } - if (count($adapters[$pool]) === 1) { + if (\count($adapters[$pool]) === 1) { self::$pools[$pool] = array_pop($adapters[$pool]); } else { self::$pools[$pool] = new ChainAdapter($adapters[$pool]); @@ -133,7 +136,7 @@ abstract class Cache public static function set(string $key, mixed $value, string $pool = 'default') { // there's no set method, must be done this way - return self::$pools[$pool]->get($key, function ($i) use ($value) { return $value; }, INF); + return self::$pools[$pool]->get($key, fn ($i) => $value, \INF); } public static function get(string $key, callable $calculate, string $pool = 'default', float $beta = 1.0) @@ -153,12 +156,12 @@ abstract class Cache public static function getList(string $key, callable $calculate, string $pool = 'default', ?int $max_count = null, ?int $left = null, ?int $right = null, float $beta = 1.0): array { if (isset(self::$redis[$pool])) { - if (!($recompute = $beta === INF || !(self::$redis[$pool]->exists($key)))) { - if (is_float($er = Common::config('cache', 'early_recompute'))) { + if (!($recompute = $beta === \INF || !(self::$redis[$pool]->exists($key)))) { + if (\is_float($er = Common::config('cache', 'early_recompute'))) { $recompute = (mt_rand() / mt_getrandmax() > $er); Log::info('Item "{key}" elected for early recomputation', ['key' => $key]); } else { - if ($recompute = ($idletime = self::$redis[$pool]->object('idletime', $key) ?? false) && ($expiry = self::$redis[$pool]->ttl($key) ?? false) && $expiry <= $idletime / 1000 * $beta * log(random_int(1, PHP_INT_MAX) / PHP_INT_MAX)) { + if ($recompute = ($idletime = self::$redis[$pool]->object('idletime', $key) ?? false) && ($expiry = self::$redis[$pool]->ttl($key) ?? false) && $expiry <= $idletime / 1000 * $beta * log(random_int(1, \PHP_INT_MAX) / \PHP_INT_MAX)) { // @codeCoverageIgnoreStart Log::info('Item "{key}" elected for early recomputation {delta}s before its expiration', [ 'key' => $key, @@ -173,7 +176,7 @@ abstract class Cache $res = $calculate(null, $save); if ($save) { self::setList($key, $res, $pool, $max_count, $beta); - return array_slice($res, $left ?? 0, $right - ($left ?? 0)); + return \array_slice($res, $left ?? 0, $right - ($left ?? 0)); } } return self::$redis[$pool]->lRange($key, $left ?? 0, ($right ?? $max_count ?? 0) - 1); @@ -181,7 +184,7 @@ abstract class Cache return self::get($key, function () use ($calculate, $max_count) { $res = $calculate(null); if ($max_count != -1) { - $res = array_slice($res, 0, $max_count); + $res = \array_slice($res, 0, $max_count); } return $res; }, $pool, $beta); @@ -221,11 +224,11 @@ abstract class Cache ->lTrim($key, -$max_count ?? 0, -1) ->exec(); } else { - $res = self::get($key, function () { return []; }, $pool, $beta); + $res = self::get($key, fn () => [], $pool, $beta); $res[] = $value; if ($max_count != null) { - $count = count($res); - $res = array_slice($res, $count - $max_count, $count); // Trim the older values + $count = \count($res); + $res = \array_slice($res, $count - $max_count, $count); // Trim the older values } self::set($key, $res, $pool); } @@ -255,30 +258,28 @@ abstract class Cache */ public static function pagedStream(string $key, string $query, array $query_args, LocalUser|Actor|null $actor = null, int $page = 1, ?int $per_page = null, string $pool = 'default', ?int $max_count = null, float $beta = 1.0): array { - $max_count = $max_count ?? Common::config('cache', 'max_note_count'); + $max_count ??= Common::config('cache', 'max_note_count'); if ($per_page > $max_count) { - throw new \InvalidArgumentException; + throw new InvalidArgumentException; } - if (is_null($per_page)) { + if (\is_null($per_page)) { $per_page = Common::config('streams', 'notes_per_page'); } $filter_scope = fn (Note $n) => $n->isVisibleTo($actor); - $getter = function (int $offset, int $lenght) use ($query, $query_args) { - return DB::dql($query, $query_args, options: ['offset' => $offset, 'limit' => $lenght]); - }; + $getter = fn (int $offset, int $lenght) => DB::dql($query, $query_args, options: ['offset' => $offset, 'limit' => $lenght]); $requested_left = $offset = $per_page * ($page - 1); $requested_right = $requested_left + $per_page; [$stored_left, $stored_right] = F\map( explode(':', self::get("{$key}-bounds", fn () => "{$requested_left}:{$requested_right}")), - fn (string $v) => (int) $v + fn (string $v) => (int) $v, ); $lenght = $stored_right - $stored_left; - if (!is_null($max_count) && $lenght > $max_count) { + if (!\is_null($max_count) && $lenght > $max_count) { $lenght = $max_count; $requested_right = $requested_left + $max_count; } @@ -293,8 +294,13 @@ abstract class Cache return F\filter( self::getList( $key, - fn () => $getter($requested_left, $lenght), max_count: $max_count, left: $requested_left, right: $requested_right, beta: $beta), - $filter_scope + fn () => $getter($requested_left, $lenght), + max_count: $max_count, + left: $requested_left, + right: $requested_right, + beta: $beta, + ), + $filter_scope, ); } } diff --git a/src/Core/DB/DB.php b/src/Core/DB/DB.php index 1c13a24644..016f07117c 100644 --- a/src/Core/DB/DB.php +++ b/src/Core/DB/DB.php @@ -1,5 +1,7 @@ {$method}(...$expr); } else { $expressions[] = $eb->{$method}($expr); @@ -152,7 +154,7 @@ class DB } elseif ($op == 'is_null') { $expressions[] = $eb->isNull($exp); } else { - if (in_array($op, self::$find_by_ops)) { + if (\in_array($op, self::$find_by_ops)) { foreach ($exp as $field => $value) { $expressions[] = $eb->{$op}($field, $value); } @@ -174,7 +176,7 @@ class DB */ public static function findBy(string $table, array $criteria, ?array $orderBy = null, ?int $limit = null, ?int $offset = null): array { - $criteria = array_change_key_case($criteria, CASE_LOWER); + $criteria = array_change_key_case($criteria, \CASE_LOWER); $ops = array_intersect(array_keys($criteria), self::$find_by_ops); /** @var EntityRepository */ $repo = self::getRepository($table); @@ -193,7 +195,7 @@ class DB public static function findOneBy(string $table, array $criteria, ?array $orderBy = null, ?int $offset = null) { $res = self::findBy($table, $criteria, $orderBy, 2, $offset); // Use limit 2 to check for consistency - switch (count($res)) { + switch (\count($res)) { case 0: throw new NotFoundException("No value in table {$table} matches the requested criteria"); case 1: @@ -213,15 +215,15 @@ class DB /** * Insert all given objects with the generated ID of the first one */ - public static function persistWithSameId(object $owner, object | array $others, ?callable $extra = null) + public static function persistWithSameId(object $owner, object|array $others, ?callable $extra = null) { $conn = self::getConnection(); - $metadata = self::getClassMetadata(get_class($owner)); + $metadata = self::getClassMetadata(\get_class($owner)); $seqName = $metadata->getSequenceName($conn->getDatabasePlatform()); self::persist($owner); $id = $conn->lastInsertId($seqName); - F\map(is_array($others) ? $others : [$others], function ($o) use ($id) { $o->setId($id); self::persist($o); }); - if (!is_null($extra)) { + F\map(\is_array($others) ? $others : [$others], function ($o) use ($id) { $o->setId($id); self::persist($o); }); + if (!\is_null($extra)) { $extra($id); } self::flush(); @@ -248,8 +250,8 @@ class DB */ public static function filterTableName(string $method, array $args): mixed { - if (in_array($method, self::METHODS_ACCEPTING_TABLE_NAME) - && is_string($args[0]) && array_key_exists($args[0], self::$table_map)) { + if (\in_array($method, self::METHODS_ACCEPTING_TABLE_NAME) + && \is_string($args[0]) && \array_key_exists($args[0], self::$table_map)) { return self::$table_map[$args[0]]; } else { return $args[0]; diff --git a/src/Core/DB/UpdateListener.php b/src/Core/DB/UpdateListener.php index a06a8cc12e..7779ea1989 100644 --- a/src/Core/DB/UpdateListener.php +++ b/src/Core/DB/UpdateListener.php @@ -1,5 +1,7 @@ getEntityManager(); $uow = $em->getUnitOfWork(); - $md = $em->getClassMetadata(get_class($entity)); + $md = $em->getClassMetadata(\get_class($entity)); $entity->setModified(new DateTime()); $uow->recomputeSingleEntityChangeSet($md, $entity); diff --git a/src/Core/Entity.php b/src/Core/Entity.php index 8959a6d3a9..ef8eee3d84 100644 --- a/src/Core/Entity.php +++ b/src/Core/Entity.php @@ -1,5 +1,7 @@ {$prop}); }; - $private_property_accessor = $private_property_accessor->bindTo($this, get_called_class()); + $private_property_accessor = fn ($prop) => isset($this->{$prop}); + $private_property_accessor = $private_property_accessor->bindTo($this, \get_called_class()); return $private_property_accessor($prop); } - throw new \BadMethodCallException('Non existent method ' . get_called_class() . "::{$name} called with arguments: " . print_r($arguments, true)); + throw new BadMethodCallException('Non existent method ' . \get_called_class() . "::{$name} called with arguments: " . print_r($arguments, true)); } /** @@ -67,7 +72,7 @@ abstract class Entity $obj->{$set}($val); } else { Log::error($m = "Property {$class}::{$prop} doesn't exist"); - throw new \InvalidArgumentException($m); + throw new InvalidArgumentException($m); } } return $obj; @@ -78,16 +83,16 @@ abstract class Entity * * @return array [$obj, $is_update] */ - public static function createOrUpdate(array $args, array $find_by_keys = []) + public static function createOrUpdate(array $args, array $find_by_keys = []): array { - $table = DB::getTableForClass(get_called_class()); + $table = DB::getTableForClass(\get_called_class()); $find_by = $find_by_keys == [] ? $args : array_intersect_key($args, array_flip($find_by_keys)); try { $obj = DB::findOneBy($table, $find_by); } catch (NotFoundException) { $obj = null; // @codeCoverageIgnoreStart - } catch (\Exception $e) { + } catch (Exception $e) { Log::unexpected_exception($e); // @codeCoverageIgnoreEnd } @@ -112,12 +117,12 @@ abstract class Entity */ public static function getWithPK(mixed $values): ?self { - $values = is_array($values) ? $values : [$values]; - $class = get_called_class(); + $values = \is_array($values) ? $values : [$values]; + $class = \get_called_class(); $keys = DB::getPKForClass($class); $find_by = []; foreach ($values as $k => $v) { - if (is_string($k)) { + if (\is_string($k)) { $find_by[$k] = $v; } else { $find_by[$keys[$k]] = $v; diff --git a/src/Core/Event.php b/src/Core/Event.php index b9ad9ed48d..a4b806ed18 100644 --- a/src/Core/Event.php +++ b/src/Core/Event.php @@ -1,5 +1,7 @@ addListener( $ns . $name, function ($event, $event_name, $dispatcher) use ($handler, $name) { // Old style of events (preferred) if ($event instanceof GenericEvent) { - if (call_user_func_array($handler, $event->getArguments()) === self::stop) { + if ($handler(...$event->getArguments()) === self::stop) { $event->stopPropagation(); } return $event; @@ -94,11 +94,11 @@ abstract class Event // @codeCoverageIgnoreStart // Symfony style of events Log::warning("Event::addHandler for {$name} doesn't Conform to GNU social guidelines. Use of this style of event is discouraged."); - call_user_func($handler, $event, $event_name, $dispatcher); - return null; + $handler($event, $event_name, $dispatcher); + // @codeCoverageIgnoreEnd }, - $priority + $priority, ); } @@ -117,7 +117,7 @@ abstract class Event * @param string $ns Namspace for the event * * @return bool flag saying whether to continue processing, based - * on results of handlers. + * on results of handlers */ public static function handle(string $name, array $args = [], string $ns = 'GNUsocial.'): bool { @@ -155,9 +155,6 @@ abstract class Event * Get the array of handlers for $name * * @param string $name Name of event - * - * @return array - * @return array */ public static function getHandlers(string $name, string $ns = 'GNUsocial.'): array { diff --git a/src/Core/Form.php b/src/Core/Form.php index b0b19f8568..0552da8535 100644 --- a/src/Core/Form.php +++ b/src/Core/Form.php @@ -1,5 +1,7 @@ createNamedBuilder($name, $type, data: null, options: array_merge($form_options, ['translation_domain' => false])); foreach ($form as [$key, $class, $options]) { - if ($class == SubmitType::class && in_array($key, ['save', 'publish', 'post'])) { + if ($class == SubmitType::class && \in_array($key, ['save', 'publish', 'post'])) { Log::critical($m = "It's generally a bad idea to use {$key} as a form name, because it can conflict with other forms in the same page"); throw new ServerException($m); } - if ($target != null && empty($options['data']) && (strstr($key, 'password') == false) && $class != SubmitType::class) { + if ($target != null && empty($options['data']) && (mb_strstr($key, 'password') == false) && $class != SubmitType::class) { if (isset($extra_data[$key])) { // @codeCoverageIgnoreStart $options['data'] = $extra_data[$key]; @@ -135,7 +138,7 @@ abstract class Form * Handle the full life cycle of a form. Creates it with @see * self::create and inserts the submitted values into the database */ - public static function handle(array $form_definition, Request $request, ?object $target, array $extra_args = [], ?callable $extra_step = null, array $create_args = [], SymfForm $testing_only_form = null) + public static function handle(array $form_definition, Request $request, ?object $target, array $extra_args = [], ?callable $extra_step = null, array $create_args = [], ?SymfForm $testing_only_form = null) { $form = $testing_only_form ?? self::create($form_definition, $target, ...$create_args); diff --git a/src/Core/GNUsocial.php b/src/Core/GNUsocial.php index 1807a98903..9e4e98cbf5 100644 --- a/src/Core/GNUsocial.php +++ b/src/Core/GNUsocial.php @@ -1,5 +1,7 @@ logger = $logger; $this->translator = $trans; $this->entity_manager = $em; @@ -161,7 +164,7 @@ class GNUsocial implements EventSubscriberInterface { if (!$this->initialized) { Common::setupConfig($this->config); - if (!is_null($this->request)) { + if (!\is_null($this->request)) { Common::setRequest($this->request); } Log::setLogger($this->logger); @@ -189,10 +192,6 @@ class GNUsocial implements EventSubscriberInterface /** * Event very early on in the Symfony HTTP lifecycle, but after everything is registered * where we get access to the event dispatcher - * - * @param RequestEvent $event - * - * @return RequestEvent */ public function onKernelRequest(RequestEvent $event): RequestEvent { @@ -211,11 +210,7 @@ class GNUsocial implements EventSubscriberInterface /** * Event after everything is initialized when using the `bin/console` command * - * @param ConsoleCommandEvent $event - * * @throws ConfigurationException - * - * @return ConsoleCommandEvent */ public function onCommand(ConsoleCommandEvent $event): ConsoleCommandEvent { @@ -251,7 +246,7 @@ class GNUsocial implements EventSubscriberInterface // Merge parameter $from with values already set in $to $merge_config = function ($from, $to = null) use ($container, $locals) { - $to = $to ?? $from; + $to ??= $from; $wrapper = $container->hasParameter($to) ? $container->getParameter($to) : []; $content = [$from => $container->getParameter($from)]; $container->getParameterBag()->remove($from); @@ -261,7 +256,7 @@ class GNUsocial implements EventSubscriberInterface }; // Override and merge any of the previous settings from the locals - if (is_array($locals)) { + if (\is_array($locals)) { $merge_config('gnusocial'); foreach ($parameters as $mod => $type) { $merge_config($mod, $type); @@ -272,7 +267,6 @@ class GNUsocial implements EventSubscriberInterface /** * Tell Symfony which events we want to listen to, which Symfony detects and auto-wires * due to this implementing the `EventSubscriberInterface` - * */ public static function getSubscribedEvents(): array { diff --git a/src/Core/GSFile.php b/src/Core/GSFile.php index a64f141566..aa39d6f15f 100644 --- a/src/Core/GSFile.php +++ b/src/Core/GSFile.php @@ -1,5 +1,7 @@ livesIncrementAndGet(); // We had this attachment, but not the file, thus no filename, update meta - if (is_null($attachment->getFilename())) { + if (\is_null($attachment->getFilename())) { $mimetype = $attachment->getMimetype(); $width = $attachment->getWidth(); $height = $attachment->getHeight(); @@ -152,7 +150,7 @@ class GSFile public: true, // contentDisposition: $disposition, autoEtag: true, - autoLastModified: true + autoLastModified: true, ); if (Common::config('site', 'x_static_delivery')) { // @codeCoverageIgnoreStart @@ -170,13 +168,10 @@ class GSFile /** * Throw a client exception if the cache key $id doesn't contain * exactly one entry - * - * @param mixed $except - * @param mixed $id */ public static function error($except, $id, array $res) { - switch (count($res)) { + switch (\count($res)) { case 0: throw new $except(); case 1: @@ -196,15 +191,21 @@ class GSFile */ public static function getFileInfo(int $id) { - return self::error(NoSuchFileException::class, + return self::error( + NoSuchFileException::class, $id, - Cache::get("file-info-{$id}", + Cache::get( + "file-info-{$id}", function () use ($id) { - return DB::dql('select at.filename, at.mimetype ' . - 'from App\\Entity\\Attachment at ' . - 'where at.id = :id', - ['id' => $id]); - })); + return DB::dql( + 'select at.filename, at.mimetype ' + . 'from App\\Entity\\Attachment at ' + . 'where at.id = :id', + ['id' => $id], + ); + }, + ), + ); } // ----- Attachment ------ @@ -217,7 +218,7 @@ class GSFile public static function getAttachmentFileInfo(int $id): array { $res = self::getFileInfo($id); - if (!is_null($res['filename'])) { + if (!\is_null($res['filename'])) { $res['filepath'] = Common::config('attachments', 'dir') . $res['filename']; } return $res; @@ -263,7 +264,7 @@ class GSFile * * @return null|string the most appropriate filename or null if we deem it imposible */ - public static function ensureFilenameWithProperExtension(string $title, string $mimetype, ?string $ext = null, bool $force = false): string | null + public static function ensureFilenameWithProperExtension(string $title, string $mimetype, ?string $ext = null, bool $force = false): string|null { $valid_extensions = MimeTypes::getDefault()->getExtensions($mimetype); @@ -272,16 +273,15 @@ class GSFile if ($pathinfo['extension'] ?? '' != '') { $title_without_extension = $pathinfo['filename']; $original_extension = $pathinfo['extension']; - if (empty(MimeTypes::getDefault()->getMimeTypes($original_extension)) || !in_array($original_extension, $valid_extensions)) { + if (empty(MimeTypes::getDefault()->getMimeTypes($original_extension)) || !\in_array($original_extension, $valid_extensions)) { unset($title_without_extension, $original_extension); } } $fallback = function ($title) use ($ext) { - if (!is_null($ext)) { + if (!\is_null($ext)) { return ($title) . ".{$ext}"; } - return null; }; if ($force) { diff --git a/src/Core/HTTPClient.php b/src/Core/HTTPClient.php index 869d9b4ade..09fb00218a 100644 --- a/src/Core/HTTPClient.php +++ b/src/Core/HTTPClient.php @@ -1,5 +1,7 @@ request(strtoupper($name), ...$args); + if (\in_array(mb_strtoupper($name), ['GET', 'HEAD', 'POST', 'PUT', 'DELETE', 'CONNECT', 'OPTIONS', 'TRACE', 'PATCH'])) { + return self::$client->request(mb_strtoupper($name), ...$args); } return self::$client->{$name}(...$args); } diff --git a/src/Core/I18n/I18n.php b/src/Core/I18n/I18n.php index 68ad66be3f..70d477d87a 100644 --- a/src/Core/I18n/I18n.php +++ b/src/Core/I18n/I18n.php @@ -1,5 +1,7 @@ $name) { - if (!defined($name)) { - define($name, $key); + if (!\defined($name)) { + \define($name, $key); } } @@ -71,11 +73,7 @@ abstract class I18n * Looks for which plugin we've been called from to get the gettext domain; * if not in a plugin subdirectory, we'll use the default 'core+intl-icu'. * - * @param string $path - * * @throws ServerException - * - * @return string */ public static function _mdomain(string $path): string { @@ -104,15 +102,18 @@ abstract class I18n * * @return string language code for best language match, false otherwise */ - public static function clientPreferredLanguage(string $http_accept_lang_header): string | bool + public static function clientPreferredLanguage(string $http_accept_lang_header): string|bool { $client_langs = []; $all_languages = self::getAllLanguages(); - preg_match_all('"(((\S\S)-?(\S\S)?)(;q=([0-9.]+))?)\s*(,\s*|$)"', - mb_strtolower($http_accept_lang_header), $http_langs); + preg_match_all( + '"(((\S\S)-?(\S\S)?)(;q=([0-9.]+))?)\s*(,\s*|$)"', + mb_strtolower($http_accept_lang_header), + $http_langs, + ); - for ($i = 0; $i < count($http_langs); ++$i) { + for ($i = 0; $i < \count($http_langs); ++$i) { if (!empty($http_langs[2][$i])) { // if no q default to 1.0 $client_langs[$http_langs[2][$i]] = ($http_langs[6][$i] ? (float) $http_langs[6][$i] : 1.0 - ($i * 0.01)); @@ -136,7 +137,7 @@ abstract class I18n /** * returns a simple code -> name mapping for languages * - * @return array map of available languages by code to language name. + * @return array map of available languages by code to language name */ public static function getNiceLanguageList(): array { @@ -253,11 +254,11 @@ abstract class I18n public static function formatICU(array $messages, array $params): string { $res = ''; - foreach (array_slice($params, 0, 1, true) as $var => $type) { - if (is_int($type)) { + foreach (\array_slice($params, 0, 1, true) as $var => $type) { + if (\is_int($type)) { $pref = '='; $op = 'plural'; - } elseif (is_string($type)) { + } elseif (\is_string($type)) { $pref = ''; $op = 'select'; } else { @@ -266,7 +267,7 @@ abstract class I18n $res = "{$var}, {$op}, "; $i = 0; - $cnt = count($messages) - 1; + $cnt = \count($messages) - 1; foreach ($messages as $val => $m) { if ($i !== $cnt) { $res .= "{$pref}{$val}"; @@ -274,9 +275,9 @@ abstract class I18n $res .= 'other'; } - if (is_array($m)) { - $res .= ' {' . self::formatICU($m, array_slice($params, 1, null, true)) . '} '; - } elseif (is_string($m)) { + if (\is_array($m)) { + $res .= ' {' . self::formatICU($m, \array_slice($params, 1, null, true)) . '} '; + } elseif (\is_string($m)) { $res .= " {{$m}} "; } else { throw new InvalidArgumentException('Invalid message array'); @@ -307,8 +308,6 @@ abstract class I18n * * @throws ServerException * - * @return string - * * @todo add parameters */ function _m(...$args): string @@ -316,26 +315,26 @@ function _m(...$args): string // Get the file where this function was called from, reducing the // memory and performance impact by not returning the arguments, // and only 2 frames (this and previous) - $domain = I18n::_mdomain(debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS, 2)[0]['file']); - switch (count($args)) { + $domain = I18n::_mdomain(debug_backtrace(\DEBUG_BACKTRACE_IGNORE_ARGS, 2)[0]['file']); + switch (\count($args)) { case 1: // Empty parameters, simple message return I18n::$translator->trans($args[0], [], $domain); case 3: // @codeCoverageIgnoreStart - if (is_int($args[2])) { - throw new InvalidArgumentException('Calling `_m()` with a number for pluralization is deprecated, ' . - 'use an explicit parameter'); + if (\is_int($args[2])) { + throw new InvalidArgumentException('Calling `_m()` with a number for pluralization is deprecated, ' + . 'use an explicit parameter', ); } // @codeCoverageIgnoreEnd // Falthrough // no break case 2: - if (is_array($args[0])) { + if (\is_array($args[0])) { $args[0] = I18n::formatICU($args[0], $args[1]); } - if (is_string($args[0])) { + if (\is_string($args[0])) { $msg = $args[0]; $params = $args[1] ?? []; return I18n::$translator->trans($msg, $params, $domain); diff --git a/src/Core/I18n/TransExtractor.php b/src/Core/I18n/TransExtractor.php index e855849dc7..f1d1f59a48 100644 --- a/src/Core/I18n/TransExtractor.php +++ b/src/Core/I18n/TransExtractor.php @@ -1,5 +1,7 @@ valid(); $tokenIterator->next()) { $t = $tokenIterator->current(); - if (T_WHITESPACE !== $t[0]) { + if (\T_WHITESPACE !== $t[0]) { break; } } } /** - * {@inheritdoc} + * {@inheritDoc} */ private function skipMethodArgument(Iterator $tokenIterator) { @@ -180,20 +173,16 @@ class TransExtractor extends AbstractFileExtractor implements ExtractorInterface /** * @throws InvalidArgumentException - * - * @return bool - * - * */ - protected function canBeExtracted(string $file) + protected function canBeExtracted(string $file): bool { return $this->isFile($file) - && 'php' === pathinfo($file, PATHINFO_EXTENSION) - && strstr($file, '/src/') !== false; + && 'php' === pathinfo($file, \PATHINFO_EXTENSION) + && mb_strstr($file, '/src/') !== false; } /** - * {@inheritdoc} + * {@inheritDoc} */ protected function extractFromDirectory($directory) { @@ -222,23 +211,23 @@ class TransExtractor extends AbstractFileExtractor implements ExtractorInterface } switch ($t[0]) { - case T_START_HEREDOC: + case \T_START_HEREDOC: $docToken = $t[1]; break; - case T_ENCAPSED_AND_WHITESPACE: - case T_CONSTANT_ENCAPSED_STRING: + case \T_ENCAPSED_AND_WHITESPACE: + case \T_CONSTANT_ENCAPSED_STRING: if ('' === $docToken) { $message .= PhpStringTokenParser::parse($t[1]); } else { $docPart = $t[1]; } break; - case T_END_HEREDOC: + case \T_END_HEREDOC: $message .= PhpStringTokenParser::parseDocString($docToken, $docPart); $docToken = ''; $docPart = ''; break; - case T_WHITESPACE: + case \T_WHITESPACE: break; default: break 2; @@ -272,7 +261,7 @@ class TransExtractor extends AbstractFileExtractor implements ExtractorInterface } elseif (self::MESSAGE_TOKEN === $item) { $message = $this->getValue($tokenIterator); - if (count($sequence) === ($sequenceKey + 1)) { + if (\count($sequence) === ($sequenceKey + 1)) { break; } } elseif (self::METHOD_ARGUMENTS_TOKEN === $item) { @@ -302,9 +291,13 @@ class TransExtractor extends AbstractFileExtractor implements ExtractorInterface /** * Store the $message in the message catalogue $mc */ - private function store(MessageCatalogue $mc, string $message, - string $domain, string $filename, ?int $line_no = null) - { + private function store( + MessageCatalogue $mc, + string $message, + string $domain, + string $filename, + ?int $line_no = null, + ) { $mc->set($message, $this->prefix . $message, $domain); $metadata = $mc->getMetadata($message, $domain) ?? []; $metadata['sources'][] = Formatting::normalizePath($filename) . (!empty($line_no) ? ":{$line_no}" : ''); @@ -324,7 +317,7 @@ class TransExtractor extends AbstractFileExtractor implements ExtractorInterface // Find FQCN of $class foreach ($classes as $c) { - if (strstr($c, $class) !== false) { + if (mb_strstr($c, $class) !== false) { $class = $c; break; } diff --git a/src/Core/Log.php b/src/Core/Log.php index 633a976d11..13feb8bd9d 100644 --- a/src/Core/Log.php +++ b/src/Core/Log.php @@ -1,5 +1,7 @@ {$name}(...$args); } else { // @codeCoverageIgnoreStart - return null; + return; // @codeCoverageIgnoreEnd } } diff --git a/src/Core/ModuleManager.php b/src/Core/ModuleManager.php index 496c2b46fa..cf24fec4d8 100644 --- a/src/Core/ModuleManager.php +++ b/src/Core/ModuleManager.php @@ -1,5 +1,7 @@ addPsr4("\\{$type}\\{$module}\\", dirname($path)); + [$type, $module] = preg_split('/\\\\/', $fqcn, 0, \PREG_SPLIT_NO_EMPTY); + self::$loader->addPsr4("\\{$type}\\{$module}\\", \dirname($path)); $id = Formatting::camelCaseToSnakeCase($type . '.' . $module); $obj = new $fqcn(); $this->modules[$id] = $obj; @@ -74,13 +79,16 @@ class ModuleManager public function preRegisterEvents() { foreach ($this->modules as $id => $obj) { - F\map(F\select(get_class_methods($obj), - F\ary(F\partial_right('App\Util\Formatting::startsWith', 'on'), 1)), - function (string $m) use ($obj) { - $ev = substr($m, 2); - $this->events[$ev] = $this->events[$ev] ?? []; - $this->events[$ev][] = [$obj, $m]; - } + F\map( + F\select( + get_class_methods($obj), + F\ary(F\partial_right('App\Util\Formatting::startsWith', 'on'), 1), + ), + function (string $m) use ($obj) { + $ev = mb_substr($m, 2); + $this->events[$ev] ??= []; + $this->events[$ev][] = [$obj, $m]; + }, ); } } @@ -95,27 +103,27 @@ class ModuleManager $entity_paths = []; foreach ($module_paths as $path) { $type = ucfirst(preg_replace('%' . INSTALLDIR . '/(component|plugin)s/.*%', '\1', $path)); - $dir = dirname($path); + $dir = \dirname($path); $module = basename($dir); // component or plugin $fqcn = "\\{$type}\\{$module}\\{$module}"; $module_manager->add($fqcn, $path); - if (!is_null($container) && file_exists($dir = $dir . '/Entity') && is_dir($dir)) { + if (!\is_null($container) && file_exists($dir = $dir . '/Entity') && is_dir($dir)) { // Happens at compile time, so it's hard to do integration testing. However, // everything would break if this did :') // @codeCoverageIgnoreStart $entity_paths[] = $dir; $container->findDefinition('doctrine.orm.default_metadata_driver')->addMethodCall( 'addDriver', - [new Reference('app.schemadef_driver'), "{$type}\\{$module}\\Entity"] + [new Reference('app.schemadef_driver'), "{$type}\\{$module}\\Entity"], ); // @codeCoverageIgnoreEnd } } - if (!is_null($container)) { + if (!\is_null($container)) { // @codeCoverageIgnoreStart $container->findDefinition('app.schemadef_driver') - ->addMethodCall('addPaths', ['$paths' => $entity_paths]); + ->addMethodCall('addPaths', ['$paths' => $entity_paths]); // @codeCoverageIgnoreEnd } @@ -126,8 +134,6 @@ class ModuleManager /** * Serialize this class, for dumping into the cache - * - * @param mixed $state */ public static function __set_state($state) { @@ -145,15 +151,15 @@ class ModuleManager { if ($_ENV['APP_ENV'] === 'prod' && !file_exists(MODULE_CACHE_FILE)) { // @codeCoverageIgnoreStart - throw new \Exception('The application needs to be compiled before using in production'); + throw new Exception('The application needs to be compiled before using in production'); // @codeCoverageIgnoreEnd } else { $rdi = new AppendIterator(); $rdi->append(new RecursiveIteratorIterator(new RecursiveDirectoryIterator(INSTALLDIR . '/components', FilesystemIterator::CURRENT_AS_FILEINFO | FilesystemIterator::SKIP_DOTS))); - $rdi->append(new RecursiveIteratorIterator(new RecursiveDirectoryIterator(INSTALLDIR . '/plugins', FilesystemIterator::CURRENT_AS_FILEINFO | FilesystemIterator::SKIP_DOTS))); + $rdi->append(new RecursiveIteratorIterator(new RecursiveDirectoryIterator(INSTALLDIR . '/plugins', FilesystemIterator::CURRENT_AS_FILEINFO | FilesystemIterator::SKIP_DOTS))); $time = file_exists(MODULE_CACHE_FILE) ? filemtime(MODULE_CACHE_FILE) : 0; - if ($_ENV['APP_ENV'] === 'test' || F\some($rdi, function ($e) use ($time) { return $e->getMTime() > $time; })) { + if ($_ENV['APP_ENV'] === 'test' || F\some($rdi, fn ($e) => $e->getMTime() > $time)) { Log::info('Rebuilding plugin cache at runtime. This means we can\'t update DB definitions'); self::process(); } @@ -195,9 +201,9 @@ class ModuleManager foreach ($modules as $mod) { $path = "{$mod}/config" . Kernel::CONFIG_EXTS; $loader->load($path, 'glob'); // Is supposed to, but doesn't return anything that would let us identify if loading worked - foreach (explode(',', substr(Kernel::CONFIG_EXTS, 2, -1)) as $ext) { + foreach (explode(',', mb_substr(Kernel::CONFIG_EXTS, 2, -1)) as $ext) { if (file_exists("{$mod}/config.{$ext}")) { - $parameters[basename(strtolower($mod))] = basename(dirname(strtolower($mod))); + $parameters[basename(mb_strtolower($mod))] = basename(\dirname(mb_strtolower($mod))); break; } } diff --git a/src/Core/Modules/Component.php b/src/Core/Modules/Component.php index b01fa319a0..f756b4dbdb 100644 --- a/src/Core/Modules/Component.php +++ b/src/Core/Modules/Component.php @@ -1,8 +1,10 @@ isVisibleTo($user)) { // ^ Ensure user isn't trying to trip us up - Log::warning('Suspicious activity: user ' . $user->getNickname() . - ' tried to interact with note ' . $note->getId() . - ', but they shouldn\'t have access to it'); + Log::warning('Suspicious activity: user ' . $user->getNickname() + . ' tried to interact with note ' . $note->getId() + . ', but they shouldn\'t have access to it', ); throw new NoSuchNoteException(); } else { if ($form->isValid()) { diff --git a/src/Core/Modules/Plugin.php b/src/Core/Modules/Plugin.php index 312ed0db2d..97ee018feb 100644 --- a/src/Core/Modules/Plugin.php +++ b/src/Core/Modules/Plugin.php @@ -1,5 +1,7 @@ rc->getIterator(); - $it->uasort(fn (Route $left, Route $right) => count($left->getDefaults()['accept']) <=> count($right->getDefaults()['accept'])); + $it->uasort(fn (Route $left, Route $right) => \count($left->getDefaults()['accept']) <=> \count($right->getDefaults()['accept'])); $this->rc = new RouteCollection(); foreach ($it as $id => $route) { $this->rc->add($id, $route); @@ -100,7 +100,8 @@ class RouteLoader extends Loader */ public function connect(string $id, string $uri_path, $target, ?array $options = [], ?array $param_reqs = []) { - $this->rc->add($id, + $this->rc->add( + $id, new Route( // path -- URI path path: $uri_path, @@ -108,7 +109,7 @@ class RouteLoader extends Loader // and special configuration options defaults: array_merge( [ - '_controller' => is_array($target) ? $target : [$target, '__invoke'], + '_controller' => \is_array($target) ? $target : [$target, '__invoke'], '_format' => $options['format'] ?? 'html', '_fragment' => $options['fragment'] ?? '', '_locale' => $options['locale'] ?? 'en', @@ -116,7 +117,7 @@ class RouteLoader extends Loader 'accept' => $options['accept'] ?? [], 'is_system_path' => $options['is_system_path'] ?? true, ], - $options['defaults'] ?? [] + $options['defaults'] ?? [], ), // requirements = [] -- param => regex requirements: $param_reqs, @@ -133,8 +134,8 @@ class RouteLoader extends Loader methods: $options['http-methods'] ?? $options['methods'] ?? [], // condition = '' -- Symfony condition expression, // see https://symfony.com/doc/current/routing.html#matching-expressions - condition: isset($options['accept']) ? "request.headers.get('Accept') in " . json_encode($options['accept']) : ($options['condition'] ?? '') - ) + condition: isset($options['accept']) ? "request.headers.get('Accept') in " . json_encode($options['accept']) : ($options['condition'] ?? ''), + ), ); } @@ -143,7 +144,6 @@ class RouteLoader extends Loader * Passed the arguments from the `RoutingConfigurator::import` call from * `config/routes.php` * - * @param mixed $resource * @codeCoverageIgnore */ public function supports($resource, ?string $type = null): bool diff --git a/src/Core/Router/Router.php b/src/Core/Router/Router.php index 0576924c7b..133af1ffaa 100644 --- a/src/Core/Router/Router.php +++ b/src/Core/Router/Router.php @@ -1,5 +1,7 @@ generate($id, $args, $type); } - /** function match($url) throws Symfony\Component\Routing\Exception\ResourceNotFoundException */ + /** + * function match($url) throws Symfony\Component\Routing\Exception\ResourceNotFoundException + */ public static function __callStatic(string $name, array $args) { return self::$router->{$name}(...$args); diff --git a/src/Core/Security.php b/src/Core/Security.php index a063a00f4e..fed24a9891 100644 --- a/src/Core/Security.php +++ b/src/Core/Security.php @@ -1,5 +1,7 @@ {$name}(...$args); } else { - throw new \BadMethodCallException("Method Security::{$name} doesn't exist"); + throw new BadMethodCallException("Method Security::{$name} doesn't exist"); } } } diff --git a/src/Core/UserRoles.php b/src/Core/UserRoles.php index 63067dbe7c..b1c1ea722b 100644 --- a/src/Core/UserRoles.php +++ b/src/Core/UserRoles.php @@ -1,5 +1,7 @@ write(file_get_contents($filepath)); - try { - GSFile::storeFileAsAttachment($file); - } catch (Exception $e) { - echo "Could not save file {$filepath}, failed with {$e}\n"; - } finally { - unset($file); - } - }); + F\map( + glob(INSTALLDIR . '/tests/sample-uploads/*'), + function (string $filepath) { + $file = new TemporaryFile(); + $file->write(file_get_contents($filepath)); + try { + GSFile::storeFileAsAttachment($file); + } catch (Exception $e) { + echo "Could not save file {$filepath}, failed with {$e}\n"; + } finally { + unset($file); + } + }, + ); $manager->flush(); } } diff --git a/src/DependencyInjection/Compiler/ModuleManagerPass.php b/src/DependencyInjection/Compiler/ModuleManagerPass.php index df3f77f68a..ba1be1082d 100644 --- a/src/DependencyInjection/Compiler/ModuleManagerPass.php +++ b/src/DependencyInjection/Compiler/ModuleManagerPass.php @@ -1,5 +1,7 @@ findDefinition('doctrine.orm.default_metadata_driver') - ->addMethodCall('addDriver', - [new Reference('app.schemadef_driver'), 'App\\Entity'] - ); + ->addMethodCall( + 'addDriver', + [new Reference('app.schemadef_driver'), 'App\\Entity'], + ); } /** @@ -87,11 +91,8 @@ class SchemaDefDriver extends StaticPHPDriver implements CompilerPassInterface /** * Fill in the database $metadata for $class_name - * - * @param string $class_name - * @param ClassMetadataInfo $metadata */ - public function loadMetadataForClass($class_name, $metadata) + public function loadMetadataForClass(string $class_name, ClassMetadataInfo $metadata) { $schema = $class_name::schemaDef(); @@ -105,7 +106,7 @@ class SchemaDefDriver extends StaticPHPDriver implements CompilerPassInterface foreach ($schema['fields'] as $name => $opts) { $unique = null; foreach ($schema['unique keys'] ?? [] as $key => $uniq_arr) { - if (in_array($name, $uniq_arr)) { + if (\in_array($name, $uniq_arr)) { $unique = $key; break; } @@ -116,7 +117,7 @@ class SchemaDefDriver extends StaticPHPDriver implements CompilerPassInterface // TODO: Get foreign keys working foreach (['target', 'multiplicity'] as $f) { if (!isset($opts[$f])) { - throw new \Exception("{$class_name}.{$name} doesn't have the required field `{$f}`"); + throw new Exception("{$class_name}.{$name} doesn't have the required field `{$f}`"); } } @@ -132,7 +133,7 @@ class SchemaDefDriver extends StaticPHPDriver implements CompilerPassInterface 'name' => $name, 'referencedColumnName' => $target_field, ]], - 'id' => in_array($name, $schema['primary key']), + 'id' => \in_array($name, $schema['primary key']), 'unique' => $unique, ]; @@ -151,7 +152,7 @@ class SchemaDefDriver extends StaticPHPDriver implements CompilerPassInterface $metadata->mapManyToMany($map); break; default: - throw new \Exception("Invalid multiplicity specified: '${opts['multiplicity']}' in class: {$class_name}"); + throw new Exception("Invalid multiplicity specified: '${opts['multiplicity']}' in class: {$class_name}"); } // @codeCoverageIgnoreEnd } else { @@ -163,7 +164,7 @@ class SchemaDefDriver extends StaticPHPDriver implements CompilerPassInterface $field = [ // boolean, optional - 'id' => in_array($name, $schema['primary key']), + 'id' => \in_array($name, $schema['primary key']), // string 'fieldName' => $name, // string @@ -207,22 +208,14 @@ class SchemaDefDriver extends StaticPHPDriver implements CompilerPassInterface * Override StaticPHPDriver's method, * we care about classes that have the method `schemaDef`, * instead of `loadMetadata`. - * - * @param string $class_name - * - * @return bool */ - public function isTransient($class_name) + public function isTransient(string $class_name): bool { return !method_exists($class_name, 'schemaDef'); } /** * Convert [$key => $val] to ['name' => $key, 'columns' => $val] - * - * @param array $arr - * - * @return array */ private static function kv_to_name_col(array $arr): array { diff --git a/src/Kernel.php b/src/Kernel.php index 1a14e014c6..6b3b56298f 100644 --- a/src/Kernel.php +++ b/src/Kernel.php @@ -1,5 +1,7 @@ getName(), DB::METHODS_ACCEPTING_TABLE_NAME); + return \in_array($methodReflection->getName(), DB::METHODS_ACCEPTING_TABLE_NAME); } /** @@ -37,9 +39,9 @@ class ClassFromTableNameDynamicStaticMethodReturnTypeExtension implements Dynami public function getTypeFromStaticMethodCall( MethodReflection $methodReflection, StaticCall $staticCall, - Scope $scope + Scope $scope, ): \PHPStan\Type\Type { - if (isset($_ENV['PHPSTAN_BOOT_KERNEL']) && count($staticCall->args) >= 1 && ($arg = $staticCall->args[0]->value) instanceof String_) { + if (isset($_ENV['PHPSTAN_BOOT_KERNEL']) && \count($staticCall->args) >= 1 && ($arg = $staticCall->args[0]->value) instanceof String_) { // If called with the first argument as a string, it's a table name return $scope->resolveTypeByName(new Name(DB::filterTableName($staticCall->name, [$arg->value]))); } else { diff --git a/src/PHPStan/GNUsocialProvider.php b/src/PHPStan/GNUsocialProvider.php index c9e0f7bda6..991842d857 100644 --- a/src/PHPStan/GNUsocialProvider.php +++ b/src/PHPStan/GNUsocialProvider.php @@ -1,11 +1,14 @@ kernel = require __DIR__ . '/../../config/phpstan-bootstrap.php'; $container = $this->kernel->getContainer()->get('test.service_container'); $services = F\map( - (new \ReflectionClass(GNUsocial::class))->getMethod('__construct')->getParameters(), - fn ($p) => $container->get((string) $p->getType()) + (new ReflectionClass(GNUsocial::class))->getMethod('__construct')->getParameters(), + fn ($p) => $container->get((string) $p->getType()), ); $this->gnu_social = new GNUsocial(...$services); $this->gnu_social->initialize(); diff --git a/src/Repository/ResetPasswordRequestRepository.php b/src/Repository/ResetPasswordRequestRepository.php index 9ac0925455..c55daa0a0d 100644 --- a/src/Repository/ResetPasswordRequestRepository.php +++ b/src/Repository/ResetPasswordRequestRepository.php @@ -1,8 +1,11 @@ connect('attachment_show', '/attachment/{id<\d+>}', [C\Attachment::class, 'attachment_show']); - $r->connect('attachment_view', '/attachment/{id<\d+>}/view', [C\Attachment::class, 'attachment_view']); - $r->connect('attachment_download', '/attachment/{id<\d+>}/download', [C\Attachment::class, 'attachment_download']); + $r->connect('attachment_show', '/attachment/{id<\d+>}', [C\Attachment::class, 'attachment_show']); + $r->connect('attachment_view', '/attachment/{id<\d+>}/view', [C\Attachment::class, 'attachment_view']); + $r->connect('attachment_download', '/attachment/{id<\d+>}/download', [C\Attachment::class, 'attachment_download']); $r->connect('attachment_thumbnail', '/attachment/{id<\d+>}/thumbnail/{size}', [C\Attachment::class, 'attachment_thumbnail']); } } diff --git a/src/Routes/Main.php b/src/Routes/Main.php index 95f4e19b1e..8490a10fbf 100644 --- a/src/Routes/Main.php +++ b/src/Routes/Main.php @@ -1,5 +1,7 @@ connect('note_view', '/object/note/{id<\d+>}', [C\Note::class, 'NoteShow']); diff --git a/src/Routes/Subscribers.php b/src/Routes/Subscribers.php index a3ee7f1dc0..6231e82de0 100644 --- a/src/Routes/Subscribers.php +++ b/src/Routes/Subscribers.php @@ -1,5 +1,7 @@ connect(id: 'actor_subscribers_id', uri_path: '/actor/{id<\d+>}/subscribers', target: [C\Subscribers::class, 'SubscribersByActorId']); diff --git a/src/Routes/Subscriptions.php b/src/Routes/Subscriptions.php index f73ff0a363..81ce493c24 100644 --- a/src/Routes/Subscriptions.php +++ b/src/Routes/Subscriptions.php @@ -1,5 +1,7 @@ connect(id: 'actor_subscriptions_id', uri_path: '/actor/{id<\d+>}/subscriptions', target: [C\Subscriptions::class, 'SubscriptionsByActorId']); diff --git a/src/Security/Authenticator.php b/src/Security/Authenticator.php index ffcad46e24..8e8fe5aa60 100644 --- a/src/Security/Authenticator.php +++ b/src/Security/Authenticator.php @@ -1,5 +1,7 @@ getNickname(); } catch (Exception) { throw new CustomUserMessageAuthenticationException( - _m('Invalid login credentials.')); + _m('Invalid login credentials.'), + ); } return $user; } - /** - * @param LocalUser $user - * @param mixed $credentials - */ - public function checkCredentials($credentials, $user) + public function checkCredentials($credentials, LocalUser $user) { if (!$user->checkPassword($credentials['password'])) { throw new CustomUserMessageAuthenticationException(_m('Invalid login credentials.')); diff --git a/src/Security/EmailVerifier.php b/src/Security/EmailVerifier.php index d453870662..d566bff62f 100644 --- a/src/Security/EmailVerifier.php +++ b/src/Security/EmailVerifier.php @@ -1,5 +1,7 @@ from(new Address(Common::config('site', 'email'), Common::config('site', 'nickname'))) - ->to($user->getOutgoingEmail()) - ->subject(_m('Please Confirm your Email')) - ->htmlTemplate('security/confirmation_email.html.twig'); + ->from(new Address(Common::config('site', 'email'), Common::config('site', 'nickname'))) + ->to($user->getOutgoingEmail()) + ->subject(_m('Please Confirm your Email')) + ->htmlTemplate('security/confirmation_email.html.twig'); $signatureComponents = self::$verify_email_helper->generateSignature( 'verify_email', $user->getId(), - $user->getOutgoingEmail() + $user->getOutgoingEmail(), ); $context = $email->getContext(); @@ -86,19 +88,19 @@ abstract class EmailVerifier $user = DB::findOneBy('local_user', ['outgoing_email' => $emailFormData]); $reset_token = self::$reset_password_helper->generateResetToken($user); // Found a user - } catch (NotFoundException | ResetPasswordExceptionInterface) { + } catch (NotFoundException|ResetPasswordExceptionInterface) { // Not found, do not reveal whether a user account was found or not. throw new RedirectException('check_email'); } $email = (new TemplatedEmail()) - ->from(new Address('foo@email.com', 'FOO NAME')) - ->to($user->getOutgoingEmail()) - ->subject('Your password reset request') - ->htmlTemplate('reset_password/email.html.twig') - ->context([ - 'resetToken' => $reset_token, - ]); + ->from(new Address('foo@email.com', 'FOO NAME')) + ->to($user->getOutgoingEmail()) + ->subject('Your password reset request') + ->htmlTemplate('reset_password/email.html.twig') + ->context([ + 'resetToken' => $reset_token, + ]); self::send($email); diff --git a/src/Twig/Extension.php b/src/Twig/Extension.php index d6376a1397..4c7c0b2331 100644 --- a/src/Twig/Extension.php +++ b/src/Twig/Extension.php @@ -1,5 +1,7 @@ */ - public function embedSvgIcon(Environment $twig, string $icon_name = '', string $icon_css_class = '') + public function embedSvgIcon(Environment $twig, string $icon_name = '', string $icon_css_class = ''): string { return $twig->render('@public_path/assets/icons/' . $icon_name . '.svg.twig', ['iconClass' => $icon_css_class]); } diff --git a/src/Util/Bitmap.php b/src/Util/Bitmap.php index 3cf2523b7f..057e980d31 100644 --- a/src/Util/Bitmap.php +++ b/src/Util/Bitmap.php @@ -1,5 +1,7 @@ getConstants(); + $consts = (new ReflectionClass($class))->getConstants(); $have_prefix = false; if (isset($consts['PREFIX'])) { $have_prefix = true; @@ -51,7 +54,7 @@ abstract class Bitmap foreach ($consts as $c => $v) { $b = ($r & $v) !== 0; if ($instance) { - $c = strtolower($c); + $c = mb_strtolower($c); $obj->{$c} = $b; } if ($b) { diff --git a/src/Util/Common.php b/src/Util/Common.php index ebf60b21d0..6c378639d1 100644 --- a/src/Util/Common.php +++ b/src/Util/Common.php @@ -1,5 +1,7 @@ attributes->get('_route'); } - public static function isRoute(string | array $routes) + public static function isRoute(string|array $routes) { - return in_array(self::route(), is_array($routes) ? $routes : [$routes]); + return \in_array(self::route(), \is_array($routes) ? $routes : [$routes]); } /** @@ -94,8 +96,6 @@ abstract class Common /** * Set sysadmin's configuration preferences for GNU social - * - * @param mixed $value */ public static function setConfig(string $section, string $setting, $value): void { @@ -152,7 +152,7 @@ abstract class Common */ public static function isLoggedIn(): bool { - return self::user() != null; + return self::user() != null; } /** @@ -172,18 +172,15 @@ abstract class Common /** * A recursive `array_diff`, while PHP itself doesn't provide one - * - * @param mixed $array1 - * @param mixed $array2 */ public static function arrayDiffRecursive($array1, $array2): array { $diff = []; foreach ($array1 as $key => $value) { - if (array_key_exists($key, $array2)) { - if (is_array($value)) { + if (\array_key_exists($key, $array2)) { + if (\is_array($value)) { $recursive_diff = static::arrayDiffRecursive($value, $array2[$key]); - if (count($recursive_diff)) { + if (\count($recursive_diff)) { $diff[$key] = $recursive_diff; } } else { @@ -203,7 +200,7 @@ abstract class Common */ public static function arrayRemoveKeys(array $from, array $keys, bool $strict = false) { - return F\filter($from, function ($_, $key) use ($keys, $strict) { return !in_array($key, $keys, $strict); }); + return F\filter($from, fn ($_, $key) => !\in_array($key, $keys, $strict)); } /** @@ -222,9 +219,9 @@ abstract class Common $size = '3M'; } - $suffix = substr($size, -1); - $size = (int) substr($size, 0, -1); - switch (strtoupper($suffix)) { + $suffix = mb_substr($size, -1); + $size = (int) mb_substr($size, 0, -1); + switch (mb_strtoupper($suffix)) { case 'P': $size *= 1024; // no break @@ -250,15 +247,13 @@ abstract class Common /** * Uses `size_str_to_int()` to find the smallest value for uploads in php.ini - * - * @return int */ public static function getPreferredPhpUploadLimit(): int { return min( self::sizeStrToInt(ini_get('post_max_size')), self::sizeStrToInt(ini_get('upload_max_filesize')), - self::sizeStrToInt(ini_get('memory_limit')) + self::sizeStrToInt(ini_get('memory_limit')), ); } @@ -267,7 +262,7 @@ abstract class Common * * @return float|int clamped value */ - public static function clamp(int | float $value, int | float $min, int | float $max): int | float + public static function clamp(int|float $value, int|float $min, int|float $max): int|float { return min(max($value, $min), $max); } @@ -283,8 +278,8 @@ abstract class Common // (if false, we use '?' in 'https?' to say the 's' is optional) $regex = $ensure_secure ? '/^https$/' : '/^https?$/'; - return filter_var($url, FILTER_VALIDATE_URL) - && preg_match($regex, parse_url($url, PHP_URL_SCHEME)); + return filter_var($url, \FILTER_VALIDATE_URL) + && preg_match($regex, parse_url($url, \PHP_URL_SCHEME)); } /** diff --git a/src/Util/Exception/AuthenticationException.php b/src/Util/Exception/AuthenticationException.php index 7fa36c2525..3943a6feae 100644 --- a/src/Util/Exception/AuthenticationException.php +++ b/src/Util/Exception/AuthenticationException.php @@ -1,5 +1,7 @@ defaultMessage(); diff --git a/src/Util/Exception/EmailNotFoundException.php b/src/Util/Exception/EmailNotFoundException.php index 2c97eced6e..f054e7f52c 100644 --- a/src/Util/Exception/EmailNotFoundException.php +++ b/src/Util/Exception/EmailNotFoundException.php @@ -1,7 +1,10 @@ defaultMessage(); diff --git a/src/Util/Exception/NicknameInvalidException.php b/src/Util/Exception/NicknameInvalidException.php index f30b654efb..c3412bcacc 100644 --- a/src/Util/Exception/NicknameInvalidException.php +++ b/src/Util/Exception/NicknameInvalidException.php @@ -1,5 +1,7 @@ getNickname(); }, - $a) + return parent::transform( + array_map( + fn ($actor) => $actor->getNickname(), + $a, + ), ); } /** * Transforms string of nicknames into Actors - * - * @param string $s - * - * @return array */ - public function reverseTransform($s) + public function reverseTransform(string $s): array { return array_map( - function ($nickmame) { return Actor::getFromNickname($nickmame); }, - parent::reverseTransform($s) + fn ($nickmame) => Actor::getFromNickname($nickmame), + parent::reverseTransform($s), ); } } diff --git a/src/Util/Form/ArrayTransformer.php b/src/Util/Form/ArrayTransformer.php index 4e4a6c5325..a5b0b3b592 100644 --- a/src/Util/Form/ArrayTransformer.php +++ b/src/Util/Form/ArrayTransformer.php @@ -1,5 +1,7 @@ [ 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')]), ]), + 'max' => Common::config('password', 'max_length'), 'maxMessage' => _m(['Your password should be at most # characters'], ['count' => Common::config('password', 'max_length')]), ]), ], 'help' => _m('Write a password with at least {min_length} characters, and a maximum of {max_length}.', ['min_length' => Common::config('password', 'min_length'), 'max_length' => Common::config('password', 'max_length')]), ], @@ -55,7 +57,7 @@ abstract class FormFields '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')]), ]), + 'max' => Common::config('password', 'max_length'), 'maxMessage' => _m(['Your password should be at most # characters'], ['count' => Common::config('password', 'max_length')]), ]), ], ], ]; } diff --git a/src/Util/Formatting.php b/src/Util/Formatting.php index 5bbd9d4d98..7ce3c4b813 100644 --- a/src/Util/Formatting.php +++ b/src/Util/Formatting.php @@ -1,5 +1,7 @@ str_starts_with($haystack, $n)); + if (\is_string($haystack)) { + return F\some(\is_array($needle) ? $needle : [$needle], fn ($n) => str_starts_with($haystack, $n)); } else { return F\every($haystack, fn ($haystack) => self::startsWith($haystack, $needle)); } @@ -121,13 +114,11 @@ abstract class Formatting * * @param array|string $haystack if array, check that all strings end with $needle (see below) * @param array|string $needle if array, check that one of the $needles is found - * - * @return bool */ public static function endsWith(array|string $haystack, array|string $needle): bool { - if (is_string($haystack)) { - return F\some(is_array($needle) ? $needle : [$needle], fn ($n) => str_ends_with($haystack, $n)); + if (\is_string($haystack)) { + return F\some(\is_array($needle) ? $needle : [$needle], fn ($n) => str_ends_with($haystack, $n)); } else { return F\every($haystack, fn ($haystack) => self::endsWith($haystack, $needle)); } @@ -138,7 +129,7 @@ abstract class Formatting */ public static function removePrefix(string $haystack, string $needle) { - return self::startsWith($haystack, $needle) ? substr($haystack, strlen($needle)) : $haystack; + return self::startsWith($haystack, $needle) ? mb_substr($haystack, mb_strlen($needle)) : $haystack; } /** @@ -146,12 +137,12 @@ abstract class Formatting */ public static function removeSuffix(string $haystack, string $needle) { - return self::endsWith($haystack, $needle) && !empty($needle) ? substr($haystack, 0, -strlen($needle)) : $haystack; + return self::endsWith($haystack, $needle) && !empty($needle) ? mb_substr($haystack, 0, -mb_strlen($needle)) : $haystack; } public static function camelCaseToSnakeCase(string $str): string { - return strtolower(preg_replace('/([a-z])([A-Z])/', '$1_$2', $str)); + return mb_strtolower(preg_replace('/([a-z])([A-Z])/', '$1_$2', $str)); } public static function snakeCaseToCamelCase(string $str): string @@ -165,43 +156,39 @@ abstract class Formatting * @param array|string $in * @param int $level How many levels of indentation * @param int $count How many spaces per indentation - * - * @return string */ public static function indent($in, int $level = 1, int $count = 2): string { - if (is_string($in)) { + if (\is_string($in)) { return self::indent(explode("\n", $in), $level, $count); - } elseif (is_array($in)) { + } elseif (\is_array($in)) { $indent = str_repeat(' ', $count * $level); - return implode("\n", F\map(F\select($in, - F\ary(function ($s) { - return $s != ''; - }, 1)), - function ($val) use ($indent) { - return F\concat($indent . $val); - })); + return implode("\n", F\map( + F\select( + $in, + F\ary(fn ($s) => $s != '', 1), + ), + fn ($val) => F\concat($indent . $val), + )); } throw new InvalidArgumentException('Formatting::indent\'s first parameter must be either an array or a string. Input was: ' . $in); } - const SPLIT_BY_SPACE = ' '; - const JOIN_BY_SPACE = ' '; - const SPLIT_BY_COMMA = ', '; - const JOIN_BY_COMMA = ', '; - const SPLIT_BY_BOTH = '/[, ]/'; + public const SPLIT_BY_SPACE = ' '; + public const JOIN_BY_SPACE = ' '; + public const SPLIT_BY_COMMA = ', '; + public const JOIN_BY_COMMA = ', '; + public const SPLIT_BY_BOTH = '/[, ]/'; /** * Convert scalars, objects implementing __toString or arrays to strings - * - * @param mixed $value */ public static function toString($value, string $join_type = self::JOIN_BY_COMMA): string { - if (!in_array($join_type, [static::JOIN_BY_SPACE, static::JOIN_BY_COMMA])) { - throw new \Exception('Formatting::toString received invalid join option'); + if (!\in_array($join_type, [static::JOIN_BY_SPACE, static::JOIN_BY_COMMA])) { + throw new Exception('Formatting::toString received invalid join option'); } else { - if (!is_array($value)) { + if (!\is_array($value)) { return (string) $value; } else { return implode($join_type, $value); @@ -211,13 +198,11 @@ abstract class Formatting /** * Convert a user supplied string to array and return whether the conversion was successfull - * - * @param mixed $output */ public static function toArray(string $input, &$output, string $split_type = self::SPLIT_BY_COMMA): bool { - if (!in_array($split_type, [static::SPLIT_BY_SPACE, static::SPLIT_BY_COMMA, static::SPLIT_BY_BOTH])) { - throw new \Exception('Formatting::toArray received invalid split option'); + if (!\in_array($split_type, [static::SPLIT_BY_SPACE, static::SPLIT_BY_COMMA, static::SPLIT_BY_BOTH])) { + throw new Exception('Formatting::toArray received invalid split option'); } if ($input == '') { $output = []; @@ -227,7 +212,7 @@ abstract class Formatting if (preg_match('/^ *\[?([^,]+(, ?[^,]+)*)\]? *$/', $input, $matches)) { switch ($split_type) { case self::SPLIT_BY_BOTH: - $arr = preg_split($split_type, $matches[1], 0, PREG_SPLIT_NO_EMPTY); + $arr = preg_split($split_type, $matches[1], 0, \PREG_SPLIT_NO_EMPTY); break; case self::SPLIT_BY_COMMA: $arr = preg_split('/, ?/', $matches[1]); @@ -250,14 +235,12 @@ abstract class Formatting $text = self::quoteAndRemoveControlCodes($text); // Split \n\n into paragraphs, process each paragrah and merge - $text = implode("\n", F\map(explode("\n\n", $text), function (string $paragraph) { + return implode("\n", F\map(explode("\n\n", $text), function (string $paragraph) { $paragraph = nl2br($paragraph, use_xhtml: false); Event::handle('RenderContent', [&$paragraph]); return HTML::html(['p' => [$paragraph]], options: ['raw' => true, 'indent' => false]); })); - - return $text; } /** @@ -268,7 +251,7 @@ abstract class Formatting public static function quoteAndRemoveControlCodes(string $text): string { // Quote special chars - $text = htmlspecialchars($text, flags: ENT_QUOTES | ENT_SUBSTITUTE, double_encode: false); + $text = htmlspecialchars($text, flags: \ENT_QUOTES | \ENT_SUBSTITUTE, double_encode: false); // Normalize newlines to strictly \n and remove ASCII control codes return preg_replace(['/[\x{0}-\x{8}\x{b}-\x{c}\x{e}-\x{19}\x{200b}-\x{200f}\x{202a}-\x{202e}]/u', '/\R/u'], ['', "\n"], $text); } @@ -279,21 +262,20 @@ abstract class Formatting public static function slugify(string $str, int $length = 64): string { // php-intl is highly recommended... - if (!function_exists('transliterator_transliterate')) { + if (!\function_exists('transliterator_transliterate')) { $str = preg_replace('/[^\pL\pN]/u', '', $str); - $str = mb_convert_case($str, MB_CASE_LOWER, 'UTF-8'); - $str = substr($str, 0, $length); - return $str; + $str = mb_convert_case($str, \MB_CASE_LOWER, 'UTF-8'); + return mb_substr($str, 0, $length); } - $str = transliterator_transliterate('Any-Latin;' . // any charset to latin compatible - 'NFD;' . // decompose - '[:Nonspacing Mark:] Remove;' . // remove nonspacing marks (accents etc.) - 'NFC;' . // composite again - '[:Punctuation:] Remove;' . // remove punctuation (.,¿? etc.) - 'Lower();' . // turn into lowercase - 'Latin-ASCII;', // get ASCII equivalents (ð to d for example) - $str); - return substr(preg_replace('/[^\pL\pN]/u', '', $str), 0, $length); + $str = transliterator_transliterate('Any-Latin;' // any charset to latin compatible + . 'NFD;' // decompose + . '[:Nonspacing Mark:] Remove;' // remove nonspacing marks (accents etc.) + . 'NFC;' // composite again + . '[:Punctuation:] Remove;' // remove punctuation (.,¿? etc.) + . 'Lower();' // turn into lowercase + . 'Latin-ASCII;', // get ASCII equivalents (ð to d for example) + $str, ); + return mb_substr(preg_replace('/[^\pL\pN]/u', '', $str), 0, $length); } /** @@ -304,14 +286,10 @@ abstract class Formatting * Note the return data format is internal, to be used for building links and * such. Should not be used directly; rather, call common_linkify_mentions(). * - * @param string $text - * @param Actor $actor the Actor that is sending the current text - * @param Note $parent the Note this text is in reply to, if any - * - * @return array - * + * @param Actor $actor the Actor that is sending the current text + * @param Note $parent the Note this text is in reply to, if any */ - public static function findMentions(string $text, Actor $actor, Note $parent = null) + public static function findMentions(string $text, Actor $actor, ?Note $parent = null): array { $mentions = []; if (Event::handle('StartFindMentions', [$actor, $text, &$mentions])) { @@ -440,7 +418,6 @@ abstract class Formatting * Does the actual regex pulls to find @-mentions in text. * Should generally not be called directly; for use in common_find_mentions. * - * @param string $text * @param string $preMention Character(s) that signals a mention ('@', '!'...) * * @return array of PCRE match arrays @@ -452,7 +429,7 @@ abstract class Formatting '/^T (' . Nickname::DISPLAY_FMT . ') /', $text, $tmatches, - PREG_OFFSET_CAPTURE + \PREG_OFFSET_CAPTURE, ); $atmatches = []; @@ -461,11 +438,10 @@ abstract class Formatting '/' . Nickname::BEFORE_MENTIONS . preg_quote($preMention, '/') . '(' . Nickname::DISPLAY_FMT . ')\b(?!\@)/', $text, $atmatches, - PREG_OFFSET_CAPTURE + \PREG_OFFSET_CAPTURE, ); - $matches = array_merge($tmatches[1], $atmatches[1]); - return $matches; + return array_merge($tmatches[1], $atmatches[1]); } /** @@ -480,7 +456,7 @@ abstract class Formatting * * @return string partially-rendered HTML */ - public static function linkifyMentions($text, Actor $author, ?Note $parent = null) + public static function linkifyMentions(string $text, Actor $author, ?Note $parent = null): string { $mentions = self::findMentions($text, $author, $parent); diff --git a/src/Util/GNUsocialTestCase.php b/src/Util/GNUsocialTestCase.php index b76d418d84..05e70f9fa5 100644 --- a/src/Util/GNUsocialTestCase.php +++ b/src/Util/GNUsocialTestCase.php @@ -1,5 +1,7 @@ getContainer()->get('test.service_container'); $services = F\map( - (new \ReflectionClass(GNUsocial::class))->getMethod('__construct')->getParameters(), - function ($p) use ($container) { return $container->get((string) $p->getType()); } + (new ReflectionClass(GNUsocial::class))->getMethod('__construct')->getParameters(), + fn ($p) => $container->get((string) $p->getType()), ); self::$social = new GNUsocial(...$services); return $kernel; diff --git a/src/Util/HTML.php b/src/Util/HTML.php index 1c0f773703..c9b6d4c4a4 100644 --- a/src/Util/HTML.php +++ b/src/Util/HTML.php @@ -1,5 +1,7 @@ '; } else { @@ -67,44 +70,41 @@ abstract class HTML /** * Attribute with given optional value - * - * @param array $attrs - * @param array $options=[] ['forbidden_attributes' => string[]] - * - * @return string */ private static function attr(array $attrs, array $options = []): string { - return ' ' . implode(' ', - F\map($attrs, + return ' ' . implode( + ' ', + F\map( + $attrs, /** * Convert an attr ($key), $val pair to an HTML attribute, but validate to exclude some vectors of injection */ function (string $val, string $key, array $_): string { - if (in_array($key, array_merge($options['forbidden_attributes'] ?? [], self::FORBIDDEN_ATTRIBUTES)) + if (\in_array($key, array_merge($options['forbidden_attributes'] ?? [], self::FORBIDDEN_ATTRIBUTES)) || str_starts_with($val, 'javascript:')) { - throw new \InvalidArgumentException("HTML::html: Attribute {$key} is not allowed"); + throw new InvalidArgumentException("HTML::html: Attribute {$key} is not allowed"); } if (!($options['raw'] ?? false)) { - $val = htmlspecialchars($val, flags: ENT_QUOTES | ENT_SUBSTITUTE, double_encode: false); + $val = htmlspecialchars($val, flags: \ENT_QUOTES | \ENT_SUBSTITUTE, double_encode: false); } return "{$key}=\"{$val}\""; - })); + }, + ), + ); } /** * @param array|string $html The input to convert to HTML * @param array $options = [] ['allowed_tags' => string[], 'forbidden_attributes' => string[], 'raw' => bool, 'indent' => bool] - * - * @return string */ public static function html(string|array $html, array $options = [], int $indent = 1): string { - if (is_string($html)) { + if (\is_string($html)) { if ($options['raw'] ?? false) { return $html; } else { - return htmlspecialchars($html, flags: ENT_QUOTES | ENT_SUBSTITUTE, double_encode: false); + return htmlspecialchars($html, flags: \ENT_QUOTES | \ENT_SUBSTITUTE, double_encode: false); } } else { $out = ''; @@ -116,8 +116,8 @@ abstract class HTML $is_tag = preg_match('/[A-Za-z][A-Za-z0-9]*/', $tag); $inner = self::html($contents, $options, $indent + 1); if ($is_tag) { - if (!in_array($tag, array_merge($options['allowed_tags'] ?? [], self::ALLOWED_TAGS))) { - throw new \InvalidArgumentException("HTML::html: Tag {$tag} is not allowed"); + if (!\in_array($tag, array_merge($options['allowed_tags'] ?? [], self::ALLOWED_TAGS))) { + throw new InvalidArgumentException("HTML::html: Tag {$tag} is not allowed"); } if (!empty($inner)) { $inner = ($options['indent'] ?? true) ? ("\n" . Formatting::indent($inner, $indent) . "\n") : $inner; diff --git a/src/Util/Nickname.php b/src/Util/Nickname.php index 68d3300c98..ae587534dd 100644 --- a/src/Util/Nickname.php +++ b/src/Util/Nickname.php @@ -1,5 +1,7 @@ $this->getName()]); default: - throw new \InvalidArgumentException('Given an invalid Notification constant value'); + throw new InvalidArgumentException('Given an invalid Notification constant value'); } } @@ -98,7 +101,7 @@ abstract class AbstractTransport case Notification::DM: return _m('Notify of new DMs'); default: - throw new \InvalidArgumentException('Given an invalid Notification constant value'); + throw new InvalidArgumentException('Given an invalid Notification constant value'); } } } diff --git a/src/Util/Notification/Notification.php b/src/Util/Notification/Notification.php index 9fbdbba998..81930142a2 100644 --- a/src/Util/Notification/Notification.php +++ b/src/Util/Notification/Notification.php @@ -1,5 +1,7 @@ resource)) { + if (!\is_null($this->resource)) { return fwrite($this->resource, $data); } else { // @codeCoverageIgnoreStart @@ -103,12 +107,12 @@ class TemporaryFile extends \SplFileInfo /** * Closes the file descriptor if opened. * - * @return bool true on success or false on failure. + * @return bool true on success or false on failure */ protected function close(): bool { $ret = true; - if (!is_null($this->resource) && $this->resource !== false) { + if (!\is_null($this->resource) && $this->resource !== false) { $ret = fclose($this->resource); } if ($ret) { @@ -119,8 +123,6 @@ class TemporaryFile extends \SplFileInfo /** * Closes the file descriptor and removes the temporary file. - * - * @return void */ protected function cleanup(): void { @@ -153,8 +155,6 @@ class TemporaryFile extends \SplFileInfo * @param int $filemode New file permissions (in octal mode) * * @throws TemporaryFileException - * - * @return void */ public function move(string $directory, string $filename, int $dirmode = 0755, int $filemode = 0644): void { @@ -170,7 +170,7 @@ class TemporaryFile extends \SplFileInfo // @codeCoverageIgnoreEnd } - $destpath = rtrim($directory, '/\\') . DIRECTORY_SEPARATOR . $this->getName($filename); + $destpath = rtrim($directory, '/\\') . \DIRECTORY_SEPARATOR . $this->getName($filename); $this->commit($destpath, $dirmode, $filemode); } @@ -184,8 +184,6 @@ class TemporaryFile extends \SplFileInfo * @param int $filemode New file permissions (in octal mode) * * @throws TemporaryFileException - * - * @return void */ public function commit(string $destpath, int $dirmode = 0755, int $filemode = 0644): void { @@ -232,11 +230,11 @@ class TemporaryFile extends \SplFileInfo * * @see MimeTypes */ - public function getMimeType() + public function getMimeType(): ?string { // @codeCoverageIgnoreStart if (!class_exists(MimeTypes::class)) { - throw new \LogicException('You cannot guess the mime type as the Mime component is not installed. Try running "composer require symfony/mime".'); + throw new LogicException('You cannot guess the mime type as the Mime component is not installed. Try running "composer require symfony/mime".'); } // @codeCoverageIgnoreEnd @@ -246,15 +244,11 @@ class TemporaryFile extends \SplFileInfo /** * This function is a copy of Symfony\Component\HttpFoundation\File\File->getName() * Returns locale independent base name of the given path. - * - * @return string */ - protected function getName(string $name) + protected function getName(string $name): string { $originalName = str_replace('\\', '/', $name); - $pos = strrpos($originalName, '/'); - $originalName = false === $pos ? $originalName : substr($originalName, $pos + 1); - - return $originalName; + $pos = mb_strrpos($originalName, '/'); + return false === $pos ? $originalName : mb_substr($originalName, $pos + 1); } } diff --git a/tests/Controller/AdminTest.php b/tests/Controller/AdminTest.php index 3a826233ac..39d9e2d040 100644 --- a/tests/Controller/AdminTest.php +++ b/tests/Controller/AdminTest.php @@ -1,5 +1,7 @@ test(['attachments', 'dir'], fn () => Common::config('storage', 'dir') . 'foo' . DIRECTORY_SEPARATOR); + $this->test(['attachments', 'dir'], fn () => Common::config('storage', 'dir') . 'foo' . \DIRECTORY_SEPARATOR); } public function testSiteInt() @@ -81,10 +84,12 @@ class AdminTest extends GNUsocialTestCase { $client = static::createClient(); $client->request('GET', '/panel'); - $this->assertThrows(\InvalidArgumentException::class, - fn () => $client->submitForm('Set site setting', [ - 'save_admin[setting]' => 'invalid:section', - 'save_admin[value]' => 'false', - ])); + $this->assertThrows( + InvalidArgumentException::class, + fn () => $client->submitForm('Set site setting', [ + 'save_admin[setting]' => 'invalid:section', + 'save_admin[value]' => 'false', + ]), + ); } } diff --git a/tests/Controller/AttachmentTest.php b/tests/Controller/AttachmentTest.php index 60d528249f..75069da19e 100644 --- a/tests/Controller/AttachmentTest.php +++ b/tests/Controller/AttachmentTest.php @@ -1,5 +1,7 @@ createMock(Request::class); @@ -78,11 +80,11 @@ class NetworkTest extends GNUsocialTestCase $result = $network->{$route}($req, ...$extra_args); static::assertSame($result['_template'], 'network/public.html.twig'); foreach ($result['notes'] as $n) { - static::assertTrue(is_array($n['replies'])); + static::assertIsArray($n['replies']); } $notes = Common::flattenNoteArray($result['notes']); foreach ($notes as $n) { - static::assertTrue(get_class($n) == Note::class); + static::assertTrue(\get_class($n) == Note::class); $vis = VisibilityScope::create($n->getScope()); static::assertTrue($visibility($vis)); } diff --git a/tests/Controller/SecurityTest.php b/tests/Controller/SecurityTest.php index b5d4b2be22..a7e3d3ac6b 100644 --- a/tests/Controller/SecurityTest.php +++ b/tests/Controller/SecurityTest.php @@ -1,5 +1,7 @@ createMock(ContainerBagInterface::class); static::assertTrue($cb instanceof ContainerBagInterface); $cb->method('get') - ->willReturnMap([['gnusocial', $conf], ['gnusocial_defaults', $conf]]); + ->willReturnMap([['gnusocial', $conf], ['gnusocial_defaults', $conf]]); Common::setupConfig($cb); if ($throws != null) { @@ -46,7 +49,7 @@ class CacheTest extends KernelTestCase Cache::setupCache(); - $reflector = new \ReflectionClass('App\Core\Cache'); + $reflector = new ReflectionClass('App\Core\Cache'); $pools = $reflector->getStaticPropertyValue('pools'); foreach ($result_pool as $name => $type) { static::assertInstanceOf($type, $pools[$name]); @@ -87,19 +90,19 @@ class CacheTest extends KernelTestCase // Need a connection to run the tests self::doTest(['default' => 'redis://redis'], ['default' => \Symfony\Component\Cache\Adapter\RedisAdapter::class]); - static::assertSame('value', Cache::get('test', function ($i) { return 'value'; })); + static::assertSame('value', Cache::get('test', fn ($i) => 'value')); Cache::set('test', 'other_value'); - static::assertSame('other_value', Cache::get('test', function ($i) { return 'value'; })); + static::assertSame('other_value', Cache::get('test', fn ($i) => 'value')); static::assertTrue(Cache::delete('test')); } - private function _testRedis($recompute = INF) + private function _testRedis($recompute = \INF) { self::doTest(['default' => 'redis://redis'], ['default' => \Symfony\Component\Cache\Adapter\RedisAdapter::class], throws: null, recompute: $recompute); // Redis supports lists directly, uses different implementation $key = 'test' . time(); - static::assertSame(['foo', 'bar'], Cache::getList($key, function ($i) { return ['foo', 'bar']; })); + static::assertSame(['foo', 'bar'], Cache::getList($key, fn ($i) => ['foo', 'bar'])); Cache::pushList($key, 'quux'); static::assertSame(['foo', 'bar', 'quux'], Cache::getList($key, function ($i) { $this->assertFalse('should not be called'); })); Cache::pushList($key, 'foobar', pool: 'default', max_count: 2); diff --git a/tests/Core/ControllerTest.php b/tests/Core/ControllerTest.php index dea95208d4..33112ab51e 100644 --- a/tests/Core/ControllerTest.php +++ b/tests/Core/ControllerTest.php @@ -1,5 +1,7 @@ 'taken_user']); - static::assertTrue(is_array($actor)); + static::assertIsArray($actor); static::assertTrue($actor[0] instanceof Actor); } @@ -43,7 +45,7 @@ class DBTest extends GNUsocialTestCase { static::bootKernel(); $actor = DB::sql('select {select} from actor a where a.nickname = :nickname', ['a' => 'App\Entity\Actor'], ['nickname' => 'taken_user']); - static::assertTrue(is_array($actor)); + static::assertIsArray($actor); static::assertTrue($actor[0] instanceof Actor); } @@ -51,11 +53,11 @@ class DBTest extends GNUsocialTestCase { static::bootKernel(); $actor = DB::findBy('actor', ['nickname' => 'taken_user']); - static::assertTrue(is_array($actor)); + static::assertIsArray($actor); static::assertTrue($actor[0] instanceof Actor); $actor = DB::findBy('actor', ['and' => ['is_null' => 'bio', 'or' => ['nickname' => 'user does not exist', 'gte' => ['id' => 0]]]]); - static::assertTrue(is_array($actor)); + static::assertIsArray($actor); static::assertTrue($actor[0] instanceof Actor); } diff --git a/tests/Core/DB/UpdateListenerTest.php b/tests/Core/DB/UpdateListenerTest.php index a4580c2e33..779871fb9b 100644 --- a/tests/Core/DB/UpdateListenerTest.php +++ b/tests/Core/DB/UpdateListenerTest.php @@ -1,5 +1,7 @@ 'foo']); static::assertTrue($user->hasNickname()); static::assertFalse($user->hasPassword()); - static::assertThrows(\BadMethodCallException::class, fn () => $user->nonExistantMethod()); + static::assertThrows(BadMethodCallException::class, fn () => $user->nonExistantMethod()); } public function testCreate() { $user = LocalUser::create(['nickname' => 'foo']); static::assertSame('foo', $user->getNickname()); - static::assertThrows(\InvalidArgumentException::class, fn () => LocalUser::create(['non_existant_property' => 'bar'])); + static::assertThrows(InvalidArgumentException::class, fn () => LocalUser::create(['non_existant_property' => 'bar'])); } public function testCreateOrUpdate() diff --git a/tests/Core/EventTest.php b/tests/Core/EventTest.php index fee5bad499..7f745b2e58 100644 --- a/tests/Core/EventTest.php +++ b/tests/Core/EventTest.php @@ -1,5 +1,7 @@ ['foo', 'bar'], 'transformer' => ArrayTransformer::class]], ['testpost', SubmitType::class, ['label' => 'Post']], ]); - static::assertSame(get_class($form), 'Symfony\\Component\\Form\\Form'); + static::assertSame(\get_class($form), 'Symfony\\Component\\Form\\Form'); foreach ($form as $name => $f) { if ($name == 'testpost') { - static::assertSame(get_class($f), 'Symfony\Component\Form\SubmitButton'); + static::assertSame(\get_class($f), 'Symfony\Component\Form\SubmitButton'); } else { - static::assertSame(get_class($f), 'Symfony\Component\Form\Form'); + static::assertSame(\get_class($f), 'Symfony\Component\Form\Form'); } $config = $f->getConfig(); @@ -62,7 +64,7 @@ class FormTest extends GNUsocialTestCase foreach ($form_array as [$array_name, $array_class, $options]) { if ($name === $array_name) { $found = true; - static::assertSame(get_class($form_class), $array_class); + static::assertSame(\get_class($form_class), $array_class); foreach (['label', 'attr', 'data'] as $field) { if (isset($options[$field])) { static::assertSame($form_options[$field], $options[$field]); @@ -73,7 +75,7 @@ class FormTest extends GNUsocialTestCase } static::assertTrue($found); - static::assertSame(get_class($f->getParent()), 'Symfony\\Component\\Form\\Form'); + static::assertSame(\get_class($f->getParent()), 'Symfony\\Component\\Form\\Form'); } static::assertTrue(Form::isRequired($form_array, 'content')); } diff --git a/tests/Core/GSFileTest.php b/tests/Core/GSFileTest.php index 481c57571f..20a2f0aff1 100644 --- a/tests/Core/GSFileTest.php +++ b/tests/Core/GSFileTest.php @@ -1,5 +1,7 @@ '1 apple', '# apples']; - static::assertSame('-42 apples', _m($apples, ['count' => -42])); - static::assertSame('0 apples', _m($apples, ['count' => 0])); - static::assertSame('1 apple', _m($apples, ['count' => 1])); - static::assertSame('2 apples', _m($apples, ['count' => 2])); - static::assertSame('42 apples', _m($apples, ['count' => 42])); + static::assertSame('-42 apples', _m($apples, ['count' => -42])); + static::assertSame('0 apples', _m($apples, ['count' => 0])); + static::assertSame('1 apple', _m($apples, ['count' => 1])); + static::assertSame('2 apples', _m($apples, ['count' => 2])); + static::assertSame('42 apples', _m($apples, ['count' => 42])); $apples = [0 => 'no apples', 1 => '1 apple', '# apples']; static::assertSame('no apples', _m($apples, ['count' => 0])); - static::assertSame('1 apple', _m($apples, ['count' => 1])); - static::assertSame('2 apples', _m($apples, ['count' => 2])); + static::assertSame('1 apple', _m($apples, ['count' => 1])); + static::assertSame('2 apples', _m($apples, ['count' => 2])); static::assertSame('42 apples', _m($apples, ['count' => 42])); $pronouns = ['she' => 'her apple', 'he' => 'his apple', 'they' => 'their apple']; - static::assertSame('her apple', _m($pronouns, ['pronoun' => 'she'])); - static::assertSame('his apple', _m($pronouns, ['pronoun' => 'he'])); + static::assertSame('her apple', _m($pronouns, ['pronoun' => 'she'])); + static::assertSame('his apple', _m($pronouns, ['pronoun' => 'he'])); static::assertSame('their apple', _m($pronouns, ['pronoun' => 'they'])); static::assertSame('their apple', _m($pronouns, ['pronoun' => 'unkown'])); // a bit odd, not sure if we want this @@ -71,10 +74,10 @@ class I18nTest extends KernelTestCase 'he' => [1 => 'his apple', 'his # apples'], ]; - static::assertSame('her apple', _m($complex, ['pronoun' => 'she', 'count' => 1])); - static::assertSame('his apple', _m($complex, ['pronoun' => 'he', 'count' => 1])); - static::assertSame('her 2 apples', _m($complex, ['pronoun' => 'she', 'count' => 2])); - static::assertSame('his 2 apples', _m($complex, ['pronoun' => 'he', 'count' => 2])); + static::assertSame('her apple', _m($complex, ['pronoun' => 'she', 'count' => 1])); + static::assertSame('his apple', _m($complex, ['pronoun' => 'he', 'count' => 1])); + static::assertSame('her 2 apples', _m($complex, ['pronoun' => 'she', 'count' => 2])); + static::assertSame('his 2 apples', _m($complex, ['pronoun' => 'he', 'count' => 2])); static::assertSame('her 42 apples', _m($complex, ['pronoun' => 'she', 'count' => 42])); $complex = [ @@ -83,24 +86,24 @@ class I18nTest extends KernelTestCase 'their' => [1 => 'their apple', 'their # apples'], ]; - static::assertSame('her apple', _m($complex, ['pronoun' => 'she', 'count' => 1])); - static::assertSame('his apple', _m($complex, ['pronoun' => 'he', 'count' => 1])); - static::assertSame('her 2 apples', _m($complex, ['pronoun' => 'she', 'count' => 2])); - static::assertSame('his 2 apples', _m($complex, ['pronoun' => 'he', 'count' => 2])); - static::assertSame('her 42 apples', _m($complex, ['pronoun' => 'she', 'count' => 42])); - static::assertSame('their apple', _m($complex, ['pronoun' => 'they', 'count' => 1])); + static::assertSame('her apple', _m($complex, ['pronoun' => 'she', 'count' => 1])); + static::assertSame('his apple', _m($complex, ['pronoun' => 'he', 'count' => 1])); + static::assertSame('her 2 apples', _m($complex, ['pronoun' => 'she', 'count' => 2])); + static::assertSame('his 2 apples', _m($complex, ['pronoun' => 'he', 'count' => 2])); + static::assertSame('her 42 apples', _m($complex, ['pronoun' => 'she', 'count' => 42])); + static::assertSame('their apple', _m($complex, ['pronoun' => 'they', 'count' => 1])); static::assertSame('their 3 apples', _m($complex, ['pronoun' => 'they', 'count' => 3])); - static::assertThrows(\InvalidArgumentException::class, fn () => _m($apples, ['count' => []])); - static::assertThrows(\InvalidArgumentException::class, fn () => _m([1], ['foo' => 'bar'])); + static::assertThrows(InvalidArgumentException::class, fn () => _m($apples, ['count' => []])); + static::assertThrows(InvalidArgumentException::class, fn () => _m([1], ['foo' => 'bar'])); } public function testIsRTL() { static::assertFalse(I18n::isRTL('af')); static::assertTrue(I18n::isRTL('ar')); - static::assertThrows(\InvalidArgumentException::class, fn () => I18n::isRTL('')); - static::assertThrows(\InvalidArgumentException::class, fn () => I18n::isRTL('not a language')); + static::assertThrows(InvalidArgumentException::class, fn () => I18n::isRTL('')); + static::assertThrows(InvalidArgumentException::class, fn () => I18n::isRTL('not a language')); } public function testGetNiceList() diff --git a/tests/Core/RouterTest.php b/tests/Core/RouterTest.php index c507c6034e..511533b5e4 100644 --- a/tests/Core/RouterTest.php +++ b/tests/Core/RouterTest.php @@ -1,5 +1,7 @@ connect(id: 'test_route', uri_path: '/test/{id<\d+>}', target: []); - $refl = (new \ReflectionClass($rl))->getProperty('rc'); + $refl = (new ReflectionClass($rl))->getProperty('rc'); $refl->setAccessible(true); $routes = $refl->getValue($rl)->all(); static::assertIsArray($routes); diff --git a/tests/Entity/ActorTest.php b/tests/Entity/ActorTest.php index 1766b53590..946508f402 100644 --- a/tests/Entity/ActorTest.php +++ b/tests/Entity/ActorTest.php @@ -1,5 +1,7 @@ getPath(); $hash = $attachment->getFilehash(); - static::assertTrue(file_exists($attachment->getPath())); + static::assertFileExists($attachment->getPath()); static::assertSame(1, $attachment->getLives()); - static::assertTrue(file_exists($path)); + static::assertFileExists($path); // Delete the backed storage of the attachment static::assertTrue($attachment->deleteStorage()); - static::assertFalse(file_exists($path)); + static::assertFileNotExists($path); static::assertNull($attachment->getPath()); DB::persist($attachment); DB::flush(); @@ -58,17 +61,17 @@ class AttachmentTest extends GNUsocialTestCase $repeated_attachment = GSFile::storeFileAsAttachment($file); $path = $attachment->getPath(); static::assertSame(2, $repeated_attachment->getLives()); - static::assertTrue(file_exists($path)); + static::assertFileExists($path); // Garbage collect the attachment $attachment->kill(); - static::assertTrue(file_exists($path)); + static::assertFileExists($path); static::assertSame(1, $repeated_attachment->getLives()); // Garbage collect the second attachment, which should delete everything $repeated_attachment->kill(); static::assertSame(0, $repeated_attachment->getLives()); - static::assertFalse(file_exists($path)); + static::assertFileNotExists($path); static::assertSame([], DB::findBy('attachment', ['filehash' => $hash])); } @@ -86,7 +89,7 @@ class AttachmentTest extends GNUsocialTestCase $file = new File($temp_file->getRealPath()); GSFile::storeFileAsAttachment($file); static::assertNotNull($attachment->getFilename()); - static::assertTrue(file_exists($attachment->getPath())); + static::assertFileExists($attachment->getPath()); }; $test('deleteStorage'); @@ -119,7 +122,7 @@ class AttachmentTest extends GNUsocialTestCase public function testMimetype() { - $file = new \SplFileInfo(INSTALLDIR . '/tests/sample-uploads/image.jpg'); + $file = new SplFileInfo(INSTALLDIR . '/tests/sample-uploads/image.jpg'); $hash = null; Event::handle('HashFile', [$file->getPathname(), &$hash]); $attachment = DB::findOneBy('attachment', ['filehash' => $hash]); diff --git a/tests/Entity/AttachmentThumbnailTest.php b/tests/Entity/AttachmentThumbnailTest.php index 622ab863ec..928943bb92 100644 --- a/tests/Entity/AttachmentThumbnailTest.php +++ b/tests/Entity/AttachmentThumbnailTest.php @@ -1,5 +1,7 @@ getPathname(), &$hash]); $attachment = DB::findOneBy('attachment', ['filehash' => $hash]); @@ -73,7 +76,7 @@ class AttachmentThumbnailTest extends GNUsocialTestCase { parent::bootKernel(); - $file = new \SplFileInfo(INSTALLDIR . '/tests/sample-uploads/spreadsheet.ods'); + $file = new SplFileInfo(INSTALLDIR . '/tests/sample-uploads/spreadsheet.ods'); $hash = null; Event::handle('HashFile', [$file->getPathname(), &$hash]); $attachment = DB::findOneBy('attachment', ['filehash' => $hash]); diff --git a/tests/Entity/GroupTest.php b/tests/Entity/GroupTest.php index c61ff12ffe..649a3d1795 100644 --- a/tests/Entity/GroupTest.php +++ b/tests/Entity/GroupTest.php @@ -1,5 +1,7 @@ Link::getOrCreate('not a url')); + static::assertThrows(InvalidArgumentException::class, fn () => Link::getOrCreate('not a url')); $link = Link::getOrCreate('https://gnu.org'); static::assertNotNull($link->getUrl()); - static::assertThrows(\InvalidArgumentException::class, fn () => Link::getOrCreate('https://' . $_ENV['SOCIAL_DOMAIN'])); + static::assertThrows(InvalidArgumentException::class, fn () => Link::getOrCreate('https://' . $_ENV['SOCIAL_DOMAIN'])); } } diff --git a/tests/Entity/LocalUserTest.php b/tests/Entity/LocalUserTest.php index ae8028ea8c..67d5248949 100644 --- a/tests/Entity/LocalUserTest.php +++ b/tests/Entity/LocalUserTest.php @@ -1,5 +1,7 @@ LocalUser::algoNameToConstant($name)); + static::assertThrows(Exception::class, fn () => LocalUser::algoNameToConstant($name)); } }; $if_exists('bcrypt', 'PASSWORD_BCRYPT'); diff --git a/tests/Entity/NoteTest.php b/tests/Entity/NoteTest.php index 79d6035d26..73c4f0cba9 100644 --- a/tests/Entity/NoteTest.php +++ b/tests/Entity/NoteTest.php @@ -1,5 +1,7 @@ implode("\n",['option 1', '2nd option'])]); + $poll1 = Poll::create(['options' => implode("\n", ['option 1', '2nd option'])]); static::assertSame("option 1\n2nd option", $poll1->getOptions()); static::assertSame(['option 1', '2nd option'], $poll1->getOptionsArr()); diff --git a/tests/Twig/ExtensionTest.php b/tests/Twig/ExtensionTest.php index c284be74c1..9a3d76d569 100644 --- a/tests/Twig/ExtensionTest.php +++ b/tests/Twig/ExtensionTest.php @@ -1,5 +1,7 @@ createMock(ContainerBagInterface::class); static::assertTrue($cb instanceof ContainerBagInterface); $cb->method('get') - ->willReturnMap([['gnusocial', $conf], ['gnusocial_defaults', $conf]]); + ->willReturnMap([['gnusocial', $conf], ['gnusocial_defaults', $conf]]); Common::setupConfig($cb); if ($exists = file_exists(INSTALLDIR . '/social.local.yaml')) { @@ -130,11 +132,17 @@ class CommonTest extends GNUsocialTestCase static::assertSame([], Common::arrayDiffRecursive(['foo' => []], ['foo' => 'bar'])); static::assertSame([], Common::arrayDiffRecursive(['foo' => ['bar']], ['foo' => ['bar']])); static::assertSame(['foo' => [1 => 'quux']], Common::arrayDiffRecursive(['foo' => ['bar', 'quux']], ['foo' => ['bar']])); - static::assertSame([], Common::arrayDiffRecursive(['hydrogen' => ['helium' => ['lithium'], 'boron' => 'carbon']], - ['hydrogen' => ['helium' => ['lithium'], 'boron' => 'carbon']])); - static::assertSame(['hydrogen' => ['helium' => ['lithium']]], - Common::arrayDiffRecursive(['hydrogen' => ['helium' => ['lithium'], 'boron' => 'carbon']], - ['hydrogen' => ['helium' => ['beryllium'], 'boron' => 'carbon']])); + static::assertSame([], Common::arrayDiffRecursive( + ['hydrogen' => ['helium' => ['lithium'], 'boron' => 'carbon']], + ['hydrogen' => ['helium' => ['lithium'], 'boron' => 'carbon']], + )); + static::assertSame( + ['hydrogen' => ['helium' => ['lithium']]], + Common::arrayDiffRecursive( + ['hydrogen' => ['helium' => ['lithium'], 'boron' => 'carbon']], + ['hydrogen' => ['helium' => ['beryllium'], 'boron' => 'carbon']], + ), + ); } public function testArrayRemoveKeys() @@ -145,16 +153,16 @@ class CommonTest extends GNUsocialTestCase public function testSizeStrToInt() { - static::assertSame(pow(1024, 0), Common::sizeStrToInt('1')); - static::assertSame(pow(1024, 1), Common::sizeStrToInt('1K')); - static::assertSame(pow(1024, 2), Common::sizeStrToInt('1M')); - static::assertSame(3 * pow(1024, 2), Common::sizeStrToInt('')); - static::assertSame(pow(1024, 3), Common::sizeStrToInt('1G')); - static::assertSame(pow(1024, 4), Common::sizeStrToInt('1T')); - static::assertSame(pow(1024, 5), Common::sizeStrToInt('1P')); - static::assertSame(128, Common::sizeStrToInt('128')); - static::assertSame(128 * 1024, Common::sizeStrToInt('128K')); - static::assertSame(128 * 1024, Common::sizeStrToInt('128.5K')); + static::assertSame(1024 ** 0, Common::sizeStrToInt('1')); + static::assertSame(1024 ** 1, Common::sizeStrToInt('1K')); + static::assertSame(1024 ** 2, Common::sizeStrToInt('1M')); + static::assertSame(3 * 1024 ** 2, Common::sizeStrToInt('')); + static::assertSame(1024 ** 3, Common::sizeStrToInt('1G')); + static::assertSame(1024 ** 4, Common::sizeStrToInt('1T')); + static::assertSame(1024 ** 5, Common::sizeStrToInt('1P')); + static::assertSame(128, Common::sizeStrToInt('128')); + static::assertSame(128 * 1024, Common::sizeStrToInt('128K')); + static::assertSame(128 * 1024, Common::sizeStrToInt('128.5K')); } public function testGetPreferredPhpUploadLimit() diff --git a/tests/Util/Form/ActorArrayTransformerTest.php b/tests/Util/Form/ActorArrayTransformerTest.php index 9f4050e42f..45930183a3 100644 --- a/tests/Util/Form/ActorArrayTransformerTest.php +++ b/tests/Util/Form/ActorArrayTransformerTest.php @@ -1,5 +1,7 @@ Formatting::toString('foo', '')); static::assertSame('', Formatting::toString('')); static::assertSame('foo', Formatting::toString('foo')); static::assertSame('42', Formatting::toString(42)); @@ -182,7 +185,7 @@ class FormattingTest extends WebTestCase public function testToArray() { - static::assertThrows(\Exception::class, function () { return Formatting::toArray('foo', $a, ''); }); + static::assertThrows(Exception::class, fn () => Formatting::toArray('foo', $a, '')); static::assertTrue(Formatting::toArray('', $a)); static::assertSame([], $a); diff --git a/tests/Util/HTMLTest.php b/tests/Util/HTMLTest.php index 0df4916097..c9863955c7 100644 --- a/tests/Util/HTMLTest.php +++ b/tests/Util/HTMLTest.php @@ -1,5 +1,7 @@ \n

\n

\n\n", HTML::html(['a' => ['p' => '']])); static::assertSame("\n

\n

\n
\n", HTML::html(['a' => ['attrs' => ['href' => 'test'], 'p' => '']])); static::assertSame("\n

\n foo\n

\n
\n
\n", HTML::html(['a' => ['p' => 'foo', 'br' => 'empty']])); - static::assertThrows(\InvalidArgumentException::class, fn () => HTML::html(1)); + static::assertThrows(InvalidArgumentException::class, fn () => HTML::html(1)); static::assertSame("\n foo\n", implode("\n", HTML::tag('a', ['href' => 'test'], content: 'foo', options: ['empty' => false]))); static::assertSame('
', implode("\n", HTML::tag('br', attrs: null, content: null, options: ['empty' => true]))); } diff --git a/tests/Util/NicknameTest.php b/tests/Util/NicknameTest.php index 33712092ea..831f570d9d 100644 --- a/tests/Util/NicknameTest.php +++ b/tests/Util/NicknameTest.php @@ -1,5 +1,7 @@ createMock(ContainerBagInterface::class); static::assertTrue($cb instanceof ContainerBagInterface); $cb->method('get') - ->willReturnMap([['gnusocial', $conf], ['gnusocial_defaults', $conf]]); + ->willReturnMap([['gnusocial', $conf], ['gnusocial_defaults', $conf]]); Common::setupConfig($cb); static::assertThrows(NicknameTooLongException::class, fn () => Nickname::normalize(str_repeat('longstring-', 128), check_already_used: false)); @@ -51,7 +53,7 @@ class NicknameTest extends GNUsocialTestCase // static::assertSame('foobar', Nickname::normalize('foo_bar', check_already_used: false)); // static::assertSame('foobar', Nickname::normalize('FooBar', check_already_used: false)); static::assertThrows(NicknameTooShortException::class, fn () => Nickname::normalize('foo', check_already_used: false)); - static::assertThrows(NicknameEmptyException::class, fn () => Nickname::normalize('', check_already_used: false)); + static::assertThrows(NicknameEmptyException::class, fn () => Nickname::normalize('', check_already_used: false)); // static::assertThrows(NicknameInvalidException::class, fn () => Nickname::normalize('FóóBár', check_already_used: false)); static::assertThrows(NicknameNotAllowedException::class, fn () => Nickname::normalize('this_nickname_is_reserved', check_already_used: false)); diff --git a/tests/Util/Notification/NotificationTest.php b/tests/Util/Notification/NotificationTest.php index 9ab87bd185..b474ddfb74 100644 --- a/tests/Util/Notification/NotificationTest.php +++ b/tests/Util/Notification/NotificationTest.php @@ -1,5 +1,7 @@ getResource()); $filepath = uniqid(sys_get_temp_dir() . '/'); $temp->commit($filepath); - static::assertTrue(file_exists($filepath)); + static::assertFileExists($filepath); @unlink($filepath); } @@ -51,6 +53,6 @@ class TemporaryFileTest extends WebTestCase $temp = new TemporaryFile(); @unlink('/tmp/social-test-folder/test'); $temp->move('/tmp/social-test-folder/', 'test'); - static::assertTrue(file_exists('/tmp/social-test-folder/test')); + static::assertFileExists('/tmp/social-test-folder/test'); } } diff --git a/tests/bootstrap.php b/tests/bootstrap.php index 5160486cc0..28ba8eeb41 100644 --- a/tests/bootstrap.php +++ b/tests/bootstrap.php @@ -1,11 +1,13 @@ bootEnv(dirname(__DIR__) . '/.env'); + (new Dotenv())->bootEnv(\dirname(__DIR__) . '/.env'); }