From ed6e953010b774c228591a22f858084cf47c7c90 Mon Sep 17 00:00:00 2001
From: Yassine Doghri <yassine@doghri.fr>
Date: Tue, 4 Aug 2020 11:25:22 +0000
Subject: [PATCH] refactor: add php_codesniffer to define castopod's coding
 style based on psr-1

- add .editorconfig file
- format all files to comply with castopod's coding style
- switch parsedown dependency with commonmark library to better follow commonmark spec for markdown
- add prettier command to format all project files at once

closes #16
---
 .devcontainer/devcontainer.json               |   4 +-
 .editorconfig                                 |  12 +
 .phpcs.xml                                    |   7 +
 .prettierrc.json                              |   3 +-
 DEPENDENCIES.md                               |   2 +-
 app/Authorization/FlatAuthorization.php       |  14 +-
 app/Authorization/GroupModel.php              |   4 +-
 app/Authorization/PermissionModel.php         |   4 +-
 app/Config/App.php                            | 438 ++++----
 app/Config/Boot/development.php               |   1 +
 app/Config/Cache.php                          | 144 +--
 app/Config/ContentSecurityPolicy.php          |   4 +-
 app/Config/Database.php                       |   4 +-
 app/Config/DocTypes.php                       |   4 +-
 app/Config/Email.php                          |   1 +
 app/Config/Encryption.php                     |  31 +-
 app/Config/Events.php                         |   4 +-
 app/Config/Exceptions.php                     |  48 +-
 app/Config/Filters.php                        |   4 +-
 app/Config/ForeignCharacters.php              |   4 +-
 app/Config/Format.php                         |  48 +-
 app/Config/Honeypot.php                       |   4 +-
 app/Config/Images.php                         |   4 +-
 app/Config/Kint.php                           |  50 +-
 app/Config/Logger.php                         | 120 +--
 app/Config/Migrations.php                     |  72 +-
 app/Config/Mimes.php                          |   4 +-
 app/Config/Modules.php                        |  50 +-
 app/Config/Pager.php                          |  42 +-
 app/Config/Paths.php                          |   4 +-
 app/Config/Services.php                       |   4 +-
 app/Config/Toolbar.php                        |  86 +-
 app/Config/UserAgents.php                     |  20 +-
 app/Config/Validation.php                     |   4 +-
 app/Config/View.php                           |   4 +-
 app/Controllers/Admin/Contributor.php         |  17 +-
 app/Controllers/Admin/Episode.php             |  22 +-
 app/Controllers/Admin/Home.php                |   1 +
 app/Controllers/Admin/Myaccount.php           |  15 +-
 app/Controllers/Admin/Podcast.php             |  37 +-
 app/Controllers/Admin/User.php                |  51 +-
 app/Controllers/Analytics.php                 |   5 +-
 app/Controllers/BaseController.php            |   4 +-
 app/Controllers/Episode.php                   |  31 +-
 app/Controllers/Feed.php                      |  12 +-
 app/Controllers/Home.php                      |   9 +-
 app/Controllers/Migrate.php                   |   1 +
 app/Controllers/Podcast.php                   |   5 +-
 app/Controllers/UnknownUserAgents.php         |   6 +-
 .../2020-05-29-152000_add_categories.php      |   1 +
 .../2020-05-30-101000_add_languages.php       |   1 +
 .../2020-05-30-101500_add_podcasts.php        |   1 +
 .../2020-06-05-170000_add_episodes.php        |   1 +
 .../2020-06-05-190000_add_platforms.php       |   1 +
 .../2020-06-08-160000_add_platform_links.php  |   1 +
 ...0000_add_analytics_episodes_by_country.php |   2 +
 ...10000_add_analytics_episodes_by_player.php |   2 +
 ...0000_add_analytics_podcasts_by_country.php |   2 +
 ...10000_add_analytics_podcasts_by_player.php |   2 +
 ...10000_add_analytics_unknown_useragents.php |   2 +
 ...10000_add_analytics_website_by_browser.php |   2 +
 ...10000_add_analytics_website_by_country.php |   2 +
 ...10000_add_analytics_website_by_referer.php |   2 +
 ...dd_analytics_podcasts_stored_procedure.php |   2 +
 ...cs_unknown_useragents_stored_procedure.php |   2 +
 ...add_analytics_website_stored_procedure.php |   2 +
 .../2020-07-03-191500_add_users_podcasts.php  |   1 +
 app/Database/Seeds/AuthSeeder.php             |  35 +-
 app/Database/Seeds/CategorySeeder.php         |   1 +
 app/Database/Seeds/LanguageSeeder.php         |   1 +
 app/Database/Seeds/PlatformSeeder.php         |   1 +
 app/Database/Seeds/TestSeeder.php             |   3 +-
 app/Entities/AnalyticsEpisodesByCountry.php   |   2 +
 app/Entities/AnalyticsEpisodesByPlayer.php    |   2 +
 app/Entities/AnalyticsPodcastsByCountry.php   |   2 +
 app/Entities/AnalyticsPodcastsByPlayer.php    |   2 +
 app/Entities/AnalyticsUnknownUseragents.php   |   2 +
 app/Entities/AnalyticsWebsiteByBrowser.php    |   2 +
 app/Entities/AnalyticsWebsiteByCountry.php    |   2 +
 app/Entities/AnalyticsWebsiteByReferer.php    |   2 +
 app/Entities/Category.php                     |   8 +-
 app/Entities/Episode.php                      |  32 +-
 app/Entities/Language.php                     |   1 +
 app/Entities/Podcast.php                      |  11 +-
 app/Entities/User.php                         |   4 +-
 app/Filters/Permission.php                    |  10 +-
 app/Helpers/analytics_helper.php              |   3 +-
 app/Helpers/html_helper.php                   |   1 +
 app/Helpers/id3_helper.php                    |   1 +
 app/Helpers/media_helper.php                  |   1 +
 app/Helpers/misc_helper.php                   |   1 +
 app/Helpers/rss_helper.php                    |   2 +
 app/Helpers/url_helper.php                    |   1 +
 app/Language/en/AdminNavigation.php           |  27 +-
 app/Language/en/Contributor.php               |  17 +-
 app/Language/en/Countries.php                 |   5 +-
 app/Language/en/Episode.php                   |   9 +-
 app/Language/en/Home.php                      |   3 +-
 app/Language/en/MyAccount.php                 |  11 +-
 app/Language/en/Podcast.php                   |   9 +-
 app/Language/en/User.php                      |  28 +-
 app/Language/fr/Countries.php                 |   8 +-
 app/Libraries/SimpleRSSElement.php            |   5 +
 .../AnalyticsEpisodesByCountryModel.php       |   4 +-
 app/Models/AnalyticsEpisodesByPlayerModel.php |   4 +-
 .../AnalyticsPodcastsByCountryModel.php       |   4 +-
 app/Models/AnalyticsPodcastsByPlayerModel.php |   4 +-
 .../AnalyticsUnknownUseragentsModel.php       |   4 +-
 app/Models/AnalyticsWebsiteByBrowserModel.php |   4 +-
 app/Models/AnalyticsWebsiteByCountryModel.php |   4 +-
 app/Models/AnalyticsWebsiteByRefererModel.php |   4 +-
 app/Models/CategoryModel.php                  |   8 +-
 app/Models/EpisodeModel.php                   |  10 +-
 app/Models/LanguageModel.php                  |   3 +-
 app/Models/PlatformLinkModel.php              |   4 +-
 app/Models/PlatformModel.php                  |   4 +-
 app/Models/PodcastModel.php                   |  19 +-
 app/Models/UnknownUserAgentsModel.php         |   4 +-
 app/Models/UserModel.php                      |   6 +-
 app/Views/_layout.php                         |  40 +-
 app/Views/_message_block.php                  |  21 +-
 app/Views/admin/_layout.php                   |  48 +-
 app/Views/admin/_partials/_episode-card.php   |   6 +-
 app/Views/admin/_sidenav.php                  |   2 +-
 app/Views/admin/contributor/edit.php          |   2 +-
 app/Views/admin/episode/create.php            |   6 +-
 app/Views/admin/episode/edit.php              |  11 +-
 app/Views/admin/episode/view.php              |   4 +-
 app/Views/admin/podcast/create.php            |   2 +-
 app/Views/admin/podcast/list.php              |   6 +-
 app/Views/admin/podcast/view.php              |   6 +-
 app/Views/admin/user/list.php                 |   4 +-
 app/Views/auth/login.php                      |  42 +-
 app/Views/errors/cli/error_exception.php      |  22 +-
 app/Views/errors/html/debug.css               | 193 ++--
 app/Views/errors/html/debug.js                | 149 +--
 app/Views/errors/html/error_404.php           | 150 +--
 app/Views/errors/html/error_exception.php     | 936 ++++++++++--------
 app/Views/errors/html/production.php          |   3 -
 app/Views/podcast.php                         |   1 -
 composer.json                                 |   7 +-
 composer.lock                                 | 204 +++-
 package.json                                  |   1 +
 tests/README.md                               |  72 +-
 .../2020-02-22-222222_example_migration.php   | 108 +-
 .../_support/Database/Seeds/ExampleSeeder.php |  61 +-
 tests/_support/DatabaseTestCase.php           |  92 +-
 tests/_support/Libraries/ConfigReader.php     |   7 +-
 tests/_support/Models/ExampleModel.php        |  24 +-
 tests/_support/SessionTestCase.php            |  43 +-
 tests/database/ExampleDatabaseTest.php        |  56 +-
 tests/session/ExampleSessionTest.php          |  20 +-
 tests/unit/HealthTest.php                     |  46 +-
 153 files changed, 2338 insertions(+), 1900 deletions(-)
 create mode 100644 .editorconfig
 create mode 100644 .phpcs.xml

diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json
index 3be9a407bf..4422b82f12 100644
--- a/.devcontainer/devcontainer.json
+++ b/.devcontainer/devcontainer.json
@@ -9,6 +9,7 @@
     "[php]": {
       "editor.defaultFormatter": "esbenp.prettier-vscode"
     },
+    "phpSniffer.autoDetect": true,
     "color-highlight.markerType": "dot-before"
   },
   "extensions": [
@@ -22,6 +23,7 @@
     "bradlc.vscode-tailwindcss",
     "jamesbirtles.svelte-vscode",
     "dbaeumer.vscode-eslint",
-    "stylelint.vscode-stylelint"
+    "stylelint.vscode-stylelint",
+    "wongjn.php-sniffer"
   ]
 }
diff --git a/.editorconfig b/.editorconfig
new file mode 100644
index 0000000000..6441287494
--- /dev/null
+++ b/.editorconfig
@@ -0,0 +1,12 @@
+; top-most EditorConfig file
+root = true
+
+; Unix-style newlines
+[*]
+end_of_line = lf
+
+[*.php]
+indent_style = spaces
+charset = utf-8
+trim_trailing_whitespace = true
+insert_final_newline = true
\ No newline at end of file
diff --git a/.phpcs.xml b/.phpcs.xml
new file mode 100644
index 0000000000..741acfb0a9
--- /dev/null
+++ b/.phpcs.xml
@@ -0,0 +1,7 @@
+<?xml version="1.0"?>
+<ruleset xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" name="Castopod">
+    <description>Castopod's coding standard based on the PSR-1 standard.</description>
+
+    <!-- Include the whole PSR-1 standard -->
+    <rule ref="PSR1"/>
+</ruleset>
\ No newline at end of file
diff --git a/.prettierrc.json b/.prettierrc.json
index fe8eb4697a..e6b50d4cfc 100644
--- a/.prettierrc.json
+++ b/.prettierrc.json
@@ -5,8 +5,7 @@
       "files": "*.php",
       "options": {
         "phpVersion": "7.2",
-        "singleQuote": true,
-        "trailingCommaPHP": true
+        "singleQuote": true
       }
     }
   ]
