diff --git a/app/Controllers/EpisodeAudioController.php b/app/Controllers/EpisodeAudioController.php index fadb311f..4c94cf80 100644 --- a/app/Controllers/EpisodeAudioController.php +++ b/app/Controllers/EpisodeAudioController.php @@ -101,9 +101,9 @@ class EpisodeAudioController extends Controller $subscription = null; // check if podcast is already unlocked before any token validation - if ($this->episode->is_premium && ($subscription = service('premium_podcasts')->subscription( + if ($this->episode->is_premium && ! ($subscription = service('premium_podcasts')->subscription( $this->episode->podcast->handle - )) === null) { + )) instanceof Subscription) { // look for token as GET parameter if (($token = $this->request->getGet('token')) === null) { return $this->response->setStatusCode(401) @@ -164,7 +164,7 @@ class EpisodeAudioController extends Controller $audioDuration, $this->episode->published_at->getTimestamp(), $serviceName, - $subscription !== null ? $subscription->id : null + $subscription instanceof Subscription ? $subscription->id : null ); return redirect()->to($this->analyticsConfig->getAudioUrl($this->episode, $this->request->getGet())); diff --git a/app/Controllers/EpisodeController.php b/app/Controllers/EpisodeController.php index 7ca30bb1..00d87eeb 100644 --- a/app/Controllers/EpisodeController.php +++ b/app/Controllers/EpisodeController.php @@ -177,8 +177,8 @@ class EpisodeController extends BaseController $session = Services::session(); $session->start(); - if (isset($_SERVER['HTTP_REFERER'])) { - $session->set('embed_domain', parse_url((string) $_SERVER['HTTP_REFERER'], PHP_URL_HOST)); + if (service('superglobals')->server('HTTP_REFERER') !== null) { + $session->set('embed_domain', parse_url(service('superglobals')->server('HTTP_REFERER'), PHP_URL_HOST)); } $cacheName = implode( diff --git a/app/Controllers/FeedController.php b/app/Controllers/FeedController.php index fbf742f9..a99cfcda 100644 --- a/app/Controllers/FeedController.php +++ b/app/Controllers/FeedController.php @@ -43,7 +43,7 @@ class FeedController extends Controller $service = null; try { - $service = UserAgentsRSS::find($_SERVER['HTTP_USER_AGENT']); + $service = UserAgentsRSS::find(service('superglobals')->server('HTTP_USER_AGENT')); } catch (Exception $exception) { // If things go wrong the show must go on and the user must be able to download the file log_message('critical', $exception->getMessage()); diff --git a/app/Helpers/url_helper.php b/app/Helpers/url_helper.php index b5e53c17..656c8459 100644 --- a/app/Helpers/url_helper.php +++ b/app/Helpers/url_helper.php @@ -16,13 +16,14 @@ if (! function_exists('host_url')) { */ function host_url(): ?string { - if (isset($_SERVER['HTTP_HOST'])) { + $superglobals = service('superglobals'); + if ($superglobals->server('HTTP_HOST') !== null) { $protocol = - (isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off') || - $_SERVER['SERVER_PORT'] === 443 + ($superglobals->server('HTTPS') !== null && $superglobals->server('HTTPS') !== 'off') || + (int) $superglobals->server('SERVER_PORT') === 443 ? 'https://' : 'http://'; - return $protocol . $_SERVER['HTTP_HOST'] . '/'; + return $protocol . $superglobals->server('HTTP_HOST') . '/'; } return null; diff --git a/composer.json b/composer.json index 644be9a3..88e8a0d2 100644 --- a/composer.json +++ b/composer.json @@ -29,13 +29,15 @@ "yassinedoghri/podcast-feed": "dev-main" }, "require-dev": { - "mikey179/vfsstream": "^v1.6.11", - "phpunit/phpunit": "^10.3.2", "captainhook/captainhook": "^5.16.4", - "symplify/easy-coding-standard": "^12.0.7", + "codeigniter/phpstan-codeigniter": "^1.0", + "mikey179/vfsstream": "^v1.6.11", + "phpstan/extension-installer": "^1.3", "phpstan/phpstan": "^1.10.32", + "phpunit/phpunit": "^10.3.2", "rector/rector": "^0.18.0", - "symplify/coding-standard": "^12.0.3" + "symplify/coding-standard": "^12.0.3", + "symplify/easy-coding-standard": "^12.0.7" }, "autoload": { "exclude-from-classmap": [ diff --git a/composer.lock b/composer.lock index 970c6488..e4fc770f 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "4526c68d78e5abe8e5c86016356e15f9", + "content-hash": "02db4cf9b79f67dad431f7d10f5c19f4", "packages": [ { "name": "adaures/ipcat-php", @@ -3224,6 +3224,73 @@ ], "time": "2023-04-17T19:48:47+00:00" }, + { + "name": "codeigniter/phpstan-codeigniter", + "version": "v1.0.0", + "source": { + "type": "git", + "url": "https://github.com/CodeIgniter/phpstan-codeigniter.git", + "reference": "2c6eebd9798e463ea8596493bd068310b7a701d9" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/CodeIgniter/phpstan-codeigniter/zipball/2c6eebd9798e463ea8596493bd068310b7a701d9", + "reference": "2c6eebd9798e463ea8596493bd068310b7a701d9", + "shasum": "" + }, + "require": { + "php": "^8.1", + "phpstan/phpstan": "^1.10" + }, + "conflict": { + "codeigniter/framework": "*" + }, + "require-dev": { + "codeigniter/coding-standard": "^1.7", + "codeigniter4/framework": "^4.3", + "friendsofphp/php-cs-fixer": "^3.20", + "nexusphp/cs-config": "^3.12", + "phpstan/extension-installer": "^1.3", + "phpstan/phpstan-deprecation-rules": "^1.1", + "phpstan/phpstan-phpunit": "^1.3", + "phpstan/phpstan-strict-rules": "^1.5", + "phpunit/phpunit": "^10.2" + }, + "type": "phpstan-extension", + "extra": { + "phpstan": { + "includes": ["extension.neon"] + } + }, + "autoload": { + "psr-4": { + "CodeIgniter\\PHPStan\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": ["MIT"], + "authors": [ + { + "name": "John Paul E. Balandan, CPA", + "email": "paulbalandan@gmail.com" + } + ], + "description": "CodeIgniter extensions and rules for PHPStan", + "keywords": [ + "PHPStan", + "codeigniter", + "codeigniter4", + "dev", + "static analysis" + ], + "support": { + "forum": "http://forum.codeigniter.com/", + "issues": "https://github.com/CodeIgniter/phpstan-codeigniter/issues", + "slack": "https://codeigniterchat.slack.com", + "source": "https://github.com/CodeIgniter/phpstan-codeigniter" + }, + "time": "2023-08-27T09:19:23+00:00" + }, { "name": "composer/pcre", "version": "3.1.0", @@ -3905,6 +3972,48 @@ }, "time": "2022-02-21T01:04:05+00:00" }, + { + "name": "phpstan/extension-installer", + "version": "1.3.1", + "source": { + "type": "git", + "url": "https://github.com/phpstan/extension-installer.git", + "reference": "f45734bfb9984c6c56c4486b71230355f066a58a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpstan/extension-installer/zipball/f45734bfb9984c6c56c4486b71230355f066a58a", + "reference": "f45734bfb9984c6c56c4486b71230355f066a58a", + "shasum": "" + }, + "require": { + "composer-plugin-api": "^2.0", + "php": "^7.2 || ^8.0", + "phpstan/phpstan": "^1.9.0" + }, + "require-dev": { + "composer/composer": "^2.0", + "php-parallel-lint/php-parallel-lint": "^1.2.0", + "phpstan/phpstan-strict-rules": "^0.11 || ^0.12 || ^1.0" + }, + "type": "composer-plugin", + "extra": { + "class": "PHPStan\\ExtensionInstaller\\Plugin" + }, + "autoload": { + "psr-4": { + "PHPStan\\ExtensionInstaller\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": ["MIT"], + "description": "Composer plugin for automatic installation of PHPStan extensions", + "support": { + "issues": "https://github.com/phpstan/extension-installer/issues", + "source": "https://github.com/phpstan/extension-installer/tree/1.3.1" + }, + "time": "2023-05-24T08:59:17+00:00" + }, { "name": "phpstan/phpstan", "version": "1.10.32", diff --git a/modules/Fediverse/Controllers/ActorController.php b/modules/Fediverse/Controllers/ActorController.php index 8e725dee..589a3ff8 100644 --- a/modules/Fediverse/Controllers/ActorController.php +++ b/modules/Fediverse/Controllers/ActorController.php @@ -17,6 +17,7 @@ use CodeIgniter\HTTP\ResponseInterface; use CodeIgniter\I18n\Time; use Exception; use Modules\Fediverse\Config\Fediverse; +use Modules\Fediverse\Entities\Activity; use Modules\Fediverse\Entities\Actor; use Modules\Fediverse\Entities\Post; use Modules\Fediverse\Objects\OrderedCollectionObject; @@ -45,7 +46,7 @@ class ActorController extends Controller } if ( - ($actor = model('ActorModel', false)->getActorByUsername($params[0])) === null + ! ($actor = model('ActorModel', false)->getActorByUsername($params[0])) instanceof Actor ) { throw PageNotFoundException::forPageNotFound(); } @@ -101,7 +102,7 @@ class ActorController extends Controller ->getPostByUri($payload->object->inReplyTo); $reply = null; - if ($replyToPost !== null) { + if ($replyToPost instanceof Post) { // TODO: strip content from html to retrieve message // remove all html tags and reconstruct message with mentions? $message = get_message_from_object($payload->object); @@ -136,7 +137,7 @@ class ActorController extends Controller $postToDelete = model('PostModel', false) ->getPostByUri($payload->object->id); - if ($postToDelete !== null) { + if ($postToDelete instanceof Post) { model('PostModel', false) ->removePost($postToDelete, false); } @@ -160,7 +161,7 @@ class ActorController extends Controller $post = model('PostModel', false) ->getPostByUri($payload->object); - if ($post !== null) { + if ($post instanceof Post) { // Like side-effect model('FavouriteModel', false) ->addFavourite($payloadActor, $post, false); @@ -177,7 +178,7 @@ class ActorController extends Controller $post = model('PostModel', false) ->getPostByUri($payload->object); - if ($post !== null) { + if ($post instanceof Post) { model('ActivityModel', false) ->update($activityId, [ 'post_id' => $post->id, @@ -205,7 +206,7 @@ class ActorController extends Controller $post = model('PostModel', false) ->getPostByUri($payload->object->object); - if ($post !== null) { + if ($post instanceof Post) { // revert side-effect by removing favourite from database model('FavouriteModel', false) ->removeFavourite($payloadActor, $post, false); @@ -223,7 +224,7 @@ class ActorController extends Controller ->getPostByUri($payload->object->object); $reblogPost = null; - if ($post !== null) { + if ($post instanceof Post) { $reblogPost = model('PostModel', false) ->where([ 'actor_id' => $payloadActor->id, @@ -374,7 +375,7 @@ class ActorController extends Controller public function activity(string $activityId): ResponseInterface { if ( - ! ($activity = model('ActivityModel', false)->getActivityById($activityId)) + ! ($activity = model('ActivityModel', false)->getActivityById($activityId)) instanceof Activity ) { throw PageNotFoundException::forPageNotFound(); } diff --git a/modules/Fediverse/Controllers/PostController.php b/modules/Fediverse/Controllers/PostController.php index 267e818e..8837521c 100644 --- a/modules/Fediverse/Controllers/PostController.php +++ b/modules/Fediverse/Controllers/PostController.php @@ -50,7 +50,7 @@ class PostController extends Controller public function _remap(string $method, string ...$params): mixed { - if (($post = model('PostModel', false)->getPostById($params[0])) === null) { + if (! ($post = model('PostModel', false)->getPostById($params[0])) instanceof Post) { throw PageNotFoundException::forPageNotFound(); } diff --git a/modules/Fediverse/Entities/Actor.php b/modules/Fediverse/Entities/Actor.php index 97948796..1a7a3f6c 100644 --- a/modules/Fediverse/Entities/Actor.php +++ b/modules/Fediverse/Entities/Actor.php @@ -102,7 +102,7 @@ class Actor extends Entity } if ($this->followers === null) { - $this->followers = (array) model('ActorModel', false) + $this->followers = model('ActorModel', false) ->getFollowers($this->id); } diff --git a/modules/Fediverse/Entities/Post.php b/modules/Fediverse/Entities/Post.php index 45f43bee..f0990601 100644 --- a/modules/Fediverse/Entities/Post.php +++ b/modules/Fediverse/Entities/Post.php @@ -126,7 +126,7 @@ class Post extends UuidEntity } if ($this->replies === null) { - $this->replies = (array) model('PostModel', false) + $this->replies = model('PostModel', false) ->getPostReplies($this->id); } @@ -162,7 +162,7 @@ class Post extends UuidEntity } if ($this->reblogs === null) { - $this->reblogs = (array) model('PostModel', false) + $this->reblogs = model('PostModel', false) ->getPostReblogs($this->id); } diff --git a/modules/Fediverse/Helpers/fediverse_helper.php b/modules/Fediverse/Helpers/fediverse_helper.php index 53f662f2..5a6a3004 100644 --- a/modules/Fediverse/Helpers/fediverse_helper.php +++ b/modules/Fediverse/Helpers/fediverse_helper.php @@ -212,8 +212,8 @@ if (! function_exists('get_or_create_preview_card_from_url')) { { // check if preview card has already been generated if ( - $previewCard = model('PreviewCardModel', false) - ->getPreviewCardFromUrl((string) $url) + ($previewCard = model('PreviewCardModel', false) + ->getPreviewCardFromUrl((string) $url)) instanceof PreviewCard ) { return $previewCard; } @@ -231,7 +231,7 @@ if (! function_exists('get_or_create_actor_from_uri')) { function get_or_create_actor_from_uri(string $actorUri): ?Actor { // check if actor exists in database already and return it - if ($actor = model('ActorModel', false)->getActorByUri($actorUri)) { + if (($actor = model('ActorModel', false)->getActorByUri($actorUri)) instanceof Actor) { return $actor; } @@ -249,8 +249,8 @@ if (! function_exists('get_or_create_actor')) { { // check if actor exists in database already and return it if ( - $actor = model('ActorModel', false) - ->getActorByUsername($username, $domain) + ($actor = model('ActorModel', false) + ->getActorByUsername($username, $domain)) instanceof Actor ) { return $actor; } @@ -412,9 +412,9 @@ if (! function_exists('linkify')) { // check if host is set and look for actor in database if (isset($match['host'])) { if ( - $actor = model( + ($actor = model( 'ActorModel', - )->getActorByUsername($match['username'], $match['domain']) + )->getActorByUsername($match['username'], $match['domain'])) instanceof Actor ) { // TODO: check that host is local to remove target blank? return '<' . @@ -447,8 +447,8 @@ if (! function_exists('linkify')) { } } else { if ( - $actor = model('ActorModel', false) - ->getActorByUsername($match['username']) + ($actor = model('ActorModel', false) + ->getActorByUsername($match['username'])) instanceof Actor ) { return '<' . array_push($links, anchor($actor->uri, $match[0])) . diff --git a/modules/Fediverse/WebFinger.php b/modules/Fediverse/WebFinger.php index fd731ad8..788e0fdf 100644 --- a/modules/Fediverse/WebFinger.php +++ b/modules/Fediverse/WebFinger.php @@ -11,6 +11,7 @@ declare(strict_types=1); namespace Modules\Fediverse; use Exception; +use Modules\Fediverse\Entities\Actor; class WebFinger { @@ -62,7 +63,7 @@ class WebFinger } if ( - ! ($actor = model('ActorModel', false)->getActorByUsername($username, $domain)) + ! ($actor = model('ActorModel', false)->getActorByUsername($username, $domain)) instanceof Actor ) { throw new Exception('Could not find actor'); } diff --git a/modules/PremiumPodcasts/Config/Services.php b/modules/PremiumPodcasts/Config/Services.php index c8fb03b4..54250431 100644 --- a/modules/PremiumPodcasts/Config/Services.php +++ b/modules/PremiumPodcasts/Config/Services.php @@ -4,14 +4,16 @@ declare(strict_types=1); namespace Modules\PremiumPodcasts\Config; -use Config\Services as BaseService; +use CodeIgniter\Config\BaseService; use Modules\PremiumPodcasts\Models\SubscriptionModel; use Modules\PremiumPodcasts\PremiumPodcasts; class Services extends BaseService { - public static function premium_podcasts(?SubscriptionModel $subscriptionModel = null, bool $getShared = true) - { + public static function premium_podcasts( + ?SubscriptionModel $subscriptionModel = null, + bool $getShared = true + ): PremiumPodcasts { if ($getShared) { return self::getSharedInstance('premium_podcasts', $subscriptionModel); } diff --git a/phpstan.neon b/phpstan.neon index b5a2a9f5..183ded38 100644 --- a/phpstan.neon +++ b/phpstan.neon @@ -16,11 +16,34 @@ parameters: - app/Views/* - modules/*/Views/* - themes/* + codeigniter: + additionalConfigNamespaces: + - Modules\Admin\Config\ + - Modules\Analytics\Config\ + - Modules\Api\Rest\V1\Config\ + - Modules\Auth\Config\ + - Modules\Fediverse\Config\ + - Modules\Install\Config\ + - Modules\Media\Config\ + - Modules\MediaClipper\Config\ + - Modules\PodcastImport\Config\ + - Modules\PremiumPodcasts\Config\ + - Modules\WebSub\Config\ + additionalModelNamespaces: + - Modules\Analytics\Models\ + - Modules\Auth\Models\ + - Modules\Fediverse\Models\ + - Modules\Media\Models\ + - Modules\PremiumPodcasts\Models\ + additionalServices: + - CodeIgniter\Settings\Config\Services + - Michalsn\Uuid\Config\Services + - Modules\PremiumPodcasts\Config\Services + - Modules\Media\Config\Services dynamicConstantNames: - APP_NAMESPACE - CI_DEBUG - ENVIRONMENT - SODIUM_LIBRARY_VERSION ignoreErrors: - - '#^Access to an undefined property Modules\\Media\\Entities\\Image#' - '#^Call to an undefined method CodeIgniter\\Cache\\CacheInterface\:\:deleteMatching\(\)#' diff --git a/rector.php b/rector.php index 782fdda8..ef860a13 100644 --- a/rector.php +++ b/rector.php @@ -71,4 +71,5 @@ return static function (RectorConfig $rectorConfig): void { // Path to phpstan with extensions, that PHPStan in Rector uses to determine types $rectorConfig->phpstanConfig(__DIR__ . '/phpstan.neon'); + $rectorConfig->phpstanConfigs(['vendor/codeigniter/phpstan-codeigniter/extension.neon']); };