Unverified Commit 6b74a9e9 authored by Yassine Doghri's avatar Yassine Doghri
Browse files

refactor: update code base to php 8 and set phpstan lvl to 6

parent 4a33c50f
Pipeline #877 failed with stages
in 9 minutes and 27 seconds
image: php:7.3-fpm
image: php:8.0-fpm
stages:
- quality
......
......@@ -4,7 +4,7 @@
{
"files": "*.php",
"options": {
"phpVersion": "7.3",
"phpVersion": "7.4",
"singleQuote": true
}
},
......
......@@ -5,7 +5,7 @@
# should be used only for development purposes
####################################################
FROM php:7.3-fpm
FROM php:8.0-fpm
LABEL maintainer="Yassine Doghri<yassine@podlibre.org>"
......@@ -37,8 +37,8 @@ RUN apt-get update && apt-get install -y \
zlib1g-dev \
&& docker-php-ext-install intl
RUN docker-php-ext-configure gd --with-jpeg-dir=/usr/include/ \
&& docker-php-ext-install gd
RUN docker-php-ext-configure gd --with-jpeg \
&& docker-php-ext-install gd
RUN pecl install -o -f redis \
&& rm -rf /tmp/pear \
......
......@@ -10,7 +10,7 @@ or shared hosting, you can install it on most PHP-MySQL compatible web servers.
- [1. Install Wizard](#1-install-wizard)
- [1-alt Manual configuration](#1-alt-manual-configuration)
- [Web Server Requirements](#web-server-requirements)
- [PHP v7.3 or higher](#php-v73-or-higher)
- [PHP v8.0 or higher](#php-v73-or-higher)
- [MySQL compatible database](#mysql-compatible-database)
- [Privileges](#privileges)
- [(Optional) Other recommendations](#optional-other-recommendations)
......@@ -59,9 +59,9 @@ through the install wizard, you can create and update the `.env` file yourself:
## Web Server Requirements
### PHP v7.3 or higher
### PHP v8.0 or higher
PHP version 7.3 or higher is required, with the following extensions installed:
PHP version 8.0 or higher is required, with the following extensions installed:
- [intl](https://php.net/manual/en/intl.requirements.php)
- [libcurl](https://php.net/manual/en/curl.requirements.php)
......
......@@ -17,10 +17,8 @@ class FlatAuthorization extends MythAuthFlatAuthorization
/**
* Checks a group to see if they have the specified permission.
*
* @param int|string $permission
*/
public function groupHasPermission($permission, int $groupId): bool
public function groupHasPermission(int|string $permission, int $groupId): bool
{
// Get the Permission ID
$permissionId = $this->getPermissionID($permission);
......
<?php namespace Config;
use App\Libraries\PodcastActor;
use App\Libraries\NoteObject;
use ActivityPub\Config\ActivityPub as ActivityPubBase;
class ActivityPub extends ActivityPubBase
......@@ -8,18 +10,32 @@ class ActivityPub extends ActivityPubBase
* --------------------------------------------------------------------
* ActivityPub Objects
* --------------------------------------------------------------------
* @var string
*/
public $actorObject = 'App\Libraries\PodcastActor';
public $noteObject = 'App\Libraries\NoteObject';
public $actorObject = PodcastActor::class;
/**
* @var string
*/
public $noteObject = NoteObject::class;
/**
* --------------------------------------------------------------------
* Default avatar and cover images
* --------------------------------------------------------------------
* @var string
*/
public $defaultAvatarImagePath = 'assets/images/castopod-avatar-default.jpg';
/**
* @var string
*/
public $defaultAvatarImageMimetype = 'image/jpeg';
/**
* @var string
*/
public $defaultCoverImagePath = 'assets/images/castopod-cover-default.jpg';
/**
* @var string
*/
public $defaultCoverImageMimetype = 'image/jpeg';
}
......@@ -10,6 +10,7 @@ class Analytics extends AnalyticsBase
* --------------------------------------------------------------------
* Route filters options
* --------------------------------------------------------------------
* @var array<string, string>
*/
public $routeFilters = [
'analytics-full-data' => 'permission:podcasts-view,podcast-view',
......
......@@ -12,25 +12,21 @@ class Database extends Config
/**
* The directory that holds the Migrations
* and Seeds directories.
*
* @var string
*/
public $filesPath = APPPATH . 'Database' . DIRECTORY_SEPARATOR;
public string $filesPath = APPPATH . 'Database' . DIRECTORY_SEPARATOR;
/**
* Lets you choose which connection group to
* use if no other is specified.
*
* @var string
*/
public $defaultGroup = 'default';
public string $defaultGroup = 'default';
/**
* The default database connection.
*
* @var array
* @var array<string, string|bool|int|array>
*/
public $default = [
public array $default = [
'DSN' => '',
'hostname' => 'localhost',
'username' => '',
......@@ -54,9 +50,9 @@ class Database extends Config
* This database connection is used when
* running PHPUnit database tests.
*
* @var array
* @var array<string, string|bool|int|array>
*/
public $tests = [
public array $tests = [
'DSN' => '',
'hostname' => '127.0.0.1',
'username' => '',
......
......@@ -29,7 +29,7 @@ class Exceptions extends BaseConfig
* Any status codes here will NOT be logged if logging is turned on.
* By default, only 404 (Page Not Found) exceptions are ignored.
*
* @var array
* @var int[]
*/
public $ignoreCodes = [404];
......
......@@ -17,7 +17,7 @@ class Filters extends BaseConfig
* Configures aliases for Filter classes to
* make reading things nicer and simpler.
*
* @var array
* @var array<string, string>
*/
public $aliases = [
'csrf' => CSRF::class,
......@@ -33,7 +33,7 @@ class Filters extends BaseConfig
* List of filter aliases that are always
* applied before and after every request.
*
* @var array
* @var array<string, string[]>
*/
public $globals = [
'before' => [
......@@ -53,7 +53,7 @@ class Filters extends BaseConfig
* Example:
* 'post' => ['csrf', 'throttle']
*
* @var array
* @var array<string, string[]>
*/
public $methods = [];
......@@ -64,7 +64,7 @@ class Filters extends BaseConfig
* Example:
* 'isLoggedIn' => ['before' => ['account/*', 'profiles/*']]
*
* @var array
* @var array<string, array<string, string[]>>
*/
public $filters = [];
......
......@@ -23,7 +23,10 @@ class Kint extends BaseConfig
|--------------------------------------------------------------------------
*/
public $plugins;
/**
* @var string[]
*/
public $plugins = [];
/**
* @var int
......@@ -60,9 +63,15 @@ class Kint extends BaseConfig
*/
public $richSort = Renderer::SORT_FULL;
public $richObjectPlugins;
/**
* @var string[]
*/
public $richObjectPlugins = [];
public $richTabPlugins;
/**
* @var string[]
*/
public $richTabPlugins = [];
/*
|--------------------------------------------------------------------------
......
......@@ -36,9 +36,9 @@ class Logger extends BaseConfig
* For a live site you'll usually enable Critical or higher (3) to be logged otherwise
* your log files will fill up very fast.
*
* @var integer|array
* @var integer|int[]
*/
public $threshold = 4;
public int|array $threshold = 4;
/**
* --------------------------------------------------------------------------
......@@ -50,7 +50,7 @@ class Logger extends BaseConfig
*
* @var string
*/
public $dateFormat = 'Y-m-d H:i:s';
public string $dateFormat = 'Y-m-d H:i:s';
/**
* --------------------------------------------------------------------------
......@@ -75,9 +75,9 @@ class Logger extends BaseConfig
* Handlers are executed in the order defined in this array, starting with
* the handler on top and continuing down.
*
* @var array
* @var array<string, string|int|array<string, string>>
*/
public $handlers = [
public array $handlers = [
/*
* --------------------------------------------------------------------
* File Handler
......@@ -125,9 +125,9 @@ class Logger extends BaseConfig
],
/**
* The ChromeLoggerHandler requires the use of the Chrome web browser
* and the ChromeLogger extension. Uncomment this block to use it.
*/
* The ChromeLoggerHandler requires the use of the Chrome web browser
* and the ChromeLogger extension. Uncomment this block to use it.
*/
// 'CodeIgniter\Log\Handlers\ChromeLoggerHandler' => [
// /*
// * The log levels that this handler will handle.
......
......@@ -164,13 +164,13 @@ $routes->group(
]);
$routes->group('persons', function ($routes): void {
$routes->get('/', 'PodcastPersonController/$1', [
$routes->get('/', 'PodcastPodcastController/$1', [
'as' => 'podcast-person-manage',
'filter' => 'permission:podcast-edit',
]);
$routes->post(
'/',
'PodcastPersonController::attemptAdd/$1',
'PodcastPodcastController::attemptAdd/$1',
[
'filter' => 'permission:podcast-edit',
],
......@@ -178,7 +178,7 @@ $routes->group(
$routes->get(
'(:num)/remove',
'PodcastPersonController::remove/$1/$2',
'PodcastPodcastController::remove/$1/$2',
[
'as' => 'podcast-person-remove',
'filter' => 'permission:podcast-edit',
......
......@@ -34,18 +34,12 @@ class Services extends BaseService
/**
* The Router class uses a RouteCollection's array of routes, and determines
* the correct Controller and Method to execute.
*
* @param RouteCollectionInterface|null $routes
* @param Request|null $request
* @param boolean $getShared
*
* @return Router
*/
public static function router(
RouteCollectionInterface $routes = null,
Request $request = null,
?RouteCollectionInterface $routes = null,
?Request $request = null,
bool $getShared = true
) {
): Router {
if ($getShared) {
return static::getSharedInstance('router', $routes, $request);
}
......@@ -60,16 +54,11 @@ class Services extends BaseService
* The Negotiate class provides the content negotiation features for
* working the request to determine correct language, encoding, charset,
* and more.
*
* @param RequestInterface|null $request
* @param boolean $getShared
*
* @return Negotiate
*/
public static function negotiator(
RequestInterface $request = null,
?RequestInterface $request = null,
bool $getShared = true
) {
): Negotiate {
if ($getShared) {
return static::getSharedInstance('negotiator', $request);
}
......@@ -79,6 +68,9 @@ class Services extends BaseService
return new Negotiate($request);
}
/**
* @return mixed
*/
public static function authentication(
string $lib = 'local',
Model $userModel = null,
......@@ -112,6 +104,9 @@ class Services extends BaseService
return $instance->setUserModel($userModel)->setLoginModel($loginModel);
}
/**
* @return mixed
*/
public static function authorization(
Model $groupModel = null,
Model $permissionModel = null,
......@@ -144,7 +139,7 @@ class Services extends BaseService
return $instance->setUserModel($userModel);
}
public static function breadcrumb(bool $getShared = true)
public static function breadcrumb(bool $getShared = true): Breadcrumb
{
if ($getShared) {
return self::getSharedInstance('breadcrumb');
......
......@@ -29,7 +29,7 @@ class View extends BaseView
* { title|esc(js) }
* { created_on|date(Y-m-d)|esc(attr) }
*
* @var array
* @var string[]
*/
public $filters = [];
......@@ -38,7 +38,7 @@ class View extends BaseView
* by the core Parser by creating aliases that will be replaced with
* any callable. Can be single or tag pair.
*
* @var array
* @var string[]
*/
public $plugins = [];
}
......@@ -15,9 +15,12 @@ class ActorController extends ActivityPubActorController
{
use AnalyticsTrait;
/**
* @var string[]
*/
protected $helpers = ['auth', 'svg', 'components', 'misc'];
public function follow()
public function follow(): string
{
// Prevent analytics hit when authenticated
if (!can_user_interact()) {
......
......@@ -25,7 +25,7 @@ class BaseController extends Controller
* class instantiation. These helpers will be available
* to all other controllers that extend BaseController.
*
* @var array
* @var string[]
*/
protected $helpers = ['auth', 'breadcrumb', 'svg', 'components', 'misc'];
......
......@@ -15,6 +15,7 @@ use Exception;
use App\Authorization\GroupModel;
use App\Models\PodcastModel;
use App\Models\UserModel;
use CodeIgniter\HTTP\RedirectResponse;
class ContributorController extends BaseController
{
......@@ -28,9 +29,9 @@ class ContributorController extends BaseController
*/
protected $user;
public function _remap($method, ...$params)
public function _remap(string $method, string ...$params): mixed
{
$this->podcast = (new PodcastModel())->getPodcastById($params[0]);
$this->podcast = (new PodcastModel())->getPodcastById((int) $params[0]);
if (count($params) <= 1) {
return $this->$method();
......@@ -38,8 +39,8 @@ class ContributorController extends BaseController
if (
$this->user = (new UserModel())->getPodcastContributor(
$params[1],
$params[0],
(int) $params[1],
(int) $params[0],
)
) {
return $this->$method();
......@@ -48,7 +49,7 @@ class ContributorController extends BaseController
throw PageNotFoundException::forPageNotFound();
}
public function list()
public function list(): string
{
$data = [
'podcast' => $this->podcast,
......@@ -58,7 +59,7 @@ class ContributorController extends BaseController
return view('admin/contributor/list', $data);
}
public function view()
public function view(): string
{
$data = [
'contributor' => (new UserModel())->getPodcastContributor(
......@@ -74,7 +75,7 @@ class ContributorController extends BaseController
return view('admin/contributor/view', $data);
}
public function add()
public function add(): string
{
helper('form');
......@@ -108,7 +109,7 @@ class ContributorController extends BaseController
return view('admin/contributor/add', $data);
}
public function attemptAdd()
public function attemptAdd(): RedirectResponse
{
try {
(new PodcastModel())->addPodcastContributor(
......@@ -116,7 +117,7 @@ class ContributorController extends BaseController
$this->podcast->id,
$this->request->getPost('role'),
);
} catch (Exception $exception) {
} catch (Exception) {
return redirect()
->back()
->withInput()
......@@ -128,7 +129,7 @@ class ContributorController extends BaseController
return redirect()->route('contributor-list', [$this->podcast->id]);
}
public function edit()
public function edit(): string
{
helper('form');
......@@ -159,7 +160,7 @@ class ContributorController extends BaseController
return view('admin/contributor/edit', $data);
}
public function attemptEdit()
public function attemptEdit(): RedirectResponse
{
(new PodcastModel())->updatePodcastContributor(
$this->user->id,
......@@ -170,7 +171,7 @@ class ContributorController extends BaseController
return redirect()->route('contributor-list', [$this->podcast->id]);
}
public function remove()
public function remove(): RedirectResponse
{
if ($this->podcast->created_by === $this->user->id) {
return redirect()
......
......@@ -8,6 +8,9 @@
namespace App\Controllers\Admin;
use CodeIgniter\Exceptions\PageNotFoundException;
use CodeIgniter\HTTP\RedirectResponse;
use Config\Database;
use App\Entities\Episode;
use App\Entities\Note;
use App\Entities\Podcast;
......@@ -29,12 +32,14 @@ class EpisodeController extends BaseController
*/
protected $episode;
public function _remap(string $method, ...$params)
public function _remap(string $method, string ...$params): mixed
{
if (
!($this->podcast = (new PodcastModel())->getPodcastById($params[0]))
($this->podcast = (new PodcastModel())->getPodcastById(
(int) $params[0],
)) === null
) {
throw \CodeIgniter\Exceptions\PageNotFoundException::forPageNotFound();
throw PageNotFoundException::forPageNotFound();
}
if (count($params) > 1) {
......@@ -46,7 +51,7 @@ class EpisodeController extends BaseController
])
->first())
) {
throw \CodeIgniter\Exceptions\PageNotFoundException::forPageNotFound();
throw PageNotFoundException::forPageNotFound();
}
unset($params[1]);
......@@ -56,7 +61,7 @@ class EpisodeController extends BaseController
return $this->$method(...$params);
}
public function list()
public function list(): string
{
$episodes = (new EpisodeModel())
->where('podcast_id', $this->podcast->id)
......@@ -74,7 +79,7 @@ class EpisodeController extends BaseController
return view('admin/episode/list', $data);
}
public function view()
public function view(): string
{
$data = [
'podcast' => $this->podcast,
......@@ -88,7 +93,7 @@ class EpisodeController extends BaseController
return view('admin/episode/view', $data);
}
public function create()
public function create(): string
{
helper(['form']);
......@@ -102,7 +107,7 @@ class EpisodeController extends BaseController
return view('admin/episode/create', $data);
}
public function attemptCreate()
public function attemptCreate(): RedirectResponse
{
$rules = [
'audio_file' => 'uploaded[audio_file]|ext_in[audio_file,mp3,m4a]',
......@@ -204,7 +209,7 @@ class EpisodeController extends BaseController
]);
}
public function edit()
public function edit(): string
{
helper(['form']);
......@@ -220,7 +225,7 @@ class EpisodeController extends BaseController
return view('admin/episode/edit', $data);
}
public function attemptEdit()
public function attemptEdit(): RedirectResponse
{
$rules = [
'audio_file' =>
......@@ -282,17 +287,14 @@ class EpisodeController extends BaseController
}
} elseif ($transcriptChoice === 'remote-url') {
if (
$transcriptFileRemoteUrl = $this->request->getPost(
($transcriptFileRemoteUrl = $this->request->getPost(
'transcript_file_remote_url',
)
)) &&
(($transcriptFile = $this->episode->transcript_file) &&
$transcriptFile !== null)
) {
if (
($transcriptFile = $this->episode->transcript_file) &&
$transcriptFile !== null
) {
unlink($transcriptFile);
$this->episode->transcript_file_path = null;
}
unlink($transcriptFile);
$this->episode->transcript_file_path = null;