diff --git a/DEPENDENCIES.md b/DEPENDENCIES.md
index c34592c2cc..62ea05ab40 100644
--- a/DEPENDENCIES.md
+++ b/DEPENDENCIES.md
@@ -10,7 +10,7 @@ PHP Dependencies:
 - [GeoIP2 PHP API](https://github.com/maxmind/GeoIP2-php) ([Apache License 2.0](https://github.com/maxmind/GeoIP2-php/blob/master/LICENSE))
 - [getID3](https://github.com/JamesHeinrich/getID3) ([GNU General Public License v3](https://github.com/JamesHeinrich/getID3/blob/2.0/licenses/license.gpl-30.txt))
 - [myth-auth](https://github.com/lonnieezell/myth-auth) ([MIT license](https://github.com/lonnieezell/myth-auth/blob/develop/LICENSE.md))
-- [parsedown](https://github.com/erusev/parsedown) ([MIT license](https://github.com/erusev/parsedown/blob/master/LICENSE.txt))
+- [commonmark](https://commonmark.thephpleague.com/) ([BSD 3-Clause "New" or "Revised" License](https://github.com/thephpleague/commonmark/blob/latest/LICENSE))
 
 Javascript dependencies:
 
diff --git a/app/Authorization/FlatAuthorization.php b/app/Authorization/FlatAuthorization.php
index 48b4ad7351..a732a8cbfd 100644
--- a/app/Authorization/FlatAuthorization.php
+++ b/app/Authorization/FlatAuthorization.php
@@ -1,4 +1,6 @@
-<?php namespace App\Authorization;
+<?php
+
+namespace App\Authorization;
 
 class FlatAuthorization extends \Myth\Auth\Authorization\FlatAuthorization
 {
@@ -49,26 +51,26 @@ class FlatAuthorization extends \Myth\Auth\Authorization\FlatAuthorization
     /**
      * Makes a member a part of multiple groups.
      *
-     * @param $user_id
+     * @param $userId
      * @param array|null $groups // Either collection of ID or names
      *
      * @return bool
      */
-    public function setUserGroups(int $user_id, $groups)
+    public function setUserGroups(int $userId, $groups)
     {
-        if (empty($user_id) || !is_numeric($user_id)) {
+        if (empty($userId) || !is_numeric($userId)) {
             return null;
         }
 
         // remove user from all groups before resetting it in new groups
-        $this->groupModel->removeUserFromAllGroups($user_id);
+        $this->groupModel->removeUserFromAllGroups($userId);
 
         if (empty($groups)) {
             return true;
         }
 
         foreach ($groups as $group) {
-            $this->addUserToGroup($user_id, $group);
+            $this->addUserToGroup($userId, $group);
         }
 
         return true;
diff --git a/app/Authorization/GroupModel.php b/app/Authorization/GroupModel.php
index 597a54f155..74455708d7 100644
--- a/app/Authorization/GroupModel.php
+++ b/app/Authorization/GroupModel.php
@@ -1,4 +1,6 @@
-<?php namespace App\Authorization;
+<?php
+
+namespace App\Authorization;
 
 class GroupModel extends \Myth\Auth\Authorization\GroupModel
 {
diff --git a/app/Authorization/PermissionModel.php b/app/Authorization/PermissionModel.php
index b8b56274f6..f60fe7d66e 100644
--- a/app/Authorization/PermissionModel.php
+++ b/app/Authorization/PermissionModel.php
@@ -1,4 +1,6 @@
-<?php namespace App\Authorization;
+<?php
+
+namespace App\Authorization;
 
 class PermissionModel extends \Myth\Auth\Authorization\PermissionModel
 {
diff --git a/app/Config/App.php b/app/Config/App.php
index 0f03019e94..55952114ae 100644
--- a/app/Config/App.php
+++ b/app/Config/App.php
@@ -7,181 +7,181 @@ use CodeIgniter\Config\BaseConfig;
 class App extends BaseConfig
 {
     /*
-	|--------------------------------------------------------------------------
-	| Base Site URL
-	|--------------------------------------------------------------------------
-	|
-	| URL to your CodeIgniter root. Typically this will be your base URL,
-	| WITH a trailing slash:
-	|
-	|	http://example.com/
-	|
-	| If this is not set then CodeIgniter will try guess the protocol, domain
-	| and path to your installation. However, you should always configure this
-	| explicitly and never rely on auto-guessing, especially in production
-	| environments.
-	|
-	*/
+    |--------------------------------------------------------------------------
+    | Base Site URL
+    |--------------------------------------------------------------------------
+    |
+    | URL to your CodeIgniter root. Typically this will be your base URL,
+    | WITH a trailing slash:
+    |
+    |   http://example.com/
+    |
+    | If this is not set then CodeIgniter will try guess the protocol, domain
+    | and path to your installation. However, you should always configure this
+    | explicitly and never rely on auto-guessing, especially in production
+    | environments.
+    |
+    */
     public $baseURL = 'http://localhost:8080/';
 
     /*
-	|--------------------------------------------------------------------------
-	| Index File
-	|--------------------------------------------------------------------------
-	|
-	| Typically this will be your index.php file, unless you've renamed it to
-	| something else. If you are using mod_rewrite to remove the page set this
-	| variable so that it is blank.
-	|
-	*/
+    |--------------------------------------------------------------------------
+    | Index File
+    |--------------------------------------------------------------------------
+    |
+    | Typically this will be your index.php file, unless you've renamed it to
+    | something else. If you are using mod_rewrite to remove the page set this
+    | variable so that it is blank.
+    |
+    */
     public $indexPage = 'index.php';
 
     /*
-	|--------------------------------------------------------------------------
-	| URI PROTOCOL
-	|--------------------------------------------------------------------------
-	|
-	| This item determines which getServer global should be used to retrieve the
-	| URI string.  The default setting of 'REQUEST_URI' works for most servers.
-	| If your links do not seem to work, try one of the other delicious flavors:
-	|
-	| 'REQUEST_URI'    Uses $_SERVER['REQUEST_URI']
-	| 'QUERY_STRING'   Uses $_SERVER['QUERY_STRING']
-	| 'PATH_INFO'      Uses $_SERVER['PATH_INFO']
-	|
-	| WARNING: If you set this to 'PATH_INFO', URIs will always be URL-decoded!
-	*/
+    |--------------------------------------------------------------------------
+    | URI PROTOCOL
+    |--------------------------------------------------------------------------
+    |
+    | This item determines which getServer global should be used to retrieve the
+    | URI string.  The default setting of 'REQUEST_URI' works for most servers.
+    | If your links do not seem to work, try one of the other delicious flavors:
+    |
+    | 'REQUEST_URI'    Uses $_SERVER['REQUEST_URI']
+    | 'QUERY_STRING'   Uses $_SERVER['QUERY_STRING']
+    | 'PATH_INFO'      Uses $_SERVER['PATH_INFO']
+    |
+    | WARNING: If you set this to 'PATH_INFO', URIs will always be URL-decoded!
+    */
     public $uriProtocol = 'REQUEST_URI';
 
     /*
-	|--------------------------------------------------------------------------
-	| Default Locale
-	|--------------------------------------------------------------------------
-	|
-	| The Locale roughly represents the language and location that your visitor
-	| is viewing the site from. It affects the language strings and other
-	| strings (like currency markers, numbers, etc), that your program
-	| should run under for this request.
-	|
-	*/
+    |--------------------------------------------------------------------------
+    | Default Locale
+    |--------------------------------------------------------------------------
+    |
+    | The Locale roughly represents the language and location that your visitor
+    | is viewing the site from. It affects the language strings and other
+    | strings (like currency markers, numbers, etc), that your program
+    | should run under for this request.
+    |
+    */
     public $defaultLocale = 'en';
 
     /*
-	|--------------------------------------------------------------------------
-	| Negotiate Locale
-	|--------------------------------------------------------------------------
-	|
-	| If true, the current Request object will automatically determine the
-	| language to use based on the value of the Accept-Language header.
-	|
-	| If false, no automatic detection will be performed.
-	|
-	*/
+    |--------------------------------------------------------------------------
+    | Negotiate Locale
+    |--------------------------------------------------------------------------
+    |
+    | If true, the current Request object will automatically determine the
+    | language to use based on the value of the Accept-Language header.
+    |
+    | If false, no automatic detection will be performed.
+    |
+    */
     public $negotiateLocale = true;
 
     /*
-	|--------------------------------------------------------------------------
-	| Supported Locales
-	|--------------------------------------------------------------------------
-	|
-	| If $negotiateLocale is true, this array lists the locales supported
-	| by the application in descending order of priority. If no match is
-	| found, the first locale will be used.
-	|
-	*/
+    |--------------------------------------------------------------------------
+    | Supported Locales
+    |--------------------------------------------------------------------------
+    |
+    | If $negotiateLocale is true, this array lists the locales supported
+    | by the application in descending order of priority. If no match is
+    | found, the first locale will be used.
+    |
+    */
     public $supportedLocales = ['en'];
 
     /*
-	|--------------------------------------------------------------------------
-	| Application Timezone
-	|--------------------------------------------------------------------------
-	|
-	| The default timezone that will be used in your application to display
-	| dates with the date helper, and can be retrieved through app_timezone()
-	|
-	*/
+    |--------------------------------------------------------------------------
+    | Application Timezone
+    |--------------------------------------------------------------------------
+    |
+    | The default timezone that will be used in your application to display
+    | dates with the date helper, and can be retrieved through app_timezone()
+    |
+    */
     public $appTimezone = 'UTC';
 
     /*
-	|--------------------------------------------------------------------------
-	| Default Character Set
-	|--------------------------------------------------------------------------
-	|
-	| This determines which character set is used by default in various methods
-	| that require a character set to be provided.
-	|
-	| See http://php.net/htmlspecialchars for a list of supported charsets.
-	|
-	*/
+    |--------------------------------------------------------------------------
+    | Default Character Set
+    |--------------------------------------------------------------------------
+    |
+    | This determines which character set is used by default in various methods
+    | that require a character set to be provided.
+    |
+    | See http://php.net/htmlspecialchars for a list of supported charsets.
+    |
+    */
     public $charset = 'UTF-8';
 
     /*
-	|--------------------------------------------------------------------------
-	| URI PROTOCOL
-	|--------------------------------------------------------------------------
-	|
-	| If true, this will force every request made to this application to be
-	| made via a secure connection (HTTPS). If the incoming request is not
-	| secure, the user will be redirected to a secure version of the page
-	| and the HTTP Strict Transport Security header will be set.
-	*/
+    |--------------------------------------------------------------------------
+    | URI PROTOCOL
+    |--------------------------------------------------------------------------
+    |
+    | If true, this will force every request made to this application to be
+    | made via a secure connection (HTTPS). If the incoming request is not
+    | secure, the user will be redirected to a secure version of the page
+    | and the HTTP Strict Transport Security header will be set.
+    */
     public $forceGlobalSecureRequests = false;
 
     /*
-	|--------------------------------------------------------------------------
-	| Session Variables
-	|--------------------------------------------------------------------------
-	|
-	| 'sessionDriver'
-	|
-	|	The storage driver to use: files, database, redis, memcached
-	|       - CodeIgniter\Session\Handlers\FileHandler
-	|       - CodeIgniter\Session\Handlers\DatabaseHandler
-	|       - CodeIgniter\Session\Handlers\MemcachedHandler
-	|       - CodeIgniter\Session\Handlers\RedisHandler
-	|
-	| 'sessionCookieName'
-	|
-	|	The session cookie name, must contain only [0-9a-z_-] characters
-	|
-	| 'sessionExpiration'
-	|
-	|	The number of SECONDS you want the session to last.
-	|	Setting to 0 (zero) means expire when the browser is closed.
-	|
-	| 'sessionSavePath'
-	|
-	|	The location to save sessions to, driver dependent.
-	|
-	|	For the 'files' driver, it's a path to a writable directory.
-	|	WARNING: Only absolute paths are supported!
-	|
-	|	For the 'database' driver, it's a table name.
-	|	Please read up the manual for the format with other session drivers.
-	|
-	|	IMPORTANT: You are REQUIRED to set a valid save path!
-	|
-	| 'sessionMatchIP'
-	|
-	|	Whether to match the user's IP address when reading the session data.
-	|
-	|	WARNING: If you're using the database driver, don't forget to update
-	|	         your session table's PRIMARY KEY when changing this setting.
-	|
-	| 'sessionTimeToUpdate'
-	|
-	|	How many seconds between CI regenerating the session ID.
-	|
-	| 'sessionRegenerateDestroy'
-	|
-	|	Whether to destroy session data associated with the old session ID
-	|	when auto-regenerating the session ID. When set to FALSE, the data
-	|	will be later deleted by the garbage collector.
-	|
-	| Other session cookie settings are shared with the rest of the application,
-	| except for 'cookie_prefix' and 'cookie_httponly', which are ignored here.
-	|
-	*/
+    |--------------------------------------------------------------------------
+    | Session Variables
+    |--------------------------------------------------------------------------
+    |
+    | 'sessionDriver'
+    |
+    |   The storage driver to use: files, database, redis, memcached
+    |       - CodeIgniter\Session\Handlers\FileHandler
+    |       - CodeIgniter\Session\Handlers\DatabaseHandler
+    |       - CodeIgniter\Session\Handlers\MemcachedHandler
+    |       - CodeIgniter\Session\Handlers\RedisHandler
+    |
+    | 'sessionCookieName'
+    |
+    |   The session cookie name, must contain only [0-9a-z_-] characters
+    |
+    | 'sessionExpiration'
+    |
+    |   The number of SECONDS you want the session to last.
+    |   Setting to 0 (zero) means expire when the browser is closed.
+    |
+    | 'sessionSavePath'
+    |
+    |   The location to save sessions to, driver dependent.
+    |
+    |   For the 'files' driver, it's a path to a writable directory.
+    |   WARNING: Only absolute paths are supported!
+    |
+    |   For the 'database' driver, it's a table name.
+    |   Please read up the manual for the format with other session drivers.
+    |
+    |   IMPORTANT: You are REQUIRED to set a valid save path!
+    |
+    | 'sessionMatchIP'
+    |
+    |   Whether to match the user's IP address when reading the session data.
+    |
+    |   WARNING: If you're using the database driver, don't forget to update
+    |            your session table's PRIMARY KEY when changing this setting.
+    |
+    | 'sessionTimeToUpdate'
+    |
+    |   How many seconds between CI regenerating the session ID.
+    |
+    | 'sessionRegenerateDestroy'
+    |
+    |   Whether to destroy session data associated with the old session ID
+    |   when auto-regenerating the session ID. When set to FALSE, the data
+    |   will be later deleted by the garbage collector.
+    |
+    | Other session cookie settings are shared with the rest of the application,
+    | except for 'cookie_prefix' and 'cookie_httponly', which are ignored here.
+    |
+    */
     public $sessionDriver = 'CodeIgniter\Session\Handlers\FileHandler';
     public $sessionCookieName = 'ci_session';
     public $sessionExpiration = 7200;
@@ -191,20 +191,20 @@ class App extends BaseConfig
     public $sessionRegenerateDestroy = false;
 
     /*
-	|--------------------------------------------------------------------------
-	| Cookie Related Variables
-	|--------------------------------------------------------------------------
-	|
-	| 'cookiePrefix'   = Set a cookie name prefix if you need to avoid collisions
-	| 'cookieDomain'   = Set to .your-domain.com for site-wide cookies
-	| 'cookiePath'     = Typically will be a forward slash
-	| 'cookieSecure'   = Cookie will only be set if a secure HTTPS connection exists.
-	| 'cookieHTTPOnly' = Cookie will only be accessible via HTTP(S) (no javascript)
-	|
-	| Note: These settings (with the exception of 'cookie_prefix' and
-	|       'cookie_httponly') will also affect sessions.
-	|
-	*/
+    |--------------------------------------------------------------------------
+    | Cookie Related Variables
+    |--------------------------------------------------------------------------
+    |
+    | 'cookiePrefix'   = Set a cookie name prefix if you need to avoid collisions
+    | 'cookieDomain'   = Set to .your-domain.com for site-wide cookies
+    | 'cookiePath'     = Typically will be a forward slash
+    | 'cookieSecure'   = Cookie will only be set if a secure HTTPS connection exists.
+    | 'cookieHTTPOnly' = Cookie will only be accessible via HTTP(S) (no javascript)
+    |
+    | Note: These settings (with the exception of 'cookie_prefix' and
+    |       'cookie_httponly') will also affect sessions.
+    |
+    */
     public $cookiePrefix = '';
     public $cookieDomain = '';
     public $cookiePath = '/';
@@ -212,38 +212,38 @@ class App extends BaseConfig
     public $cookieHTTPOnly = false;
 
     /*
-	|--------------------------------------------------------------------------
-	| Reverse Proxy IPs
-	|--------------------------------------------------------------------------
-	|
-	| If your server is behind a reverse proxy, you must whitelist the proxy
-	| IP addresses from which CodeIgniter should trust headers such as
-	| HTTP_X_FORWARDED_FOR and HTTP_CLIENT_IP in order to properly identify
-	| the visitor's IP address.
-	|
-	| You can use both an array or a comma-separated list of proxy addresses,
-	| as well as specifying whole subnets. Here are a few examples:
-	|
-	| Comma-separated:	'10.0.1.200,192.168.5.0/24'
-	| Array:		array('10.0.1.200', '192.168.5.0/24')
-	*/
+    |--------------------------------------------------------------------------
+    | Reverse Proxy IPs
+    |--------------------------------------------------------------------------
+    |
+    | If your server is behind a reverse proxy, you must whitelist the proxy
+    | IP addresses from which CodeIgniter should trust headers such as
+    | HTTP_X_FORWARDED_FOR and HTTP_CLIENT_IP in order to properly identify
+    | the visitor's IP address.
+    |
+    | You can use both an array or a comma-separated list of proxy addresses,
+    | as well as specifying whole subnets. Here are a few examples:
+    |
+    | Comma-separated:  '10.0.1.200,192.168.5.0/24'
+    | Array:        array('10.0.1.200', '192.168.5.0/24')
+    */
     public $proxyIPs = '';
 
     /*
-	|--------------------------------------------------------------------------
-	| Cross Site Request Forgery
-	|--------------------------------------------------------------------------
-	| Enables a CSRF cookie token to be set. When set to TRUE, token will be
-	| checked on a submitted form. If you are accepting user data, it is strongly
-	| recommended CSRF protection be enabled.
-	|
-	| CSRFTokenName   = The token name
-	| CSRFHeaderName  = The header name
-	| CSRFCookieName  = The cookie name
-	| CSRFExpire      = The number in seconds the token should expire.
-	| CSRFRegenerate  = Regenerate token on every submission
-	| CSRFRedirect    = Redirect to previous page with error on failure
-	*/
+    |--------------------------------------------------------------------------
+    | Cross Site Request Forgery
+    |--------------------------------------------------------------------------
+    | Enables a CSRF cookie token to be set. When set to TRUE, token will be
+    | checked on a submitted form. If you are accepting user data, it is strongly
+    | recommended CSRF protection be enabled.
+    |
+    | CSRFTokenName   = The token name
+    | CSRFHeaderName  = The header name
+    | CSRFCookieName  = The cookie name
+    | CSRFExpire      = The number in seconds the token should expire.
+    | CSRFRegenerate  = Regenerate token on every submission
+    | CSRFRedirect    = Redirect to previous page with error on failure
+    */
     public $CSRFTokenName = 'csrf_test_name';
     public $CSRFHeaderName = 'X-CSRF-TOKEN';
     public $CSRFCookieName = 'csrf_cookie_name';
@@ -252,42 +252,42 @@ class App extends BaseConfig
     public $CSRFRedirect = true;
 
     /*
-	|--------------------------------------------------------------------------
-	| Content Security Policy
-	|--------------------------------------------------------------------------
-	| Enables the Response's Content Secure Policy to restrict the sources that
-	| can be used for images, scripts, CSS files, audio, video, etc. If enabled,
-	| the Response object will populate default values for the policy from the
-	| ContentSecurityPolicy.php file. Controllers can always add to those
-	| restrictions at run time.
-	|
-	| For a better understanding of CSP, see these documents:
-	|   - http://www.html5rocks.com/en/tutorials/security/content-security-policy/
-	|   - http://www.w3.org/TR/CSP/
-	*/
+    |--------------------------------------------------------------------------
+    | Content Security Policy
+    |--------------------------------------------------------------------------
+    | Enables the Response's Content Secure Policy to restrict the sources that
+    | can be used for images, scripts, CSS files, audio, video, etc. If enabled,
+    | the Response object will populate default values for the policy from the
+    | ContentSecurityPolicy.php file. Controllers can always add to those
+    | restrictions at run time.
+    |
+    | For a better understanding of CSP, see these documents:
+    |   - http://www.html5rocks.com/en/tutorials/security/content-security-policy/
+    |   - http://www.w3.org/TR/CSP/
+    */
     public $CSPEnabled = false;
 
     /*
-	|--------------------------------------------------------------------------
-	| Media root folder
-	|--------------------------------------------------------------------------
-	| Defines the root folder for media files storage
-	*/
+    |--------------------------------------------------------------------------
+    | Media root folder
+    |--------------------------------------------------------------------------
+    | Defines the root folder for media files storage
+    */
     public $mediaRoot = 'media';
 
     /*
-	|--------------------------------------------------------------------------
-	| Admin gateway
-	|--------------------------------------------------------------------------
-	| Defines a base route for all admin pages
-	*/
+    |--------------------------------------------------------------------------
+    | Admin gateway
+    |--------------------------------------------------------------------------
+    | Defines a base route for all admin pages
+    */
     public $adminGateway = 'admin';
 
     /*
-	|--------------------------------------------------------------------------
-	| Auth gateway
-	|--------------------------------------------------------------------------
-	| Defines a base route for all authentication related pages
-	*/
+    |--------------------------------------------------------------------------
+    | Auth gateway
+    |--------------------------------------------------------------------------
+    | Defines a base route for all authentication related pages
+    */
     public $authGateway = 'auth';
 }
diff --git a/app/Config/Boot/development.php b/app/Config/Boot/development.php
index 7d6ae48d21..59c9732a82 100644
--- a/app/Config/Boot/development.php
+++ b/app/Config/Boot/development.php
@@ -1,4 +1,5 @@
 <?php
+
 /*
   |--------------------------------------------------------------------------
   | ERROR DISPLAY
diff --git a/app/Config/Cache.php b/app/Config/Cache.php
index d743c58a89..8aeec9642b 100644
--- a/app/Config/Cache.php
+++ b/app/Config/Cache.php
@@ -7,78 +7,78 @@ use CodeIgniter\Config\BaseConfig;
 class Cache extends BaseConfig
 {
     /*
-	|--------------------------------------------------------------------------
-	| Primary Handler
-	|--------------------------------------------------------------------------
-	|
-	| The name of the preferred handler that should be used. If for some reason
-	| it is not available, the $backupHandler will be used in its place.
-	|
-	*/
+    |--------------------------------------------------------------------------
+    | Primary Handler
+    |--------------------------------------------------------------------------
+    |
+    | The name of the preferred handler that should be used. If for some reason
+    | it is not available, the $backupHandler will be used in its place.
+    |
+    */
     public $handler = 'file';
 
     /*
-	|--------------------------------------------------------------------------
-	| Backup Handler
-	|--------------------------------------------------------------------------
-	|
-	| The name of the handler that will be used in case the first one is
-	| unreachable. Often, 'file' is used here since the filesystem is
-	| always available, though that's not always practical for the app.
-	|
-	*/
+    |--------------------------------------------------------------------------
+    | Backup Handler
+    |--------------------------------------------------------------------------
+    |
+    | The name of the handler that will be used in case the first one is
+    | unreachable. Often, 'file' is used here since the filesystem is
+    | always available, though that's not always practical for the app.
+    |
+    */
     public $backupHandler = 'dummy';
 
     /*
-	|--------------------------------------------------------------------------
-	| Cache Directory Path
-	|--------------------------------------------------------------------------
-	|
-	| The path to where cache files should be stored, if using a file-based
-	| system.
-	|
-	*/
+    |--------------------------------------------------------------------------
+    | Cache Directory Path
+    |--------------------------------------------------------------------------
+    |
+    | The path to where cache files should be stored, if using a file-based
+    | system.
+    |
+    */
     public $storePath = WRITEPATH . 'cache/';
 
     /*
-	|--------------------------------------------------------------------------
-	| Cache Include Query String
-	|--------------------------------------------------------------------------
-	|
-	| Whether to take the URL query string into consideration when generating
-	| output cache files. Valid options are:
-	|
-	|	false      = Disabled
-	|	true       = Enabled, take all query parameters into account.
-	|	             Please be aware that this may result in numerous cache
-	|	             files generated for the same page over and over again.
-	|	array('q') = Enabled, but only take into account the specified list
-	|	             of query parameters.
-	|
-	*/
+    |--------------------------------------------------------------------------
+    | Cache Include Query String
+    |--------------------------------------------------------------------------
+    |
+    | Whether to take the URL query string into consideration when generating
+    | output cache files. Valid options are:
+    |
+    |   false      = Disabled
+    |   true       = Enabled, take all query parameters into account.
+    |                Please be aware that this may result in numerous cache
+    |                files generated for the same page over and over again.
+    |   array('q') = Enabled, but only take into account the specified list
+    |                of query parameters.
+    |
+    */
     public $cacheQueryString = false;
 
     /*
-	|--------------------------------------------------------------------------
-	| Key Prefix
-	|--------------------------------------------------------------------------
-	|
-	| This string is added to all cache item names to help avoid collisions
-	| if you run multiple applications with the same cache engine.
-	|
-	*/
+    |--------------------------------------------------------------------------
+    | Key Prefix
+    |--------------------------------------------------------------------------
+    |
+    | This string is added to all cache item names to help avoid collisions
+    | if you run multiple applications with the same cache engine.
+    |
+    */
     public $prefix = '';
 
     /*
-	| -------------------------------------------------------------------------
-	| Memcached settings
-	| -------------------------------------------------------------------------
-	| Your Memcached servers can be specified below, if you are using
-	| the Memcached drivers.
-	|
-	|	See: https://codeigniter.com/user_guide/libraries/caching.html#memcached
-	|
-	*/
+    | -------------------------------------------------------------------------
+    | Memcached settings
+    | -------------------------------------------------------------------------
+    | Your Memcached servers can be specified below, if you are using
+    | the Memcached drivers.
+    |
+    |   See: https://codeigniter.com/user_guide/libraries/caching.html#memcached
+    |
+    */
     public $memcached = [
         'host' => '127.0.0.1',
         'port' => 11211,
@@ -87,13 +87,13 @@ class Cache extends BaseConfig
     ];
 
     /*
-	| -------------------------------------------------------------------------
-	| Redis settings
-	| -------------------------------------------------------------------------
-	| Your Redis server can be specified below, if you are using
-	| the Redis or Predis drivers.
-	|
-	*/
+    | -------------------------------------------------------------------------
+    | Redis settings
+    | -------------------------------------------------------------------------
+    | Your Redis server can be specified below, if you are using
+    | the Redis or Predis drivers.
+    |
+    */
     public $redis = [
         'host' => '127.0.0.1',
         'password' => null,
@@ -103,14 +103,14 @@ class Cache extends BaseConfig
     ];
 
     /*
-	|--------------------------------------------------------------------------
-	| Available Cache Handlers
-	|--------------------------------------------------------------------------
-	|
-	| This is an array of cache engine alias' and class names. Only engines
-	| that are listed here are allowed to be used.
-	|
-	*/
+    |--------------------------------------------------------------------------
+    | Available Cache Handlers
+    |--------------------------------------------------------------------------
+    |
+    | This is an array of cache engine alias' and class names. Only engines
+    | that are listed here are allowed to be used.
+    |
+    */
     public $validHandlers = [
         'dummy' => \CodeIgniter\Cache\Handlers\DummyHandler::class,
         'file' => \CodeIgniter\Cache\Handlers\FileHandler::class,
diff --git a/app/Config/ContentSecurityPolicy.php b/app/Config/ContentSecurityPolicy.php
index 2a0f15682a..2ff4a68a5b 100644
--- a/app/Config/ContentSecurityPolicy.php
+++ b/app/Config/ContentSecurityPolicy.php
@@ -1,4 +1,6 @@
-<?php namespace Config;
+<?php
+
+namespace Config;
 
 use CodeIgniter\Config\BaseConfig;
 
diff --git a/app/Config/Database.php b/app/Config/Database.php
index 235a49a313..a77c5865d3 100644
--- a/app/Config/Database.php
+++ b/app/Config/Database.php
@@ -1,4 +1,6 @@
-<?php namespace Config;
+<?php
+
+namespace Config;
 
 /**
  * Database Configuration
diff --git a/app/Config/DocTypes.php b/app/Config/DocTypes.php
index d203af7159..7ce591b59f 100644
--- a/app/Config/DocTypes.php
+++ b/app/Config/DocTypes.php
@@ -1,4 +1,6 @@
-<?php namespace Config;
+<?php
+
+namespace Config;
 
 /**
  * DocTypes
diff --git a/app/Config/Email.php b/app/Config/Email.php
index d1703a595e..61f9f14066 100644
--- a/app/Config/Email.php
+++ b/app/Config/Email.php
@@ -1,4 +1,5 @@
 <?php
+
 namespace Config;
 
 use CodeIgniter\Config\BaseConfig;
diff --git a/app/Config/Encryption.php b/app/Config/Encryption.php
index d21657d16a..7beac59d9c 100644
--- a/app/Config/Encryption.php
+++ b/app/Config/Encryption.php
@@ -1,4 +1,5 @@
 <?php
+
 namespace Config;
 
 use CodeIgniter\Config\BaseConfig;
@@ -12,24 +13,24 @@ use CodeIgniter\Config\BaseConfig;
 class Encryption extends BaseConfig
 {
     /*
-	  |--------------------------------------------------------------------------
-	  | Encryption Key Starter
-	  |--------------------------------------------------------------------------
-	  |
-	  | If you use the Encryption class you must set an encryption key (seed).
-	  | You need to ensure it is long enough for the cipher and mode you plan to use.
-	  | See the user guide for more info.
-	 */
+      |--------------------------------------------------------------------------
+      | Encryption Key Starter
+      |--------------------------------------------------------------------------
+      |
+      | If you use the Encryption class you must set an encryption key (seed).
+      | You need to ensure it is long enough for the cipher and mode you plan to use.
+      | See the user guide for more info.
+     */
 
     public $key = '';
 
     /*
-	  |--------------------------------------------------------------------------
-	  | Encryption driver to use
-	  |--------------------------------------------------------------------------
-	  |
-	  | One of the supported drivers, eg 'OpenSSL' or 'Sodium'.
-	  | The default driver, if you don't specify one, is 'OpenSSL'.
-	 */
+      |--------------------------------------------------------------------------
+      | Encryption driver to use
+      |--------------------------------------------------------------------------
+      |
+      | One of the supported drivers, eg 'OpenSSL' or 'Sodium'.
+      | The default driver, if you don't specify one, is 'OpenSSL'.
+     */
     public $driver = 'OpenSSL';
 }
diff --git a/app/Config/Events.php b/app/Config/Events.php
index 9d26d71717..ce8331e9f0 100644
--- a/app/Config/Events.php
+++ b/app/Config/Events.php
@@ -1,4 +1,6 @@
-<?php namespace Config;
+<?php
+
+namespace Config;
 
 use CodeIgniter\Events\Events;
 
diff --git a/app/Config/Exceptions.php b/app/Config/Exceptions.php
index a58ea923c5..90f43581ad 100644
--- a/app/Config/Exceptions.php
+++ b/app/Config/Exceptions.php
@@ -1,4 +1,6 @@
-<?php namespace Config;
+<?php
+
+namespace Config;
 
 /**
  * Setup how the exception handler works.
@@ -9,33 +11,33 @@
 class Exceptions
 {
     /*
-	 |--------------------------------------------------------------------------
-	 | LOG EXCEPTIONS?
-	 |--------------------------------------------------------------------------
-	 | If true, then exceptions will be logged
-	 | through Services::Log.
-	 |
-	 | Default: true
-	 */
+     |--------------------------------------------------------------------------
+     | LOG EXCEPTIONS?
+     |--------------------------------------------------------------------------
+     | If true, then exceptions will be logged
+     | through Services::Log.
+     |
+     | Default: true
+     */
     public $log = true;
 
     /*
-	 |--------------------------------------------------------------------------
-	 | DO NOT LOG STATUS CODES
-	 |--------------------------------------------------------------------------
-	 | Any status codes here will NOT be logged if logging is turned on.
-	 | By default, only 404 (Page Not Found) exceptions are ignored.
-	 */
+     |--------------------------------------------------------------------------
+     | DO NOT LOG STATUS CODES
+     |--------------------------------------------------------------------------
+     | Any status codes here will NOT be logged if logging is turned on.
+     | By default, only 404 (Page Not Found) exceptions are ignored.
+     */
     public $ignoreCodes = [404];
 
     /*
-	|--------------------------------------------------------------------------
-	| Error Views Path
-	|--------------------------------------------------------------------------
-	| This is the path to the directory that contains the 'cli' and 'html'
-	| directories that hold the views used to generate errors.
-	|
-	| Default: APPPATH.'Views/errors'
-	*/
+    |--------------------------------------------------------------------------
+    | Error Views Path
+    |--------------------------------------------------------------------------
+    | This is the path to the directory that contains the 'cli' and 'html'
+    | directories that hold the views used to generate errors.
+    |
+    | Default: APPPATH.'Views/errors'
+    */
     public $errorViewPath = APPPATH . 'Views/errors';
 }
diff --git a/app/Config/Filters.php b/app/Config/Filters.php
index da69ca64af..bb46e71695 100644
--- a/app/Config/Filters.php
+++ b/app/Config/Filters.php
@@ -1,4 +1,6 @@
-<?php namespace Config;
+<?php
+
+namespace Config;
 
 use CodeIgniter\Config\BaseConfig;
 
diff --git a/app/Config/ForeignCharacters.php b/app/Config/ForeignCharacters.php
index fb9da5c160..acb06ddbf5 100644
--- a/app/Config/ForeignCharacters.php
+++ b/app/Config/ForeignCharacters.php
@@ -1,4 +1,6 @@
-<?php namespace Config;
+<?php
+
+namespace Config;
 
 class ForeignCharacters extends \CodeIgniter\Config\ForeignCharacters
 {
diff --git a/app/Config/Format.php b/app/Config/Format.php
index 989bcfe35d..e732d07f61 100644
--- a/app/Config/Format.php
+++ b/app/Config/Format.php
@@ -1,23 +1,25 @@
-<?php namespace Config;
+<?php
+
+namespace Config;
 
 use CodeIgniter\Config\BaseConfig;
 
 class Format extends BaseConfig
 {
     /*
-	|--------------------------------------------------------------------------
-	| Available Response Formats
-	|--------------------------------------------------------------------------
-	|
-	| When you perform content negotiation with the request, these are the
-	| available formats that your application supports. This is currently
-	| only used with the API\ResponseTrait. A valid Formatter must exist
-	| for the specified format.
-	|
-	| These formats are only checked when the data passed to the respond()
-	| method is an array.
-	|
-	*/
+    |--------------------------------------------------------------------------
+    | Available Response Formats
+    |--------------------------------------------------------------------------
+    |
+    | When you perform content negotiation with the request, these are the
+    | available formats that your application supports. This is currently
+    | only used with the API\ResponseTrait. A valid Formatter must exist
+    | for the specified format.
+    |
+    | These formats are only checked when the data passed to the respond()
+    | method is an array.
+    |
+    */
     public $supportedResponseFormats = [
         'application/json',
         'application/xml', // machine-readable XML
@@ -25,15 +27,15 @@ class Format extends BaseConfig
     ];
 
     /*
-	|--------------------------------------------------------------------------
-	| Formatters
-	|--------------------------------------------------------------------------
-	|
-	| Lists the class to use to format responses with of a particular type.
-	| For each mime type, list the class that should be used. Formatters
-	| can be retrieved through the getFormatter() method.
-	|
-	*/
+    |--------------------------------------------------------------------------
+    | Formatters
+    |--------------------------------------------------------------------------
+    |
+    | Lists the class to use to format responses with of a particular type.
+    | For each mime type, list the class that should be used. Formatters
+    | can be retrieved through the getFormatter() method.
+    |
+    */
     public $formatters = [
         'application/json' => \CodeIgniter\Format\JSONFormatter::class,
         'application/xml' => \CodeIgniter\Format\XMLFormatter::class,
diff --git a/app/Config/Honeypot.php b/app/Config/Honeypot.php
index e49a268192..fe99eb2b16 100644
--- a/app/Config/Honeypot.php
+++ b/app/Config/Honeypot.php
@@ -1,4 +1,6 @@
-<?php namespace Config;
+<?php
+
+namespace Config;
 
 use CodeIgniter\Config\BaseConfig;
 
diff --git a/app/Config/Images.php b/app/Config/Images.php
index a66c993e34..e5632dbc07 100644
--- a/app/Config/Images.php
+++ b/app/Config/Images.php
@@ -1,4 +1,6 @@
-<?php namespace Config;
+<?php
+
+namespace Config;
 
 use CodeIgniter\Config\BaseConfig;
 
diff --git a/app/Config/Kint.php b/app/Config/Kint.php
index c9f89c5447..df20e85751 100644
--- a/app/Config/Kint.php
+++ b/app/Config/Kint.php
@@ -1,4 +1,6 @@
-<?php namespace Config;
+<?php
+
+namespace Config;
 
 use CodeIgniter\Config\BaseConfig;
 use Kint\Renderer\Renderer;
@@ -6,23 +8,23 @@ use Kint\Renderer\Renderer;
 class Kint extends BaseConfig
 {
     /*
-	|--------------------------------------------------------------------------
-	| Kint
-	|--------------------------------------------------------------------------
-	|
-	| We use Kint's RichRenderer and CLIRenderer. This area contains options
-	| that you can set to customize how Kint works for you.
-	|
-	| For details on these settings, see Kint's docs:
-	|	https://kint-php.github.io/kint/
-	|
-	*/
+    |--------------------------------------------------------------------------
+    | Kint
+    |--------------------------------------------------------------------------
+    |
+    | We use Kint's RichRenderer and CLIRenderer. This area contains options
+    | that you can set to customize how Kint works for you.
+    |
+    | For details on these settings, see Kint's docs:
+    |   https://kint-php.github.io/kint/
+    |
+    */
 
     /*
-	|--------------------------------------------------------------------------
-	| Global Settings
-	|--------------------------------------------------------------------------
-	*/
+    |--------------------------------------------------------------------------
+    | Global Settings
+    |--------------------------------------------------------------------------
+    */
 
     public $plugins = null;
 
@@ -33,10 +35,10 @@ class Kint extends BaseConfig
     public $expanded = false;
 
     /*
-	|--------------------------------------------------------------------------
-	| RichRenderer Settings
-	|--------------------------------------------------------------------------
-	*/
+    |--------------------------------------------------------------------------
+    | RichRenderer Settings
+    |--------------------------------------------------------------------------
+    */
     public $richTheme = 'aante-light.css';
 
     public $richFolder = false;
@@ -48,10 +50,10 @@ class Kint extends BaseConfig
     public $richTabPlugins = null;
 
     /*
-	|--------------------------------------------------------------------------
-	| CLI Settings
-	|--------------------------------------------------------------------------
-	*/
+    |--------------------------------------------------------------------------
+    | CLI Settings
+    |--------------------------------------------------------------------------
+    */
     public $cliColors = true;
 
     public $cliForceUTF8 = false;
diff --git a/app/Config/Logger.php b/app/Config/Logger.php
index 597924faaf..b6c5ca4b41 100644
--- a/app/Config/Logger.php
+++ b/app/Config/Logger.php
@@ -1,74 +1,76 @@
-<?php namespace Config;
+<?php
+
+namespace Config;
 
 use CodeIgniter\Config\BaseConfig;
 
 class Logger extends BaseConfig
 {
     /*
-	|--------------------------------------------------------------------------
-	| Error Logging Threshold
-	|--------------------------------------------------------------------------
-	|
-	| You can enable error logging by setting a threshold over zero. The
-	| threshold determines what gets logged. Any values below or equal to the
-	| threshold will be logged. Threshold options are:
-	|
-	|	0 = Disables logging, Error logging TURNED OFF
-	|	1 = Emergency Messages  - System is unusable
-	|	2 = Alert Messages      - Action Must Be Taken Immediately
-	|   3 = Critical Messages   - Application component unavailable, unexpected exception.
-	|   4 = Runtime Errors      - Don't need immediate action, but should be monitored.
-	|   5 = Warnings               - Exceptional occurrences that are not errors.
-	|   6 = Notices            - Normal but significant events.
-	|   7 = Info             - Interesting events, like user logging in, etc.
-	|   8 = Debug                - Detailed debug information.
-	|   9 = All Messages
-	|
-	| You can also pass an array with threshold levels to show individual error types
-	|
-	| 	array(1, 2, 3, 8) = Emergency, Alert, Critical, and Debug messages
-	|
-	| For a live site you'll usually enable Critical or higher (3) to be logged otherwise
-	| your log files will fill up very fast.
-	|
-	*/
+    |--------------------------------------------------------------------------
+    | Error Logging Threshold
+    |--------------------------------------------------------------------------
+    |
+    | You can enable error logging by setting a threshold over zero. The
+    | threshold determines what gets logged. Any values below or equal to the
+    | threshold will be logged. Threshold options are:
+    |
+    |   0 = Disables logging, Error logging TURNED OFF
+    |   1 = Emergency Messages  - System is unusable
+    |   2 = Alert Messages      - Action Must Be Taken Immediately
+    |   3 = Critical Messages   - Application component unavailable, unexpected exception.
+    |   4 = Runtime Errors      - Don't need immediate action, but should be monitored.
+    |   5 = Warnings               - Exceptional occurrences that are not errors.
+    |   6 = Notices            - Normal but significant events.
+    |   7 = Info             - Interesting events, like user logging in, etc.
+    |   8 = Debug                - Detailed debug information.
+    |   9 = All Messages
+    |
+    | You can also pass an array with threshold levels to show individual error types
+    |
+    |   array(1, 2, 3, 8) = Emergency, Alert, Critical, and Debug messages
+    |
+    | For a live site you'll usually enable Critical or higher (3) to be logged otherwise
+    | your log files will fill up very fast.
+    |
+    */
     public $threshold = 3;
 
     /*
-	|--------------------------------------------------------------------------
-	| Date Format for Logs
-	|--------------------------------------------------------------------------
-	|
-	| Each item that is logged has an associated date. You can use PHP date
-	| codes to set your own date formatting
-	|
-	*/
+    |--------------------------------------------------------------------------
+    | Date Format for Logs
+    |--------------------------------------------------------------------------
+    |
+    | Each item that is logged has an associated date. You can use PHP date
+    | codes to set your own date formatting
+    |
+    */
     public $dateFormat = 'Y-m-d H:i:s';
 
     /*
-	|--------------------------------------------------------------------------
-	| Log Handlers
-	|--------------------------------------------------------------------------
-	|
-	| The logging system supports multiple actions to be taken when something
-	| is logged. This is done by allowing for multiple Handlers, special classes
-	| designed to write the log to their chosen destinations, whether that is
-	| a file on the getServer, a cloud-based service, or even taking actions such
-	| as emailing the dev team.
-	|
-	| Each handler is defined by the class name used for that handler, and it
-	| MUST implement the CodeIgniter\Log\Handlers\HandlerInterface interface.
-	|
-	| The value of each key is an array of configuration items that are sent
-	| to the constructor of each handler. The only required configuration item
-	| is the 'handles' element, which must be an array of integer log levels.
-	| This is most easily handled by using the constants defined in the
-	| Psr\Log\LogLevel class.
-	|
-	| Handlers are executed in the order defined in this array, starting with
-	| the handler on top and continuing down.
-	|
-	*/
+    |--------------------------------------------------------------------------
+    | Log Handlers
+    |--------------------------------------------------------------------------
+    |
+    | The logging system supports multiple actions to be taken when something
+    | is logged. This is done by allowing for multiple Handlers, special classes
+    | designed to write the log to their chosen destinations, whether that is
+    | a file on the getServer, a cloud-based service, or even taking actions such
+    | as emailing the dev team.
+    |
+    | Each handler is defined by the class name used for that handler, and it
+    | MUST implement the CodeIgniter\Log\Handlers\HandlerInterface interface.
+    |
+    | The value of each key is an array of configuration items that are sent
+    | to the constructor of each handler. The only required configuration item
+    | is the 'handles' element, which must be an array of integer log levels.
+    | This is most easily handled by using the constants defined in the
+    | Psr\Log\LogLevel class.
+    |
+    | Handlers are executed in the order defined in this array, starting with
+    | the handler on top and continuing down.
+    |
+    */
     public $handlers = [
         //--------------------------------------------------------------------
         // File Handler
diff --git a/app/Config/Migrations.php b/app/Config/Migrations.php
index efb48dbec9..36b9900b10 100644
--- a/app/Config/Migrations.php
+++ b/app/Config/Migrations.php
@@ -1,49 +1,51 @@
-<?php namespace Config;
+<?php
+
+namespace Config;
 
 use CodeIgniter\Config\BaseConfig;
 
 class Migrations extends BaseConfig
 {
     /*
-	|--------------------------------------------------------------------------
-	| Enable/Disable Migrations
-	|--------------------------------------------------------------------------
-	|
-	| Migrations are enabled by default for security reasons.
-	| You should enable migrations whenever you intend to do a schema migration
-	| and disable it back when you're done.
-	|
-	*/
+    |--------------------------------------------------------------------------
+    | Enable/Disable Migrations
+    |--------------------------------------------------------------------------
+    |
+    | Migrations are enabled by default for security reasons.
+    | You should enable migrations whenever you intend to do a schema migration
+    | and disable it back when you're done.
+    |
+    */
     public $enabled = true;
 
     /*
-	|--------------------------------------------------------------------------
-	| Migrations table
-	|--------------------------------------------------------------------------
-	|
-	| This is the name of the table that will store the current migrations state.
-	| When migrations runs it will store in a database table which migration
-	| level the system is at. It then compares the migration level in this
-	| table to the $config['migration_version'] if they are not the same it
-	| will migrate up. This must be set.
-	|
-	*/
+    |--------------------------------------------------------------------------
+    | Migrations table
+    |--------------------------------------------------------------------------
+    |
+    | This is the name of the table that will store the current migrations state.
+    | When migrations runs it will store in a database table which migration
+    | level the system is at. It then compares the migration level in this
+    | table to the $config['migration_version'] if they are not the same it
+    | will migrate up. This must be set.
+    |
+    */
     public $table = 'migrations';
 
     /*
-	|--------------------------------------------------------------------------
-	| Timestamp Format
-	|--------------------------------------------------------------------------
-	|
-	| This is the format that will be used when creating new migrations
-	| using the cli command:
-	|   > php spark migrate:create
-	|
-	| Typical formats:
-	|   YmdHis_
-	|   Y-m-d-His_
-	|   Y_m_d_His_
-	|
-	*/
+    |--------------------------------------------------------------------------
+    | Timestamp Format
+    |--------------------------------------------------------------------------
+    |
+    | This is the format that will be used when creating new migrations
+    | using the cli command:
+    |   > php spark migrate:create
+    |
+    | Typical formats:
+    |   YmdHis_
+    |   Y-m-d-His_
+    |   Y_m_d_His_
+    |
+    */
     public $timestampFormat = 'Y-m-d-His_';
 }
diff --git a/app/Config/Mimes.php b/app/Config/Mimes.php
index 0e246852d6..ac5c7f4638 100644
--- a/app/Config/Mimes.php
+++ b/app/Config/Mimes.php
@@ -1,4 +1,6 @@
-<?php namespace Config;
+<?php
+
+namespace Config;
 
 /*
 | -------------------------------------------------------------------
diff --git a/app/Config/Modules.php b/app/Config/Modules.php
index e179f48969..8e4c1273f0 100644
--- a/app/Config/Modules.php
+++ b/app/Config/Modules.php
@@ -1,38 +1,40 @@
-<?php namespace Config;
+<?php
+
+namespace Config;
 
 // Cannot extend BaseConfig or looping resources occurs.
 class Modules
 {
     /*
-	 |--------------------------------------------------------------------------
-	 | Auto-Discovery Enabled?
-	 |--------------------------------------------------------------------------
-	 |
-	 | If true, then auto-discovery will happen across all elements listed in
-	 | $activeExplorers below. If false, no auto-discovery will happen at all,
-	 | giving a slight performance boost.
-	 */
+     |--------------------------------------------------------------------------
+     | Auto-Discovery Enabled?
+     |--------------------------------------------------------------------------
+     |
+     | If true, then auto-discovery will happen across all elements listed in
+     | $activeExplorers below. If false, no auto-discovery will happen at all,
+     | giving a slight performance boost.
+     */
     public $enabled = true;
 
     /*
-	 |--------------------------------------------------------------------------
-	 | Auto-Discovery Within Composer Packages Enabled?
-	 |--------------------------------------------------------------------------
-	 |
-	 | If true, then auto-discovery will happen across all namespaces loaded
-	 | by Composer, as well as the namespaces configured locally.
-	 */
+     |--------------------------------------------------------------------------
+     | Auto-Discovery Within Composer Packages Enabled?
+     |--------------------------------------------------------------------------
+     |
+     | If true, then auto-discovery will happen across all namespaces loaded
+     | by Composer, as well as the namespaces configured locally.
+     */
     public $discoverInComposer = true;
 
     /*
-	|--------------------------------------------------------------------------
-	| Auto-discover Rules
-	|--------------------------------------------------------------------------
-	|
-	| Lists the aliases of all discovery classes that will be active
-	| and used during the current application request. If it is not
-	| listed here, only the base application elements will be used.
-	*/
+    |--------------------------------------------------------------------------
+    | Auto-discover Rules
+    |--------------------------------------------------------------------------
+    |
+    | Lists the aliases of all discovery classes that will be active
+    | and used during the current application request. If it is not
+    | listed here, only the base application elements will be used.
+    */
     public $activeExplorers = ['events', 'registrars', 'routes', 'services'];
 
     /**
diff --git a/app/Config/Pager.php b/app/Config/Pager.php
index e3ada2e6c0..50a4a5f97e 100644
--- a/app/Config/Pager.php
+++ b/app/Config/Pager.php
@@ -1,22 +1,24 @@
-<?php namespace Config;
+<?php
+
+namespace Config;
 
 use CodeIgniter\Config\BaseConfig;
 
 class Pager extends BaseConfig
 {
     /*
-	|--------------------------------------------------------------------------
-	| Templates
-	|--------------------------------------------------------------------------
-	|
-	| Pagination links are rendered out using views to configure their
-	| appearance. This array contains aliases and the view names to
-	| use when rendering the links.
-	|
-	| Within each view, the Pager object will be available as $pager,
-	| and the desired group as $pagerGroup;
-	|
-	*/
+    |--------------------------------------------------------------------------
+    | Templates
+    |--------------------------------------------------------------------------
+    |
+    | Pagination links are rendered out using views to configure their
+    | appearance. This array contains aliases and the view names to
+    | use when rendering the links.
+    |
+    | Within each view, the Pager object will be available as $pager,
+    | and the desired group as $pagerGroup;
+    |
+    */
     public $templates = [
         'default_full' => 'CodeIgniter\Pager\Views\default_full',
         'default_simple' => 'CodeIgniter\Pager\Views\default_simple',
@@ -24,12 +26,12 @@ class Pager extends BaseConfig
     ];
 
     /*
-	|--------------------------------------------------------------------------
-	| Items Per Page
-	|--------------------------------------------------------------------------
-	|
-	| The default number of results shown in a single page.
-	|
-	*/
+    |--------------------------------------------------------------------------
+    | Items Per Page
+    |--------------------------------------------------------------------------
+    |
+    | The default number of results shown in a single page.
+    |
+    */
     public $perPage = 20;
 }
diff --git a/app/Config/Paths.php b/app/Config/Paths.php
index f574dad59d..79c3408fa5 100644
--- a/app/Config/Paths.php
+++ b/app/Config/Paths.php
@@ -1,4 +1,6 @@
-<?php namespace Config;
+<?php
+
+namespace Config;
 
 /**
  * Holds the paths that are used by the system to
diff --git a/app/Config/Services.php b/app/Config/Services.php
index 634c54608e..275caab237 100644
--- a/app/Config/Services.php
+++ b/app/Config/Services.php
@@ -1,4 +1,6 @@
-<?php namespace Config;
+<?php
+
+namespace Config;
 
 use CodeIgniter\Config\Services as CoreServices;
 use CodeIgniter\Model;
diff --git a/app/Config/Toolbar.php b/app/Config/Toolbar.php
index 14d3e7bd3b..d2b4082550 100644
--- a/app/Config/Toolbar.php
+++ b/app/Config/Toolbar.php
@@ -1,21 +1,23 @@
-<?php namespace Config;
+<?php
+
+namespace Config;
 
 use CodeIgniter\Config\BaseConfig;
 
 class Toolbar extends BaseConfig
 {
     /*
-	|--------------------------------------------------------------------------
-	| Debug Toolbar
-	|--------------------------------------------------------------------------
-	| The Debug Toolbar provides a way to see information about the performance
-	| and state of your application during that page display. By default it will
-	| NOT be displayed under production environments, and will only display if
-	| CI_DEBUG is true, since if it's not, there's not much to display anyway.
-	|
-	| toolbarMaxHistory = Number of history files, 0 for none or -1 for unlimited
-	|
-	*/
+    |--------------------------------------------------------------------------
+    | Debug Toolbar
+    |--------------------------------------------------------------------------
+    | The Debug Toolbar provides a way to see information about the performance
+    | and state of your application during that page display. By default it will
+    | NOT be displayed under production environments, and will only display if
+    | CI_DEBUG is true, since if it's not, there's not much to display anyway.
+    |
+    | toolbarMaxHistory = Number of history files, 0 for none or -1 for unlimited
+    |
+    */
     public $collectors = [
         \CodeIgniter\Debug\Toolbar\Collectors\Timers::class,
         \CodeIgniter\Debug\Toolbar\Collectors\Database::class,
@@ -29,41 +31,41 @@ class Toolbar extends BaseConfig
     ];
 
     /*
-	|--------------------------------------------------------------------------
-	| Max History
-	|--------------------------------------------------------------------------
-	| The Toolbar allows you to view recent requests that have been made to
-	| the application while the toolbar is active. This allows you to quickly
-	| view and compare multiple requests.
-	|
-	| $maxHistory sets a limit on the number of past requests that are stored,
-	| helping to conserve file space used to store them. You can set it to
-	| 0 (zero) to not have any history stored, or -1 for unlimited history.
-	|
-	*/
+    |--------------------------------------------------------------------------
+    | Max History
+    |--------------------------------------------------------------------------
+    | The Toolbar allows you to view recent requests that have been made to
+    | the application while the toolbar is active. This allows you to quickly
+    | view and compare multiple requests.
+    |
+    | $maxHistory sets a limit on the number of past requests that are stored,
+    | helping to conserve file space used to store them. You can set it to
+    | 0 (zero) to not have any history stored, or -1 for unlimited history.
+    |
+    */
     public $maxHistory = 20;
 
     /*
-	|--------------------------------------------------------------------------
-	| Toolbar Views Path
-	|--------------------------------------------------------------------------
-	| The full path to the the views that are used by the toolbar.
-	| MUST have a trailing slash.
-	|
-	*/
+    |--------------------------------------------------------------------------
+    | Toolbar Views Path
+    |--------------------------------------------------------------------------
+    | The full path to the the views that are used by the toolbar.
+    | MUST have a trailing slash.
+    |
+    */
     public $viewsPath = SYSTEMPATH . 'Debug/Toolbar/Views/';
 
     /*
-	|--------------------------------------------------------------------------
-	| Max Queries
-	|--------------------------------------------------------------------------
-	| If the Database Collector is enabled, it will log every query that the
-	| the system generates so they can be displayed on the toolbar's timeline
-	| and in the query log. This can lead to memory issues in some instances
-	| with hundreds of queries.
-	|
-	| $maxQueries defines the maximum amount of queries that will be stored.
-	|
-	*/
+    |--------------------------------------------------------------------------
+    | Max Queries
+    |--------------------------------------------------------------------------
+    | If the Database Collector is enabled, it will log every query that the
+    | the system generates so they can be displayed on the toolbar's timeline
+    | and in the query log. This can lead to memory issues in some instances
+    | with hundreds of queries.
+    |
+    | $maxQueries defines the maximum amount of queries that will be stored.
+    |
+    */
     public $maxQueries = 100;
 }
diff --git a/app/Config/UserAgents.php b/app/Config/UserAgents.php
index 8cf7b2f691..fab20be24e 100644
--- a/app/Config/UserAgents.php
+++ b/app/Config/UserAgents.php
@@ -1,18 +1,20 @@
-<?php namespace Config;
+<?php
+
+namespace Config;
 
 use CodeIgniter\Config\BaseConfig;
 
 class UserAgents extends BaseConfig
 {
     /*
-	| -------------------------------------------------------------------
-	| USER AGENT TYPES
-	| -------------------------------------------------------------------
-	| This file contains four arrays of user agent data. It is used by the
-	| User Agent Class to help identify browser, platform, robot, and
-	| mobile device data. The array keys are used to identify the device
-	| and the array values are used to set the actual name of the item.
-	*/
+    | -------------------------------------------------------------------
+    | USER AGENT TYPES
+    | -------------------------------------------------------------------
+    | This file contains four arrays of user agent data. It is used by the
+    | User Agent Class to help identify browser, platform, robot, and
+    | mobile device data. The array keys are used to identify the device
+    | and the array values are used to set the actual name of the item.
+    */
     public $platforms = [
         'windows nt 10.0' => 'Windows 10',
         'windows nt 6.3' => 'Windows 8.1',
diff --git a/app/Config/Validation.php b/app/Config/Validation.php
index d93c623fc2..25ec0ce8e4 100644
--- a/app/Config/Validation.php
+++ b/app/Config/Validation.php
@@ -1,4 +1,6 @@
-<?php namespace Config;
+<?php
+
+namespace Config;
 
 class Validation
 {
diff --git a/app/Config/View.php b/app/Config/View.php
index 9e8f2a2542..ceec2776ae 100644
--- a/app/Config/View.php
+++ b/app/Config/View.php
@@ -1,4 +1,6 @@
-<?php namespace Config;
+<?php
+
+namespace Config;
 
 class View extends \CodeIgniter\Config\View
 {
diff --git a/app/Controllers/Admin/Contributor.php b/app/Controllers/Admin/Contributor.php
index 708912f73b..4f5a8ae825 100644
--- a/app/Controllers/Admin/Contributor.php
+++ b/app/Controllers/Admin/Contributor.php
@@ -1,4 +1,5 @@
 <?php
+
 /**
  * @copyright  2020 Podlibre
  * @license    https://www.gnu.org/licenses/agpl-3.0.en.html AGPL3
@@ -66,7 +67,9 @@ class Contributor extends BaseController
             return redirect()
                 ->back()
                 ->withInput()
-                ->with('errors', [lang('Contributor.alreadyAddedError')]);
+                ->with('errors', [
+                    lang('Contributor.messages.alreadyAddedError'),
+                ]);
         }
 
         return redirect()->route('contributor_list', [$this->podcast->id]);
@@ -77,7 +80,7 @@ class Contributor extends BaseController
         $data = [
             'podcast' => $this->podcast,
             'user' => $this->user,
-            'contributor_group_id' => (new PodcastModel())->getContributorGroupId(
+            'contributorGroupId' => (new PodcastModel())->getContributorGroupId(
                 $this->user->id,
                 $this->podcast->id
             ),
@@ -104,27 +107,27 @@ class Contributor extends BaseController
             return redirect()
                 ->back()
                 ->with('errors', [
-                    lang('Contributor.removeOwnerContributorError'),
+                    lang('Contributor.messages.removeOwnerContributorError'),
                 ]);
         }
 
-        $podcast_model = new PodcastModel();
+        $podcastModel = new PodcastModel();
         if (
-            !$podcast_model->removePodcastContributor(
+            !$podcastModel->removePodcastContributor(
                 $this->user->id,
                 $this->podcast->id
             )
         ) {
             return redirect()
                 ->back()
-                ->with('errors', $podcast_model->errors());
+                ->with('errors', $podcastModel->errors());
         }
 
         return redirect()
             ->back()
             ->with(
                 'message',
-                lang('Contributor.removeContributorSuccess', [
+                lang('Contributor.messages.removeContributorSuccess', [
                     'username' => $this->user->username,
                     'podcastTitle' => $this->podcast->title,
                 ])
diff --git a/app/Controllers/Admin/Episode.php b/app/Controllers/Admin/Episode.php
index 74efa4362d..0c5ce4c273 100644
--- a/app/Controllers/Admin/Episode.php
+++ b/app/Controllers/Admin/Episode.php
@@ -1,4 +1,5 @@
 <?php
+
 /**
  * @copyright  2020 Podlibre
  * @license    https://www.gnu.org/licenses/agpl-3.0.en.html AGPL3
@@ -20,9 +21,8 @@ class Episode extends BaseController
         $this->podcast = (new PodcastModel())->find($params[0]);
 
         if (count($params) > 1) {
-            $episode_model = new EpisodeModel();
             if (
-                !($this->episode = $episode_model
+                !($this->episode = (new EpisodeModel())
                     ->where([
                         'id' => $params[1],
                         'podcast_id' => $params[0],
@@ -78,7 +78,7 @@ class Episode extends BaseController
                 ->with('errors', $this->validator->getErrors());
         }
 
-        $new_episode = new \App\Entities\Episode([
+        $newEpisode = new \App\Entities\Episode([
             'podcast_id' => $this->podcast->id,
             'title' => $this->request->getPost('title'),
             'slug' => $this->request->getPost('slug'),
@@ -95,13 +95,13 @@ class Episode extends BaseController
             'block' => (bool) $this->request->getPost('block'),
         ]);
 
-        $episode_model = new EpisodeModel();
+        $episodeModel = new EpisodeModel();
 
-        if (!$episode_model->save($new_episode)) {
+        if (!$episodeModel->save($newEpisode)) {
             return redirect()
                 ->back()
                 ->withInput()
-                ->with('errors', $episode_model->errors());
+                ->with('errors', $episodeModel->errors());
         }
 
         return redirect()->route('episode_list', [$this->podcast->id]);
@@ -112,7 +112,6 @@ class Episode extends BaseController
         helper(['form']);
 
         $data = [
-            'podcast' => $this->podcast,
             'episode' => $this->episode,
         ];
 
@@ -158,13 +157,13 @@ class Episode extends BaseController
             $this->episode->image = $image;
         }
 
-        $episode_model = new EpisodeModel();
+        $episodeModel = new EpisodeModel();
 
-        if (!$episode_model->save($this->episode)) {
+        if (!$episodeModel->save($this->episode)) {
             return redirect()
                 ->back()
                 ->withInput()
-                ->with('errors', $episode_model->errors());
+                ->with('errors', $episodeModel->errors());
         }
 
         return redirect()->route('episode_list', [$this->podcast->id]);
@@ -172,8 +171,7 @@ class Episode extends BaseController
 
     public function delete()
     {
-        $episode_model = new EpisodeModel();
-        $episode_model->delete($this->episode->id);
+        (new EpisodeModel())->delete($this->episode->id);
 
         return redirect()->route('episode_list', [$this->podcast->id]);
     }
diff --git a/app/Controllers/Admin/Home.php b/app/Controllers/Admin/Home.php
index 6e3b80aa01..a1db30a705 100644
--- a/app/Controllers/Admin/Home.php
+++ b/app/Controllers/Admin/Home.php
@@ -1,4 +1,5 @@
 <?php
+
 /**
  * @copyright  2020 Podlibre
  * @license    https://www.gnu.org/licenses/agpl-3.0.en.html AGPL3
diff --git a/app/Controllers/Admin/Myaccount.php b/app/Controllers/Admin/Myaccount.php
index 4f3f757192..fa7e7b4d39 100644
--- a/app/Controllers/Admin/Myaccount.php
+++ b/app/Controllers/Admin/Myaccount.php
@@ -1,4 +1,5 @@
 <?php
+
 /**
  * @copyright  2020 Podlibre
  * @license    https://www.gnu.org/licenses/agpl-3.0.en.html AGPL3
@@ -25,7 +26,7 @@ class Myaccount extends BaseController
     public function attemptChange()
     {
         $auth = Services::authentication();
-        $user_model = new UserModel();
+        $userModel = new UserModel();
 
         // Validate here first, since some things,
         // like the password, can only be validated properly here.
@@ -40,7 +41,7 @@ class Myaccount extends BaseController
             return redirect()
                 ->back()
                 ->withInput()
-                ->with('errors', $user_model->errors());
+                ->with('errors', $userModel->errors());
         }
 
         $credentials = [
@@ -52,22 +53,22 @@ class Myaccount extends BaseController
             return redirect()
                 ->back()
                 ->withInput()
-                ->with('errors', $user_model->errors());
+                ->with('errors', $userModel->errors());
         }
 
         user()->password = $this->request->getPost('new_password');
-        $user_model->save(user());
+        $userModel->save(user());
 
-        if (!$user_model->save(user())) {
+        if (!$userModel->save(user())) {
             return redirect()
                 ->back()
                 ->withInput()
-                ->with('errors', $user_model->errors());
+                ->with('errors', $userModel->errors());
         }
 
         // Success!
         return redirect()
             ->route('myAccount')
-            ->with('message', lang('MyAccount.passwordChangeSuccess'));
+            ->with('message', lang('MyAccount.messages.passwordChangeSuccess'));
     }
 }
diff --git a/app/Controllers/Admin/Podcast.php b/app/Controllers/Admin/Podcast.php
index 4b99340cd4..99209e0761 100644
--- a/app/Controllers/Admin/Podcast.php
+++ b/app/Controllers/Admin/Podcast.php
@@ -1,9 +1,11 @@
 <?php
+
 /**
  * @copyright  2020 Podlibre
  * @license    https://www.gnu.org/licenses/agpl-3.0.en.html AGPL3
  * @link       https://castopod.org/
  */
+
 namespace App\Controllers\Admin;
 
 use App\Models\CategoryModel;
@@ -29,7 +31,7 @@ class Podcast extends BaseController
     public function myPodcasts()
     {
         $data = [
-            'all_podcasts' => (new PodcastModel())->getUserPodcasts(user()->id),
+            'podcasts' => (new PodcastModel())->getUserPodcasts(user()->id),
         ];
 
         return view('admin/podcast/list', $data);
@@ -41,7 +43,7 @@ class Podcast extends BaseController
             return redirect()->route('my_podcasts');
         }
 
-        $data = ['all_podcasts' => (new PodcastModel())->findAll()];
+        $data = ['podcasts' => (new PodcastModel())->findAll()];
 
         return view('admin/podcast/list', $data);
     }
@@ -62,7 +64,7 @@ class Podcast extends BaseController
         $data = [
             'languages' => $languageModel->findAll(),
             'categories' => $categoryModel->findAll(),
-            'browser_lang' => get_browser_language(
+            'browserLang' => get_browser_language(
                 $this->request->getServer('HTTP_ACCEPT_LANGUAGE')
             ),
         ];
@@ -106,26 +108,26 @@ class Podcast extends BaseController
             'custom_html_head' => $this->request->getPost('custom_html_head'),
         ]);
 
-        $podcast_model = new PodcastModel();
+        $podcastModel = new PodcastModel();
         $db = \Config\Database::connect();
 
         $db->transStart();
 
-        if (!($new_podcast_id = $podcast_model->insert($podcast, true))) {
+        if (!($newPodcastId = $podcastModel->insert($podcast, true))) {
             $db->transComplete();
             return redirect()
                 ->back()
                 ->withInput()
-                ->with('errors', $podcast_model->errors());
+                ->with('errors', $podcastModel->errors());
         }
 
         $authorize = Services::authorization();
-        $podcast_admin_group = $authorize->group('podcast_admin');
+        $podcastAdminGroup = $authorize->group('podcast_admin');
 
-        $podcast_model->addPodcastContributor(
+        $podcastModel->addPodcastContributor(
             user()->id,
-            $new_podcast_id,
-            $podcast_admin_group->id
+            $newPodcastId,
+            $podcastAdminGroup->id
         );
 
         $db->transComplete();
@@ -137,12 +139,10 @@ class Podcast extends BaseController
     {
         helper('form');
 
-        $languageModel = new LanguageModel();
-        $categoryModel = new CategoryModel();
         $data = [
             'podcast' => $this->podcast,
-            'languages' => $languageModel->findAll(),
-            'categories' => $categoryModel->findAll(),
+            'languages' => (new LanguageModel())->findAll(),
+            'categories' => (new CategoryModel())->findAll(),
         ];
 
         echo view('admin/podcast/edit', $data);
@@ -188,13 +188,13 @@ class Podcast extends BaseController
             'custom_html_head'
         );
 
-        $podcast_model = new PodcastModel();
+        $podcastModel = new PodcastModel();
 
-        if (!$podcast_model->save($this->podcast)) {
+        if (!$podcastModel->save($this->podcast)) {
             return redirect()
                 ->back()
                 ->withInput()
-                ->with('errors', $podcast_model->errors());
+                ->with('errors', $podcastModel->errors());
         }
 
         return redirect()->route('podcast_list');
@@ -202,8 +202,7 @@ class Podcast extends BaseController
 
     public function delete()
     {
-        $podcast_model = new PodcastModel();
-        $podcast_model->delete($this->podcast->id);
+        (new PodcastModel())->delete($this->podcast->id);
 
         return redirect()->route('podcast_list');
     }
diff --git a/app/Controllers/Admin/User.php b/app/Controllers/Admin/User.php
index f958fe2edd..98470cf13f 100644
--- a/app/Controllers/Admin/User.php
+++ b/app/Controllers/Admin/User.php
@@ -1,4 +1,5 @@
 <?php
+
 /**
  * @copyright  2020 Podlibre
  * @license    https://www.gnu.org/licenses/agpl-3.0.en.html AGPL3
@@ -18,8 +19,7 @@ class User extends BaseController
     public function _remap($method, ...$params)
     {
         if (count($params) > 0) {
-            $user_model = new UserModel();
-            if (!($this->user = $user_model->find($params[0]))) {
+            if (!($this->user = (new UserModel())->find($params[0]))) {
                 throw \CodeIgniter\Exceptions\PageNotFoundException::forPageNotFound();
             }
         }
@@ -29,7 +29,7 @@ class User extends BaseController
 
     public function list()
     {
-        $data = ['all_users' => (new UserModel())->findAll()];
+        $data = ['users' => (new UserModel())->findAll()];
 
         return view('admin/user/list', $data);
     }
@@ -45,12 +45,12 @@ class User extends BaseController
 
     public function attemptCreate()
     {
-        $user_model = new UserModel();
+        $userModel = new UserModel();
 
         // Validate here first, since some things,
         // like the password, can only be validated properly here.
         $rules = array_merge(
-            $user_model->getValidationRules(['only' => ['username']]),
+            $userModel->getValidationRules(['only' => ['username']]),
             [
                 'email' => 'required|valid_email|is_unique[users.email]',
                 'password' => 'required|strong_password',
@@ -74,11 +74,11 @@ class User extends BaseController
         // Force user to reset his password on first connection
         $user->forcePasswordReset();
 
-        if (!$user_model->save($user)) {
+        if (!$userModel->save($user)) {
             return redirect()
                 ->back()
                 ->withInput()
-                ->with('errors', $user_model->errors());
+                ->with('errors', $userModel->errors());
         }
 
         // Success!
@@ -86,7 +86,7 @@ class User extends BaseController
             ->route('user_list')
             ->with(
                 'message',
-                lang('User.createSuccess', [
+                lang('User.messages.createSuccess', [
                     'username' => $user->username,
                 ])
             );
@@ -114,7 +114,7 @@ class User extends BaseController
             ->route('user_list')
             ->with(
                 'message',
-                lang('User.rolesEditSuccess', [
+                lang('User.messages.rolesEditSuccess', [
                     'username' => $this->user->username,
                 ])
             );
@@ -122,13 +122,13 @@ class User extends BaseController
 
     public function forcePassReset()
     {
-        $user_model = new UserModel();
+        $userModel = new UserModel();
         $this->user->forcePasswordReset();
 
-        if (!$user_model->save($this->user)) {
+        if (!$userModel->save($this->user)) {
             return redirect()
                 ->back()
-                ->with('errors', $user_model->errors());
+                ->with('errors', $userModel->errors());
         }
 
         // Success!
@@ -136,7 +136,7 @@ class User extends BaseController
             ->route('user_list')
             ->with(
                 'message',
-                lang('User.forcePassResetSuccess', [
+                lang('User.messages.forcePassResetSuccess', [
                     'username' => $this->user->username,
                 ])
             );
@@ -149,27 +149,27 @@ class User extends BaseController
             return redirect()
                 ->back()
                 ->with('errors', [
-                    lang('User.banSuperAdminError', [
+                    lang('User.messages.banSuperAdminError', [
                         'username' => $this->user->username,
                     ]),
                 ]);
         }
 
-        $user_model = new UserModel();
+        $userModel = new UserModel();
         // TODO: add ban reason?
         $this->user->ban('');
 
-        if (!$user_model->save($this->user)) {
+        if (!$userModel->save($this->user)) {
             return redirect()
                 ->back()
-                ->with('errors', $user_model->errors());
+                ->with('errors', $userModel->errors());
         }
 
         return redirect()
             ->route('user_list')
             ->with(
                 'message',
-                lang('User.banSuccess', [
+                lang('User.messages.banSuccess', [
                     'username' => $this->user->username,
                 ])
             );
@@ -177,20 +177,20 @@ class User extends BaseController
 
     public function unBan()
     {
-        $user_model = new UserModel();
+        $userModel = new UserModel();
         $this->user->unBan();
 
-        if (!$user_model->save($this->user)) {
+        if (!$userModel->save($this->user)) {
             return redirect()
                 ->back()
-                ->with('errors', $user_model->errors());
+                ->with('errors', $userModel->errors());
         }
 
         return redirect()
             ->route('user_list')
             ->with(
                 'message',
-                lang('User.unbanSuccess', [
+                lang('User.messages.unbanSuccess', [
                     'username' => $this->user->username,
                 ])
             );
@@ -203,20 +203,19 @@ class User extends BaseController
             return redirect()
                 ->back()
                 ->with('errors', [
-                    lang('User.deleteSuperAdminError', [
+                    lang('User.messages.deleteSuperAdminError', [
                         'username' => $this->user->username,
                     ]),
                 ]);
         }
 
-        $user_model = new UserModel();
-        $user_model->delete($this->user->id);
+        (new UserModel())->delete($this->user->id);
 
         return redirect()
             ->back()
             ->with(
                 'message',
-                lang('User.deleteSuccess', [
+                lang('User.messages.deleteSuccess', [
                     'username' => $this->user->username,
                 ])
             );
diff --git a/app/Controllers/Analytics.php b/app/Controllers/Analytics.php
index 9a2621c24c..d9c82d31c1 100644
--- a/app/Controllers/Analytics.php
+++ b/app/Controllers/Analytics.php
@@ -1,4 +1,5 @@
 <?php
+
 /**
  * Class Analytics
  * Creates Analytics controller
@@ -44,9 +45,9 @@ class Analytics extends Controller
     }
 
     // Add one hit to this episode:
-    public function hit($p_podcast_id, $p_episode_id, ...$filename)
+    public function hit($p_podcastId, $p_episodeId, ...$filename)
     {
-        podcast_hit($p_podcast_id, $p_episode_id);
+        podcast_hit($p_podcastId, $p_episodeId);
         return redirect()->to(media_url(implode('/', $filename)));
     }
 }
diff --git a/app/Controllers/BaseController.php b/app/Controllers/BaseController.php
index 58cd127630..895838ca79 100644
--- a/app/Controllers/BaseController.php
+++ b/app/Controllers/BaseController.php
@@ -50,8 +50,8 @@ class BaseController extends Controller
         set_user_session_referer();
     }
 
-    protected static function triggerWebpageHit($postcast_id)
+    protected static function triggerWebpageHit($podcastId)
     {
-        webpage_hit($postcast_id);
+        webpage_hit($podcastId);
     }
 }
diff --git a/app/Controllers/Episode.php b/app/Controllers/Episode.php
index b5174ad637..d3fc965f84 100644
--- a/app/Controllers/Episode.php
+++ b/app/Controllers/Episode.php
@@ -1,4 +1,5 @@
 <?php
+
 /**
  * @copyright  2020 Podlibre
  * @license    https://www.gnu.org/licenses/agpl-3.0.en.html AGPL3
@@ -17,22 +18,20 @@ class Episode extends BaseController
 
     public function _remap($method, ...$params)
     {
-        $podcast_model = new PodcastModel();
-
-        $this->podcast = $podcast_model->where('name', $params[0])->first();
-
-        if (count($params) > 1) {
-            $episode_model = new EpisodeModel();
-            if (
-                !($this->episode = $episode_model
-                    ->where([
-                        'podcast_id' => $this->podcast->id,
-                        'slug' => $params[1],
-                    ])
-                    ->first())
-            ) {
-                throw \CodeIgniter\Exceptions\PageNotFoundException::forPageNotFound();
-            }
+        $this->podcast = (new PodcastModel())
+            ->where('name', $params[0])
+            ->first();
+
+        if (
+            count($params) > 1 &&
+            !($this->episode = (new EpisodeModel())
+                ->where([
+                    'podcast_id' => $this->podcast->id,
+                    'slug' => $params[1],
+                ])
+                ->first())
+        ) {
+            throw \CodeIgniter\Exceptions\PageNotFoundException::forPageNotFound();
         }
 
         return $this->$method();
diff --git a/app/Controllers/Feed.php b/app/Controllers/Feed.php
index 48064d0a6e..a739a793b1 100644
--- a/app/Controllers/Feed.php
+++ b/app/Controllers/Feed.php
@@ -1,4 +1,5 @@
 <?php
+
 /**
  * @copyright  2020 Podlibre
  * @license    https://www.gnu.org/licenses/agpl-3.0.en.html AGPL3
@@ -12,16 +13,15 @@ use CodeIgniter\Controller;
 
 class Feed extends Controller
 {
-    public function index($podcast_name)
+    public function index($podcastName)
     {
-        helper('rss');
-
-        $podcast_model = new PodcastModel();
-        $podcast = $podcast_model->where('name', $podcast_name)->first();
-
         // The page cache is set to a decade so it is deleted manually upon podcast update
         $this->cachePage(DECADE);
 
+        helper('rss');
+
+        $podcast = (new PodcastModel())->where('name', $podcastName)->first();
+
         return $this->response->setXML(get_rss_feed($podcast));
     }
 }
diff --git a/app/Controllers/Home.php b/app/Controllers/Home.php
index 0f9ca24fb2..7f8aad52b6 100644
--- a/app/Controllers/Home.php
+++ b/app/Controllers/Home.php
@@ -1,4 +1,5 @@
 <?php
+
 /**
  * @copyright  2020 Podlibre
  * @license    https://www.gnu.org/licenses/agpl-3.0.en.html AGPL3
@@ -15,15 +16,15 @@ class Home extends BaseController
     {
         $model = new PodcastModel();
 
-        $all_podcasts = $model->findAll();
+        $allPodcasts = $model->findAll();
 
         // check if there's only one podcast to redirect user to it
-        if (count($all_podcasts) == 1) {
-            return redirect()->route('podcast', [$all_podcasts[0]->name]);
+        if (count($allPodcasts) == 1) {
+            return redirect()->route('podcast', [$allPodcasts[0]->name]);
         }
 
         // default behavior: list all podcasts on home page
-        $data = ['podcasts' => $all_podcasts];
+        $data = ['podcasts' => $allPodcasts];
         return view('home', $data);
     }
 }
diff --git a/app/Controllers/Migrate.php b/app/Controllers/Migrate.php
index 0155b49be5..6cf2b69923 100644
--- a/app/Controllers/Migrate.php
+++ b/app/Controllers/Migrate.php
@@ -1,4 +1,5 @@
 <?php
+
 /**
  * @copyright  2020 Podlibre
  * @license    https://www.gnu.org/licenses/agpl-3.0.en.html AGPL3
diff --git a/app/Controllers/Podcast.php b/app/Controllers/Podcast.php
index 5fd0e14123..90d04bc85d 100644
--- a/app/Controllers/Podcast.php
+++ b/app/Controllers/Podcast.php
@@ -1,9 +1,11 @@
 <?php
+
 /**
  * @copyright  2020 Podlibre
  * @license    https://www.gnu.org/licenses/agpl-3.0.en.html AGPL3
  * @link       https://castopod.org/
  */
+
 namespace App\Controllers;
 
 use App\Models\PodcastModel;
@@ -15,9 +17,8 @@ class Podcast extends BaseController
     public function _remap($method, ...$params)
     {
         if (count($params) > 0) {
-            $podcast_model = new PodcastModel();
             if (
-                !($this->podcast = $podcast_model
+                !($this->podcast = (new PodcastModel())
                     ->where('name', $params[0])
                     ->first())
             ) {
diff --git a/app/Controllers/UnknownUserAgents.php b/app/Controllers/UnknownUserAgents.php
index 3eb284712a..94718725aa 100644
--- a/app/Controllers/UnknownUserAgents.php
+++ b/app/Controllers/UnknownUserAgents.php
@@ -1,4 +1,5 @@
 <?php
+
 /**
  * @copyright  2020 Podlibre
  * @license    https://www.gnu.org/licenses/agpl-3.0.en.html AGPL3
@@ -6,14 +7,15 @@
  */
 
 namespace App\Controllers;
+
 use CodeIgniter\Controller;
 
 class UnknownUserAgents extends Controller
 {
-    public function index($last_known_id = 0)
+    public function index($lastKnownId = 0)
     {
         $model = new \App\Models\UnknownUserAgentsModel();
 
-        return $this->response->setJSON($model->getUserAgents($last_known_id));
+        return $this->response->setJSON($model->getUserAgents($lastKnownId));
     }
 }
diff --git a/app/Database/Migrations/2020-05-29-152000_add_categories.php b/app/Database/Migrations/2020-05-29-152000_add_categories.php
index 717adc423e..576a8daaf9 100644
--- a/app/Database/Migrations/2020-05-29-152000_add_categories.php
+++ b/app/Database/Migrations/2020-05-29-152000_add_categories.php
@@ -1,4 +1,5 @@
 <?php
+
 /**
  * Class AddCategories
  * Creates categories table in database
diff --git a/app/Database/Migrations/2020-05-30-101000_add_languages.php b/app/Database/Migrations/2020-05-30-101000_add_languages.php
index fa7c0b71e2..95c817ff3c 100644
--- a/app/Database/Migrations/2020-05-30-101000_add_languages.php
+++ b/app/Database/Migrations/2020-05-30-101000_add_languages.php
@@ -1,4 +1,5 @@
 <?php
+
 /**
  * Class AddLanguages
  * Creates languages table in database
diff --git a/app/Database/Migrations/2020-05-30-101500_add_podcasts.php b/app/Database/Migrations/2020-05-30-101500_add_podcasts.php
index cd35fe3797..373345dc36 100644
--- a/app/Database/Migrations/2020-05-30-101500_add_podcasts.php
+++ b/app/Database/Migrations/2020-05-30-101500_add_podcasts.php
@@ -1,4 +1,5 @@
 <?php
+
 /**
  * Class AddPodcasts
  * Creates podcasts table in database
diff --git a/app/Database/Migrations/2020-06-05-170000_add_episodes.php b/app/Database/Migrations/2020-06-05-170000_add_episodes.php
index 4a4fc52894..b29f0583ac 100644
--- a/app/Database/Migrations/2020-06-05-170000_add_episodes.php
+++ b/app/Database/Migrations/2020-06-05-170000_add_episodes.php
@@ -1,4 +1,5 @@
 <?php
+
 /**
  * Class AddEpisodes
  * Creates episodes table in database
diff --git a/app/Database/Migrations/2020-06-05-190000_add_platforms.php b/app/Database/Migrations/2020-06-05-190000_add_platforms.php
index 7a96523d54..5c3b53af93 100644
--- a/app/Database/Migrations/2020-06-05-190000_add_platforms.php
+++ b/app/Database/Migrations/2020-06-05-190000_add_platforms.php
@@ -1,4 +1,5 @@
 <?php
+
 /**
  * Class AddPlatforms
  * Creates platforms table in database
diff --git a/app/Database/Migrations/2020-06-08-160000_add_platform_links.php b/app/Database/Migrations/2020-06-08-160000_add_platform_links.php
index 49938f26e4..214a27c677 100644
--- a/app/Database/Migrations/2020-06-08-160000_add_platform_links.php
+++ b/app/Database/Migrations/2020-06-08-160000_add_platform_links.php
@@ -1,4 +1,5 @@
 <?php
+
 /**
  * Class AddPlatformsLinks
  * Creates platform_links table in database
diff --git a/app/Database/Migrations/2020-06-08-210000_add_analytics_episodes_by_country.php b/app/Database/Migrations/2020-06-08-210000_add_analytics_episodes_by_country.php
index 4c4217696a..18141d0d00 100644
--- a/app/Database/Migrations/2020-06-08-210000_add_analytics_episodes_by_country.php
+++ b/app/Database/Migrations/2020-06-08-210000_add_analytics_episodes_by_country.php
@@ -1,4 +1,5 @@
 <?php
+
 /**
  * Class AddAnalyticsEpisodesByCountry
  * Creates analytics_episodes_by_country table in database
@@ -6,6 +7,7 @@
  * @license    https://www.gnu.org/licenses/agpl-3.0.en.html AGPL3
  * @link       https://castopod.org/
  */
+
 namespace App\Database\Migrations;
 
 use CodeIgniter\Database\Migration;
diff --git a/app/Database/Migrations/2020-06-08-210000_add_analytics_episodes_by_player.php b/app/Database/Migrations/2020-06-08-210000_add_analytics_episodes_by_player.php
index 89cead4509..7e6fd2bbaf 100644
--- a/app/Database/Migrations/2020-06-08-210000_add_analytics_episodes_by_player.php
+++ b/app/Database/Migrations/2020-06-08-210000_add_analytics_episodes_by_player.php
@@ -1,4 +1,5 @@
 <?php
+
 /**
  * Class AddAnalyticsEpisodesByPlayer
  * Creates analytics_episodes_by_player table in database
@@ -6,6 +7,7 @@
  * @license    https://www.gnu.org/licenses/agpl-3.0.en.html AGPL3
  * @link       https://castopod.org/
  */
+
 namespace App\Database\Migrations;
 
 use CodeIgniter\Database\Migration;
diff --git a/app/Database/Migrations/2020-06-08-210000_add_analytics_podcasts_by_country.php b/app/Database/Migrations/2020-06-08-210000_add_analytics_podcasts_by_country.php
index 72cc32b071..c4d1ec3738 100644
--- a/app/Database/Migrations/2020-06-08-210000_add_analytics_podcasts_by_country.php
+++ b/app/Database/Migrations/2020-06-08-210000_add_analytics_podcasts_by_country.php
@@ -1,4 +1,5 @@
 <?php
+
 /**
  * Class AddAnalyticsPodcastsByCountry
  * Creates analytics_podcasts_by_country table in database
@@ -6,6 +7,7 @@
  * @license    https://www.gnu.org/licenses/agpl-3.0.en.html AGPL3
  * @link       https://castopod.org/
  */
+
 namespace App\Database\Migrations;
 
 use CodeIgniter\Database\Migration;
diff --git a/app/Database/Migrations/2020-06-08-210000_add_analytics_podcasts_by_player.php b/app/Database/Migrations/2020-06-08-210000_add_analytics_podcasts_by_player.php
index 5cbaca7518..7aa84b624f 100644
--- a/app/Database/Migrations/2020-06-08-210000_add_analytics_podcasts_by_player.php
+++ b/app/Database/Migrations/2020-06-08-210000_add_analytics_podcasts_by_player.php
@@ -1,4 +1,5 @@
 <?php
+
 /**
  * Class AddAnalyticsPodcastsByPlayer
  * Creates analytics_podcasts_by_player table in database
@@ -6,6 +7,7 @@
  * @license    https://www.gnu.org/licenses/agpl-3.0.en.html AGPL3
  * @link       https://castopod.org/
  */
+
 namespace App\Database\Migrations;
 
 use CodeIgniter\Database\Migration;
diff --git a/app/Database/Migrations/2020-06-08-210000_add_analytics_unknown_useragents.php b/app/Database/Migrations/2020-06-08-210000_add_analytics_unknown_useragents.php
index 8960323c23..9a65045f76 100644
--- a/app/Database/Migrations/2020-06-08-210000_add_analytics_unknown_useragents.php
+++ b/app/Database/Migrations/2020-06-08-210000_add_analytics_unknown_useragents.php
@@ -1,4 +1,5 @@
 <?php
+
 /**
  * Class AddAnalyticsUnknownUseragents
  * Creates analytics_unknown_useragents table in database
@@ -6,6 +7,7 @@
  * @license    https://www.gnu.org/licenses/agpl-3.0.en.html AGPL3
  * @link       https://castopod.org/
  */
+
 namespace App\Database\Migrations;
 
 use CodeIgniter\Database\Migration;
diff --git a/app/Database/Migrations/2020-06-08-210000_add_analytics_website_by_browser.php b/app/Database/Migrations/2020-06-08-210000_add_analytics_website_by_browser.php
index 7c6763913a..d86c3395e1 100644
--- a/app/Database/Migrations/2020-06-08-210000_add_analytics_website_by_browser.php
+++ b/app/Database/Migrations/2020-06-08-210000_add_analytics_website_by_browser.php
@@ -1,4 +1,5 @@
 <?php
+
 /**
  * Class AddAnalyticsWebsiteByBrowser
  * Creates analytics_website_by_browser table in database
@@ -6,6 +7,7 @@
  * @license    https://www.gnu.org/licenses/agpl-3.0.en.html AGPL3
  * @link       https://castopod.org/
  */
+
 namespace App\Database\Migrations;
 
 use CodeIgniter\Database\Migration;
diff --git a/app/Database/Migrations/2020-06-08-210000_add_analytics_website_by_country.php b/app/Database/Migrations/2020-06-08-210000_add_analytics_website_by_country.php
index a531781ea1..c0e5b73183 100644
--- a/app/Database/Migrations/2020-06-08-210000_add_analytics_website_by_country.php
+++ b/app/Database/Migrations/2020-06-08-210000_add_analytics_website_by_country.php
@@ -1,4 +1,5 @@
 <?php
+
 /**
  * Class AddAnalyticsWebsiteByCountry
  * Creates analytics_website_by_country table in database
@@ -6,6 +7,7 @@
  * @license    https://www.gnu.org/licenses/agpl-3.0.en.html AGPL3
  * @link       https://castopod.org/
  */
+
 namespace App\Database\Migrations;
 
 use CodeIgniter\Database\Migration;
diff --git a/app/Database/Migrations/2020-06-08-210000_add_analytics_website_by_referer.php b/app/Database/Migrations/2020-06-08-210000_add_analytics_website_by_referer.php
index 4c5f27fcfc..fa0ec5ea02 100644
--- a/app/Database/Migrations/2020-06-08-210000_add_analytics_website_by_referer.php
+++ b/app/Database/Migrations/2020-06-08-210000_add_analytics_website_by_referer.php
@@ -1,4 +1,5 @@
 <?php
+
 /**
  * Class AddAnalyticsWebsiteByReferer
  * Creates analytics_website_by_referer table in database
@@ -6,6 +7,7 @@
  * @license    https://www.gnu.org/licenses/agpl-3.0.en.html AGPL3
  * @link       https://castopod.org/
  */
+
 namespace App\Database\Migrations;
 
 use CodeIgniter\Database\Migration;
diff --git a/app/Database/Migrations/2020-06-11-210000_add_analytics_podcasts_stored_procedure.php b/app/Database/Migrations/2020-06-11-210000_add_analytics_podcasts_stored_procedure.php
index ab327728a5..18bd203af4 100644
--- a/app/Database/Migrations/2020-06-11-210000_add_analytics_podcasts_stored_procedure.php
+++ b/app/Database/Migrations/2020-06-11-210000_add_analytics_podcasts_stored_procedure.php
@@ -1,4 +1,5 @@
 <?php
+
 /**
  * Class AddAnalyticsPodcastsStoredProcedure
  * Creates analytics_podcasts stored procedure in database
@@ -6,6 +7,7 @@
  * @license    https://www.gnu.org/licenses/agpl-3.0.en.html AGPL3
  * @link       https://castopod.org/
  */
+
 namespace App\Database\Migrations;
 
 use CodeIgniter\Database\Migration;
diff --git a/app/Database/Migrations/2020-06-11-210000_add_analytics_unknown_useragents_stored_procedure.php b/app/Database/Migrations/2020-06-11-210000_add_analytics_unknown_useragents_stored_procedure.php
index 683078b90e..eef223943d 100644
--- a/app/Database/Migrations/2020-06-11-210000_add_analytics_unknown_useragents_stored_procedure.php
+++ b/app/Database/Migrations/2020-06-11-210000_add_analytics_unknown_useragents_stored_procedure.php
@@ -1,4 +1,5 @@
 <?php
+
 /**
  * Class AddAnalyticsUnknownUseragentsStoredProcedure
  * Creates analytics_unknown_useragents stored procedure in database
@@ -6,6 +7,7 @@
  * @license    https://www.gnu.org/licenses/agpl-3.0.en.html AGPL3
  * @link       https://castopod.org/
  */
+
 namespace App\Database\Migrations;
 
 use CodeIgniter\Database\Migration;
diff --git a/app/Database/Migrations/2020-06-11-210000_add_analytics_website_stored_procedure.php b/app/Database/Migrations/2020-06-11-210000_add_analytics_website_stored_procedure.php
index e66739cd49..c263a8a1b3 100644
--- a/app/Database/Migrations/2020-06-11-210000_add_analytics_website_stored_procedure.php
+++ b/app/Database/Migrations/2020-06-11-210000_add_analytics_website_stored_procedure.php
@@ -1,4 +1,5 @@
 <?php
+
 /**
  * Class AddAnalyticsWebsiteStoredProcedure
  * Creates analytics_website stored procedure in database
@@ -6,6 +7,7 @@
  * @license    https://www.gnu.org/licenses/agpl-3.0.en.html AGPL3
  * @link       https://castopod.org/
  */
+
 namespace App\Database\Migrations;
 
 use CodeIgniter\Database\Migration;
diff --git a/app/Database/Migrations/2020-07-03-191500_add_users_podcasts.php b/app/Database/Migrations/2020-07-03-191500_add_users_podcasts.php
index 5b731576cb..3fd5fb182e 100644
--- a/app/Database/Migrations/2020-07-03-191500_add_users_podcasts.php
+++ b/app/Database/Migrations/2020-07-03-191500_add_users_podcasts.php
@@ -1,4 +1,5 @@
 <?php
+
 /**
  * Class AddLanguages
  * Creates languages table in database
diff --git a/app/Database/Seeds/AuthSeeder.php b/app/Database/Seeds/AuthSeeder.php
index 1c60c4271e..5ce7edcce6 100644
--- a/app/Database/Seeds/AuthSeeder.php
+++ b/app/Database/Seeds/AuthSeeder.php
@@ -1,4 +1,5 @@
 <?php
+
 /**
  * Class PermissionSeeder
  * Inserts permissions
@@ -224,9 +225,9 @@ class AuthSeeder extends Seeder
         ],
     ];
 
-    static function getGroupIdByName($name, $data_groups)
+    static function getGroupIdByName($name, $dataGroups)
     {
-        foreach ($data_groups as $group) {
+        foreach ($dataGroups as $group) {
             if ($group['name'] === $name) {
                 return $group['id'];
             }
@@ -236,45 +237,45 @@ class AuthSeeder extends Seeder
 
     public function run()
     {
-        $group_id = 0;
-        $data_groups = [];
+        $groupId = 0;
+        $dataGroups = [];
         foreach ($this->groups as $group) {
-            array_push($data_groups, [
-                'id' => ++$group_id,
+            array_push($dataGroups, [
+                'id' => ++$groupId,
                 'name' => $group['name'],
                 'description' => $group['description'],
             ]);
         }
 
         // Map permissions to a format the `auth_permissions` table expects
-        $data_permissions = [];
-        $data_groups_permissions = [];
-        $permission_id = 0;
+        $dataPermissions = [];
+        $dataGroupsPermissions = [];
+        $permissionId = 0;
         foreach ($this->permissions as $context => $actions) {
             foreach ($actions as $action) {
-                array_push($data_permissions, [
-                    'id' => ++$permission_id,
+                array_push($dataPermissions, [
+                    'id' => ++$permissionId,
                     'name' => $context . '-' . $action['name'],
                     'description' => $action['description'],
                 ]);
 
                 foreach ($action['has_permission'] as $role) {
                     // link permission to specified groups
-                    array_push($data_groups_permissions, [
+                    array_push($dataGroupsPermissions, [
                         'group_id' => $this->getGroupIdByName(
                             $role,
-                            $data_groups
+                            $dataGroups
                         ),
-                        'permission_id' => $permission_id,
+                        'permission_id' => $permissionId,
                     ]);
                 }
             }
         }
 
-        $this->db->table('auth_permissions')->insertBatch($data_permissions);
-        $this->db->table('auth_groups')->insertBatch($data_groups);
+        $this->db->table('auth_permissions')->insertBatch($dataPermissions);
+        $this->db->table('auth_groups')->insertBatch($dataGroups);
         $this->db
             ->table('auth_groups_permissions')
-            ->insertBatch($data_groups_permissions);
+            ->insertBatch($dataGroupsPermissions);
     }
 }
diff --git a/app/Database/Seeds/CategorySeeder.php b/app/Database/Seeds/CategorySeeder.php
index d256acc55a..a62113981a 100644
--- a/app/Database/Seeds/CategorySeeder.php
+++ b/app/Database/Seeds/CategorySeeder.php
@@ -1,4 +1,5 @@
 <?php
+
 /**
  * Class CategorySeeder
  * Inserts values in categories table in database
diff --git a/app/Database/Seeds/LanguageSeeder.php b/app/Database/Seeds/LanguageSeeder.php
index aa91eeafa3..da497e5e30 100644
--- a/app/Database/Seeds/LanguageSeeder.php
+++ b/app/Database/Seeds/LanguageSeeder.php
@@ -1,4 +1,5 @@
 <?php
+
 /**
  * Class LanguageSeeder
  * Inserts values in languages table in database
diff --git a/app/Database/Seeds/PlatformSeeder.php b/app/Database/Seeds/PlatformSeeder.php
index ddbf3e1dbd..fd02b74396 100644
--- a/app/Database/Seeds/PlatformSeeder.php
+++ b/app/Database/Seeds/PlatformSeeder.php
@@ -1,4 +1,5 @@
 <?php
+
 /**
  * Class PlatformsSeeder
  * Inserts values in platforms table in database
diff --git a/app/Database/Seeds/TestSeeder.php b/app/Database/Seeds/TestSeeder.php
index efdbd5b8d7..649b98bb09 100644
--- a/app/Database/Seeds/TestSeeder.php
+++ b/app/Database/Seeds/TestSeeder.php
@@ -1,4 +1,5 @@
 <?php
+
 /**
  * Class TestSeeder
  * Inserts a superadmin user in the database
@@ -23,7 +24,7 @@ class TestSeeder extends Seeder
         $this->db->table('users')->insert([
             'id' => 1,
             'username' => 'admin',
-            'email' => 'admin@castopod.com',
+            'email' => 'admin@example.com',
             'password_hash' =>
                 '$2y$10$TXJEHX/djW8jtzgpDVf7dOOCGo5rv1uqtAYWdwwwkttQcDkAeB2.6',
             'active' => 1,
diff --git a/app/Entities/AnalyticsEpisodesByCountry.php b/app/Entities/AnalyticsEpisodesByCountry.php
index b22542b293..b173644319 100644
--- a/app/Entities/AnalyticsEpisodesByCountry.php
+++ b/app/Entities/AnalyticsEpisodesByCountry.php
@@ -1,4 +1,5 @@
 <?php
+
 /**
  * Class AnalyticsEpisodesByCountry
  * Entity for AnalyticsEpisodesByCountry
@@ -6,6 +7,7 @@
  * @license    https://www.gnu.org/licenses/agpl-3.0.en.html AGPL3
  * @link       https://castopod.org/
  */
+
 namespace App\Entities;
 
 use CodeIgniter\Entity;
diff --git a/app/Entities/AnalyticsEpisodesByPlayer.php b/app/Entities/AnalyticsEpisodesByPlayer.php
index 35a5518215..3e48c0aa95 100644
--- a/app/Entities/AnalyticsEpisodesByPlayer.php
+++ b/app/Entities/AnalyticsEpisodesByPlayer.php
@@ -1,4 +1,5 @@
 <?php
+
 /**
  * Class AnalyticsEpisodesByPlayer
  * Entity for AnalyticsEpisodesByPlayer
@@ -6,6 +7,7 @@
  * @license    https://www.gnu.org/licenses/agpl-3.0.en.html AGPL3
  * @link       https://castopod.org/
  */
+
 namespace App\Entities;
 
 use CodeIgniter\Entity;
diff --git a/app/Entities/AnalyticsPodcastsByCountry.php b/app/Entities/AnalyticsPodcastsByCountry.php
index dcdfe03788..40c0d6004b 100644
--- a/app/Entities/AnalyticsPodcastsByCountry.php
+++ b/app/Entities/AnalyticsPodcastsByCountry.php
@@ -1,4 +1,5 @@
 <?php
+
 /**
  * Class AnalyticsPodcastsByCountry
  * Entity for AnalyticsPodcastsByCountry
@@ -6,6 +7,7 @@
  * @license    https://www.gnu.org/licenses/agpl-3.0.en.html AGPL3
  * @link       https://castopod.org/
  */
+
 namespace App\Entities;
 
 use CodeIgniter\Entity;
diff --git a/app/Entities/AnalyticsPodcastsByPlayer.php b/app/Entities/AnalyticsPodcastsByPlayer.php
index 4b2d52273c..9e33ba9807 100644
--- a/app/Entities/AnalyticsPodcastsByPlayer.php
+++ b/app/Entities/AnalyticsPodcastsByPlayer.php
@@ -1,4 +1,5 @@
 <?php
+
 /**
  * Class AnalyticsPodcastsByPlayer
  * Entity for AnalyticsPodcastsByPlayer
@@ -6,6 +7,7 @@
  * @license    https://www.gnu.org/licenses/agpl-3.0.en.html AGPL3
  * @link       https://castopod.org/
  */
+
 namespace App\Entities;
 
 use CodeIgniter\Entity;
diff --git a/app/Entities/AnalyticsUnknownUseragents.php b/app/Entities/AnalyticsUnknownUseragents.php
index 2aee6c1b1c..cff8088e05 100644
--- a/app/Entities/AnalyticsUnknownUseragents.php
+++ b/app/Entities/AnalyticsUnknownUseragents.php
@@ -1,4 +1,5 @@
 <?php
+
 /**
  * Class AnalyticsUnknownUseragents
  * Entity for AnalyticsUnknownUseragents
@@ -6,6 +7,7 @@
  * @license    https://www.gnu.org/licenses/agpl-3.0.en.html AGPL3
  * @link       https://castopod.org/
  */
+
 namespace App\Entities;
 
 use CodeIgniter\Entity;
diff --git a/app/Entities/AnalyticsWebsiteByBrowser.php b/app/Entities/AnalyticsWebsiteByBrowser.php
index 0ade4dcf34..7b170f2efa 100644
--- a/app/Entities/AnalyticsWebsiteByBrowser.php
+++ b/app/Entities/AnalyticsWebsiteByBrowser.php
@@ -1,4 +1,5 @@
 <?php
+
 /**
  * Class AnalyticsWebsiteByBrowser
  * Entity for AnalyticsWebsiteByBrowser
@@ -6,6 +7,7 @@
  * @license    https://www.gnu.org/licenses/agpl-3.0.en.html AGPL3
  * @link       https://castopod.org/
  */
+
 namespace App\Entities;
 
 use CodeIgniter\Entity;
diff --git a/app/Entities/AnalyticsWebsiteByCountry.php b/app/Entities/AnalyticsWebsiteByCountry.php
index 996c61d09b..9839e3cb71 100644
--- a/app/Entities/AnalyticsWebsiteByCountry.php
+++ b/app/Entities/AnalyticsWebsiteByCountry.php
@@ -1,4 +1,5 @@
 <?php
+
 /**
  * Class AnalyticsWebsiteByCountry
  * Entity for AnalyticsWebsiteByCountry
@@ -6,6 +7,7 @@
  * @license    https://www.gnu.org/licenses/agpl-3.0.en.html AGPL3
  * @link       https://castopod.org/
  */
+
 namespace App\Entities;
 
 use CodeIgniter\Entity;
diff --git a/app/Entities/AnalyticsWebsiteByReferer.php b/app/Entities/AnalyticsWebsiteByReferer.php
index 0244076cfb..959554f957 100644
--- a/app/Entities/AnalyticsWebsiteByReferer.php
+++ b/app/Entities/AnalyticsWebsiteByReferer.php
@@ -1,4 +1,5 @@
 <?php
+
 /**
  * Class class AnalyticsWebsiteByReferer
  * Entity for AnalyticsWebsiteByReferer
@@ -6,6 +7,7 @@
  * @license    https://www.gnu.org/licenses/agpl-3.0.en.html AGPL3
  * @link       https://castopod.org/
  */
+
 namespace App\Entities;
 
 use CodeIgniter\Entity;
diff --git a/app/Entities/Category.php b/app/Entities/Category.php
index 2de786198f..688b561c0a 100644
--- a/app/Entities/Category.php
+++ b/app/Entities/Category.php
@@ -1,4 +1,5 @@
 <?php
+
 /**
  * @copyright  2020 Podlibre
  * @license    https://www.gnu.org/licenses/agpl-3.0.en.html AGPL3
@@ -23,11 +24,10 @@ class Category extends Entity
 
     public function getParent()
     {
-        $category_model = new CategoryModel();
-        $parent_id = $this->attributes['parent_id'];
+        $parentId = $this->attributes['parent_id'];
 
-        return $parent_id != 0
-            ? $category_model->find($this->attributes['parent_id'])
+        return $parentId != 0
+            ? (new CategoryModel())->findParent($parentId)
             : null;
     }
 }
diff --git a/app/Entities/Episode.php b/app/Entities/Episode.php
index a8268f32c6..0bf553fad1 100644
--- a/app/Entities/Episode.php
+++ b/app/Entities/Episode.php
@@ -1,4 +1,5 @@
 <?php
+
 /**
  * @copyright  2020 Podlibre
  * @license    https://www.gnu.org/licenses/agpl-3.0.en.html AGPL3
@@ -9,7 +10,7 @@ namespace App\Entities;
 
 use App\Models\PodcastModel;
 use CodeIgniter\Entity;
-use Parsedown;
+use League\CommonMark\CommonMarkConverter;
 
 class Episode extends Entity
 {
@@ -43,7 +44,7 @@ class Episode extends Entity
 
     public function setImage(?\CodeIgniter\HTTP\Files\UploadedFile $image)
     {
-        if ($image->isValid()) {
+        if (!empty($image) && $image->isValid()) {
             // check whether the user has inputted an image and store it
             $this->attributes['image_uri'] = save_podcast_media(
                 $image,
@@ -68,17 +69,17 @@ class Episode extends Entity
         return $this;
     }
 
-    public function getImage()
+    public function getImage(): \CodeIgniter\Files\File
     {
         return new \CodeIgniter\Files\File($this->getImageMediaPath());
     }
 
-    public function getImageMediaPath()
+    public function getImageMediaPath(): string
     {
         return media_path($this->attributes['image_uri']);
     }
 
-    public function getImageUrl()
+    public function getImageUrl(): string
     {
         if ($image_uri = $this->attributes['image_uri']) {
             return media_url($image_uri);
@@ -89,7 +90,7 @@ class Episode extends Entity
     public function setEnclosure(
         \CodeIgniter\HTTP\Files\UploadedFile $enclosure = null
     ) {
-        if ($enclosure->isValid()) {
+        if (!empty($enclosure) && $enclosure->isValid()) {
             helper('media');
 
             $this->attributes['enclosure_uri'] = save_podcast_media(
@@ -151,26 +152,25 @@ class Episode extends Entity
 
     public function getPodcast()
     {
-        $podcast_model = new PodcastModel();
-
-        return $podcast_model->find($this->attributes['podcast_id']);
+        return (new PodcastModel())->find($this->attributes['podcast_id']);
     }
 
     public function getDescriptionHtml()
     {
-        $converter = new Parsedown();
-        $converter->setBreaksEnabled(true);
+        $converter = new CommonMarkConverter([
+            'html_input' => 'strip',
+            'allow_unsafe_links' => false,
+        ]);
 
         if (
-            $description_footer = $this->getPodcast()
-                ->episode_description_footer
+            $descriptionFooter = $this->getPodcast()->episode_description_footer
         ) {
-            return $converter->text($this->attributes['description']) .
+            return $converter->convertToHtml($this->attributes['description']) .
                 '<footer>' .
-                $converter->text($description_footer) .
+                $converter->convertToHtml($descriptionFooter) .
                 '</footer>';
         }
 
-        return $converter->text($this->attributes['description']);
+        return $converter->convertToHtml($this->attributes['description']);
     }
 }
diff --git a/app/Entities/Language.php b/app/Entities/Language.php
index f2b91440d8..aa683fd73d 100644
--- a/app/Entities/Language.php
+++ b/app/Entities/Language.php
@@ -1,4 +1,5 @@
 <?php
+
 /**
  * @copyright  2020 Podlibre
  * @license    https://www.gnu.org/licenses/agpl-3.0.en.html AGPL3
diff --git a/app/Entities/Podcast.php b/app/Entities/Podcast.php
index 9a86b1d02f..4ee1bf9b69 100644
--- a/app/Entities/Podcast.php
+++ b/app/Entities/Podcast.php
@@ -1,4 +1,5 @@
 <?php
+
 /**
  * @copyright  2020 Podlibre
  * @license    https://www.gnu.org/licenses/agpl-3.0.en.html AGPL3
@@ -10,7 +11,7 @@ namespace App\Entities;
 use App\Models\EpisodeModel;
 use CodeIgniter\Entity;
 use App\Models\UserModel;
-use Parsedown;
+use League\CommonMark\CommonMarkConverter;
 
 class Podcast extends Entity
 {
@@ -158,9 +159,11 @@ class Podcast extends Entity
 
     public function getDescriptionHtml()
     {
-        $converter = new Parsedown();
-        $converter->setBreaksEnabled(true);
+        $converter = new CommonMarkConverter([
+            'html_input' => 'strip',
+            'allow_unsafe_links' => false,
+        ]);
 
-        return $converter->text($this->attributes['description']);
+        return $converter->convertToHtml($this->attributes['description']);
     }
 }
diff --git a/app/Entities/User.php b/app/Entities/User.php
index 3277fdcb9e..f710fd0692 100644
--- a/app/Entities/User.php
+++ b/app/Entities/User.php
@@ -1,4 +1,6 @@
-<?php namespace App\Entities;
+<?php
+
+namespace App\Entities;
 
 use App\Models\PodcastModel;
 
diff --git a/app/Filters/Permission.php b/app/Filters/Permission.php
index a83d966256..462257b9f1 100644
--- a/app/Filters/Permission.php
+++ b/app/Filters/Permission.php
@@ -1,4 +1,6 @@
-<?php namespace App\Filters;
+<?php
+
+namespace App\Filters;
 
 use App\Models\PodcastModel;
 use Config\Services;
@@ -57,14 +59,12 @@ class Permission implements FilterInterface
                 count($routerParams) > 0
             ) {
                 if (
-                    $group_id = (new PodcastModel())->getContributorGroupId(
+                    $groupId = (new PodcastModel())->getContributorGroupId(
                         $authenticate->id(),
                         $routerParams[0]
                     )
                 ) {
-                    if (
-                        $authorize->groupHasPermission($permission, $group_id)
-                    ) {
+                    if ($authorize->groupHasPermission($permission, $groupId)) {
                         $result = true;
                         break;
                     }
diff --git a/app/Helpers/analytics_helper.php b/app/Helpers/analytics_helper.php
index 90282c2ada..5c02363d43 100644
--- a/app/Helpers/analytics_helper.php
+++ b/app/Helpers/analytics_helper.php
@@ -1,5 +1,5 @@
-
 <?php
+
 /**
  * @copyright  2020 Podlibre
  * @license    https://www.gnu.org/licenses/agpl-3.0.en.html AGPL3
@@ -187,4 +187,3 @@ function podcast_hit($p_podcast_id, $p_episode_id)
         }
     }
 }
-
diff --git a/app/Helpers/html_helper.php b/app/Helpers/html_helper.php
index c3f8848f0d..87d9f787b4 100644
--- a/app/Helpers/html_helper.php
+++ b/app/Helpers/html_helper.php
@@ -1,4 +1,5 @@
 <?php
+
 /**
  * @copyright  2020 Podlibre
  * @license    https://www.gnu.org/licenses/agpl-3.0.en.html AGPL3
diff --git a/app/Helpers/id3_helper.php b/app/Helpers/id3_helper.php
index 1168f2964c..a80eaaf55a 100644
--- a/app/Helpers/id3_helper.php
+++ b/app/Helpers/id3_helper.php
@@ -1,4 +1,5 @@
 <?php
+
 /**
  * @copyright  2020 Podlibre
  * @license    https://www.gnu.org/licenses/agpl-3.0.en.html AGPL3
diff --git a/app/Helpers/media_helper.php b/app/Helpers/media_helper.php
index 3a3628e6bc..1f21679a84 100644
--- a/app/Helpers/media_helper.php
+++ b/app/Helpers/media_helper.php
@@ -1,4 +1,5 @@
 <?php
+
 /**
  * @copyright  2020 Podlibre
  * @license    https://www.gnu.org/licenses/agpl-3.0.en.html AGPL3
diff --git a/app/Helpers/misc_helper.php b/app/Helpers/misc_helper.php
index ce7af19a5f..b1511ef39a 100644
--- a/app/Helpers/misc_helper.php
+++ b/app/Helpers/misc_helper.php
@@ -1,4 +1,5 @@
 <?php
+
 /**
  * @copyright  2020 Podlibre
  * @license    https://www.gnu.org/licenses/agpl-3.0.en.html AGPL3
diff --git a/app/Helpers/rss_helper.php b/app/Helpers/rss_helper.php
index 97d4e324af..ba665aab39 100644
--- a/app/Helpers/rss_helper.php
+++ b/app/Helpers/rss_helper.php
@@ -1,10 +1,12 @@
 <?php
+
 /**
  * @copyright  2020 Podlibre
  * @license    https://www.gnu.org/licenses/agpl-3.0.en.html AGPL3
  * @link       https://castopod.org/
  */
 
+use App\Libraries\SimpleRSSElement;
 use App\Models\CategoryModel;
 use CodeIgniter\I18n\Time;
 
diff --git a/app/Helpers/url_helper.php b/app/Helpers/url_helper.php
index 5b3ca930e4..d1cf375827 100644
--- a/app/Helpers/url_helper.php
+++ b/app/Helpers/url_helper.php
@@ -1,4 +1,5 @@
 <?php
+
 /**
  * @copyright  2020 Podlibre
  * @license    https://www.gnu.org/licenses/agpl-3.0.en.html AGPL3
diff --git a/app/Language/en/AdminNavigation.php b/app/Language/en/AdminNavigation.php
index 61c7db3fec..714502a495 100644
--- a/app/Language/en/AdminNavigation.php
+++ b/app/Language/en/AdminNavigation.php
@@ -1,19 +1,20 @@
-<?
+<?php
+
 /**
  * @copyright  2020 Podlibre
  * @license    https://www.gnu.org/licenses/agpl-3.0.en.html AGPL3
  * @link       https://castopod.org/
  */
 
- return [
-     'dashboard' => 'Dashboard',
-     'podcasts' => 'Podcasts',
-     'users' => 'Users',
-     'admin_home' => 'Home',
-     'my_podcasts' => 'My podcasts',
-     'podcast_list' => 'All podcasts',
-     'podcast_create' => 'New podcast',
-     'user_list' => 'All users',
-     'user_create' => 'New user',
-     'go_to_website' => 'Go to website'
- ];
\ No newline at end of file
+return [
+    'dashboard' => 'Dashboard',
+    'podcasts' => 'Podcasts',
+    'users' => 'Users',
+    'admin_home' => 'Home',
+    'my_podcasts' => 'My podcasts',
+    'podcast_list' => 'All podcasts',
+    'podcast_create' => 'New podcast',
+    'user_list' => 'All users',
+    'user_create' => 'New user',
+    'go_to_website' => 'Go to website',
+];
diff --git a/app/Language/en/Contributor.php b/app/Language/en/Contributor.php
index 57a8448a10..a9bf108bc5 100644
--- a/app/Language/en/Contributor.php
+++ b/app/Language/en/Contributor.php
@@ -1,4 +1,5 @@
-<?
+<?php
+
 /**
  * @copyright  2020 Podlibre
  * @license    https://www.gnu.org/licenses/agpl-3.0.en.html AGPL3
@@ -6,9 +7,6 @@
  */
 
 return [
-    'removeOwnerContributorError' => 'You can\'t remove the podcast owner!',
-    'removeContributorSuccess' => 'You have successfully removed {username} from {podcastTitle}',
-    'alreadyAddedError' => 'The contributor you\'re trying to add has already been added!',
     'podcast_contributors' => 'Podcast contributors',
     'add' => 'Add contributor',
     'add_contributor' => 'Add a contributor for {0}',
@@ -19,6 +17,13 @@ return [
         'user' => 'User',
         'role' => 'Role',
         'submit_add' => 'Add contributor',
-        'submit_edit' => 'Update role'
-    ]
+        'submit_edit' => 'Update role',
+    ],
+    'messages' => [
+        'removeOwnerContributorError' => 'You can\'t remove the podcast owner!',
+        'removeContributorSuccess' =>
+            'You have successfully removed {username} from {podcastTitle}',
+        'alreadyAddedError' =>
+            'The contributor you\'re trying to add has already been added!',
+    ],
 ];
diff --git a/app/Language/en/Countries.php b/app/Language/en/Countries.php
index 9bd81808bc..ba39901922 100644
--- a/app/Language/en/Countries.php
+++ b/app/Language/en/Countries.php
@@ -1,4 +1,5 @@
-<?
+<?php
+
 /**
  * ISO 3166 country codes
  * @copyright  2020 Podlibre
@@ -257,4 +258,4 @@ return [
     'ZA' => 'South Africa',
     'ZM' => 'Zambia',
     'ZW' => 'Zimbabwe',
-];
\ No newline at end of file
+];
diff --git a/app/Language/en/Episode.php b/app/Language/en/Episode.php
index 80ae2df6b3..f9613bd451 100644
--- a/app/Language/en/Episode.php
+++ b/app/Language/en/Episode.php
@@ -1,4 +1,5 @@
-<?
+<?php
+
 /**
  * @copyright  2020 Podlibre
  * @license    https://www.gnu.org/licenses/agpl-3.0.en.html AGPL3
@@ -10,7 +11,7 @@ return [
     'back_to_podcast' => 'Go back to podcast',
     'edit' => 'Edit',
     'delete' => 'Delete',
-    'goto_page' => 'Go to page',
+    'go_to_page' => 'Go to page',
     'create' => 'Add an episode',
     'form' => [
         'file' => 'Audio file',
@@ -33,5 +34,5 @@ return [
         'block' => 'Block',
         'submit_create' => 'Create episode',
         'submit_edit' => 'Save episode',
-    ]
-];
\ No newline at end of file
+    ],
+];
diff --git a/app/Language/en/Home.php b/app/Language/en/Home.php
index 435307ef9d..ee18880595 100644
--- a/app/Language/en/Home.php
+++ b/app/Language/en/Home.php
@@ -1,4 +1,5 @@
-<?
+<?php
+
 /**
  * @copyright  2020 Podlibre
  * @license    https://www.gnu.org/licenses/agpl-3.0.en.html AGPL3
diff --git a/app/Language/en/MyAccount.php b/app/Language/en/MyAccount.php
index f32684b7ee..c65d934460 100644
--- a/app/Language/en/MyAccount.php
+++ b/app/Language/en/MyAccount.php
@@ -1,4 +1,5 @@
-<?
+<?php
+
 /**
  * @copyright  2020 Podlibre
  * @license    https://www.gnu.org/licenses/agpl-3.0.en.html AGPL3
@@ -6,7 +7,9 @@
  */
 
 return [
-    'passwordChangeSuccess' => 'Password has been successfully changed!',
-    'changePassword' => 'Change my password',
-    'info' => 'My account info'
+    'info' => 'My account info',
+    'messages' => [
+        'passwordChangeSuccess' => 'Password has been successfully changed!',
+        'changePassword' => 'Change my password',
+    ],
 ];
diff --git a/app/Language/en/Podcast.php b/app/Language/en/Podcast.php
index 2cad384557..d69514bffe 100644
--- a/app/Language/en/Podcast.php
+++ b/app/Language/en/Podcast.php
@@ -1,4 +1,5 @@
-<?
+<?php
+
 /**
  * @copyright  2020 Podlibre
  * @license    https://www.gnu.org/licenses/agpl-3.0.en.html AGPL3
@@ -16,7 +17,7 @@ return [
     'delete' => 'Delete podcast',
     'see_episodes' => 'See episodes',
     'see_contributors' => 'See contributors',
-    'goto_page' => 'Go to page',
+    'go_to_page' => 'Go to page',
     'form' => [
         'title' => 'Title',
         'name' => 'Name',
@@ -156,5 +157,5 @@ return [
         'tv_reviews' => 'TV Reviews',
     ],
     'list_of_episodes' => 'List of episodes',
-    'no_episode' => 'No episode found' 
-];
\ No newline at end of file
+    'no_episode' => 'No episode found',
+];
diff --git a/app/Language/en/User.php b/app/Language/en/User.php
index aa5491c0a4..2cdc1e332a 100644
--- a/app/Language/en/User.php
+++ b/app/Language/en/User.php
@@ -1,4 +1,5 @@
-<?
+<?php
+
 /**
  * @copyright  2020 Podlibre
  * @license    https://www.gnu.org/licenses/agpl-3.0.en.html AGPL3
@@ -6,14 +7,6 @@
  */
 
 return [
-    'createSuccess' => 'User created successfully! {username} will be prompted with a password reset upon first authentication.',
-    'rolesEditSuccess' => '{username}\'s roles have been successfully updated.',
-    'forcePassResetSuccess' => '{username} will be prompted with a password reset upon next visit.',
-    'banSuccess' => '{username} has been banned.',
-    'unbanSuccess' => '{username} has been unbanned.',
-    'banSuperAdminError' => '{username} is a superadmin, one does not simply ban a superadmin…',
-    'deleteSuperAdminError' => '{username} is a superadmin, one does not simply delete a superadmin…',
-    'deleteSuccess' => '{username} has been deleted.',
     'edit_roles' => 'Edit {username}\'s roles',
     'forcePassReset' => 'Force pass reset',
     'ban' => 'Ban',
@@ -31,5 +24,20 @@ return [
         'roles' => 'Roles',
         'submit_create' => 'Create user',
         'submit_edit' => 'Save',
-    ]
+    ],
+    'messages' => [
+        'createSuccess' =>
+            'User created successfully! {username} will be prompted with a password reset upon first authentication.',
+        'rolesEditSuccess' =>
+            '{username}\'s roles have been successfully updated.',
+        'forcePassResetSuccess' =>
+            '{username} will be prompted with a password reset upon next visit.',
+        'banSuccess' => '{username} has been banned.',
+        'unbanSuccess' => '{username} has been unbanned.',
+        'banSuperAdminError' =>
+            '{username} is a superadmin, one does not simply ban a superadmin…',
+        'deleteSuperAdminError' =>
+            '{username} is a superadmin, one does not simply delete a superadmin…',
+        'deleteSuccess' => '{username} has been deleted.',
+    ],
 ];
diff --git a/app/Language/fr/Countries.php b/app/Language/fr/Countries.php
index 8b25fff791..48b3654129 100644
--- a/app/Language/fr/Countries.php
+++ b/app/Language/fr/Countries.php
@@ -1,4 +1,5 @@
-<?
+<?php
+
 /**
  * ISO 3166 country codes
  * @copyright  2020 Podlibre
@@ -6,7 +7,8 @@
  * @link       https://castopod.org/
  */
 
-return ['AF ' => 'Afghanistan',
+return [
+    'AF ' => 'Afghanistan',
     'ZA ' => 'Afrique Du Sud',
     'AX ' => 'Ã…land, ÃŽles',
     'AL ' => 'Albanie',
@@ -256,4 +258,4 @@ return ['AF ' => 'Afghanistan',
     'YE ' => 'Yémen',
     'ZM ' => 'Zambie',
     'ZW ' => 'Zimbabwe',
-];
\ No newline at end of file
+];
diff --git a/app/Libraries/SimpleRSSElement.php b/app/Libraries/SimpleRSSElement.php
index c5211e9b6e..1d70a3944a 100644
--- a/app/Libraries/SimpleRSSElement.php
+++ b/app/Libraries/SimpleRSSElement.php
@@ -1,10 +1,15 @@
 <?php
+
 /**
  * @copyright  2020 Podlibre
  * @license    https://www.gnu.org/licenses/agpl-3.0.en.html AGPL3
  * @link       https://castopod.org/
  */
 
+namespace App\Libraries;
+
+use SimpleXMLElement;
+
 class SimpleRSSElement extends SimpleXMLElement
 {
     /**
diff --git a/app/Models/AnalyticsEpisodesByCountryModel.php b/app/Models/AnalyticsEpisodesByCountryModel.php
index c43e3d348f..25644114ab 100644
--- a/app/Models/AnalyticsEpisodesByCountryModel.php
+++ b/app/Models/AnalyticsEpisodesByCountryModel.php
@@ -1,4 +1,5 @@
 <?php
+
 /**
  * Class AnalyticsEpisodesByCountry
  * Model for analytics_episodes_by_country table in database
@@ -6,6 +7,7 @@
  * @license    https://www.gnu.org/licenses/agpl-3.0.en.html AGPL3
  * @link       https://castopod.org/
  */
+
 namespace App\Models;
 
 use CodeIgniter\Model;
@@ -17,7 +19,7 @@ class AnalyticsEpisodesByCountryModel extends Model
 
     protected $allowedFields = [];
 
-    protected $returnType = 'App\Entities\AnalyticsEpisodesByCountry';
+    protected $returnType = \App\Entities\AnalyticsEpisodesByCountry::class;
     protected $useSoftDeletes = false;
 
     protected $useTimestamps = false;
diff --git a/app/Models/AnalyticsEpisodesByPlayerModel.php b/app/Models/AnalyticsEpisodesByPlayerModel.php
index 21670392f5..efeefb7844 100644
--- a/app/Models/AnalyticsEpisodesByPlayerModel.php
+++ b/app/Models/AnalyticsEpisodesByPlayerModel.php
@@ -1,4 +1,5 @@
 <?php
+
 /**
  * Class AnalyticsEpisodesByPlayerModel
  * Model for analytics_episodes_by_player table in database
@@ -6,6 +7,7 @@
  * @license    https://www.gnu.org/licenses/agpl-3.0.en.html AGPL3
  * @link       https://castopod.org/
  */
+
 namespace App\Models;
 
 use CodeIgniter\Model;
@@ -17,7 +19,7 @@ class AnalyticsEpisodesByPlayerModel extends Model
 
     protected $allowedFields = [];
 
-    protected $returnType = 'App\Entities\AnalyticsEpisodesByPlayer';
+    protected $returnType = \App\Entities\AnalyticsEpisodesByPlayer::class;
     protected $useSoftDeletes = false;
 
     protected $useTimestamps = false;
diff --git a/app/Models/AnalyticsPodcastsByCountryModel.php b/app/Models/AnalyticsPodcastsByCountryModel.php
index 3fe8f0421b..70f5fc3e77 100644
--- a/app/Models/AnalyticsPodcastsByCountryModel.php
+++ b/app/Models/AnalyticsPodcastsByCountryModel.php
@@ -1,4 +1,5 @@
 <?php
+
 /**
  * Class AnalyticsPodcastsByCountryModel
  * Model for analytics_episodes_by_country table in database
@@ -6,6 +7,7 @@
  * @license    https://www.gnu.org/licenses/agpl-3.0.en.html AGPL3
  * @link       https://castopod.org/
  */
+
 namespace App\Models;
 
 use CodeIgniter\Model;
@@ -17,7 +19,7 @@ class AnalyticsPodcastsByCountryModel extends Model
 
     protected $allowedFields = [];
 
-    protected $returnType = 'App\Entities\AnalyticsPodcastsByCountry';
+    protected $returnType = \App\Entities\AnalyticsPodcastsByCountry::class;
     protected $useSoftDeletes = false;
 
     protected $useTimestamps = false;
diff --git a/app/Models/AnalyticsPodcastsByPlayerModel.php b/app/Models/AnalyticsPodcastsByPlayerModel.php
index cba3075374..5e0ff822f5 100644
--- a/app/Models/AnalyticsPodcastsByPlayerModel.php
+++ b/app/Models/AnalyticsPodcastsByPlayerModel.php
@@ -1,4 +1,5 @@
 <?php
+
 /**
  * Class AnalyticsPodcastsByPlayerModel
  * Model for analytics_podcasts_by_player table in database
@@ -6,6 +7,7 @@
  * @license    https://www.gnu.org/licenses/agpl-3.0.en.html AGPL3
  * @link       https://castopod.org/
  */
+
 namespace App\Models;
 
 use CodeIgniter\Model;
@@ -17,7 +19,7 @@ class AnalyticsPodcastsByPlayerModel extends Model
 
     protected $allowedFields = [];
 
-    protected $returnType = 'App\Entities\AnalyticsPodcastsByPlayer';
+    protected $returnType = \App\Entities\AnalyticsPodcastsByPlayer::class;
     protected $useSoftDeletes = false;
 
     protected $useTimestamps = false;
diff --git a/app/Models/AnalyticsUnknownUseragentsModel.php b/app/Models/AnalyticsUnknownUseragentsModel.php
index 97514735ad..8dae7486e6 100644
--- a/app/Models/AnalyticsUnknownUseragentsModel.php
+++ b/app/Models/AnalyticsUnknownUseragentsModel.php
@@ -1,4 +1,5 @@
 <?php
+
 /**
  * Class AnalyticsUnknownUseragentsModel
  * Model for analytics_unknown_useragents table in database
@@ -6,6 +7,7 @@
  * @license    https://www.gnu.org/licenses/agpl-3.0.en.html AGPL3
  * @link       https://castopod.org/
  */
+
 namespace App\Models;
 
 use CodeIgniter\Model;
@@ -17,7 +19,7 @@ class AnalyticsUnknownUseragentsModel extends Model
 
     protected $allowedFields = [];
 
-    protected $returnType = 'App\Entities\AnalyticsUnknownUseragents';
+    protected $returnType = \App\Entities\AnalyticsUnknownUseragents::class;
     protected $useSoftDeletes = false;
 
     protected $useTimestamps = false;
diff --git a/app/Models/AnalyticsWebsiteByBrowserModel.php b/app/Models/AnalyticsWebsiteByBrowserModel.php
index e2ac29fb3f..ceee6b3e09 100644
--- a/app/Models/AnalyticsWebsiteByBrowserModel.php
+++ b/app/Models/AnalyticsWebsiteByBrowserModel.php
@@ -1,4 +1,5 @@
 <?php
+
 /**
  * Class AnalyticsWebsiteByBrowserModel
  * Model for analytics_website_by_browser table in database
@@ -6,6 +7,7 @@
  * @license    https://www.gnu.org/licenses/agpl-3.0.en.html AGPL3
  * @link       https://castopod.org/
  */
+
 namespace App\Models;
 
 use CodeIgniter\Model;
@@ -17,7 +19,7 @@ class AnalyticsWebsiteByBrowserModel extends Model
 
     protected $allowedFields = [];
 
-    protected $returnType = 'App\Entities\AnalyticsWebsiteByBrowser';
+    protected $returnType = \App\Entities\AnalyticsWebsiteByBrowser::class;
     protected $useSoftDeletes = false;
 
     protected $useTimestamps = false;
diff --git a/app/Models/AnalyticsWebsiteByCountryModel.php b/app/Models/AnalyticsWebsiteByCountryModel.php
index 1c9a25f033..0163b65bfe 100644
--- a/app/Models/AnalyticsWebsiteByCountryModel.php
+++ b/app/Models/AnalyticsWebsiteByCountryModel.php
@@ -1,4 +1,5 @@
 <?php
+
 /**
  * Class AnalyticsWebsiteByCountryModel
  * Model for analytics_website_by_country table in database
@@ -6,6 +7,7 @@
  * @license    https://www.gnu.org/licenses/agpl-3.0.en.html AGPL3
  * @link       https://castopod.org/
  */
+
 namespace App\Models;
 
 use CodeIgniter\Model;
@@ -17,7 +19,7 @@ class AnalyticsWebsiteByCountryModel extends Model
 
     protected $allowedFields = [];
 
-    protected $returnType = 'App\Entities\AnalyticsWebsiteByCountry';
+    protected $returnType = \App\Entities\AnalyticsWebsiteByCountry::class;
     protected $useSoftDeletes = false;
 
     protected $useTimestamps = false;
diff --git a/app/Models/AnalyticsWebsiteByRefererModel.php b/app/Models/AnalyticsWebsiteByRefererModel.php
index 488b0cc9c3..108a6847ab 100644
--- a/app/Models/AnalyticsWebsiteByRefererModel.php
+++ b/app/Models/AnalyticsWebsiteByRefererModel.php
@@ -1,4 +1,5 @@
 <?php
+
 /**
  * Class AnalyticsWebsiteByRefererModel
  * Model for analytics_website_by_referer table in database
@@ -6,6 +7,7 @@
  * @license    https://www.gnu.org/licenses/agpl-3.0.en.html AGPL3
  * @link       https://castopod.org/
  */
+
 namespace App\Models;
 
 use CodeIgniter\Model;
@@ -17,7 +19,7 @@ class AnalyticsWebsiteByRefererModel extends Model
 
     protected $allowedFields = [];
 
-    protected $returnType = 'App\Entities\AnalyticsWebsiteByReferer';
+    protected $returnType = \App\Entities\AnalyticsWebsiteByReferer::class;
     protected $useSoftDeletes = false;
 
     protected $useTimestamps = false;
diff --git a/app/Models/CategoryModel.php b/app/Models/CategoryModel.php
index 69c3f9543e..66309406be 100644
--- a/app/Models/CategoryModel.php
+++ b/app/Models/CategoryModel.php
@@ -1,4 +1,5 @@
 <?php
+
 /**
  * @copyright  2020 Podlibre
  * @license    https://www.gnu.org/licenses/agpl-3.0.en.html AGPL3
@@ -21,8 +22,13 @@ class CategoryModel extends Model
         'google_category',
     ];
 
-    protected $returnType = 'App\Entities\Category';
+    protected $returnType = \App\Entities\Category::class;
     protected $useSoftDeletes = false;
 
     protected $useTimestamps = false;
+
+    public function findParent($parentId)
+    {
+        return $this->find($parentId);
+    }
 }
diff --git a/app/Models/EpisodeModel.php b/app/Models/EpisodeModel.php
index eb372fa401..9514abec0f 100644
--- a/app/Models/EpisodeModel.php
+++ b/app/Models/EpisodeModel.php
@@ -1,4 +1,5 @@
 <?php
+
 /**
  * @copyright  2020 Podlibre
  * @license    https://www.gnu.org/licenses/agpl-3.0.en.html AGPL3
@@ -31,7 +32,7 @@ class EpisodeModel extends Model
         'block',
     ];
 
-    protected $returnType = 'App\Entities\Episode';
+    protected $returnType = \App\Entities\Episode::class;
 
     protected $useSoftDeletes = true;
     protected $useTimestamps = true;
@@ -53,12 +54,13 @@ class EpisodeModel extends Model
 
     protected $afterInsert = ['writeEnclosureMetadata', 'clearCache'];
     protected $afterUpdate = ['writeEnclosureMetadata', 'clearCache'];
+    protected $beforeDelete = ['clearCache'];
 
     protected function writeEnclosureMetadata(array $data)
     {
         helper('id3');
 
-        $episode = $this->find(
+        $episode = (new EpisodeModel())->find(
             is_array($data['id']) ? $data['id'][0] : $data['id']
         );
 
@@ -69,7 +71,7 @@ class EpisodeModel extends Model
 
     protected function clearCache(array $data)
     {
-        $episode = $this->find(
+        $episode = (new EpisodeModel())->find(
             is_array($data['id']) ? $data['id'][0] : $data['id']
         );
 
@@ -80,6 +82,8 @@ class EpisodeModel extends Model
 
         // delete model requests cache
         cache()->delete("{$episode->podcast_id}_episodes");
+
+        return $data;
     }
 
     /**
diff --git a/app/Models/LanguageModel.php b/app/Models/LanguageModel.php
index 98143567a1..f89f596562 100644
--- a/app/Models/LanguageModel.php
+++ b/app/Models/LanguageModel.php
@@ -1,4 +1,5 @@
 <?php
+
 /**
  * @copyright  2020 Podlibre
  * @license    https://www.gnu.org/licenses/agpl-3.0.en.html AGPL3
@@ -16,7 +17,7 @@ class LanguageModel extends Model
 
     protected $allowedFields = ['code', 'native_name'];
 
-    protected $returnType = 'App\Entities\Language';
+    protected $returnType = \App\Entities\Language::class;
     protected $useSoftDeletes = false;
 
     protected $useTimestamps = false;
diff --git a/app/Models/PlatformLinkModel.php b/app/Models/PlatformLinkModel.php
index a8fb1a1fc8..fbddcc465d 100644
--- a/app/Models/PlatformLinkModel.php
+++ b/app/Models/PlatformLinkModel.php
@@ -1,4 +1,5 @@
 <?php
+
 /**
  * Class PlatformLinkModel
  * Model for platform links table in database
@@ -7,6 +8,7 @@
  * @license    https://www.gnu.org/licenses/agpl-3.0.en.html AGPL3
  * @link       https://castopod.org/
  */
+
 namespace App\Models;
 
 use CodeIgniter\Model;
@@ -24,7 +26,7 @@ class PlatformLinkModel extends Model
         'visible',
     ];
 
-    protected $returnType = 'App\Entities\PlatformLink';
+    protected $returnType = App\Entities\PlatformLink::class;
     protected $useSoftDeletes = false;
 
     protected $useTimestamps = true;
diff --git a/app/Models/PlatformModel.php b/app/Models/PlatformModel.php
index 782bf0ff3c..977e7fed14 100644
--- a/app/Models/PlatformModel.php
+++ b/app/Models/PlatformModel.php
@@ -1,4 +1,5 @@
 <?php
+
 /**
  * Class PlatformModel
  * Model for platforms table in database
@@ -7,6 +8,7 @@
  * @license    https://www.gnu.org/licenses/agpl-3.0.en.html AGPL3
  * @link       https://castopod.org/
  */
+
 namespace App\Models;
 
 use CodeIgniter\Model;
@@ -29,7 +31,7 @@ class PlatformModel extends Model
         'logo_file_name',
     ];
 
-    protected $returnType = 'App\Entities\Platform';
+    protected $returnType = \App\Entities\Platform::class;
     protected $useSoftDeletes = false;
 
     protected $useTimestamps = true;
diff --git a/app/Models/PodcastModel.php b/app/Models/PodcastModel.php
index ece640d993..acf34709d0 100644
--- a/app/Models/PodcastModel.php
+++ b/app/Models/PodcastModel.php
@@ -1,4 +1,5 @@
 <?php
+
 /**
  * @copyright  2020 Podlibre
  * @license    https://www.gnu.org/licenses/agpl-3.0.en.html AGPL3
@@ -36,7 +37,7 @@ class PodcastModel extends Model
         'custom_html_head',
     ];
 
-    protected $returnType = 'App\Entities\Podcast';
+    protected $returnType = \App\Entities\Podcast::class;
     protected $useSoftDeletes = true;
 
     protected $useTimestamps = true;
@@ -60,6 +61,11 @@ class PodcastModel extends Model
     protected $afterUpdate = ['clearCache'];
     protected $beforeDelete = ['clearCache'];
 
+    public function hello(array $data)
+    {
+        return $data;
+    }
+
     /**
      *  Gets all the podcasts a given user is contributing to
      *
@@ -128,19 +134,18 @@ class PodcastModel extends Model
 
     protected function clearCache(array $data)
     {
-        $podcast = $this->find(
+        $podcast = (new PodcastModel())->find(
             is_array($data['id']) ? $data['id'][0] : $data['id']
         );
 
         // delete cache for rss feed and podcast pages
         cache()->delete(md5($podcast->feed_url));
         cache()->delete(md5($podcast->link));
-        // TODO: clear cache for every podcast's episode page?
-        // foreach ($podcast->episodes as $episode) {
-        //     cache()->delete(md5($episode->link));
-        // }
 
-        $data['podcast'] = $podcast;
+        // clear cache for every podcast's episode page?
+        foreach ($podcast->episodes as $episode) {
+            cache()->delete(md5($episode->link));
+        }
 
         return $data;
     }
diff --git a/app/Models/UnknownUserAgentsModel.php b/app/Models/UnknownUserAgentsModel.php
index 5cd0b71b16..5afabf5dc9 100644
--- a/app/Models/UnknownUserAgentsModel.php
+++ b/app/Models/UnknownUserAgentsModel.php
@@ -1,4 +1,5 @@
 <?php
+
 /**
  * Class UnknownUserAgentsModel
  * Model for analytics_unknown_useragents table in database
@@ -6,6 +7,7 @@
  * @license    https://www.gnu.org/licenses/agpl-3.0.en.html AGPL3
  * @link       https://castopod.org/
  */
+
 namespace App\Models;
 
 use CodeIgniter\Model;
@@ -18,6 +20,6 @@ class UnknownUserAgentsModel extends Model
 
     public function getUserAgents($last_known_id = 0)
     {
-        return $this->where('id>', $last_known_id)->findAll();
+        return $this->where('id >', $last_known_id)->findAll();
     }
 }
diff --git a/app/Models/UserModel.php b/app/Models/UserModel.php
index 876cc94712..420c002dae 100644
--- a/app/Models/UserModel.php
+++ b/app/Models/UserModel.php
@@ -1,10 +1,10 @@
-<?php namespace App\Models;
+<?php
 
-use App\Entities\User;
+namespace App\Models;
 
 class UserModel extends \Myth\Auth\Models\UserModel
 {
-    protected $returnType = User::class;
+    protected $returnType = \App\Entities\User::class;
 
     public function getPodcastContributors($podcast_id)
     {
diff --git a/app/Views/_layout.php b/app/Views/_layout.php
index 993e5d9244..9bc3e3714b 100644
--- a/app/Views/_layout.php
+++ b/app/Views/_layout.php
@@ -2,27 +2,27 @@
 <html lang="en">
 
 <head>
-	<meta charset="UTF-8"/>
-	<title>Castopod</title>
-	<meta name="description" content="Castopod is an open-source hosting platform made for podcasters who want engage and interact with their audience."/>
-	<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
-	<link rel="shortcut icon" type="image/png" href="/favicon.ico" />
-	<link rel="stylesheet" href="/assets/index.css"/>
-	<?php if (isset($podcast)): ?>
-		<?= $podcast->custom_html_head ?>
-	<?php endif; ?>
+    <meta charset="UTF-8"/>
+    <title>Castopod</title>
+    <meta name="description" content="Castopod is an open-source hosting platform made for podcasters who want engage and interact with their audience."/>
+    <meta name="viewport" content="width=device-width, initial-scale=1.0"/>
+    <link rel="shortcut icon" type="image/png" href="/favicon.ico" />
+    <link rel="stylesheet" href="/assets/index.css"/>
+    <?php if (isset($podcast)): ?>
+        <?= $podcast->custom_html_head ?>
+    <?php endif; ?>
 </head>
 
 <body class="flex flex-col min-h-screen mx-auto">
-	<header class="border-b">
-		<div class="container flex items-center justify-between px-2 py-4 mx-auto">
-			<a href="<?= route_to('home') ?>" class="text-2xl">Castopod</a>
-		</div>
-	</header>
-	<main class="container flex-1 px-4 py-10 mx-auto">
-		<?= $this->renderSection('content') ?>
-	</main>
-	<footer class="container px-2 py-4 mx-auto text-sm text-right border-t">
-		Powered by <a class="underline hover:no-underline" href="https://castopod.org" target="_blank" rel="noreferrer noopener">Castopod</a>, a <a class="underline hover:no-underline" href="https://podlibre.org/" target="_blank" rel="noreferrer noopener">Podlibre</a> initiative.
-	</footer>
+    <header class="border-b">
+        <div class="container flex items-center justify-between px-2 py-4 mx-auto">
+            <a href="<?= route_to('home') ?>" class="text-2xl">Castopod</a>
+        </div>
+    </header>
+    <main class="container flex-1 px-4 py-10 mx-auto">
+        <?= $this->renderSection('content') ?>
+    </main>
+    <footer class="container px-2 py-4 mx-auto text-sm text-right border-t">
+        Powered by <a class="underline hover:no-underline" href="https://castopod.org" target="_blank" rel="noreferrer noopener">Castopod</a>, a <a class="underline hover:no-underline" href="https://podlibre.org/" target="_blank" rel="noreferrer noopener">Podlibre</a> initiative.
+    </footer>
 </body>
diff --git a/app/Views/_message_block.php b/app/Views/_message_block.php
index 2504c21135..f086baf6fb 100644
--- a/app/Views/_message_block.php
+++ b/app/Views/_message_block.php
@@ -1,16 +1,17 @@
 <?php if (session()->has('message')): ?>
-	<div class="px-4 py-2 mb-4 font-semibold text-green-900 bg-green-200 border border-green-700">
-		<?= session('message') ?>
-	</div>
+    <div class="px-4 py-2 mb-4 font-semibold text-green-900 bg-green-200 border border-green-700">
+        <?= session('message') ?>
+    </div>
 <?php endif; ?>
 
 <?php if (session()->has('error')): ?>
-	<div class="px-4 py-2 mb-4 font-semibold text-red-900 bg-red-200 border border-red-700">
-		<?= session('error') ?>
-	</div>
+    <div class="px-4 py-2 mb-4 font-semibold text-red-900 bg-red-200 border border-red-700">
+        <?= session('error') ?>
+    </div>
 <?php endif; ?>
 
 <?php if (session()->has('errors')): ?>
+<<<<<<< HEAD
 	<ul class="px-4 py-2 mb-4 font-semibold text-red-900 bg-red-200 border border-red-700">
 	<?php foreach (session('errors') as $error): ?>
 		<li><?= $error ?></li>
@@ -18,3 +19,11 @@
 	</ul>
 <?php endif;
 ?>
+=======
+    <ul class="px-4 py-2 mb-4 font-semibold text-red-900 bg-red-200 border border-red-700">
+    <?php foreach (session('errors') as $error): ?>
+        <li><?= $error ?></li>
+    <?php endforeach; ?>
+    </ul>
+<?php endif; ?>
+>>>>>>> ef31ffe... refactor: add php_codesniffer to define castopod's coding style based on psr-1
diff --git a/app/Views/admin/_layout.php b/app/Views/admin/_layout.php
index a2d2a763c6..75b11ac5ed 100644
--- a/app/Views/admin/_layout.php
+++ b/app/Views/admin/_layout.php
@@ -1,33 +1,35 @@
-<?php helper('html'); ?>
+<?php
+
+helper('html'); ?>
 
 <!DOCTYPE html>
 <html lang="en">
 
 <head>
-	<meta charset="UTF-8"/>
-	<title>Castopod Admin</title>
-	<meta name="description" content="Castopod is an open-source hosting platform made for podcasters who want engage and interact with their audience."/>
-	<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
-	<link rel="shortcut icon" type="image/png" href="/favicon.ico" />
-	<link rel="stylesheet" href="/assets/admin.css"/>
-	<link rel="stylesheet" href="/assets/index.css"/>
+    <meta charset="UTF-8"/>
+    <title>Castopod Admin</title>
+    <meta name="description" content="Castopod is an open-source hosting platform made for podcasters who want engage and interact with their audience."/>
+    <meta name="viewport" content="width=device-width, initial-scale=1.0"/>
+    <link rel="shortcut icon" type="image/png" href="/favicon.ico" />
+    <link rel="stylesheet" href="/assets/admin.css"/>
+    <link rel="stylesheet" href="/assets/index.css"/>
 </head>
 
 <body class="min-h-screen bg-gray-100 holy-grail-grid">
-	<?= view('admin/_header', [
-     'class' => 'flex items-center px-4 py-2 holy-grail-header',
- ]) ?>
-		<?= view('admin/_sidenav', [
-      'class' => 'flex flex-col w-64 py-6 holy-grail-sidenav',
-  ]) ?>
-	<main class="container px-4 py-6 mx-auto holy-grail-main">
-		<h1 class="mb-4 text-2xl"><?= $this->renderSection('title') ?></h1>
-		<?= view('_message_block') ?>
-		<?= $this->renderSection('content') ?>
-	</main>
-	<footer class="w-full px-2 py-4 mx-auto text-xs text-right border-t holy-grail-footer">
-		Powered by <a class="underline hover:no-underline" href="https://castopod.org" target="_blank" rel="noreferrer noopener">Castopod</a>, a <a class="underline hover:no-underline" href="https://podlibre.org/" target="_blank" rel="noreferrer noopener">Podlibre</a> initiative.
-	</footer>
+    <?= view('admin/_header', [
+        'class' => 'flex items-center px-4 py-2 holy-grail-header',
+    ]) ?>
+        <?= view('admin/_sidenav', [
+            'class' => 'flex flex-col w-64 py-6 holy-grail-sidenav',
+        ]) ?>
+    <main class="container px-4 py-6 mx-auto holy-grail-main">
+        <h1 class="mb-4 text-2xl"><?= $this->renderSection('title') ?></h1>
+        <?= view('_message_block') ?>
+        <?= $this->renderSection('content') ?>
+    </main>
+    <footer class="w-full px-2 py-4 mx-auto text-xs text-right border-t holy-grail-footer">
+        Powered by <a class="underline hover:no-underline" href="https://castopod.org" target="_blank" rel="noreferrer noopener">Castopod</a>, a <a class="underline hover:no-underline" href="https://podlibre.org/" target="_blank" rel="noreferrer noopener">Podlibre</a> initiative.
+    </footer>
 
-	<script src="/assets/admin.js"></script>
+    <script src="/assets/admin.js"></script>
 </body>
diff --git a/app/Views/admin/_partials/_episode-card.php b/app/Views/admin/_partials/_episode-card.php
index 6bdfede8fe..baf0b5677f 100644
--- a/app/Views/admin/_partials/_episode-card.php
+++ b/app/Views/admin/_partials/_episode-card.php
@@ -1,4 +1,6 @@
-<?php helper('html'); ?>
+<?php
+
+helper('html'); ?>
 
 <article class="flex w-full max-w-lg mb-4 bg-white border rounded shadow">
     <img src="<?= $episode->image_url ?>" alt="<?= $episode->title ?>" class="object-cover w-32 h-32 rounded-l" />
@@ -27,7 +29,7 @@
                         'episode',
                         $episode->podcast->id,
                         $episode->slug
-                    ) ?>"><?= lang('Episode.goto_page') ?></a>
+                    ) ?>"><?= lang('Episode.go_to_page') ?></a>
                     <a class="px-4 py-1 hover:bg-gray-100" href="<?= route_to(
                         'episode_delete',
                         $episode->podcast->id,
diff --git a/app/Views/admin/_sidenav.php b/app/Views/admin/_sidenav.php
index 5698f1055b..8b51f31397 100644
--- a/app/Views/admin/_sidenav.php
+++ b/app/Views/admin/_sidenav.php
@@ -17,7 +17,7 @@ $navigation = [
         </button>
         <ul>
             <?php foreach ($data['items'] as $item): ?>
-            <?php $isActive = base_url(route_to($item)) == current_url(); ?>
+                <?php $isActive = base_url(route_to($item)) == current_url(); ?>
             <li>
                 <a class="block py-1 pl-10 pr-2 text-sm text-gray-600 outline-none hover:text-gray-900 focus:shadow-outline <?= $isActive
                     ? 'font-semibold text-gray-900'
diff --git a/app/Views/admin/contributor/edit.php b/app/Views/admin/contributor/edit.php
index fb80c1a5fa..3329cf85b7 100644
--- a/app/Views/admin/contributor/edit.php
+++ b/app/Views/admin/contributor/edit.php
@@ -19,7 +19,7 @@
             <?php foreach ($roles as $role): ?>
                 <option value="<?= $role->id ?>"
                 <?php if (
-                    old('role') == $role->id
+                    $contributorGroupId == $role->id
                 ): ?> selected <?php endif; ?>>
                     <?= $role->name ?>
                 </option>
diff --git a/app/Views/admin/episode/create.php b/app/Views/admin/episode/create.php
index 0238c0fa77..1651f833b2 100644
--- a/app/Views/admin/episode/create.php
+++ b/app/Views/admin/episode/create.php
@@ -97,19 +97,19 @@
             !old('type') ||
             old('type') == 'full'
         ): ?> checked <?php endif; ?> />
-        <span class="ml-2"><?= lang('Episode.form.type.full') ?></span>  
+        <span class="ml-2"><?= lang('Episode.form.type.full') ?></span>
     </label>
     <label for="trailer" class="inline-flex items-center">
         <input type="radio" class="form-radio" value="trailer" id="trailer" name="type" required <?php if (
             old('type') == 'trailer'
         ): ?> checked <?php endif; ?> />
-        <span class="ml-2"><?= lang('Episode.form.type.trailer') ?></span>  
+        <span class="ml-2"><?= lang('Episode.form.type.trailer') ?></span>
     </label>
     <label for="bonus" class="inline-flex items-center">
         <input type="radio" class="form-radio" value="bonus" id="bonus" name="type" required <?php if (
             old('type') == 'bonus'
         ): ?> checked <?php endif; ?> />
-        <span class="ml-2"><?= lang('Episode.form.type.bonus') ?></span>  
+        <span class="ml-2"><?= lang('Episode.form.type.bonus') ?></span>
     </label>
 </fieldset>
 
diff --git a/app/Views/admin/episode/edit.php b/app/Views/admin/episode/edit.php
index 54b49fd4bd..4128b90672 100644
--- a/app/Views/admin/episode/edit.php
+++ b/app/Views/admin/episode/edit.php
@@ -7,10 +7,13 @@
 
 <?= $this->section('content') ?>
 
-<?= form_open_multipart(route_to('episode_edit', $podcast->id, $episode->id), [
-    'method' => 'post',
-    'class' => 'flex flex-col max-w-md',
-]) ?>
+<?= form_open_multipart(
+    route_to('episode_edit', $episode->podcast->id, $episode->id),
+    [
+        'method' => 'post',
+        'class' => 'flex flex-col max-w-md',
+    ]
+) ?>
 <?= csrf_field() ?>
 
 <div class="flex flex-col mb-4">
diff --git a/app/Views/admin/episode/view.php b/app/Views/admin/episode/view.php
index e54cc0d437..5bea39c45a 100644
--- a/app/Views/admin/episode/view.php
+++ b/app/Views/admin/episode/view.php
@@ -20,10 +20,10 @@
 ) ?>"><?= lang('Episode.edit') ?></a>
     <a href="<?= route_to(
         'episode',
-        $episode->podcast->id,
+        $episode->podcast->name,
         $episode->slug
     ) ?>" class="inline-flex px-4 py-2 text-white bg-gray-700 hover:bg-gray-800"><?= lang(
-    'Episode.goto_page'
+    'Episode.go_to_page'
 ) ?></a>
     <a href="<?= route_to(
         'episode_delete',
diff --git a/app/Views/admin/podcast/create.php b/app/Views/admin/podcast/create.php
index 2f4fa21aa9..299ab325c6 100644
--- a/app/Views/admin/podcast/create.php
+++ b/app/Views/admin/podcast/create.php
@@ -58,7 +58,7 @@
             ): ?> selected <?php endif; ?>
             <?php if (
                 !old('language') &&
-                $language->code == $browser_lang
+                $language->code == $browserLang
             ): ?> selected <?php endif; ?>
                 >
                 <?= $language->native_name ?>
diff --git a/app/Views/admin/podcast/list.php b/app/Views/admin/podcast/list.php
index 7538184202..9f18b1cfec 100644
--- a/app/Views/admin/podcast/list.php
+++ b/app/Views/admin/podcast/list.php
@@ -3,7 +3,7 @@
 <?= $this->extend('admin/_layout') ?>
 
 <?= $this->section('title') ?>
-<?= lang('Podcast.all_podcasts') ?> (<?= count($all_podcasts) ?>)
+<?= lang('Podcast.all_podcasts') ?> (<?= count($podcasts) ?>)
 <a class="inline-flex items-center px-2 py-1 mb-2 ml-4 text-sm text-white bg-green-500 rounded shadow-xs outline-none hover:bg-green-600 focus:shadow-outline" href="<?= route_to(
     'podcast_create'
 ) ?>">
@@ -15,8 +15,8 @@
 <?= $this->section('content') ?>
 
 <div class="flex flex-wrap">
-    <?php if ($all_podcasts): ?>
-        <?php foreach ($all_podcasts as $podcast): ?>
+    <?php if (!empty($podcasts)): ?>
+        <?php foreach ($podcasts as $podcast): ?>
             <?= view('admin/_partials/_podcast-card', [
                 'podcast' => $podcast,
             ]) ?>
diff --git a/app/Views/admin/podcast/view.php b/app/Views/admin/podcast/view.php
index b0af9c9dbb..9a781031c0 100644
--- a/app/Views/admin/podcast/view.php
+++ b/app/Views/admin/podcast/view.php
@@ -1,4 +1,6 @@
-<?php helper('html'); ?>
+<?php
+
+helper('html'); ?>
 
 <?= $this->extend('admin/_layout') ?>
 
@@ -28,7 +30,7 @@
     <a class="inline-flex px-2 py-1 text-white bg-gray-700 hover:bg-gray-800" href="<?= route_to(
         'podcast',
         $podcast->name
-    ) ?>"><?= lang('Podcast.goto_page') ?></a>
+    ) ?>"><?= lang('Podcast.go_to_page') ?></a>
     <a class="inline-flex px-2 py-1 text-white bg-red-700 hover:bg-red-800" href="<?= route_to(
         'podcast_delete',
         $podcast->id
diff --git a/app/Views/admin/user/list.php b/app/Views/admin/user/list.php
index cd64b07615..078d14ea70 100644
--- a/app/Views/admin/user/list.php
+++ b/app/Views/admin/user/list.php
@@ -3,7 +3,7 @@
 <?= $this->extend('admin/_layout') ?>
 
 <?= $this->section('title') ?>
-<?= lang('User.all_users') ?> (<?= count($all_users) ?>)
+<?= lang('User.all_users') ?> (<?= count($users) ?>)
 <?= $this->endSection() ?>
 
 
@@ -20,7 +20,7 @@
         </tr>
     </thead>
     <tbody>
-        <?php foreach ($all_users as $user): ?>
+        <?php foreach ($users as $user): ?>
         <tr>
             <td class="px-4 py-2 border"><?= $user->username ?></td>
             <td class="px-4 py-2 border"><?= $user->email ?></td>
diff --git a/app/Views/auth/login.php b/app/Views/auth/login.php
index 2d7fcee16d..106851d06d 100644
--- a/app/Views/auth/login.php
+++ b/app/Views/auth/login.php
@@ -1,28 +1,28 @@
 <?= $this->extend($config->viewLayout) ?>
 
 <?= $this->section('title') ?>
-	<?= lang('Auth.loginTitle') ?>
+    <?= lang('Auth.loginTitle') ?>
 <?= $this->endSection() ?>
 
 
 <?= $this->section('content') ?>
 
 <form action="<?= route_to('login') ?>" method="post" class="flex flex-col">
-	<?= csrf_field() ?>
+    <?= csrf_field() ?>
 
-	<label for="login"><?= lang('Auth.emailOrUsername') ?></label>
-	<input type="text" name="login" class="mb-4 form-input" placeholder="<?= lang(
-     'Auth.emailOrUsername'
- ) ?>">
+    <label for="login"><?= lang('Auth.emailOrUsername') ?></label>
+    <input type="text" name="login" class="mb-4 form-input" placeholder="<?= lang(
+        'Auth.emailOrUsername'
+    ) ?>">
 
-	<label for="password"><?= lang('Auth.password') ?></label>
-	<input type="password" name="password" class="mb-6 form-input" placeholder="<?= lang(
-     'Auth.password'
- ) ?>">
+    <label for="password"><?= lang('Auth.password') ?></label>
+    <input type="password" name="password" class="mb-6 form-input" placeholder="<?= lang(
+        'Auth.password'
+    ) ?>">
 
-	<button type="submit" class="px-4 py-2 ml-auto border">
-		<?= lang('Auth.loginAction') ?>
-	</button>
+    <button type="submit" class="px-4 py-2 ml-auto border">
+        <?= lang('Auth.loginAction') ?>
+    </button>
 </form>
 
 <?= $this->endSection() ?>
@@ -31,14 +31,14 @@
 <?= $this->section('footer') ?>
 
 <div class="flex flex-col items-center py-4 text-sm text-center">
-	<?php if ($config->allowRegistration): ?>
-		<a class="underline hover:no-underline" href="<?= route_to(
-      'register'
-  ) ?>"><?= lang('Auth.needAnAccount') ?></a>
-	<?php endif; ?>
-	<a class="underline hover:no-underline" href="<?= route_to(
-     'forgot'
- ) ?>"><?= lang('Auth.forgotYourPassword') ?></a>
+    <?php if ($config->allowRegistration): ?>
+        <a class="underline hover:no-underline" href="<?= route_to(
+            'register'
+        ) ?>"><?= lang('Auth.needAnAccount') ?></a>
+    <?php endif; ?>
+    <a class="underline hover:no-underline" href="<?= route_to(
+        'forgot'
+    ) ?>"><?= lang('Auth.forgotYourPassword') ?></a>
 </div>
 
 <?= $this->endSection() ?>
diff --git a/app/Views/errors/cli/error_exception.php b/app/Views/errors/cli/error_exception.php
index a91a3f6a65..1ad33d0679 100644
--- a/app/Views/errors/cli/error_exception.php
+++ b/app/Views/errors/cli/error_exception.php
@@ -6,14 +6,18 @@ Filename: <?= $exception->getFile(), "\n" ?>
 Line Number: <?= $exception->getLine() ?>
 
 <?php if (defined('SHOW_DEBUG_BACKTRACE') && SHOW_DEBUG_BACKTRACE === true): ?>
-
-	Backtrace:
-	<?php foreach ($exception->getTrace() as $error): ?>
-		<?php if (isset($error['file'])): ?>
-			<?= trim(
-       '-' . $error['line'] . ' - ' . $error['file'] . '::' . $error['function']
-   ) . "\n" ?>
-		<?php endif; ?>
-	<?php endforeach; ?>
+    Backtrace:
+    <?php foreach ($exception->getTrace() as $error): ?>
+        <?php if (isset($error['file'])): ?>
+            <?= trim(
+                '-' .
+                    $error['line'] .
+                    ' - ' .
+                    $error['file'] .
+                    '::' .
+                    $error['function']
+            ) . "\n" ?>
+        <?php endif; ?>
+    <?php endforeach; ?>
 
 <?php endif; ?>
diff --git a/app/Views/errors/html/debug.css b/app/Views/errors/html/debug.css
index e526b24fd0..6595eedb32 100644
--- a/app/Views/errors/html/debug.css
+++ b/app/Views/errors/html/debug.css
@@ -1,176 +1,177 @@
 body {
-    height: 100%;
-    background: #fafafa;
-    font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
-    color: #777;
-    font-weight: 300;
-    margin: 0;
-    padding: 0;
+  height: 100%;
+  background: #fafafa;
+  font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
+  color: #777;
+  font-weight: 300;
+  margin: 0;
+  padding: 0;
 }
 h1 {
-    font-weight: lighter;
-    letter-spacing: 0.8;
-    font-size: 3rem;
-    color: #222;
-    margin: 0;
+  font-weight: lighter;
+  letter-spacing: 0.8;
+  font-size: 3rem;
+  color: #222;
+  margin: 0;
 }
 h1.headline {
-    margin-top: 20%;
-    font-size: 5rem;
+  margin-top: 20%;
+  font-size: 5rem;
 }
 .text-center {
-    text-align: center;
+  text-align: center;
 }
 p.lead {
-    font-size: 1.6rem;
+  font-size: 1.6rem;
 }
 .container {
-    max-width: 75rem;
-    margin: 0 auto;
-    padding: 1rem;
+  max-width: 75rem;
+  margin: 0 auto;
+  padding: 1rem;
 }
 .header {
-    background: #85271f;
-    color: #fff;
+  background: #85271f;
+  color: #fff;
 }
 .header h1 {
-    color: #fff;
+  color: #fff;
 }
 .header p {
-    font-size: 1.2rem;
-    margin: 0;
-    line-height: 2.5;
+  font-size: 1.2rem;
+  margin: 0;
+  line-height: 2.5;
 }
 .header a {
-    color: rgba(255,255,255,0.5);
-    margin-left: 2rem;
-    display: none;
-    text-decoration: none;
+  color: rgba(255, 255, 255, 0.5);
+  margin-left: 2rem;
+  display: none;
+  text-decoration: none;
 }
 .header:hover a {
-    display: inline;
+  display: inline;
 }
 
 .footer .container {
-    border-top: 1px solid #e7e7e7;
-    margin-top: 1rem;
-    text-align: center;
+  border-top: 1px solid #e7e7e7;
+  margin-top: 1rem;
+  text-align: center;
 }
 
 .source {
-    background: #333;
-    color: #c7c7c7;
-    padding: 0.5em 1em;
-    border-radius: 5px;
-    font-family: Menlo, Monaco, Consolas, "Courier New", monospace;
-    margin: 0;
+  background: #333;
+  color: #c7c7c7;
+  padding: 0.5em 1em;
+  border-radius: 5px;
+  font-family: Menlo, Monaco, Consolas, "Courier New", monospace;
+  margin: 0;
 }
 .source span.line {
-    line-height: 1.4;
+  line-height: 1.4;
 }
 .source span.line .number {
-    color: #666;
+  color: #666;
 }
 .source .line .highlight {
-    display: block;
-    background: #555;
-    color: #fff;
+  display: block;
+  background: #555;
+  color: #fff;
 }
 .source span.highlight .number {
-    color: #fff;
+  color: #fff;
 }
 
 .tabs {
-    list-style: none;
-    list-style-position: inside;
-    margin: 0;
-    padding: 0;
-    margin-bottom: -1px;
+  list-style: none;
+  list-style-position: inside;
+  margin: 0;
+  padding: 0;
+  margin-bottom: -1px;
 }
 .tabs li {
-    display: inline;
+  display: inline;
 }
 .tabs a:link,
 .tabs a:visited {
-    padding: 0rem 1rem;
-    line-height: 2.7;
-    text-decoration: none;
-    color: #a7a7a7;
-    background: #f1f1f1;
-    border: 1px solid #e7e7e7;
-    border-bottom: 0;
-    border-top-left-radius: 5px;
-    border-top-right-radius: 5px;
-    display: inline-block;
+  padding: 0rem 1rem;
+  line-height: 2.7;
+  text-decoration: none;
+  color: #a7a7a7;
+  background: #f1f1f1;
+  border: 1px solid #e7e7e7;
+  border-bottom: 0;
+  border-top-left-radius: 5px;
+  border-top-right-radius: 5px;
+  display: inline-block;
 }
 .tabs a:hover {
-    background: #e7e7e7;
-    border-color: #e1e1e1;
+  background: #e7e7e7;
+  border-color: #e1e1e1;
 }
 .tabs a.active {
-    background: #fff;
+  background: #fff;
 }
 .tab-content {
-    background: #fff;
-    border: 1px solid #efefef;
+  background: #fff;
+  border: 1px solid #efefef;
 }
 .content {
-    padding: 1rem;
+  padding: 1rem;
 }
 .hide {
-    display: none;
+  display: none;
 }
 
 .alert {
-    margin-top: 2rem;
-    display: block;
-    text-align: center;
-    line-height: 3.0;
-    background: #d9edf7;
-    border: 1px solid #bcdff1;
-    border-radius: 5px;
-    color: #31708f;
-}
-ul, ol {
-    line-height: 1.8;
+  margin-top: 2rem;
+  display: block;
+  text-align: center;
+  line-height: 3;
+  background: #d9edf7;
+  border: 1px solid #bcdff1;
+  border-radius: 5px;
+  color: #31708f;
+}
+ul,
+ol {
+  line-height: 1.8;
 }
 
 table {
-    width: 100%;
-    overflow: hidden;
+  width: 100%;
+  overflow: hidden;
 }
 th {
-    text-align: left;
-    border-bottom: 1px solid #e7e7e7;
-    padding-bottom: 0.5rem;
+  text-align: left;
+  border-bottom: 1px solid #e7e7e7;
+  padding-bottom: 0.5rem;
 }
 td {
-    padding: 0.2rem 0.5rem 0.2rem 0;
+  padding: 0.2rem 0.5rem 0.2rem 0;
 }
 tr:hover td {
-    background: #f1f1f1;
+  background: #f1f1f1;
 }
 td pre {
-    white-space: pre-wrap;
+  white-space: pre-wrap;
 }
 
 .trace a {
-    color: inherit;
+  color: inherit;
 }
 .trace table {
-    width: auto;
+  width: auto;
 }
 .trace tr td:first-child {
-    min-width: 5em;
-    font-weight: bold;
+  min-width: 5em;
+  font-weight: bold;
 }
 .trace td {
-    background: #e7e7e7;
-    padding: 0 1rem;
+  background: #e7e7e7;
+  padding: 0 1rem;
 }
 .trace td pre {
-    margin: 0;
+  margin: 0;
 }
 .args {
-    display: none;
-}
\ No newline at end of file
+  display: none;
+}
diff --git a/app/Views/errors/html/debug.js b/app/Views/errors/html/debug.js
index 07e8124e0a..3428750fba 100644
--- a/app/Views/errors/html/debug.js
+++ b/app/Views/errors/html/debug.js
@@ -2,107 +2,108 @@
 // Tabs
 //--------------------------------------------------------------------
 
-var tabLinks = new Array();
-var contentDivs = new Array();
+var tabLinks = [];
+var contentDivs = [];
 
 function init() {
-
-    // Grab the tab links and content divs from the page
-    var tabListItems = document.getElementById('tabs').childNodes;
-    console.log(tabListItems);
-    for (var i = 0; i < tabListItems.length; i++) {
-        if (tabListItems[i].nodeName == "LI") {
-            var tabLink = getFirstChildWithTagName(tabListItems[i], 'A');
-            var id = getHash(tabLink.getAttribute('href'));
-            tabLinks[id] = tabLink;
-            contentDivs[id] = document.getElementById(id);
-        }
+  // Grab the tab links and content divs from the page
+  var tabListItems = document.getElementById("tabs").childNodes;
+  console.log(tabListItems);
+  for (var i = 0; i < tabListItems.length; i++) {
+    if (tabListItems[i].nodeName == "LI") {
+      var tabLink = getFirstChildWithTagName(tabListItems[i], "A");
+      var id = getHash(tabLink.getAttribute("href"));
+      tabLinks[id] = tabLink;
+      contentDivs[id] = document.getElementById(id);
     }
-
-    // Assign onclick events to the tab links, and
-    // highlight the first tab
-    var i = 0;
-
-    for (var id in tabLinks) {
-        tabLinks[id].onclick = showTab;
-        tabLinks[id].onfocus = function () { this.blur() };
-        if (i == 0) {
-            tabLinks[id].className = 'active';
-        }
-        i++;
+  }
+
+  // Assign onclick events to the tab links, and
+  // highlight the first tab
+  var j = 0;
+
+  for (id in tabLinks) {
+    tabLinks[id].onclick = showTab;
+    tabLinks[id].onfocus = function () {
+      this.blur();
+    };
+    if (j == 0) {
+      tabLinks[id].className = "active";
     }
+    j++;
+  }
 
-    // Hide all content divs except the first
-    var i = 0;
+  // Hide all content divs except the first
+  var k = 0;
 
-    for (var id in contentDivs) {
-        if (i != 0) {
-            console.log(contentDivs[id]);
-            contentDivs[id].className = 'content hide';
-        }
-        i++;
+  for (id in contentDivs) {
+    if (k != 0) {
+      console.log(contentDivs[id]);
+      contentDivs[id].className = "content hide";
     }
+    k++;
+  }
 }
 
 //--------------------------------------------------------------------
 
 function showTab() {
-    var selectedId = getHash(this.getAttribute('href'));
-
-    // Highlight the selected tab, and dim all others.
-    // Also show the selected content div, and hide all others.
-    for (var id in contentDivs) {
-        if (id == selectedId) {
-            tabLinks[id].className = 'active';
-            contentDivs[id].className = 'content';
-        }
-        else {
-            tabLinks[id].className = '';
-            contentDivs[id].className = 'content hide';
-        }
+  var selectedId = getHash(this.getAttribute("href"));
+
+  // Highlight the selected tab, and dim all others.
+  // Also show the selected content div, and hide all others.
+  for (var id in contentDivs) {
+    if (id == selectedId) {
+      tabLinks[id].className = "active";
+      contentDivs[id].className = "content";
+    } else {
+      tabLinks[id].className = "";
+      contentDivs[id].className = "content hide";
     }
+  }
 
-    // Stop the browser following the link
-    return false;
+  // Stop the browser following the link
+  return false;
 }
 
 //--------------------------------------------------------------------
 
 function getFirstChildWithTagName(element, tagName) {
-    for (var i = 0; i < element.childNodes.length; i++) {
-        if (element.childNodes[i].nodeName == tagName) {
-            return element.childNodes[i];
-        }
+  for (var i = 0; i < element.childNodes.length; i++) {
+    if (element.childNodes[i].nodeName == tagName) {
+      return element.childNodes[i];
     }
+  }
 }
 
 //--------------------------------------------------------------------
 
 function getHash(url) {
-    var hashPos = url.lastIndexOf('#');
-    return url.substring(hashPos + 1);
+  var hashPos = url.lastIndexOf("#");
+  return url.substring(hashPos + 1);
 }
 
 //--------------------------------------------------------------------
 
 function toggle(elem) {
-    elem = document.getElementById(elem);
-
-    if (elem.style && elem.style['display']) {
-        // Only works with the "style" attr
-        var disp = elem.style['display'];
-    }
-    else if (elem.currentStyle) {
-        // For MSIE, naturally
-        var disp = elem.currentStyle['display'];
-    }
-    else if (window.getComputedStyle) {
-        // For most other browsers
-        var disp = document.defaultView.getComputedStyle(elem, null).getPropertyValue('display');
-    }
-
-    // Toggle the state of the "display" style
-    elem.style.display = disp == 'block' ? 'none' : 'block';
-
-    return false;
-}
\ No newline at end of file
+  elem = document.getElementById(elem);
+
+  var disp = "";
+  if (elem.style && elem.style["display"]) {
+    // Only works with the "style" attr
+    disp = elem.style["display"];
+  } else if (elem.currentStyle) {
+    // For MSIE, naturally
+    disp = elem.currentStyle["display"];
+  } else if (window.getComputedStyle) {
+    // For most other browsers
+    disp = document.defaultView
+      .getComputedStyle(elem, null)
+      .getPropertyValue("display");
+  }
+
+  // Toggle the state of the "display" style
+  elem.style.display = disp == "block" ? "none" : "block";
+
+  return false;
+}
diff --git a/app/Views/errors/html/error_404.php b/app/Views/errors/html/error_404.php
index 35017d337e..a1f3f32fa3 100644
--- a/app/Views/errors/html/error_404.php
+++ b/app/Views/errors/html/error_404.php
@@ -2,94 +2,94 @@
 <html lang="en">
 
 <head>
-	<meta charset="utf-8">
-	<title>404 Page Not Found</title>
+    <meta charset="utf-8">
+    <title>404 Page Not Found</title>
 
-	<style>
-		div.logo {
-			height: 200px;
-			width: 155px;
-			display: inline-block;
-			opacity: 0.08;
-			position: absolute;
-			top: 2rem;
-			left: 50%;
-			margin-left: -73px;
-		}
+    <style>
+        div.logo {
+            height: 200px;
+            width: 155px;
+            display: inline-block;
+            opacity: 0.08;
+            position: absolute;
+            top: 2rem;
+            left: 50%;
+            margin-left: -73px;
+        }
 
-		body {
-			height: 100%;
-			background: #fafafa;
-			font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
-			color: #777;
-			font-weight: 300;
-		}
+        body {
+            height: 100%;
+            background: #fafafa;
+            font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
+            color: #777;
+            font-weight: 300;
+        }
 
-		h1 {
-			font-weight: lighter;
-			letter-spacing: 0.8;
-			font-size: 3rem;
-			margin-top: 0;
-			margin-bottom: 0;
-			color: #222;
-		}
+        h1 {
+            font-weight: lighter;
+            letter-spacing: 0.8;
+            font-size: 3rem;
+            margin-top: 0;
+            margin-bottom: 0;
+            color: #222;
+        }
 
-		.wrap {
-			max-width: 1024px;
-			margin: 5rem auto;
-			padding: 2rem;
-			background: #fff;
-			text-align: center;
-			border: 1px solid #efefef;
-			border-radius: 0.5rem;
-			position: relative;
-		}
+        .wrap {
+            max-width: 1024px;
+            margin: 5rem auto;
+            padding: 2rem;
+            background: #fff;
+            text-align: center;
+            border: 1px solid #efefef;
+            border-radius: 0.5rem;
+            position: relative;
+        }
 
-		pre {
-			white-space: normal;
-			margin-top: 1.5rem;
-		}
+        pre {
+            white-space: normal;
+            margin-top: 1.5rem;
+        }
 
-		code {
-			background: #fafafa;
-			border: 1px solid #efefef;
-			padding: 0.5rem 1rem;
-			border-radius: 5px;
-			display: block;
-		}
+        code {
+            background: #fafafa;
+            border: 1px solid #efefef;
+            padding: 0.5rem 1rem;
+            border-radius: 5px;
+            display: block;
+        }
 
-		p {
-			margin-top: 1.5rem;
-		}
+        p {
+            margin-top: 1.5rem;
+        }
 
-		.footer {
-			margin-top: 2rem;
-			border-top: 1px solid #efefef;
-			padding: 1em 2em 0 2em;
-			font-size: 85%;
-			color: #999;
-		}
+        .footer {
+            margin-top: 2rem;
+            border-top: 1px solid #efefef;
+            padding: 1em 2em 0 2em;
+            font-size: 85%;
+            color: #999;
+        }
 
-		a:active,
-		a:link,
-		a:visited {
-			color: #dd4814;
-		}
-	</style>
+        a:active,
+        a:link,
+        a:visited {
+            color: #dd4814;
+        }
+    </style>
 </head>
 
 <body>
-	<div class="wrap">
-		<h1>404 - File Not Found</h1>
+    <div class="wrap">
+        <h1>404 - File Not Found</h1>
 
-		<p>
-			<?php if (!empty($message) && $message !== '(null)'): ?>
-				<?= esc($message) ?>
-			<?php else: ?>
-				Sorry! Cannot seem to find the page you were looking for.
-			<?php endif; ?>
-		</p>
-	</div>
+        <p>
+            <?php if (!empty($message) && $message !== '(null)'): ?>
+                <?= esc($message) ?>
+            <?php else: ?>
+                Sorry! Cannot seem to find the page you were looking for.
+            <?php endif; ?>
+        </p>
+    </div>
 </body>
 
 </html>
\ No newline at end of file
diff --git a/app/Views/errors/html/error_exception.php b/app/Views/errors/html/error_exception.php
index 7eb3736a50..5101f1e162 100644
--- a/app/Views/errors/html/error_exception.php
+++ b/app/Views/errors/html/error_exception.php
@@ -3,426 +3,532 @@
 <html>
 
 <head>
-	<meta charset="UTF-8">
-	<meta name="robots" content="noindex">
-
-	<title><?= htmlspecialchars($title, ENT_SUBSTITUTE, 'UTF-8') ?></title>
-	<style type="text/css">
-		<?= preg_replace(
-      '#[\r\n\t ]+#',
-      ' ',
-      file_get_contents(__DIR__ . DIRECTORY_SEPARATOR . 'debug.css')
-  ) ?>
-	</style>
-
-	<script type="text/javascript">
-		<?= file_get_contents(__DIR__ . DIRECTORY_SEPARATOR . 'debug.js') ?>
-	</script>
+    <meta charset="UTF-8">
+    <meta name="robots" content="noindex">
+
+    <title><?= htmlspecialchars($title, ENT_SUBSTITUTE, 'UTF-8') ?></title>
+    <style type="text/css">
+        <?= preg_replace(
+            '#[\r\n\t ]+#',
+            ' ',
+            file_get_contents(__DIR__ . DIRECTORY_SEPARATOR . 'debug.css')
+        ) ?>
+    </style>
+
+    <script type="text/javascript">
+        <?= file_get_contents(__DIR__ . DIRECTORY_SEPARATOR . 'debug.js') ?>
+    </script>
 </head>
 
 <body onload="init()">
 
-	<!-- Header -->
-	<div class="header">
-		<div class="container">
-			<h1><?= htmlspecialchars($title, ENT_SUBSTITUTE, 'UTF-8'),
-       $exception->getCode() ? ' #' . $exception->getCode() : '' ?></h1>
-			<p>
-				<?= $exception->getMessage() ?>
-				<a href="https://www.google.com/search?q=<?= urlencode(
-        $title .
-            ' ' .
-            preg_replace('#\'.*\'|".*"#Us', '', $exception->getMessage())
-    ) ?>" rel="noreferrer" target="_blank">search &rarr;</a>
-			</p>
-		</div>
-	</div>
-
-	<!-- Source -->
-	<div class="container">
-		<p><b><?= static::cleanPath($file, $line) ?></b> at line <b><?= $line ?></b></p>
-
-		<?php if (is_file($file)): ?>
-			<div class="source">
-				<?= static::highlightFile($file, $line, 15) ?>
-			</div>
-		<?php endif; ?>
-	</div>
-
-	<div class="container">
-
-		<ul class="tabs" id="tabs">
-			<li><a href="#backtrace">Backtrace</a></li>
-			<li><a href="#server">Server</a></li>
-			<li><a href="#request">Request</a></li>
-			<li><a href="#response">Response</a></li>
-			<li><a href="#files">Files</a></li>
-			<li><a href="#memory">Memory</a></li>
-			</li>
-		</ul>
-
-		<div class="tab-content">
-
-			<!-- Backtrace -->
-			<div class="content" id="backtrace">
-
-				<ol class="trace">
-					<?php foreach ($trace as $index => $row): ?>
-
-						<li>
-							<p>
-								<!-- Trace info -->
-								<?php if (isset($row['file']) && is_file($row['file'])): ?>
-									<?php if (
-             isset($row['function']) &&
-             in_array($row['function'], [
-                 'include',
-                 'include_once',
-                 'require',
-                 'require_once',
-             ])
-         ) {
-             echo $row['function'] . ' ' . static::cleanPath($row['file']);
-         } else {
-             echo static::cleanPath($row['file']) . ' : ' . $row['line'];
-         } ?>
-								<?php else: ?>
-									{PHP internal code}
-								<?php endif; ?>
-
-								<!-- Class/Method -->
-								<?php if (isset($row['class'])): ?>
-									&nbsp;&nbsp;&mdash;&nbsp;&nbsp;<?= $row['class'] .
-             $row['type'] .
-             $row['function'] ?>
-									<?php if (!empty($row['args'])): ?>
-										<?php $args_id = $error_id . 'args' . $index; ?>
-										( <a href="#" onclick="return toggle('<?= $args_id ?>');">arguments</a> )
-										<div class="args" id="<?= $args_id ?>">
-											<table cellspacing="0">
-
-												<?php
-            $params = null;
-            // Reflection by name is not available for closure function
-            if (substr($row['function'], -1) !== '}') {
-                $mirror = isset($row['class'])
-                    ? new \ReflectionMethod($row['class'], $row['function'])
-                    : new \ReflectionFunction($row['function']);
-                $params = $mirror->getParameters();
-            }
-            foreach ($row['args'] as $key => $value): ?>
-													<tr>
-														<td><code><?= htmlspecialchars(
-                  isset($params[$key]) ? '$' . $params[$key]->name : "#$key",
-                  ENT_SUBSTITUTE,
-                  'UTF-8'
-              ) ?></code></td>
-														<td>
-															<pre><?= print_r($value, true) ?></pre>
-														</td>
-													</tr>
-												<?php endforeach;
+    <!-- Header -->
+    <div class="header">
+        <div class="container">
+            <h1><?= htmlspecialchars($title, ENT_SUBSTITUTE, 'UTF-8'),
+                $exception->getCode()
+                    ? ' #' . $exception->getCode()
+                    : '' ?></h1>
+            <p>
+                <?= $exception->getMessage() ?>
+                <a href="https://www.google.com/search?q=<?= urlencode(
+                    $title .
+                        ' ' .
+                        preg_replace(
+                            '#\'.*\'|".*"#Us',
+                            '',
+                            $exception->getMessage()
+                        )
+                ) ?>" rel="noreferrer" target="_blank">search &rarr;</a>
+            </p>
+        </div>
+    </div>
+
+    <!-- Source -->
+    <div class="container">
+        <p><b><?= static::cleanPath(
+            $file,
+            $line
+        ) ?></b> at line <b><?= $line ?></b></p>
+
+        <?php if (is_file($file)): ?>
+            <div class="source">
+                <?= static::highlightFile($file, $line, 15) ?>
+            </div>
+        <?php endif; ?>
+    </div>
+
+    <div class="container">
+
+        <ul class="tabs" id="tabs">
+            <li><a href="#backtrace">Backtrace</a></li>
+            <li><a href="#server">Server</a></li>
+            <li><a href="#request">Request</a></li>
+            <li><a href="#response">Response</a></li>
+            <li><a href="#files">Files</a></li>
+            <li><a href="#memory">Memory</a></li>
+            </li>
+        </ul>
+
+        <div class="tab-content">
+
+            <!-- Backtrace -->
+            <div class="content" id="backtrace">
+
+                <ol class="trace">
+                    <?php foreach ($trace as $index => $row): ?>
+                        <li>
+                            <p>
+                                <!-- Trace info -->
+                                <?php if (
+                                    isset($row['file']) &&
+                                    is_file($row['file'])
+                                ): ?>
+                                    <?php if (
+                                        isset($row['function']) &&
+                                        in_array($row['function'], [
+                                            'include',
+                                            'include_once',
+                                            'require',
+                                            'require_once',
+                                        ])
+                                    ) {
+                                        echo $row['function'] .
+                                            ' ' .
+                                            static::cleanPath($row['file']);
+                                    } else {
+                                        echo static::cleanPath($row['file']) .
+                                            ' : ' .
+                                            $row['line'];
+                                    } ?>
+                                <?php else: ?>
+                                    {PHP internal code}
+                                <?php endif; ?>
+
+                                <!-- Class/Method -->
+                                <?php if (isset($row['class'])): ?>
+                                    &nbsp;&nbsp;&mdash;&nbsp;&nbsp;<?= $row[
+                                        'class'
+                                    ] .
+                                        $row['type'] .
+                                        $row['function'] ?>
+                                    <?php if (!empty($row['args'])): ?>
+                                        <?php $args_id =
+                                            $error_id . 'args' . $index; ?>
+                                        ( <a href="#" onclick="return toggle('<?= $args_id ?>');">arguments</a> )
+                                        <div class="args" id="<?= $args_id ?>">
+                                            <table cellspacing="0">
+
+                                                <?php
+                                                $params = null;
+                                                // Reflection by name is not available for closure function
+                                                if (
+                                                    substr(
+                                                        $row['function'],
+                                                        -1
+                                                    ) !== '}'
+                                                ) {
+                                                    $mirror = isset(
+                                                        $row['class']
+                                                    )
+                                                        ? new \ReflectionMethod(
+                                                            $row['class'],
+                                                            $row['function']
+                                                        )
+                                                        : new \ReflectionFunction(
+                                                            $row['function']
+                                                        );
+                                                    $params = $mirror->getParameters();
+                                                }
+                                                foreach (
+                                                    $row['args']
+                                                    as $key => $value
+                                                ): ?>
+                                                    <tr>
+                                                        <td><code><?= htmlspecialchars(
+                                                            isset($params[$key])
+                                                                ? '$' .
+                                                                    $params[
+                                                                        $key
+                                                                    ]->name
+                                                                : "#$key",
+                                                            ENT_SUBSTITUTE,
+                                                            'UTF-8'
+                                                        ) ?></code></td>
+                                                        <td>
+                                                            <pre><?= print_r(
+                                                                $value,
+                                                                true
+                                                            ) ?></pre>
+                                                        </td>
+                                                    </tr>
+                                                <?php endforeach;
+                                                ?>
+
+                                            </table>
+                                        </div>
+                                    <?php else: ?>
+                                        ()
+                                    <?php endif; ?>
+                                <?php endif; ?>
+
+                                <?php if (
+                                    !isset($row['class']) &&
+                                    isset($row['function'])
+                                ): ?>
+                                    &nbsp;&nbsp;&mdash;&nbsp;&nbsp; <?= $row[
+                                        'function'
+                                    ] ?>()
+                                <?php endif; ?>
+                            </p>
+
+                            <!-- Source? -->
+                            <?php if (
+                                isset($row['file']) &&
+                                is_file($row['file']) &&
+                                isset($row['class'])
+                            ): ?>
+                                <div class="source">
+                                    <?= static::highlightFile(
+                                        $row['file'],
+                                        $row['line']
+                                    ) ?>
+                                </div>
+                            <?php endif; ?>
+                        </li>
+
+                    <?php endforeach; ?>
+                </ol>
+
+            </div>
+
+            <!-- Server -->
+            <div class="content" id="server">
+                <?php foreach (['_SERVER', '_SESSION'] as $var): ?>
+                    <?php if (
+                        empty($GLOBALS[$var]) ||
+                        !is_array($GLOBALS[$var])
+                    ) {
+                        continue;
+                    } ?>
+
+                    <h3>$<?= $var ?></h3>
+
+                    <table>
+                        <thead>
+                            <tr>
+                                <th>Key</th>
+                                <th>Value</th>
+                            </tr>
+                        </thead>
+                        <tbody>
+                            <?php foreach ($GLOBALS[$var] as $key => $value): ?>
+                                <tr>
+                                    <td><?= htmlspecialchars(
+                                        $key,
+                                        ENT_IGNORE,
+                                        'UTF-8'
+                                    ) ?></td>
+                                    <td>
+                                        <?php if (is_string($value)): ?>
+                                            <?= htmlspecialchars(
+                                                $value,
+                                                ENT_SUBSTITUTE,
+                                                'UTF-8'
+                                            ) ?>
+                                        <?php else: ?>
+                                            <?= '<pre>' .
+                                                print_r($value, true) ?>
+                                        <?php endif; ?>
+                                    </td>
+                                </tr>
+                            <?php endforeach; ?>
+                        </tbody>
+                    </table>
+
+                <?php endforeach; ?>
+
+                <!-- Constants -->
+                <?php $constants = get_defined_constants(true); ?>
+                <?php if (!empty($constants['user'])): ?>
+                    <h3>Constants</h3>
+
+                    <table>
+                        <thead>
+                            <tr>
+                                <th>Key</th>
+                                <th>Value</th>
+                            </tr>
+                        </thead>
+                        <tbody>
+                            <?php foreach (
+                                $constants['user']
+                                as $key => $value
+                            ): ?>
+                                <tr>
+                                    <td><?= htmlspecialchars(
+                                        $key,
+                                        ENT_IGNORE,
+                                        'UTF-8'
+                                    ) ?></td>
+                                    <td>
+                                        <?php if (
+                                            !is_array($value) &&
+                                            !is_object($value)
+                                        ): ?>
+                                            <?= htmlspecialchars(
+                                                $value,
+                                                ENT_SUBSTITUTE,
+                                                'UTF-8'
+                                            ) ?>
+                                        <?php else: ?>
+                                            <?= '<pre>' .
+                                                print_r($value, true) ?>
+                                        <?php endif; ?>
+                                    </td>
+                                </tr>
+                            <?php endforeach; ?>
+                        </tbody>
+                    </table>
+                <?php endif; ?>
+            </div>
+
+            <!-- Request -->
+            <div class="content" id="request">
+                <?php $request = \Config\Services::request(); ?>
+
+                <table>
+                    <tbody>
+                        <tr>
+                            <td style="width: 10em">Path</td>
+                            <td><?= $request->uri ?></td>
+                        </tr>
+                        <tr>
+                            <td>HTTP Method</td>
+                            <td><?= $request->getMethod(true) ?></td>
+                        </tr>
+                        <tr>
+                            <td>IP Address</td>
+                            <td><?= $request->getIPAddress() ?></td>
+                        </tr>
+                        <tr>
+                            <td style="width: 10em">Is AJAX Request?</td>
+                            <td><?= $request->isAJAX() ? 'yes' : 'no' ?></td>
+                        </tr>
+                        <tr>
+                            <td>Is CLI Request?</td>
+                            <td><?= $request->isCLI() ? 'yes' : 'no' ?></td>
+                        </tr>
+                        <tr>
+                            <td>Is Secure Request?</td>
+                            <td><?= $request->isSecure() ? 'yes' : 'no' ?></td>
+                        </tr>
+                        <tr>
+                            <td>User Agent</td>
+                            <td><?= $request
+                                ->getUserAgent()
+                                ->getAgentString() ?></td>
+                        </tr>
+
+                    </tbody>
+                </table>
+
+
+                <?php $empty = true; ?>
+                <?php foreach (['_GET', '_POST', '_COOKIE'] as $var): ?>
+                    <?php if (
+                        empty($GLOBALS[$var]) ||
+                        !is_array($GLOBALS[$var])
+                    ) {
+                        continue;
+                    } ?>
+
+                    <?php $empty = false; ?>
+
+                    <h3>$<?= $var ?></h3>
+
+                    <table style="width: 100%">
+                        <thead>
+                            <tr>
+                                <th>Key</th>
+                                <th>Value</th>
+                            </tr>
+                        </thead>
+                        <tbody>
+                            <?php foreach ($GLOBALS[$var] as $key => $value): ?>
+                                <tr>
+                                    <td><?= htmlspecialchars(
+                                        $key,
+                                        ENT_IGNORE,
+                                        'UTF-8'
+                                    ) ?></td>
+                                    <td>
+                                        <?php if (
+                                            !is_array($value) &&
+                                            !is_object($value)
+                                        ): ?>
+                                            <?= htmlspecialchars(
+                                                $value,
+                                                ENT_SUBSTITUTE,
+                                                'UTF-8'
+                                            ) ?>
+                                        <?php else: ?>
+                                            <?= '<pre>' .
+                                                print_r($value, true) ?>
+                                        <?php endif; ?>
+                                    </td>
+                                </tr>
+                            <?php endforeach; ?>
+                        </tbody>
+                    </table>
+
+                <?php endforeach; ?>
+
+                <?php if ($empty): ?>
+                    <div class="alert">
+                        No $_GET, $_POST, or $_COOKIE Information to show.
+                    </div>
+
+                <?php endif; ?>
+
+                <?php $headers = $request->getHeaders(); ?>
+                <?php if (!empty($headers)): ?>
+                    <h3>Headers</h3>
+
+                    <table>
+                        <thead>
+                            <tr>
+                                <th>Header</th>
+                                <th>Value</th>
+                            </tr>
+                        </thead>
+                        <tbody>
+                            <?php foreach ($headers as $value): ?>
+                                <?php if (empty($value)) {
+                                    continue;
+                                } ?>
+                                <?php if (!is_array($value)) {
+                                    $value = [$value];
+                                } ?>
+                                <?php foreach ($value as $h): ?>
+                                    <tr>
+                                        <td><?= esc(
+                                            $h->getName(),
+                                            'html'
+                                        ) ?></td>
+                                        <td><?= esc(
+                                            $h->getValueLine(),
+                                            'html'
+                                        ) ?></td>
+                                    </tr>
+                                <?php endforeach; ?>
+                            <?php endforeach; ?>
+                        </tbody>
+                    </table>
+
+                <?php endif; ?>
+            </div>
+
+            <!-- Response -->
+            <?php
+            $response = \Config\Services::response();
+            $response->setStatusCode(http_response_code());
             ?>
-
-											</table>
-										</div>
-									<?php else: ?>
-										()
-									<?php endif; ?>
-								<?php endif; ?>
-
-								<?php if (!isset($row['class']) && isset($row['function'])): ?>
-									&nbsp;&nbsp;&mdash;&nbsp;&nbsp; <?= $row['function'] ?>()
-								<?php endif; ?>
-							</p>
-
-							<!-- Source? -->
-							<?php if (
-           isset($row['file']) &&
-           is_file($row['file']) &&
-           isset($row['class'])
-       ): ?>
-								<div class="source">
-									<?= static::highlightFile($row['file'], $row['line']) ?>
-								</div>
-							<?php endif; ?>
-						</li>
-
-					<?php endforeach; ?>
-				</ol>
-
-			</div>
-
-			<!-- Server -->
-			<div class="content" id="server">
-				<?php foreach (['_SERVER', '_SESSION'] as $var): ?>
-					<?php if (empty($GLOBALS[$var]) || !is_array($GLOBALS[$var])) {
-         continue;
-     } ?>
-
-					<h3>$<?= $var ?></h3>
-
-					<table>
-						<thead>
-							<tr>
-								<th>Key</th>
-								<th>Value</th>
-							</tr>
-						</thead>
-						<tbody>
-							<?php foreach ($GLOBALS[$var] as $key => $value): ?>
-								<tr>
-									<td><?= htmlspecialchars($key, ENT_IGNORE, 'UTF-8') ?></td>
-									<td>
-										<?php if (is_string($value)): ?>
-											<?= htmlspecialchars($value, ENT_SUBSTITUTE, 'UTF-8') ?>
-										<?php else: ?>
-											<?= '<pre>' . print_r($value, true) ?>
-										<?php endif; ?>
-									</td>
-								</tr>
-							<?php endforeach; ?>
-						</tbody>
-					</table>
-
-				<?php endforeach; ?>
-
-				<!-- Constants -->
-				<?php $constants = get_defined_constants(true); ?>
-				<?php if (!empty($constants['user'])): ?>
-					<h3>Constants</h3>
-
-					<table>
-						<thead>
-							<tr>
-								<th>Key</th>
-								<th>Value</th>
-							</tr>
-						</thead>
-						<tbody>
-							<?php foreach ($constants['user'] as $key => $value): ?>
-								<tr>
-									<td><?= htmlspecialchars($key, ENT_IGNORE, 'UTF-8') ?></td>
-									<td>
-										<?php if (!is_array($value) && !is_object($value)): ?>
-											<?= htmlspecialchars($value, ENT_SUBSTITUTE, 'UTF-8') ?>
-										<?php else: ?>
-											<?= '<pre>' . print_r($value, true) ?>
-										<?php endif; ?>
-									</td>
-								</tr>
-							<?php endforeach; ?>
-						</tbody>
-					</table>
-				<?php endif; ?>
-			</div>
-
-			<!-- Request -->
-			<div class="content" id="request">
-				<?php $request = \Config\Services::request(); ?>
-
-				<table>
-					<tbody>
-						<tr>
-							<td style="width: 10em">Path</td>
-							<td><?= $request->uri ?></td>
-						</tr>
-						<tr>
-							<td>HTTP Method</td>
-							<td><?= $request->getMethod(true) ?></td>
-						</tr>
-						<tr>
-							<td>IP Address</td>
-							<td><?= $request->getIPAddress() ?></td>
-						</tr>
-						<tr>
-							<td style="width: 10em">Is AJAX Request?</td>
-							<td><?= $request->isAJAX() ? 'yes' : 'no' ?></td>
-						</tr>
-						<tr>
-							<td>Is CLI Request?</td>
-							<td><?= $request->isCLI() ? 'yes' : 'no' ?></td>
-						</tr>
-						<tr>
-							<td>Is Secure Request?</td>
-							<td><?= $request->isSecure() ? 'yes' : 'no' ?></td>
-						</tr>
-						<tr>
-							<td>User Agent</td>
-							<td><?= $request->getUserAgent()->getAgentString() ?></td>
-						</tr>
-
-					</tbody>
-				</table>
-
-
-				<?php $empty = true; ?>
-				<?php foreach (['_GET', '_POST', '_COOKIE'] as $var): ?>
-					<?php if (empty($GLOBALS[$var]) || !is_array($GLOBALS[$var])) {
-         continue;
-     } ?>
-
-					<?php $empty = false; ?>
-
-					<h3>$<?= $var ?></h3>
-
-					<table style="width: 100%">
-						<thead>
-							<tr>
-								<th>Key</th>
-								<th>Value</th>
-							</tr>
-						</thead>
-						<tbody>
-							<?php foreach ($GLOBALS[$var] as $key => $value): ?>
-								<tr>
-									<td><?= htmlspecialchars($key, ENT_IGNORE, 'UTF-8') ?></td>
-									<td>
-										<?php if (!is_array($value) && !is_object($value)): ?>
-											<?= htmlspecialchars($value, ENT_SUBSTITUTE, 'UTF-8') ?>
-										<?php else: ?>
-											<?= '<pre>' . print_r($value, true) ?>
-										<?php endif; ?>
-									</td>
-								</tr>
-							<?php endforeach; ?>
-						</tbody>
-					</table>
-
-				<?php endforeach; ?>
-
-				<?php if ($empty): ?>
-
-					<div class="alert">
-						No $_GET, $_POST, or $_COOKIE Information to show.
-					</div>
-
-				<?php endif; ?>
-
-				<?php $headers = $request->getHeaders(); ?>
-				<?php if (!empty($headers)): ?>
-
-					<h3>Headers</h3>
-
-					<table>
-						<thead>
-							<tr>
-								<th>Header</th>
-								<th>Value</th>
-							</tr>
-						</thead>
-						<tbody>
-							<?php foreach ($headers as $value): ?>
-								<?php if (empty($value)) {
-            continue;
-        } ?>
-								<?php if (!is_array($value)) {
-            $value = [$value];
-        } ?>
-								<?php foreach ($value as $h): ?>
-									<tr>
-										<td><?= esc($h->getName(), 'html') ?></td>
-										<td><?= esc($h->getValueLine(), 'html') ?></td>
-									</tr>
-								<?php endforeach; ?>
-							<?php endforeach; ?>
-						</tbody>
-					</table>
-
-				<?php endif; ?>
-			</div>
-
-			<!-- Response -->
-			<?php
-   $response = \Config\Services::response();
-   $response->setStatusCode(http_response_code());
-   ?>
-			<div class="content" id="response">
-				<table>
-					<tr>
-						<td style="width: 15em">Response Status</td>
-						<td><?= $response->getStatusCode() . ' - ' . $response->getReason() ?></td>
-					</tr>
-				</table>
-
-				<?php $headers = $response->getHeaders(); ?>
-				<?php if (!empty($headers)): ?>
-					<?php natsort($headers); ?>
-
-					<h3>Headers</h3>
-
-					<table>
-						<thead>
-							<tr>
-								<th>Header</th>
-								<th>Value</th>
-							</tr>
-						</thead>
-						<tbody>
-							<?php foreach ($headers as $name => $value): ?>
-								<tr>
-									<td><?= esc($name, 'html') ?></td>
-									<td><?= esc($response->getHeaderLine($name), 'html') ?></td>
-								</tr>
-							<?php endforeach; ?>
-						</tbody>
-					</table>
-
-				<?php endif; ?>
-			</div>
-
-			<!-- Files -->
-			<div class="content" id="files">
-				<?php $files = get_included_files(); ?>
-
-				<ol>
-					<?php foreach ($files as $file): ?>
-						<li><?= htmlspecialchars(
-          static::cleanPath($file),
-          ENT_SUBSTITUTE,
-          'UTF-8'
-      ) ?></li>
-					<?php endforeach; ?>
-				</ol>
-			</div>
-
-			<!-- Memory -->
-			<div class="content" id="memory">
-
-				<table>
-					<tbody>
-						<tr>
-							<td>Memory Usage</td>
-							<td><?= static::describeMemory(memory_get_usage(true)) ?></td>
-						</tr>
-						<tr>
-							<td style="width: 12em">Peak Memory Usage:</td>
-							<td><?= static::describeMemory(memory_get_peak_usage(true)) ?></td>
-						</tr>
-						<tr>
-							<td>Memory Limit:</td>
-							<td><?= ini_get('memory_limit') ?></td>
-						</tr>
-					</tbody>
-				</table>
-
-			</div>
-
-		</div> <!-- /tab-content -->
-
-	</div> <!-- /container -->
-
-	<div class="footer">
-		<div class="container">
-
-			<p>
-				Displayed at <?= date('H:i:sa') ?> &mdash;
-				PHP: <?= phpversion() ?> &mdash;
-				CodeIgniter: <?= \CodeIgniter\CodeIgniter::CI_VERSION ?>
-			</p>
-
-		</div>
-	</div>
+            <div class="content" id="response">
+                <table>
+                    <tr>
+                        <td style="width: 15em">Response Status</td>
+                        <td><?= $response->getStatusCode() .
+                            ' - ' .
+                            $response->getReason() ?></td>
+                    </tr>
+                </table>
+
+                <?php $headers = $response->getHeaders(); ?>
+                <?php if (!empty($headers)): ?>
+                    <?php natsort($headers); ?>
+
+                    <h3>Headers</h3>
+
+                    <table>
+                        <thead>
+                            <tr>
+                                <th>Header</th>
+                                <th>Value</th>
+                            </tr>
+                        </thead>
+                        <tbody>
+                            <?php foreach ($headers as $name => $value): ?>
+                                <tr>
+                                    <td><?= esc($name, 'html') ?></td>
+                                    <td><?= esc(
+                                        $response->getHeaderLine($name),
+                                        'html'
+                                    ) ?></td>
+                                </tr>
+                            <?php endforeach; ?>
+                        </tbody>
+                    </table>
+
+                <?php endif; ?>
+            </div>
+
+            <!-- Files -->
+            <div class="content" id="files">
+                <?php $files = get_included_files(); ?>
+
+                <ol>
+                    <?php foreach ($files as $file): ?>
+                        <li><?= htmlspecialchars(
+                            static::cleanPath($file),
+                            ENT_SUBSTITUTE,
+                            'UTF-8'
+                        ) ?></li>
+                    <?php endforeach; ?>
+                </ol>
+            </div>
+
+            <!-- Memory -->
+            <div class="content" id="memory">
+
+                <table>
+                    <tbody>
+                        <tr>
+                            <td>Memory Usage</td>
+                            <td><?= static::describeMemory(
+                                memory_get_usage(true)
+                            ) ?></td>
+                        </tr>
+                        <tr>
+                            <td style="width: 12em">Peak Memory Usage:</td>
+                            <td><?= static::describeMemory(
+                                memory_get_peak_usage(true)
+                            ) ?></td>
+                        </tr>
+                        <tr>
+                            <td>Memory Limit:</td>
+                            <td><?= ini_get('memory_limit') ?></td>
+                        </tr>
+                    </tbody>
+                </table>
+
+            </div>
+
+        </div> <!-- /tab-content -->
+
+    </div> <!-- /container -->
+
+    <div class="footer">
+        <div class="container">
+
+            <p>
+                Displayed at <?= date('H:i:sa') ?> &mdash;
+                PHP: <?= phpversion() ?> &mdash;
+                CodeIgniter: <?= \CodeIgniter\CodeIgniter::CI_VERSION ?>
+            </p>
+
+        </div>
+    </div>
 
 </body>
 
diff --git a/app/Views/errors/html/production.php b/app/Views/errors/html/production.php
index 983f519fa1..7197c1c090 100644
--- a/app/Views/errors/html/production.php
+++ b/app/Views/errors/html/production.php
@@ -18,11 +18,8 @@
 
 <body>
 	<div class="container text-center">
-
 		<h1 class="headline">Whoops!</h1>
-
 		<p class="lead">We seem to have hit a snag. Please try again later...</p>
-
 	</div>
 </body>
 
diff --git a/app/Views/podcast.php b/app/Views/podcast.php
index b4ba052aa7..b64782b0c9 100644
--- a/app/Views/podcast.php
+++ b/app/Views/podcast.php
@@ -24,7 +24,6 @@
                             <span class="mr-1 underline hover:no-underline"><?= $episode->title ?></span>
                             <span class="text-base font-bold text-gray-600">#<?= $episode->number ?></span>
                         </h3>
-                        <p><?= $episode->description ?></p>
                     </a>
                     <audio controls class="mt-auto" preload="none">
                         <source src="<?= $episode->enclosure_url ?>" type="<?= $episode->enclosure_type ?>">
diff --git a/composer.json b/composer.json
index ae4625de3f..c5f29a4aef 100644
--- a/composer.json
+++ b/composer.json
@@ -10,12 +10,13 @@
     "whichbrowser/parser": "^2.0",
     "geoip2/geoip2": "~2.0",
     "myth/auth": "dev-develop",
-    "erusev/parsedown": "^1.7",
-    "codeigniter4/codeigniter4": "dev-develop"
+    "codeigniter4/codeigniter4": "dev-develop",
+    "league/commonmark": "^1.5"
   },
   "require-dev": {
     "mikey179/vfsstream": "1.6.*",
-    "phpunit/phpunit": "8.5.*"
+    "phpunit/phpunit": "8.5.*",
+    "squizlabs/php_codesniffer": "3.*"
   },
   "autoload-dev": {
     "psr-4": {
diff --git a/composer.lock b/composer.lock
index 4b63d07ee1..1d5b5b7c85 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": "b483083efa09cc772800d5df7d339d02",
+    "content-hash": "1fe52c47fa9834960fdb1cf37f2f2776",
     "packages": [
         {
             "name": "codeigniter4/codeigniter4",
@@ -12,12 +12,12 @@
             "source": {
                 "type": "git",
                 "url": "https://github.com/codeigniter4/CodeIgniter4.git",
-                "reference": "81c08a5ddd70d2243c0842dfcc22c93dd044bc42"
+                "reference": "cbfc8d27645fc9fe19d540c796b627852b4a1142"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/codeigniter4/CodeIgniter4/zipball/81c08a5ddd70d2243c0842dfcc22c93dd044bc42",
-                "reference": "81c08a5ddd70d2243c0842dfcc22c93dd044bc42",
+                "url": "https://api.github.com/repos/codeigniter4/CodeIgniter4/zipball/cbfc8d27645fc9fe19d540c796b627852b4a1142",
+                "reference": "cbfc8d27645fc9fe19d540c796b627852b4a1142",
                 "shasum": ""
             },
             "require": {
@@ -65,7 +65,7 @@
                 "slack": "https://codeigniterchat.slack.com",
                 "issues": "https://github.com/codeigniter4/CodeIgniter4/issues"
             },
-            "time": "2020-07-29T03:07:26+00:00"
+            "time": "2020-08-04T03:43:32+00:00"
         },
         {
             "name": "composer/ca-bundle",
@@ -133,52 +133,6 @@
             ],
             "time": "2020-04-08T08:27:21+00:00"
         },
-        {
-            "name": "erusev/parsedown",
-            "version": "1.7.4",
-            "source": {
-                "type": "git",
-                "url": "https://github.com/erusev/parsedown.git",
-                "reference": "cb17b6477dfff935958ba01325f2e8a2bfa6dab3"
-            },
-            "dist": {
-                "type": "zip",
-                "url": "https://api.github.com/repos/erusev/parsedown/zipball/cb17b6477dfff935958ba01325f2e8a2bfa6dab3",
-                "reference": "cb17b6477dfff935958ba01325f2e8a2bfa6dab3",
-                "shasum": ""
-            },
-            "require": {
-                "ext-mbstring": "*",
-                "php": ">=5.3.0"
-            },
-            "require-dev": {
-                "phpunit/phpunit": "^4.8.35"
-            },
-            "type": "library",
-            "autoload": {
-                "psr-0": {
-                    "Parsedown": ""
-                }
-            },
-            "notification-url": "https://packagist.org/downloads/",
-            "license": [
-                "MIT"
-            ],
-            "authors": [
-                {
-                    "name": "Emanuil Rusev",
-                    "email": "hello@erusev.com",
-                    "homepage": "http://erusev.com"
-                }
-            ],
-            "description": "Parser for Markdown.",
-            "homepage": "http://parsedown.org",
-            "keywords": [
-                "markdown",
-                "parser"
-            ],
-            "time": "2019-12-30T22:54:17+00:00"
-        },
         {
             "name": "geoip2/geoip2",
             "version": "v2.10.0",
@@ -490,6 +444,101 @@
             ],
             "time": "2020-05-20T16:45:56+00:00"
         },
+        {
+            "name": "league/commonmark",
+            "version": "1.5.3",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/thephpleague/commonmark.git",
+                "reference": "2574454b97e4103dc4e36917bd783b25624aefcd"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/thephpleague/commonmark/zipball/2574454b97e4103dc4e36917bd783b25624aefcd",
+                "reference": "2574454b97e4103dc4e36917bd783b25624aefcd",
+                "shasum": ""
+            },
+            "require": {
+                "ext-mbstring": "*",
+                "php": "^7.1 || ^8.0"
+            },
+            "conflict": {
+                "scrutinizer/ocular": "1.7.*"
+            },
+            "require-dev": {
+                "cebe/markdown": "~1.0",
+                "commonmark/commonmark.js": "0.29.1",
+                "erusev/parsedown": "~1.0",
+                "ext-json": "*",
+                "github/gfm": "0.29.0",
+                "michelf/php-markdown": "~1.4",
+                "mikehaertl/php-shellcommand": "^1.4",
+                "phpstan/phpstan": "^0.12",
+                "phpunit/phpunit": "^7.5 || ^8.5 || ^9.2",
+                "scrutinizer/ocular": "^1.5",
+                "symfony/finder": "^4.2"
+            },
+            "bin": [
+                "bin/commonmark"
+            ],
+            "type": "library",
+            "autoload": {
+                "psr-4": {
+                    "League\\CommonMark\\": "src"
+                }
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "BSD-3-Clause"
+            ],
+            "authors": [
+                {
+                    "name": "Colin O'Dell",
+                    "email": "colinodell@gmail.com",
+                    "homepage": "https://www.colinodell.com",
+                    "role": "Lead Developer"
+                }
+            ],
+            "description": "Highly-extensible PHP Markdown parser which fully supports the CommonMark spec and Github-Flavored Markdown (GFM)",
+            "homepage": "https://commonmark.thephpleague.com",
+            "keywords": [
+                "commonmark",
+                "flavored",
+                "gfm",
+                "github",
+                "github-flavored",
+                "markdown",
+                "md",
+                "parser"
+            ],
+            "funding": [
+                {
+                    "url": "https://enjoy.gitstore.app/repositories/thephpleague/commonmark",
+                    "type": "custom"
+                },
+                {
+                    "url": "https://www.colinodell.com/sponsor",
+                    "type": "custom"
+                },
+                {
+                    "url": "https://www.paypal.me/colinpodell/10.00",
+                    "type": "custom"
+                },
+                {
+                    "url": "https://github.com/colinodell",
+                    "type": "github"
+                },
+                {
+                    "url": "https://www.patreon.com/colinodell",
+                    "type": "patreon"
+                },
+                {
+                    "url": "https://tidelift.com/funding/github/packagist/league/commonmark",
+                    "type": "tidelift"
+                }
+            ],
+            "time": "2020-07-19T22:47:30+00:00"
+        },
         {
             "name": "maxmind-db/reader",
             "version": "v1.6.0",
@@ -2251,9 +2300,60 @@
             "homepage": "https://github.com/sebastianbergmann/version",
             "time": "2016-10-03T07:35:21+00:00"
         },
+        {
+            "name": "squizlabs/php_codesniffer",
+            "version": "3.5.5",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/squizlabs/PHP_CodeSniffer.git",
+                "reference": "73e2e7f57d958e7228fce50dc0c61f58f017f9f6"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/squizlabs/PHP_CodeSniffer/zipball/73e2e7f57d958e7228fce50dc0c61f58f017f9f6",
+                "reference": "73e2e7f57d958e7228fce50dc0c61f58f017f9f6",
+                "shasum": ""
+            },
+            "require": {
+                "ext-simplexml": "*",
+                "ext-tokenizer": "*",
+                "ext-xmlwriter": "*",
+                "php": ">=5.4.0"
+            },
+            "require-dev": {
+                "phpunit/phpunit": "^4.0 || ^5.0 || ^6.0 || ^7.0"
+            },
+            "bin": [
+                "bin/phpcs",
+                "bin/phpcbf"
+            ],
+            "type": "library",
+            "extra": {
+                "branch-alias": {
+                    "dev-master": "3.x-dev"
+                }
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "BSD-3-Clause"
+            ],
+            "authors": [
+                {
+                    "name": "Greg Sherwood",
+                    "role": "lead"
+                }
+            ],
+            "description": "PHP_CodeSniffer tokenizes PHP, JavaScript and CSS files and detects violations of a defined set of coding standards.",
+            "homepage": "https://github.com/squizlabs/PHP_CodeSniffer",
+            "keywords": [
+                "phpcs",
+                "standards"
+            ],
+            "time": "2020-04-17T01:09:41+00:00"
+        },
         {
             "name": "symfony/polyfill-ctype",
-            "version": "v1.18.0",
+            "version": "v1.18.1",
             "source": {
                 "type": "git",
                 "url": "https://github.com/symfony/polyfill-ctype.git",
diff --git a/package.json b/package.json
index 37ff2d68b7..e4d85539f5 100644
--- a/package.json
+++ b/package.json
@@ -19,6 +19,7 @@
     "lint": "eslint --ext js,ts app/Views/_assets",
     "lint:fix": "eslint --ext js,ts app/Views/_assets --fix",
     "lint:css": "stylelint \"app/Views/_assets/**/*.css\"",
+    "prettier:fix": "prettier --write --ignore-path .gitignore .",
     "typecheck": "tsc",
     "commit": "git-cz"
   },
diff --git a/tests/README.md b/tests/README.md
index 545ccfed6e..24f7c828c6 100644
--- a/tests/README.md
+++ b/tests/README.md
@@ -1,40 +1,41 @@
 # Running Application Tests
 
-This is the quick-start to CodeIgniter testing. Its intent is to describe what 
-it takes to set up your application and get it ready to run unit tests. 
-It is not intended to be a full description of the test features that you can 
+This is the quick-start to CodeIgniter testing. Its intent is to describe what
+it takes to set up your application and get it ready to run unit tests.
+It is not intended to be a full description of the test features that you can
 use to test your application. Those details can be found in the documentation.
 
 ## Resources
-* [CodeIgniter 4 User Guide on Testing](https://codeigniter4.github.io/userguide/testing/index.html)
-* [PHPUnit docs](https://phpunit.readthedocs.io/en/8.3/index.html)
+
+- [CodeIgniter 4 User Guide on Testing](https://codeigniter4.github.io/userguide/testing/index.html)
+- [PHPUnit docs](https://phpunit.readthedocs.io/en/8.3/index.html)
 
 ## Requirements
 
-It is recommended to use the latest version of PHPUnit. At the time of this 
-writing we are running version 8.5.2. Support for this has been built into the 
-**composer.json** file that ships with CodeIgniter and can easily be installed 
+It is recommended to use the latest version of PHPUnit. At the time of this
+writing we are running version 8.5.2. Support for this has been built into the
+**composer.json** file that ships with CodeIgniter and can easily be installed
 via [Composer](https://getcomposer.org/) if you don't already have it installed globally.
 
-	> composer install
+    > composer install
 
 If running under OS X or Linux, you can create a symbolic link to make running tests a touch nicer.
 
-	> ln -s ./vendor/bin/phpunit ./phpunit
+    > ln -s ./vendor/bin/phpunit ./phpunit
 
 You also need to install [XDebug](https://xdebug.org/index.php) in order
 for code coverage to be calculated successfully.
 
 ## Setting Up
 
-A number of the tests use a running database. 
-In order to set up the database edit the details for the `tests` group in 
-**app/Config/Database.php** or **phpunit.xml**. Make sure that you provide a database engine 
-that is currently running on your machine. More details on a test database setup are in the 
-*Docs>>Testing>>Testing Your Database* section of the documentation.
+A number of the tests use a running database.
+In order to set up the database edit the details for the `tests` group in
+**app/Config/Database.php** or **phpunit.xml**. Make sure that you provide a database engine
+that is currently running on your machine. More details on a test database setup are in the
+_Docs>>Testing>>Testing Your Database_ section of the documentation.
 
-If you want to run the tests without using live database you can 
-exclude @DatabaseLive group. Or make a copy of **phpunit.dist.xml** - 
+If you want to run the tests without using live database you can
+exclude @DatabaseLive group. Or make a copy of **phpunit.dist.xml** -
 call it **phpunit.xml** - and comment out the <testsuite> named "database". This will make
 the tests run quite a bit faster.
 
@@ -42,45 +43,46 @@ the tests run quite a bit faster.
 
 The entire test suite can be run by simply typing one command-line command from the main directory.
 
-	> ./phpunit
+    > ./phpunit
 
-You can limit tests to those within a single test directory by specifying the 
-directory name after phpunit. 
+You can limit tests to those within a single test directory by specifying the
+directory name after phpunit.
 
-	> ./phpunit app/Models
+    > ./phpunit app/Models
 
 ## Generating Code Coverage
 
-To generate coverage information, including HTML reports you can view in your browser, 
-you can use the following command: 
+To generate coverage information, including HTML reports you can view in your browser,
+you can use the following command:
 
-	> ./phpunit --colors --coverage-text=tests/coverage.txt --coverage-html=tests/coverage/ -d memory_limit=1024m
+    > ./phpunit --colors --coverage-text=tests/coverage.txt --coverage-html=tests/coverage/ -d memory_limit=1024m
 
-This runs all of the tests again collecting information about how many lines, 
-functions, and files are tested. It also reports the percentage of the code that is covered by tests. 
-It is collected in two formats: a simple text file that provides an overview as well 
-as a comprehensive collection of HTML files that show the status of every line of code in the project. 
+This runs all of the tests again collecting information about how many lines,
+functions, and files are tested. It also reports the percentage of the code that is covered by tests.
+It is collected in two formats: a simple text file that provides an overview as well
+as a comprehensive collection of HTML files that show the status of every line of code in the project.
 
-The text file can be found at **tests/coverage.txt**. 
+The text file can be found at **tests/coverage.txt**.
 The HTML files can be viewed by opening **tests/coverage/index.html** in your favorite browser.
 
 ## PHPUnit XML Configuration
 
-The repository has a ``phpunit.xml.dist`` file in the project root that's used for
+The repository has a `phpunit.xml.dist` file in the project root that's used for
 PHPUnit configuration. This is used to provide a default configuration if you
 do not have your own configuration file in the project root.
 
-The normal practice would be to copy ``phpunit.xml.dist`` to ``phpunit.xml``
+The normal practice would be to copy `phpunit.xml.dist` to `phpunit.xml`
 (which is git ignored), and to tailor it as you see fit.
-For instance, you might wish to exclude database tests, or automatically generate 
+For instance, you might wish to exclude database tests, or automatically generate
 HTML code coverage reports.
 
 ## Test Cases
 
-Every test needs a *test case*, or class that your tests extend. CodeIgniter 4
+Every test needs a _test case_, or class that your tests extend. CodeIgniter 4
 provides a few that you may use directly:
-* `CodeIgniter\Test\CIUnitTestCase` - for basic tests with no other service needs
-* `CodeIgniter\Test\CIDatabaseTestCase` - for tests that need database access
+
+- `CodeIgniter\Test\CIUnitTestCase` - for basic tests with no other service needs
+- `CodeIgniter\Test\CIDatabaseTestCase` - for tests that need database access
 
 Most of the time you will want to write your own test cases to hold functions and services
 common to your test suites.
diff --git a/tests/_support/Database/Migrations/2020-02-22-222222_example_migration.php b/tests/_support/Database/Migrations/2020-02-22-222222_example_migration.php
index 81fe021194..360a9b00c5 100644
--- a/tests/_support/Database/Migrations/2020-02-22-222222_example_migration.php
+++ b/tests/_support/Database/Migrations/2020-02-22-222222_example_migration.php
@@ -6,58 +6,58 @@ use CodeIgniter\Database\Migration;
 
 class ExampleMigration extends Migration
 {
-	protected $DBGroup = 'tests';
-
-	public function up()
-	{
-		$fields = [
-			'name'       => [
-				'type'       => 'varchar',
-				'constraint' => 31,
-			],
-			'uid'        => [
-				'type'       => 'varchar',
-				'constraint' => 31,
-			],
-			'class'      => [
-				'type'       => 'varchar',
-				'constraint' => 63,
-			],
-			'icon'       => [
-				'type'       => 'varchar',
-				'constraint' => 31,
-			],
-			'summary'    => [
-				'type'       => 'varchar',
-				'constraint' => 255,
-			],
-			'created_at' => [
-				'type' => 'datetime',
-				'null' => true,
-			],
-			'updated_at' => [
-				'type' => 'datetime',
-				'null' => true,
-			],
-			'deleted_at' => [
-				'type' => 'datetime',
-				'null' => true,
-			],
-		];
-
-		$this->forge->addField('id');
-		$this->forge->addField($fields);
-
-		$this->forge->addKey('name');
-		$this->forge->addKey('uid');
-		$this->forge->addKey(['deleted_at', 'id']);
-		$this->forge->addKey('created_at');
-
-		$this->forge->createTable('factories');
-	}
-
-	public function down()
-	{
-		$this->forge->dropTable('factories');
-	}
+    protected $DBGroup = 'tests';
+
+    public function up()
+    {
+        $fields = [
+            'name' => [
+                'type' => 'varchar',
+                'constraint' => 31,
+            ],
+            'uid' => [
+                'type' => 'varchar',
+                'constraint' => 31,
+            ],
+            'class' => [
+                'type' => 'varchar',
+                'constraint' => 63,
+            ],
+            'icon' => [
+                'type' => 'varchar',
+                'constraint' => 31,
+            ],
+            'summary' => [
+                'type' => 'varchar',
+                'constraint' => 255,
+            ],
+            'created_at' => [
+                'type' => 'datetime',
+                'null' => true,
+            ],
+            'updated_at' => [
+                'type' => 'datetime',
+                'null' => true,
+            ],
+            'deleted_at' => [
+                'type' => 'datetime',
+                'null' => true,
+            ],
+        ];
+
+        $this->forge->addField('id');
+        $this->forge->addField($fields);
+
+        $this->forge->addKey('name');
+        $this->forge->addKey('uid');
+        $this->forge->addKey(['deleted_at', 'id']);
+        $this->forge->addKey('created_at');
+
+        $this->forge->createTable('factories');
+    }
+
+    public function down()
+    {
+        $this->forge->dropTable('factories');
+    }
 }
diff --git a/tests/_support/Database/Seeds/ExampleSeeder.php b/tests/_support/Database/Seeds/ExampleSeeder.php
index 1b14cedaa2..b5527d2144 100644
--- a/tests/_support/Database/Seeds/ExampleSeeder.php
+++ b/tests/_support/Database/Seeds/ExampleSeeder.php
@@ -4,37 +4,36 @@ use CodeIgniter\Database\Seeder;
 
 class ExampleSeeder extends Seeder
 {
-	public function run()
-	{
-		$factories = [
-			[
-				'name'    => 'Test Factory',
-				'uid'     => 'test001',
-				'class'   => 'Factories\Tests\NewFactory',
-				'icon'    => 'fas fa-puzzle-piece',
-				'summary' => 'Longer sample text for testing',
-			],
-			[
-				'name'    => 'Widget Factory',
-				'uid'     => 'widget',
-				'class'   => 'Factories\Tests\WidgetPlant',
-				'icon'    => 'fas fa-puzzle-piece',
-				'summary' => 'Create widgets in your factory',
-			],
-			[
-				'name'    => 'Evil Factory',
-				'uid'     => 'evil-maker',
-				'class'   => 'Factories\Evil\MyFactory',
-				'icon'    => 'fas fa-book-dead',
-				'summary' => 'Abandon all hope, ye who enter here',
-			],
-		];
+    public function run()
+    {
+        $factories = [
+            [
+                'name' => 'Test Factory',
+                'uid' => 'test001',
+                'class' => 'Factories\Tests\NewFactory',
+                'icon' => 'fas fa-puzzle-piece',
+                'summary' => 'Longer sample text for testing',
+            ],
+            [
+                'name' => 'Widget Factory',
+                'uid' => 'widget',
+                'class' => 'Factories\Tests\WidgetPlant',
+                'icon' => 'fas fa-puzzle-piece',
+                'summary' => 'Create widgets in your factory',
+            ],
+            [
+                'name' => 'Evil Factory',
+                'uid' => 'evil-maker',
+                'class' => 'Factories\Evil\MyFactory',
+                'icon' => 'fas fa-book-dead',
+                'summary' => 'Abandon all hope, ye who enter here',
+            ],
+        ];
 
-		$builder = $this->db->table('factories');
+        $builder = $this->db->table('factories');
 
-		foreach ($factories as $factory)
-		{
-			$builder->insert($factory);
-		}
-	}
+        foreach ($factories as $factory) {
+            $builder->insert($factory);
+        }
+    }
 }
diff --git a/tests/_support/DatabaseTestCase.php b/tests/_support/DatabaseTestCase.php
index 8b094d3005..7145f51041 100644
--- a/tests/_support/DatabaseTestCase.php
+++ b/tests/_support/DatabaseTestCase.php
@@ -2,50 +2,50 @@
 
 class DatabaseTestCase extends \CodeIgniter\Test\CIDatabaseTestCase
 {
-	/**
-	 * Should the database be refreshed before each test?
-	 *
-	 * @var boolean
-	 */
-	protected $refresh = true;
-
-	/**
-	 * The seed file(s) used for all tests within this test case.
-	 * Should be fully-namespaced or relative to $basePath
-	 *
-	 * @var string|array
-	 */
-	protected $seed = 'Tests\Support\Database\Seeds\ExampleSeeder';
-
-	/**
-	 * The path to the seeds directory.
-	 * Allows overriding the default application directories.
-	 *
-	 * @var string
-	 */
-	protected $basePath = SUPPORTPATH . 'Database/';
-
-	/**
-	 * The namespace(s) to help us find the migration classes.
-	 * Empty is equivalent to running `spark migrate -all`.
-	 * Note that running "all" runs migrations in date order,
-	 * but specifying namespaces runs them in namespace order (then date)
-	 *
-	 * @var string|array|null
-	 */
-	protected $namespace = 'Tests\Support';
-
-	public function setUp(): void
-	{
-		parent::setUp();
-
-		// Extra code to run before each test
-	}
-
-	public function tearDown(): void
-	{
-		parent::tearDown();
-
-		// Extra code to run after each test
-	}
+    /**
+     * Should the database be refreshed before each test?
+     *
+     * @var boolean
+     */
+    protected $refresh = true;
+
+    /**
+     * The seed file(s) used for all tests within this test case.
+     * Should be fully-namespaced or relative to $basePath
+     *
+     * @var string|array
+     */
+    protected $seed = 'Tests\Support\Database\Seeds\ExampleSeeder';
+
+    /**
+     * The path to the seeds directory.
+     * Allows overriding the default application directories.
+     *
+     * @var string
+     */
+    protected $basePath = SUPPORTPATH . 'Database/';
+
+    /**
+     * The namespace(s) to help us find the migration classes.
+     * Empty is equivalent to running `spark migrate -all`.
+     * Note that running "all" runs migrations in date order,
+     * but specifying namespaces runs them in namespace order (then date)
+     *
+     * @var string|array|null
+     */
+    protected $namespace = 'Tests\Support';
+
+    public function setUp(): void
+    {
+        parent::setUp();
+
+        // Extra code to run before each test
+    }
+
+    public function tearDown(): void
+    {
+        parent::tearDown();
+
+        // Extra code to run after each test
+    }
 }
diff --git a/tests/_support/Libraries/ConfigReader.php b/tests/_support/Libraries/ConfigReader.php
index a62d09fd04..6ce903bd02 100644
--- a/tests/_support/Libraries/ConfigReader.php
+++ b/tests/_support/Libraries/ConfigReader.php
@@ -1,6 +1,5 @@
 <?php
 
-
 /**
  * CodeIgniter
  *
@@ -49,7 +48,7 @@ namespace Tests\Support\Libraries;
  */
 class ConfigReader extends \Config\App
 {
-	public function __construct()
-	{
-	}
+    public function __construct()
+    {
+    }
 }
diff --git a/tests/_support/Models/ExampleModel.php b/tests/_support/Models/ExampleModel.php
index e02aeec30b..176c69283b 100644
--- a/tests/_support/Models/ExampleModel.php
+++ b/tests/_support/Models/ExampleModel.php
@@ -4,23 +4,17 @@ use CodeIgniter\Model;
 
 class ExampleModel extends Model
 {
-	protected $table      = 'factories';
-	protected $primaryKey = 'id';
+    protected $table = 'factories';
+    protected $primaryKey = 'id';
 
-	protected $returnType     = 'object';
-	protected $useSoftDeletes = false;
+    protected $returnType = 'object';
+    protected $useSoftDeletes = false;
 
-	protected $allowedFields = [
-		'name',
-		'uid',
-		'class',
-		'icon',
-		'summary',
-	];
+    protected $allowedFields = ['name', 'uid', 'class', 'icon', 'summary'];
 
-	protected $useTimestamps = true;
+    protected $useTimestamps = true;
 
-	protected $validationRules    = [];
-	protected $validationMessages = [];
-	protected $skipValidation     = false;
+    protected $validationRules = [];
+    protected $validationMessages = [];
+    protected $skipValidation = false;
 }
diff --git a/tests/_support/SessionTestCase.php b/tests/_support/SessionTestCase.php
index 9694e3fe01..2f53dacad8 100644
--- a/tests/_support/SessionTestCase.php
+++ b/tests/_support/SessionTestCase.php
@@ -6,27 +6,30 @@ use CodeIgniter\Test\Mock\MockSession;
 
 class SessionTestCase extends CIUnitTestCase
 {
-	/**
-	 * @var SessionHandler
-	 */
-	protected $session;
+    /**
+     * @var SessionHandler
+     */
+    protected $session;
 
-	public function setUp(): void
-	{
-		parent::setUp();
+    public function setUp(): void
+    {
+        parent::setUp();
 
-		$this->mockSession();
-	}
+        $this->mockSession();
+    }
 
-	/**
-	 * Pre-loads the mock session driver into $this->session.
-	 *
-	 * @var string
-	 */
-	protected function mockSession()
-	{
-		$config        = config('App');
-		$this->session = new MockSession(new ArrayHandler($config, '0.0.0.0'), $config);
-		\Config\Services::injectMock('session', $this->session);
-	}
+    /**
+     * Pre-loads the mock session driver into $this->session.
+     *
+     * @var string
+     */
+    protected function mockSession()
+    {
+        $config = config('App');
+        $this->session = new MockSession(
+            new ArrayHandler($config, '0.0.0.0'),
+            $config
+        );
+        \Config\Services::injectMock('session', $this->session);
+    }
 }
diff --git a/tests/database/ExampleDatabaseTest.php b/tests/database/ExampleDatabaseTest.php
index 2de0b6ae01..90762c3578 100644
--- a/tests/database/ExampleDatabaseTest.php
+++ b/tests/database/ExampleDatabaseTest.php
@@ -4,39 +4,43 @@ use Tests\Support\Models\ExampleModel;
 
 class ExampleDatabaseTest extends \Tests\Support\DatabaseTestCase
 {
-	public function setUp(): void
-	{
-		parent::setUp();
+    public function setUp(): void
+    {
+        parent::setUp();
 
-		// Extra code to run before each test
-	}
+        // Extra code to run before each test
+    }
 
-	public function testModelFindAll()
-	{
-		$model = new ExampleModel();
+    public function testModelFindAll()
+    {
+        $model = new ExampleModel();
 
-		// Get every row created by ExampleSeeder
-		$objects = $model->findAll();
+        // Get every row created by ExampleSeeder
+        $objects = $model->findAll();
 
-		// Make sure the count is as expected
-		$this->assertCount(3, $objects);
-	}
+        // Make sure the count is as expected
+        $this->assertCount(3, $objects);
+    }
 
-	public function testSoftDeleteLeavesRow()
-	{
-		$model = new ExampleModel();
-		$this->setPrivateProperty($model, 'useSoftDeletes', true);
-		$this->setPrivateProperty($model, 'tempUseSoftDeletes', true);
+    public function testSoftDeleteLeavesRow()
+    {
+        $model = new ExampleModel();
+        $this->setPrivateProperty($model, 'useSoftDeletes', true);
+        $this->setPrivateProperty($model, 'tempUseSoftDeletes', true);
 
-		$object = $model->first();
-		$model->delete($object->id);
+        $object = $model->first();
+        $model->delete($object->id);
 
-		// The model should no longer find it
-		$this->assertNull($model->find($object->id));
+        // The model should no longer find it
+        $this->assertNull($model->find($object->id));
 
-		// ... but it should still be in the database
-		$result = $model->builder()->where('id', $object->id)->get()->getResult();
+        // ... but it should still be in the database
+        $result = $model
+            ->builder()
+            ->where('id', $object->id)
+            ->get()
+            ->getResult();
 
-		$this->assertCount(1, $result);
-	}
+        $this->assertCount(1, $result);
+    }
 }
diff --git a/tests/session/ExampleSessionTest.php b/tests/session/ExampleSessionTest.php
index 6ec0d011bd..b0a91214de 100644
--- a/tests/session/ExampleSessionTest.php
+++ b/tests/session/ExampleSessionTest.php
@@ -2,17 +2,17 @@
 
 class ExampleSessionTest extends \Tests\Support\SessionTestCase
 {
-	public function setUp(): void
-	{
-		parent::setUp();
-	}
+    public function setUp(): void
+    {
+        parent::setUp();
+    }
 
-	public function testSessionSimple()
-	{
-		$this->session->set('logged_in', 123);
+    public function testSessionSimple()
+    {
+        $this->session->set('logged_in', 123);
 
-		$value = $this->session->get('logged_in');
+        $value = $this->session->get('logged_in');
 
-		$this->assertEquals(123, $value);
-	}
+        $this->assertEquals(123, $value);
+    }
 }
diff --git a/tests/unit/HealthTest.php b/tests/unit/HealthTest.php
index 1d059d057d..d60b0d2555 100644
--- a/tests/unit/HealthTest.php
+++ b/tests/unit/HealthTest.php
@@ -2,32 +2,34 @@
 
 class HealthTest extends \CodeIgniter\Test\CIUnitTestCase
 {
-	public function setUp(): void
-	{
-		parent::setUp();
-	}
+    public function setUp(): void
+    {
+        parent::setUp();
+    }
 
-	public function testIsDefinedAppPath()
-	{
-		$test = defined('APPPATH');
+    public function testIsDefinedAppPath()
+    {
+        $test = defined('APPPATH');
 
-		$this->assertTrue($test);
-	}
+        $this->assertTrue($test);
+    }
 
-	public function testBaseUrlHasBeenSet()
-	{
-		$env = $config = false;
+    public function testBaseUrlHasBeenSet()
+    {
+        $env = $config = false;
 
-		// First check in .env
-		if (is_file(HOMEPATH . '.env'))
-		{
-			$env = (bool) preg_grep("/^app\.baseURL = './", file(HOMEPATH . '.env'));
-		}
+        // First check in .env
+        if (is_file(HOMEPATH . '.env')) {
+            $env = (bool) preg_grep(
+                "/^app\.baseURL = './",
+                file(HOMEPATH . '.env')
+            );
+        }
 
-		// Then check the actual config file
-		$reader = new \Tests\Support\Libraries\ConfigReader();
-		$config = ! empty($reader->baseUrl);
+        // Then check the actual config file
+        $reader = new \Tests\Support\Libraries\ConfigReader();
+        $config = !empty($reader->baseUrl);
 
-		$this->assertTrue($env || $config);
-	}
+        $this->assertTrue($env || $config);
+    }
 }
-- 
GitLab