Unverified Commit 231d578d authored by Yassine Doghri's avatar Yassine Doghri
Browse files

refactor: add phpstan and update code to adhere to level 5

- move and refactor Image.php from Libraries to Entities folder
- update some database field names
/ types
- update composer packages
parent b691b927
Pipeline #872 passed with stages
in 14 minutes and 14 seconds
......@@ -7,13 +7,17 @@
"workspaceFolder": "/castopod-host",
"postCreateCommand": "cron && php spark serve --host 0.0.0.0",
"settings": {
"terminal.integrated.shell.linux": "/bin/bash",
"terminal.integrated.defaultProfile.linux": "/bin/bash",
"editor.formatOnSave": true,
"[php]": {
"editor.defaultFormatter": "esbenp.prettier-vscode"
},
"phpSniffer.autoDetect": true,
"color-highlight.markerType": "dot-before"
"color-highlight.markerType": "dot-before",
"files.associations": {
"*.xml.dist": "xml",
"spark": "php"
}
},
"extensions": [
"mikestead.dotenv",
......@@ -28,6 +32,8 @@
"dbaeumer.vscode-eslint",
"stylelint.vscode-stylelint",
"wongjn.php-sniffer",
"eamodio.gitlens"
"eamodio.gitlens",
"breezelin.phpstan",
"kasik96.latte"
]
}
......@@ -2,8 +2,19 @@
namespace App\Authorization;
class FlatAuthorization extends \Myth\Auth\Authorization\FlatAuthorization
use Myth\Auth\Authorization\FlatAuthorization as MythAuthFlatAuthorization;
class FlatAuthorization extends MythAuthFlatAuthorization
{
/**
* The group model to use. Usually the class noted
* below (or an extension thereof) but can be any
* compatible CodeIgniter Model.
*
* @var PermissionModel
*/
protected $permissionModel;
/**
* Checks a group to see if they have the specified permission.
*
......@@ -18,7 +29,7 @@ class FlatAuthorization extends \Myth\Auth\Authorization\FlatAuthorization
return false;
}
return (bool) $this->permissionModel->doesGroupHavePermission(
return $this->permissionModel->doesGroupHavePermission(
$groupId,
$permissionId,
);
......@@ -27,14 +38,14 @@ class FlatAuthorization extends \Myth\Auth\Authorization\FlatAuthorization
/**
* Makes user part of given groups.
*
* @param array $groups Either collection of ID or names
* @param array<string, string> $groups Either collection of ID or names
*/
public function setUserGroups(int $userId, array $groups = []): bool
{
// remove user from all groups before resetting it in new groups
$this->groupModel->removeUserFromAllGroups($userId);
if ($groups = []) {
if ($groups === []) {
return true;
}
......
......@@ -2,7 +2,9 @@
namespace App\Authorization;
class GroupModel extends \Myth\Auth\Authorization\GroupModel
use Myth\Auth\Authorization\GroupModel as MythAuthGroupModel;
class GroupModel extends MythAuthGroupModel
{
/**
* @return mixed[]
......
......@@ -2,7 +2,9 @@
namespace App\Authorization;
class PermissionModel extends \Myth\Auth\Authorization\PermissionModel
use Myth\Auth\Authorization\PermissionModel as MythAuthPermissionModel;
class PermissionModel extends MythAuthPermissionModel
{
/**
* Checks to see if a user, or one of their groups,
......
......@@ -28,8 +28,10 @@ class Analytics extends AnalyticsBase
/**
* get the full audio file url
*
* @param string|string[] $audioFilePath
*/
public function getAudioFileUrl(string $audioFilePath): string
public function getAudioFileUrl($audioFilePath): string
{
helper('media');
......
......@@ -2,7 +2,9 @@
namespace Config;
class Auth extends \Myth\Auth\Config\Auth
use Myth\Auth\Config\Auth as MythAuthConfig;
class Auth extends MythAuthConfig
{
/**
* --------------------------------------------------------------------------
......
......@@ -2,6 +2,9 @@
namespace Config;
use App\Entities\Actor;
use App\Entities\Note;
use App\Entities\User;
use CodeIgniter\Events\Events;
use CodeIgniter\Exceptions\FrameworkException;
......@@ -23,6 +26,7 @@ use CodeIgniter\Exceptions\FrameworkException;
*/
Events::on('pre_system', function () {
// @phpstan-ignore-next-line
if (ENVIRONMENT !== 'testing') {
if (ini_get('zlib.output_compression')) {
throw FrameworkException::forEnabledZlibOutputCompression();
......@@ -42,6 +46,8 @@ Events::on('pre_system', function () {
* Debug Toolbar Listeners.
* --------------------------------------------------------------------
* If you delete, they will no longer be collected.
*
* @phpstan-ignore-next-line
*/
if (CI_DEBUG) {
Events::on(
......@@ -52,7 +58,7 @@ Events::on('pre_system', function () {
}
});
Events::on('login', function ($user): void {
Events::on('login', function (User $user): void {
helper('auth');
// set interact_as_actor_id value
......@@ -62,7 +68,7 @@ Events::on('login', function ($user): void {
}
});
Events::on('logout', function ($user): void {
Events::on('logout', function (User $user): void {
helper('auth');
// remove user's interact_as_actor session
......@@ -75,7 +81,7 @@ Events::on('logout', function ($user): void {
* --------------------------------------------------------------------
* Update episode metadata counts
*/
Events::on('on_note_add', function ($note): void {
Events::on('on_note_add', function (Note $note): void {
if ($note->episode_id) {
model('EpisodeModel')
->where('id', $note->episode_id)
......@@ -87,7 +93,7 @@ Events::on('on_note_add', function ($note): void {
cache()->deleteMatching("page_podcast#{$note->actor->podcast->id}*");
});
Events::on('on_note_remove', function ($note): void {
Events::on('on_note_remove', function (Note $note): void {
if ($note->episode_id) {
model('EpisodeModel')
->where('id', $note->episode_id)
......@@ -106,7 +112,7 @@ Events::on('on_note_remove', function ($note): void {
cache()->deleteMatching("page_note#{$note->id}*");
});
Events::on('on_note_reblog', function ($actor, $note): void {
Events::on('on_note_reblog', function (Actor $actor, Note $note): void {
if ($episodeId = $note->episode_id) {
model('EpisodeModel')
->where('id', $episodeId)
......@@ -125,7 +131,7 @@ Events::on('on_note_reblog', function ($actor, $note): void {
}
});
Events::on('on_note_undo_reblog', function ($reblogNote): void {
Events::on('on_note_undo_reblog', function (Note $reblogNote): void {
$note = $reblogNote->reblog_of_note;
if ($episodeId = $note->episode_id) {
model('EpisodeModel')
......@@ -147,21 +153,21 @@ Events::on('on_note_undo_reblog', function ($reblogNote): void {
}
});
Events::on('on_note_reply', function ($reply): void {
Events::on('on_note_reply', function (Note $reply): void {
$note = $reply->reply_to_note;
cache()->deleteMatching("page_podcast#{$note->actor->podcast->id}*");
cache()->deleteMatching("page_note#{$note->id}*");
});
Events::on('on_reply_remove', function ($reply): void {
Events::on('on_reply_remove', function (Note $reply): void {
$note = $reply->reply_to_note;
cache()->deleteMatching("page_podcast#{$note->actor->podcast->id}*");
cache()->deleteMatching("page_note#{$note->id}*");
});
Events::on('on_note_favourite', function ($actor, $note): void {
Events::on('on_note_favourite', function (Actor $actor, Note $note): void {
if ($note->episode_id) {
model('EpisodeModel')
->where('id', $note->episode_id)
......@@ -176,7 +182,7 @@ Events::on('on_note_favourite', function ($actor, $note): void {
}
});
Events::on('on_note_undo_favourite', function ($actor, $note): void {
Events::on('on_note_undo_favourite', function (Actor $actor, Note $note): void {
if ($note->episode_id) {
model('EpisodeModel')
->where('id', $note->episode_id)
......@@ -191,22 +197,22 @@ Events::on('on_note_undo_favourite', function ($actor, $note): void {
}
});
Events::on('on_block_actor', function ($actorId): void {
Events::on('on_block_actor', function (int $actorId): void {
cache()->deleteMatching('page_podcast*');
cache()->deleteMatching('page_note*');
});
Events::on('on_unblock_actor', function ($actorId): void {
Events::on('on_unblock_actor', function (int $actorId): void {
cache()->deleteMatching('page_podcast*');
cache()->deleteMatching('page_note*');
});
Events::on('on_block_domain', function ($domainName): void {
Events::on('on_block_domain', function (string $domainName): void {
cache()->deleteMatching('page_podcast*');
cache()->deleteMatching('page_note*');
});
Events::on('on_unblock_domain', function ($domainName): void {
Events::on('on_unblock_domain', function (string $domainName): void {
cache()->deleteMatching('page_podcast*');
cache()->deleteMatching('page_note*');
});
......@@ -80,25 +80,25 @@ class Images extends BaseConfig
/**
* @var string
*/
public $thumbnailExtension = '_thumbnail';
public $thumbnailSuffix = '_thumbnail';
/**
* @var string
*/
public $mediumExtension = '_medium';
public $mediumSuffix = '_medium';
/**
* @var string
*/
public $largeExtension = '_large';
public $largeSuffix = '_large';
/**
* @var string
*/
public $feedExtension = '_feed';
public $feedSuffix = '_feed';
/**
* @var string
*/
public $id3Extension = '_id3';
public $id3Suffix = '_id3';
}
......@@ -22,7 +22,7 @@ class Mimes
/**
* Map of extensions to mime types.
*
* @var array<string, string>
* @var array<string, string|string[]>
*/
public static $mimes = [
'hqx' => [
......@@ -350,25 +350,25 @@ class Mimes
$proposedExtension = trim(strtolower($proposedExtension));
if ($proposedExtension !== '') {
if (
array_key_exists($proposedExtension, static::$mimes) &&
in_array(
$type,
is_string(static::$mimes[$proposedExtension])
? [static::$mimes[$proposedExtension]]
: static::$mimes[$proposedExtension],
true,
)
) {
// The detected mime type matches with the proposed extension.
return $proposedExtension;
}
if ($proposedExtension === '') {
// An extension was proposed, but the media type does not match the mime type list.
return null;
}
if (
array_key_exists($proposedExtension, static::$mimes) &&
in_array(
$type,
is_string(static::$mimes[$proposedExtension])
? [static::$mimes[$proposedExtension]]
: static::$mimes[$proposedExtension],
true,
)
) {
// The detected mime type matches with the proposed extension.
return $proposedExtension;
}
// Reverse check the mime type list if no extension was proposed.
// This search is order sensitive!
foreach (static::$mimes as $ext => $types) {
......
This diff is collapsed.
......@@ -101,11 +101,11 @@ class Services extends BaseService
$instance = new $class($config);
if (empty($userModel)) {
if ($userModel === null) {
$userModel = new UserModel();
}
if (empty($loginModel)) {
if ($loginModel === null) {
$loginModel = new LoginModel();
}
......
......@@ -8,9 +8,10 @@
namespace App\Controllers;
use ActivityPub\Controllers\ActorController as ActivityPubActorController;
use Analytics\AnalyticsTrait;
class Actor extends \ActivityPub\Controllers\ActorController
class ActorController extends ActivityPubActorController
{
use AnalyticsTrait;
......
......@@ -16,7 +16,7 @@ use App\Authorization\GroupModel;
use App\Models\PodcastModel;
use App\Models\UserModel;
class Contributor extends BaseController
class ContributorController extends BaseController
{
/**
* @var Podcast
......@@ -172,7 +172,7 @@ class Contributor extends BaseController
public function remove()
{
if ($this->podcast->created_by == $this->user->id) {
if ($this->podcast->created_by === $this->user->id) {
return redirect()
->back()
->with('errors', [
......
......@@ -8,15 +8,16 @@
namespace App\Controllers\Admin;
use App\Entities\Episode as EpisodeEntity;
use App\Entities\Episode;
use App\Entities\Note;
use App\Entities\Podcast;
use App\Models\EpisodeModel;
use App\Models\NoteModel;
use App\Models\PodcastModel;
use App\Models\SoundbiteModel;
use CodeIgniter\I18n\Time;
class Episode extends BaseController
class EpisodeController extends BaseController
{
/**
* @var Podcast
......@@ -28,12 +29,7 @@ class Episode extends BaseController
*/
protected $episode;
/**
* @var Soundbite|null
*/
protected $soundbites;
public function _remap($method, ...$params)
public function _remap(string $method, ...$params)
{
if (
!($this->podcast = (new PodcastModel())->getPodcastById($params[0]))
......@@ -124,7 +120,7 @@ class Episode extends BaseController
->with('errors', $this->validator->getErrors());
}
$newEpisode = new EpisodeEntity([
$newEpisode = new Episode([
'podcast_id' => $this->podcast->id,
'title' => $this->request->getPost('title'),
'slug' => $this->request->getPost('slug'),
......@@ -148,8 +144,8 @@ class Episode extends BaseController
'type' => $this->request->getPost('type'),
'is_blocked' => $this->request->getPost('block') == 'yes',
'custom_rss_string' => $this->request->getPost('custom_rss'),
'created_by' => user()->id,
'updated_by' => user()->id,
'created_by' => user_id(),
'updated_by' => user_id(),
'published_at' => null,
]);
......@@ -265,14 +261,15 @@ class Episode extends BaseController
'custom_rss',
);
$this->episode->updated_by = user()->id;
$this->episode->updated_by = user_id();
$audioFile = $this->request->getFile('audio_file');
if ($audioFile) {
if ($audioFile !== null && $audioFile->isValid()) {
$this->episode->audio_file = $audioFile;
}
$image = $this->request->getFile('image');
if ($image) {
if ($image !== null && $image->isValid()) {
$this->episode->image = $image;
}
......@@ -291,7 +288,7 @@ class Episode extends BaseController
) {
if (
($transcriptFile = $this->episode->transcript_file) &&
!empty($transcriptFile)
$transcriptFile !== null
) {
unlink($transcriptFile);
$this->episode->transcript_file_path = null;
......@@ -315,7 +312,7 @@ class Episode extends BaseController
) {
if (
($chaptersFile = $this->episode->chapters_file) &&
!empty($chaptersFile)
$chaptersFile !== null
) {
unlink($chaptersFile);
$this->episode->chapters_file_path = null;
......@@ -700,8 +697,8 @@ class Episode extends BaseController
foreach ($soundbites_array as $soundbite_id => $soundbite) {
if (
!empty($soundbite['start_time']) &&
!empty($soundbite['duration'])
$soundbite['start_time'] !== null &&
$soundbite['duration'] !== null
) {
$data = [
'podcast_id' => $this->podcast->id,
......@@ -709,10 +706,10 @@ class Episode extends BaseController
'start_time' => $soundbite['start_time'],
'duration' => $soundbite['duration'],
'label' => $soundbite['label'],
'updated_by' => user()->id,
'updated_by' => user_id(),
];
if ($soundbite_id == 0) {
$data += ['created_by' => user()->id];
$data += ['created_by' => user_id()];
} else {
$data += ['id' => $soundbite_id];
}
......
......@@ -16,7 +16,7 @@ use App\Models\PodcastModel;
use App\Models\EpisodeModel;
use App\Models\PersonModel;
class EpisodePerson extends BaseController
class EpisodePersonController extends BaseController
{
/**
* @var Podcast
......
......@@ -8,7 +8,7 @@
namespace App\Controllers\Admin;
class Fediverse extends BaseController
class FediverseController extends BaseController
{
public function dashboard()
{
......
......@@ -8,7 +8,7 @@
namespace App\Controllers\Admin;
class Home extends BaseController
class HomeController extends BaseController
{
public function index()
{
......
......@@ -11,7 +11,7 @@ namespace App\Controllers\Admin;
use Config\Services;
use App\Models\UserModel;
class MyAccount extends BaseController
class MyAccountController extends BaseController
{
public function index()
{
......@@ -58,7 +58,7 @@ class MyAccount extends BaseController
user()->password = $this->request->getPost('new_password');
if (!$userModel->update(user()->id, user())) {
if (!$userModel->update(user_id(), user())) {
return redirect()
->back()
->withInput()
......
......@@ -8,11 +8,11 @@
namespace App\Controllers\Admin;
use App\Entities\Page as EntitiesPage;
use App\Entities\Page;
use CodeIgniter\Exceptions\PageNotFoundException;
use App\Models\PageModel;
class Page extends BaseController
class PageController extends BaseController
{
/**
* @var Page|null
......@@ -55,10 +55,10 @@ class Page extends BaseController
function attemptCreate()
{
$page = new EntitiesPage([
$page = new Page([
'title' => $this->request->getPost('title'),
'slug' => $this->request->getPost('slug'),
'content' => $this->request->getPost('content'),
'content_markdown' => $this->request->getPost('content'),
]);
$pageModel = new PageModel();
......@@ -92,7 +92,7 @@ class Page extends BaseController
{
$this->page->title = $this->request->getPost('title');
$this->page->slug = $this->request->getPost('slug');
$this->page->content = $this->request->getPost('content');
$this->page->content_markdown = $this->request->getPost('content');
$pageModel = new PageModel();
......
......@@ -8,11 +8,11 @@
namespace App\Controllers\Admin;
use App\Entities\Person as EntitiesPerson;
use App\Entities\Person;
use CodeIgniter\Exceptions\PageNotFoundException;
use App\Models\PersonModel;
class Person extends BaseController
class PersonController extends BaseController
{
/**
* @var Person|null
......@@ -68,13 +68,13 @@ class Person extends BaseController
->with('errors', $this->validator->getErrors());
}
$person = new EntitiesPerson([
$person = new Person([
'full_name' => $this->request->getPost('full_name'),
'unique_name' => $this->request->getPost('unique_name'),
'information_url' => $this->request->getPost('information_url'),
'image' => $this->request->getFile('image'),
'created_by' => user()->id,
'updated_by' => user()->id,
'created_by' => user_id(),