diff --git a/screenshots/login.png b/.github/screenshots/login.png
similarity index 100%
rename from screenshots/login.png
rename to .github/screenshots/login.png
diff --git a/screenshots/permissions.png b/.github/screenshots/permissions.png
similarity index 100%
rename from screenshots/permissions.png
rename to .github/screenshots/permissions.png
diff --git a/screenshots/users.png b/.github/screenshots/users.png
similarity index 100%
rename from screenshots/users.png
rename to .github/screenshots/users.png
diff --git a/sponsors/nextgi.png b/.github/sponsors/nextgi.png
similarity index 100%
rename from sponsors/nextgi.png
rename to .github/sponsors/nextgi.png
diff --git a/sponsors/usor.png b/.github/sponsors/usor.png
similarity index 100%
rename from sponsors/usor.png
rename to .github/sponsors/usor.png
diff --git a/.github/workflows/Build.yml b/.github/workflows/Build.yml
index 0275b540b..3ad8f5ce4 100644
--- a/.github/workflows/Build.yml
+++ b/.github/workflows/Build.yml
@@ -14,7 +14,7 @@ jobs:
strategy:
fail-fast: false
matrix:
- php_versions: ['7.1', '7.2', '7.3', '7.4']
+ php_versions: ['7.2', '7.3', '7.4']
runs-on: ubuntu-latest
name: PHPUnit - PHP ${{ matrix.php_versions }} - MySQL
@@ -38,11 +38,11 @@ jobs:
php-version: ${{ matrix.php_versions }}
extensions: mbstring, dom, fileinfo, gd, memcached, redis, pdo_sqlite
coverage: xdebug
- tools: pecl, composer:v1
+ tools: pecl, composer
- uses: actions/setup-node@v2
with:
- node-version: 10
+ node-version: 14
- name: Setup Redis-server
uses: supercharge/redis-github-action@1.1.0
@@ -83,7 +83,7 @@ jobs:
run: php -r "copy('app/sprinkles.example.json', 'app/sprinkles.json');"
- name: Install Dependencies
- run: composer install --prefer-dist --no-progress --no-suggest
+ run: composer install --prefer-dist --no-progress
- name: Bakery Debug
run: php bakery debug
@@ -109,7 +109,7 @@ jobs:
strategy:
fail-fast: false
matrix:
- php_versions: ['7.1', '7.2', '7.3', '7.4']
+ php_versions: ['7.2', '7.3', '7.4']
runs-on: ubuntu-latest
name: PHPUnit - PHP ${{ matrix.php_versions }} - SQLite
@@ -129,11 +129,11 @@ jobs:
php-version: ${{ matrix.php_versions }}
extensions: mbstring, dom, fileinfo, gd, memcached, redis, pdo_sqlite
coverage: xdebug
- tools: pecl, composer:v1
+ tools: pecl, composer
- uses: actions/setup-node@v2
with:
- node-version: 10
+ node-version: 14
- name: Setup Redis-server
uses: supercharge/redis-github-action@1.1.0
@@ -147,7 +147,7 @@ jobs:
run: php -r "copy('app/sprinkles.example.json', 'app/sprinkles.json');"
- name: Install Dependencies
- run: composer install --prefer-dist --no-progress --no-suggest
+ run: composer install --prefer-dist --no-progress
- name: Create SQLite Database
run: |
@@ -178,7 +178,7 @@ jobs:
strategy:
fail-fast: false
matrix:
- php_versions: ['7.1', '7.2', '7.3', '7.4']
+ php_versions: ['7.2', '7.3', '7.4']
runs-on: ubuntu-latest
name: PHPUnit - PHP ${{ matrix.php_versions }} - PostgreSQL
@@ -202,7 +202,7 @@ jobs:
php-version: ${{ matrix.php_versions }}
extensions: mbstring, dom, fileinfo, gd, memcached, redis, pdo_sqlite, pdo_pgsql
coverage: xdebug
- tools: pecl, composer:v1
+ tools: pecl, composer
- name: Setup PostgreSQL
uses: harmon758/postgresql-action@v1
@@ -213,7 +213,7 @@ jobs:
- uses: actions/setup-node@v2
with:
- node-version: 10
+ node-version: 14
- name: Setup Redis-server
uses: supercharge/redis-github-action@1.1.0
@@ -227,7 +227,7 @@ jobs:
run: php -r "copy('app/sprinkles.example.json', 'app/sprinkles.json');"
- name: Install Dependencies
- run: composer install --prefer-dist --no-progress --no-suggest
+ run: composer install --prefer-dist --no-progress
- name: Bakery Debug
run: php bakery debug
@@ -253,7 +253,7 @@ jobs:
strategy:
fail-fast: false
matrix:
- php_versions: ['7.1', '7.2', '7.3', '7.4']
+ php_versions: ['7.2', '7.3', '7.4']
runs-on: windows-latest
name: PHPUnit - PHP ${{ matrix.php_versions }} - Windows
@@ -273,17 +273,17 @@ jobs:
php-version: ${{ matrix.php_versions }}
extensions: mbstring, dom, fileinfo, gd, pdo, sqlite, pdo_sqlite
coverage: xdebug
- tools: pecl, composer:v1
+ tools: pecl, composer
- uses: actions/setup-node@v2
with:
- node-version: 10
+ node-version: 14
- name: Copy .env
run: php -r "copy('app/sprinkles.example.json', 'app/sprinkles.json');"
- name: Install Dependencies
- run: composer install --prefer-dist --no-progress --no-suggest
+ run: composer install --prefer-dist --no-progress
- name: Create SQLite Database
run: |
@@ -314,7 +314,7 @@ jobs:
fail-fast: false
matrix:
php_versions: ['7.4']
- node_versions: ['10', '12', '14']
+ node_versions: ['12.17.0', '14', '15']
os: [ubuntu-latest, windows-latest]
runs-on: ${{ matrix.os }}
@@ -329,7 +329,7 @@ jobs:
php-version: ${{ matrix.php_versions }}
extensions: mbstring, dom, fileinfo, gd
coverage: xdebug
- tools: pecl, composer:v1
+ tools: pecl, composer
- uses: actions/setup-node@v2
with:
@@ -339,7 +339,7 @@ jobs:
run: php -r "copy('app/sprinkles.example.json', 'app/sprinkles.json');"
- name: Install Dependencies
- run: composer install --prefer-dist --no-progress --no-suggest
+ run: composer install --prefer-dist --no-progress
- name: Execute build
run: php bakery build-assets
\ No newline at end of file
diff --git a/.lando.dist.yml b/.lando.dist.yml
new file mode 100644
index 000000000..9a9e50626
--- /dev/null
+++ b/.lando.dist.yml
@@ -0,0 +1,69 @@
+# Lando is a development tool, do not use it hosting a production website
+
+name: userfrosting
+recipe: lamp
+config:
+ webroot: ./public
+ php: '7.4'
+ composer_version: '2-latest'
+ database: mariadb
+ xdebug: true
+
+services:
+ appserver:
+ build_as_root:
+ - apt-get update -y
+ - apt-get install -my wget gnupg
+ - a2enmod headers
+ # Patch to bring NodeJS into app server container
+ # https://docs.lando.dev/guides/installing-node-in-your-lando-php-service.html
+ - curl -sL https://deb.nodesource.com/setup_14.x | bash -
+ - apt-get install -y nodejs
+ overrides:
+ environment:
+ PHP_IDE_CONFIG: "serverName=userfrosting.lndo.site"
+ MAIL_MAILER: "mail"
+ DB_DRIVER: "mysql"
+ DB_HOST: "database"
+ DB_PORT: "3306"
+ DB_NAME: "lamp"
+ DB_USER: "lamp"
+ DB_PASSWORD: "lamp"
+ ssl: true
+
+ # Redis cache
+ cache:
+ type: redis
+
+ # phpMyAdmin
+ pma:
+ type: phpmyadmin
+ hosts:
+ - database
+
+ # MailHog
+ mh:
+ type: mailhog:v1.0.0
+ portforward: false
+ hogfrom:
+ # Set UF mailer config to 'mail' complete integration
+ - appserver
+
+proxy:
+ pma:
+ - pma.userfrosting.lndo.site
+ mh:
+ - mh.userfrosting.lndo.site
+
+tooling:
+ phpunit:
+ service: appserver
+ description: "Run PHP Unit tests"
+ cmd: app/vendor/bin/phpunit
+ redis-cli:
+ service: cache
+ description: "Redis cache CLI"
+ bakery:
+ service: appserver
+ description: "UserFrosting CLI"
+ cmd: php bakery
\ No newline at end of file
diff --git a/.php_cs b/.php_cs.dist
similarity index 98%
rename from .php_cs
rename to .php_cs.dist
index a12512f91..7c15cbfe2 100755
--- a/.php_cs
+++ b/.php_cs.dist
@@ -103,10 +103,11 @@ $rules = [
];
$finder = PhpCsFixer\Finder::create()
- ->exclude([
- 'vendor',
- ])
- ->in([__DIR__ . '/app', __DIR__ . '/public']);
+ ->in([
+ __DIR__ . '/app/sprinkles',
+ __DIR__ . '/app/system',
+ __DIR__ . '/public'
+ ]);
return PhpCsFixer\Config::create()
->setRules($rules)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 9a312cb33..116c9a09e 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -5,6 +5,53 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/)
and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html).
+## [v4.5.0]
+
+### Changed Requirements
+- Drop PHP 7.1 support. PHP 7.4 is now recommended.
+- Raised NodeJS version requirement from `>=10.12.0` to `^12.17.0 || >=14.0.0` ([#1138]).
+- Raised NPM version requirement from `>=6.0.0` to `>=6.14.4` ([#1138]).
+
+### Changed Composer Dependencies
+- Updated `wikimedia/composer-merge-plugin` from `^1.4.0` to `^2.1.0` ([#1117]).
+
+### Added
+- Composer 2 support ([#1117]).
+- [Lando](https://lando.dev) support.
+- Added more SMTP options in env and setup:smtp bakery command ([#1077]),
+- Added new `MAIL_MAILER` environment variable to set mailer type.
+- Added "Native mail" to `setup:mail` bakery command.
+
+### Changed
+- Implement findInt ([#1117]).
+- Replace `getenv()` with `env()` ([#1121]).
+- Replaced `UserFrosting\Sprinkle\Core\Bakery\Helper\NodeVersionCheck` with new `UserFrosting\Sprinkle\Core\Util\VersionValidator` class.
+- Bakery command `setup:smtp` renamed to `setup:mail`. The old command is still available as an alias for backward compatibility.
+- Changed `.php_cs` to `.php_cs.dist`.
+- Changed `phpunit.xml` to `phpunit.xml.dist`.
+
+### Fixed
+- Replaced AdminLTE credit in default footer (old link was dead).
+- Issue with path slashes on Windows ([#1133]).
+
+### Removed
+- Removed deprecated `UserFrosting\System\Bakery\Migration` (deprecated in 4.2.0).
+- Removed deprecated `UserFrosting\Tests\DatabaseTransactions` (deprecated in 4.2.0).
+- Removed deprecated `UserFrosting\Sprinkle\Core\Tests\ControllerTestCase` (deprecated in 4.2.2).
+- Removed deprecated `UserFrosting\Sprinkle\Core\Model\UFModel` (deprecated in 4.1).
+- Removed deprecated `UserFrosting\Sprinkle\Core\Sprunje\Sprunje::getResults` (deprecated in 4.1.7).
+- Removed deprecated `UserFrosting\Sprinkle\Account\Database\Models\User::exists` (deprecated in 4.1.7).
+- Removed deprecated `UserFrosting\Sprinkle\Core\Database\Models\Model::export` (deprecated in 4.1.8).
+- Removed deprecated `UserFrosting\Sprinkle\Core\Database\Models\Model::queryBuilder` (deprecated in 4.1.8).
+- Removed deprecated `UserFrosting\Sprinkle\Core\Database\Relations\Concerns\Unique::withLimit` (deprecated in 4.1.7).
+- Removed deprecated `UserFrosting\Sprinkle\Core\Database\Relations\Concerns\Unique::withOffset` (deprecated in 4.1.7).
+- Removed deprecated `UserFrosting\Sprinkle\Core\Error\RendererWhoopsRenderer::getResourcesPath`.
+- Removed deprecated `UserFrosting\Sprinkle\Core\Error\RendererWhoopsRenderer::setResourcesPath`.
+- Removed deprecated Handlebar `ifCond` (Deprecated in 4.1).
+- Removed migration seed.
+- Removed support for migration with non static `$dependencies` properties.
+- Removed support for deprecated `determineRedirectOnLogin` service (deprecated in 4.1.10).
+
## [v4.4.5]
### Changed
@@ -85,7 +132,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
- Improve ordering by activity date ([#1061] & [#1062]; Thanks @ktecho!)
- Updated Vagrant config and documentation
- Fixed a bug where `withTrashed` in `findUnique` was not available when `SoftDeletes` trait is not included in a model.
-- CSRF global middleware is not loaded anymore if in a CLI envrionement. This will avoid sessions to be created for bakery and tests by default.
+- CSRF global middleware is not loaded anymore if in a CLI environment. This will avoid sessions to be created for bakery and tests by default.
- Browserified node modules not being correctly loaded.
- Browserified node modules potentially colliding with real entrypoints.
@@ -994,6 +1041,12 @@ See [http://learn.userfrosting.com/upgrading/40-to-41](Upgrading 4.0.x to 4.1.x
[#1114]: https://github.com/userfrosting/UserFrosting/pull/1114
[#1126]: https://github.com/userfrosting/UserFrosting/pull/1126
[#1128]: https://github.com/userfrosting/UserFrosting/pull/1128
+[#1117]: https://github.com/userfrosting/UserFrosting/issues/1117
+[#1138]: https://github.com/userfrosting/UserFrosting/pull/1138
+[#1124]: https://github.com/userfrosting/UserFrosting/pull/1124
+[#1121]: https://github.com/userfrosting/UserFrosting/pull/1121
+[#1077]: https://github.com/userfrosting/UserFrosting/pull/1077
+[#1133]: https://github.com/userfrosting/UserFrosting/issues/1133
[v4.2.0]: https://github.com/userfrosting/UserFrosting/compare/v4.1.22...v4.2.0
[v4.2.1]: https://github.com/userfrosting/UserFrosting/compare/v4.2.0...v.4.2.1
@@ -1009,3 +1062,4 @@ See [http://learn.userfrosting.com/upgrading/40-to-41](Upgrading 4.0.x to 4.1.x
[v4.4.3]: https://github.com/userfrosting/UserFrosting/compare/v4.4.2...v4.4.3
[v4.4.4]: https://github.com/userfrosting/UserFrosting/compare/v4.4.3...v4.4.4
[v4.4.5]: https://github.com/userfrosting/UserFrosting/compare/v4.4.4...v4.4.5
+[v4.5.0]: https://github.com/userfrosting/UserFrosting/compare/v4.4.5...v4.5.0
diff --git a/README.md b/README.md
index b50f11f48..c0166ab96 100644
--- a/README.md
+++ b/README.md
@@ -1,4 +1,4 @@
-# UserFrosting 4.4
+# UserFrosting 4.5
[![Latest Version](https://img.shields.io/github/release/userfrosting/UserFrosting.svg)](https://github.com/userfrosting/UserFrosting/releases)
![PHP Version](https://img.shields.io/packagist/php-v/userfrosting/userfrosting.svg?color=brightgreen)
@@ -11,8 +11,8 @@
| Branch | Version | Build | Coverage | Style |
| ------ |:-------:|:-----:|:--------:|:-----:|
| [master] | ![](https://img.shields.io/github/release/userfrosting/userfrosting.svg?color=success&label=Version) | [![](https://github.com/userfrosting/userfrosting/workflows/Build/badge.svg?branch=master)][UF-Build] | [![](https://codecov.io/gh/userfrosting/userfrosting/branch/master/graph/badge.svg)][UF-Codecov] | [![][style-master]][style] |
-| [hotfix] | ![](https://img.shields.io/badge/Version-v4.4.x-yellow.svg) | [![](https://github.com/userfrosting/userfrosting/workflows/Build/badge.svg?branch=hotfix)][UF-Build] | [![](https://codecov.io/gh/userfrosting/userfrosting/branch/hotfix/graph/badge.svg)][UF-Codecov] | [![][style-hotfix]][style] |
-| [develop] | ![](https://img.shields.io/badge/Version-v4.5.x-orange.svg) | [![](https://github.com/userfrosting/userfrosting/workflows/Build/badge.svg?branch=develop)][UF-Build] | [![](https://codecov.io/gh/userfrosting/userfrosting/branch/develop/graph/badge.svg)][UF-Codecov] | [![][style-develop]][style] |
+| [hotfix] | ![](https://img.shields.io/badge/Version-v4.5.x-yellow.svg) | [![](https://github.com/userfrosting/userfrosting/workflows/Build/badge.svg?branch=hotfix)][UF-Build] | [![](https://codecov.io/gh/userfrosting/userfrosting/branch/hotfix/graph/badge.svg)][UF-Codecov] | [![][style-hotfix]][style] |
+| [develop] | ![](https://img.shields.io/badge/Version-v4.6.x-orange.svg) | [![](https://github.com/userfrosting/userfrosting/workflows/Build/badge.svg?branch=develop)][UF-Build] | [![](https://codecov.io/gh/userfrosting/userfrosting/branch/develop/graph/badge.svg)][UF-Codecov] | [![][style-develop]][style] |
[master]: https://github.com/userfrosting/UserFrosting
@@ -38,13 +38,13 @@ UserFrosting is a secure, modern user management system written in PHP and built
## Features
### User login screen
-![User login script](screenshots/login.png)
+![User login script](.github/screenshots/login.png)
### User management page
-![PHP user management script](screenshots/users.png)
+![PHP user management script](.github/screenshots/users.png)
### Permissions management page
-![UserFrosting permissions management](screenshots/permissions.png)
+![UserFrosting permissions management](.github/screenshots/permissions.png)
## [Demo](https://demo.userfrosting.com)
@@ -93,7 +93,7 @@ Louis's a civil engineer in Montréal, Québec who also has a passion for coding
### Jordan Mele
-Jordan's an Australian PHP Developer at [4mation](https://www.4mation.com.au) in Surry Hills, NSW. His passion is creating simple yet intuitive software-based solutions for problems that would otherwise be tedious and overcomplicated to address, while keeping the user in control.
+Jordan's an Australian Software Engineer at [Canva](https://canva.com). His passion is creating simple yet intuitive software-based solutions for problems that would otherwise be tedious and/or difficult to solve, while keeping the user in control.
### Sarah Baghdadi
@@ -139,5 +139,5 @@ Backers help us continue to develop UserFrosting by pledging a regular monthly c
Support this project by becoming a sponsor. Sponsors have contributed a total of $500 or more to UserFrosting (either as an ongoing backer or one-time contributions). Your logo will show up here with a link to your website. [[Become a sponsor](https://opencollective.com/userfrosting#sponsor)]
-[![USOR Games](sponsors/usor.png)](https://usorgames.com)
-[![Next Generation Internet](sponsors/nextgi.png)](https://nextgi.com)
+[![USOR Games](.github/sponsors/usor.png)](https://usorgames.com)
+[![Next Generation Internet](.github/sponsors/nextgi.png)](https://nextgi.com)
diff --git a/app/.env.example b/app/.env.example
index 3d22da1bc..4d04f5390 100644
--- a/app/.env.example
+++ b/app/.env.example
@@ -8,6 +8,10 @@ DB_PORT="3306"
DB_NAME="userfrosting"
DB_USER="userfrosting"
DB_PASSWORD="password"
+MAIL_MAILER="smtp" # Set to one of 'smtp', 'mail', 'qmail', 'sendmail'
SMTP_HOST="host.example.com"
SMTP_USER="relay@example.com"
SMTP_PASSWORD="password"
+SMTP_PORT="587"
+SMTP_AUTH="true"
+SMTP_SECURE="tls"
diff --git a/app/defines.php b/app/defines.php
index 778df9d38..a98f329ee 100755
--- a/app/defines.php
+++ b/app/defines.php
@@ -11,12 +11,12 @@
namespace UserFrosting;
// Some standard defines
-define('UserFrosting\VERSION', '4.4.5');
+define('UserFrosting\VERSION', '4.5.0');
define('UserFrosting\DS', '/');
-define('UserFrosting\PHP_MIN_VERSION', '7.1');
-define('UserFrosting\PHP_RECOMMENDED_VERSION', '7.3');
-define('UserFrosting\NODE_MIN_VERSION', 'v10.12.0');
-define('UserFrosting\NPM_MIN_VERSION', '6.0.0');
+define('UserFrosting\PHP_MIN_VERSION', '^7.2');
+define('UserFrosting\PHP_RECOMMENDED_VERSION', '^7.4');
+define('UserFrosting\NODE_MIN_VERSION', '^12.17.0 || >=14.0.0');
+define('UserFrosting\NPM_MIN_VERSION', '>=6.14.4');
// Directories and Paths
diff --git a/app/sprinkles/account/composer.json b/app/sprinkles/account/composer.json
index 8f57eda1a..9df9a6c08 100644
--- a/app/sprinkles/account/composer.json
+++ b/app/sprinkles/account/composer.json
@@ -17,7 +17,7 @@
{
"name": "Jordan Mele",
"email": "SiliconSoldier@outlook.com.au",
- "homepage": "https://blog.djmm.me"
+ "homepage": "https://djmm.me"
}
],
"require": {
diff --git a/app/sprinkles/account/src/Account/Registration.php b/app/sprinkles/account/src/Account/Registration.php
index 7d5968194..99ced2de4 100644
--- a/app/sprinkles/account/src/Account/Registration.php
+++ b/app/sprinkles/account/src/Account/Registration.php
@@ -156,7 +156,7 @@ public function validate()
// Make sure all required fields are defined
foreach ($this->requiredProperties as $property) {
if (!isset($this->userdata[$property])) {
- $e = new HttpException("Account can't be registrated as '$property' is required to create a new user.");
+ $e = new HttpException("Account can't be registered as '$property' is required to create a new user.");
$e->addUserMessage('USERNAME.IN_USE');
throw $e;
diff --git a/app/sprinkles/account/src/Authenticate/Authenticator.php b/app/sprinkles/account/src/Authenticate/Authenticator.php
index f4593cfe1..2180c5532 100644
--- a/app/sprinkles/account/src/Authenticate/Authenticator.php
+++ b/app/sprinkles/account/src/Authenticate/Authenticator.php
@@ -359,7 +359,7 @@ protected function loginRememberedUser()
// so we store the fact that the user was logged in via RememberMe (instead of login form)
$this->viaRemember = true;
} else {
- // If $rememberMe->login() was not successfull, check if the token was invalid as well. This means the cookie was stolen.
+ // If $rememberMe->login() was not successful, check if the token was invalid as well. This means the cookie was stolen.
if ($loginResult->hasPossibleManipulation()) {
throw new AuthCompromisedException();
}
diff --git a/app/sprinkles/account/src/Authorize/AccessConditionExpression.php b/app/sprinkles/account/src/Authorize/AccessConditionExpression.php
index 9bfbbec77..3c35136a6 100644
--- a/app/sprinkles/account/src/Authorize/AccessConditionExpression.php
+++ b/app/sprinkles/account/src/Authorize/AccessConditionExpression.php
@@ -98,7 +98,7 @@ public function evaluateCondition($condition, $params)
// Set the reserved `self` parameters.
// This replaces any values of `self` specified in the arguments, thus preventing them from being overridden in malicious user input.
// (For example, from an unfiltered request body).
- $params['self'] = $this->user->export();
+ $params['self'] = $this->user->toArray();
$this->nodeVisitor->setParams($params);
diff --git a/app/sprinkles/account/src/Bakery/CreateAdminUser.php b/app/sprinkles/account/src/Bakery/CreateAdminUser.php
index d3166e0f3..dbc53be61 100644
--- a/app/sprinkles/account/src/Bakery/CreateAdminUser.php
+++ b/app/sprinkles/account/src/Bakery/CreateAdminUser.php
@@ -272,7 +272,7 @@ protected function askLastName($lastName = '')
/**
* Validate the last name entered is valid.
*
- * @param string $lastName The lastname
+ * @param string $lastName The last name
*
* @return bool Input is valid or not
*/
diff --git a/app/sprinkles/account/src/Controller/AccountController.php b/app/sprinkles/account/src/Controller/AccountController.php
index 92b7b3757..52e30eeb2 100644
--- a/app/sprinkles/account/src/Controller/AccountController.php
+++ b/app/sprinkles/account/src/Controller/AccountController.php
@@ -418,7 +418,7 @@ public function login(Request $request, Response $response, $args)
throw $e;
}
- $ms->addMessageTranslated('success', 'WELCOME', $currentUser->export());
+ $ms->addMessageTranslated('success', 'WELCOME', $currentUser->toArray());
// Set redirect, if relevant
$redirectOnLogin = $this->ci->get('redirect.onLogin');
@@ -680,7 +680,7 @@ public function pageSetPassword(Request $request, Response $response, $args)
* @param Response $response
* @param array $args
*
- * @throws ForbiddenException If user is not authozied to access page
+ * @throws ForbiddenException If user is not authorized to access page
*/
public function pageSettings(Request $request, Response $response, $args)
{
@@ -920,7 +920,7 @@ public function register(Request $request, Response $response, $args)
}
// Security measure: do not allow registering new users until the master account has been created.
- if (!$classMapper->getClassMapping('user')::find($config['reserved_user_ids.master'])) {
+ if (!$classMapper->getClassMapping('user')::findInt($config['reserved_user_ids.master'])) {
$ms->addMessageTranslated('danger', 'ACCOUNT.MASTER_NOT_EXISTS');
return $response->withJson([], 403);
@@ -1191,7 +1191,7 @@ public function setPassword(Request $request, Response $response, $args)
$user = $passwordReset->user;
$authenticator->login($user);
- $ms->addMessageTranslated('success', 'WELCOME', $user->export());
+ $ms->addMessageTranslated('success', 'WELCOME', $user->toArray());
return $response->withJson([], 200);
}
diff --git a/app/sprinkles/account/src/Database/Migrations/v420/AddingForeignKeys.php b/app/sprinkles/account/src/Database/Migrations/v420/AddingForeignKeys.php
index 41ab504b8..89467e290 100644
--- a/app/sprinkles/account/src/Database/Migrations/v420/AddingForeignKeys.php
+++ b/app/sprinkles/account/src/Database/Migrations/v420/AddingForeignKeys.php
@@ -73,7 +73,7 @@ public function up()
public function down()
{
/*
- * sqlite can't drop foreign key wihout dropping the entire table
+ * sqlite can't drop foreign key without dropping the entire table
* since Laravel 5.7. Skip drop if an sqlite connection is detected
* @see https://github.com/laravel/framework/issues/25475
*/
diff --git a/app/sprinkles/account/src/Database/Models/User.php b/app/sprinkles/account/src/Database/Models/User.php
index e4dd6493e..432a404b4 100644
--- a/app/sprinkles/account/src/Database/Models/User.php
+++ b/app/sprinkles/account/src/Database/Models/User.php
@@ -216,22 +216,6 @@ public function delete($hardDelete = false)
return $result;
}
- /**
- * Determines whether a user exists, including checking soft-deleted records.
- *
- * @deprecated since 4.1.7 This method conflicts with and overrides the Builder::exists() method. Use Model::findUnique instead.
- *
- * @param mixed $value
- * @param string $identifier
- * @param bool $checkDeleted set to true to include soft-deleted records
- *
- * @return User|null
- */
- public static function exists($value, $identifier = 'user_name', $checkDeleted = true)
- {
- return static::findUnique($value, $identifier, $checkDeleted);
- }
-
/**
* Return a cache instance specific to that user.
*
diff --git a/app/sprinkles/account/src/I18n/SiteLocale.php b/app/sprinkles/account/src/I18n/SiteLocale.php
index 6eaeb1b40..e58f2c91b 100644
--- a/app/sprinkles/account/src/I18n/SiteLocale.php
+++ b/app/sprinkles/account/src/I18n/SiteLocale.php
@@ -32,7 +32,7 @@ public function getLocaleIndentifier(): string
/** @var \UserFrosting\Sprinkle\Account\Database\Models\Interfaces\UserInterface */
$currentUser = $this->ci->currentUser;
- // If user is note loged in, get original translator
+ // If user is note logged in, get original translator
try {
if (!$authenticator->check()) {
return parent::getLocaleIndentifier();
diff --git a/app/sprinkles/account/src/ServicesProvider/ServicesProvider.php b/app/sprinkles/account/src/ServicesProvider/ServicesProvider.php
index 27c8f9f7d..47ed47eb7 100644
--- a/app/sprinkles/account/src/ServicesProvider/ServicesProvider.php
+++ b/app/sprinkles/account/src/ServicesProvider/ServicesProvider.php
@@ -49,7 +49,7 @@ public function register(ContainerInterface $container)
*/
$container->extend('assets', function ($assets, $c) {
- // Force load the current user to add it's theme assets ressources
+ // Force load the current user to add it's theme assets resources
$currentUser = $c->currentUser;
return $assets;
@@ -263,7 +263,7 @@ public function register(ContainerInterface $container)
* @return bool true if the user is in the group, false otherwise.
*/
'in_group' => function ($user_id, $group_id) {
- $user = User::find($user_id);
+ $user = User::findInt($user_id);
return $user->group_id == $group_id;
},
@@ -317,7 +317,7 @@ public function register(ContainerInterface $container)
$authenticator = $c->authenticator;
$currentUser = $authenticator->user();
- // Add user theme sprinkles ressources
+ // Add user theme sprinkles resources
if ($authenticator->check() && $currentUser->theme) {
$c->sprinkleManager->addSprinkleResources($currentUser->theme);
}
@@ -374,13 +374,6 @@ public function register(ContainerInterface $container)
* @return \Psr\Http\Message\ResponseInterface
*/
return function (Request $request, Response $response, array $args) use ($c) {
- // Backwards compatibility for the deprecated determineRedirectOnLogin service
- if ($c->has('determineRedirectOnLogin')) {
- $determineRedirectOnLogin = $c->determineRedirectOnLogin;
-
- return $determineRedirectOnLogin($response)->withStatus(200);
- }
-
/** @var \UserFrosting\Sprinkle\Account\Authorize\AuthorizationManager */
$authorizer = $c->authorizer;
diff --git a/app/sprinkles/account/tests/Integration/AuthenticatorTest.php b/app/sprinkles/account/tests/Integration/AuthenticatorTest.php
index 86aedfac1..c9ebd9664 100644
--- a/app/sprinkles/account/tests/Integration/AuthenticatorTest.php
+++ b/app/sprinkles/account/tests/Integration/AuthenticatorTest.php
@@ -216,7 +216,7 @@ public function testLoginWithRememberMe(Authenticator $authenticator)
$this->assertNull($this->ci->session[$key]);
$this->assertNotSame($testUser->id, $this->ci->session[$key]);
- // Go througt the loginRememberedUser process
+ // Go through the loginRememberedUser process
// First, we'll simulate a page refresh by creating a new authenticator
$authenticator = $this->getAuthenticator();
$user = $authenticator->user();
@@ -344,7 +344,7 @@ public function testAttempt_withFlagVerifiedFalseNoEmailVerification(Authenticat
// Force email verification to false
$this->ci->config['site.registration.require_email_verification'] = false;
- // Forcing config requires to recreate the authentificator
+ // Forcing config requires to recreate the authenticator
$authenticator = $this->getAuthenticator();
$password = 'FooBar';
diff --git a/app/sprinkles/account/tests/Integration/Controller/AccountControllerTest.php b/app/sprinkles/account/tests/Integration/Controller/AccountControllerTest.php
index 8d75655e0..296378125 100644
--- a/app/sprinkles/account/tests/Integration/Controller/AccountControllerTest.php
+++ b/app/sprinkles/account/tests/Integration/Controller/AccountControllerTest.php
@@ -136,7 +136,7 @@ public function testRegister()
// Recreate controller to use fake config
$controller = $this->getController();
- // Perfrom common test code
+ // Perform common test code
$this->performActualRegisterTest($controller);
}
@@ -166,7 +166,7 @@ public function testRegisterWithNoEmailVerification()
// Recreate controller to use fake config
$controller = $this->getController();
- // Perfrom common test code
+ // Perform common test code
$this->performActualRegisterTest($controller);
}
@@ -175,7 +175,7 @@ public function testRegisterWithNoEmailVerification()
*/
protected function performActualRegisterTest(AccountController $controller)
{
- // Genereate a captcha for next request.
+ // Generate a captcha for next request.
$captcha = new Captcha($this->ci->session, $this->ci->config['session.keys.captcha']);
$captcha->generateRandomCode();
@@ -494,7 +494,7 @@ public function testlogin(AccountController $controller)
$result = $controller->login($request, $this->getResponse(), []);
$this->assertInstanceOf(\Psr\Http\Message\ResponseInterface::class, $result);
- // Can't assert the status code or data, as this can be overwrited by sprinkles
+ // Can't assert the status code or data, as this can be overwritten by sprinkles
// Test message
$ms = $this->ci->alerts;
@@ -531,7 +531,7 @@ public function testloginWithEmail(AccountController $controller)
$result = $controller->login($request, $this->getResponse(), []);
$this->assertInstanceOf(\Psr\Http\Message\ResponseInterface::class, $result);
- // Can't assert the status code or data, as this can be overwrited by sprinkles
+ // Can't assert the status code or data, as this can be overwritten by sprinkles
// Test message
$ms = $this->ci->alerts;
@@ -676,7 +676,7 @@ public function testloginThrottlerDoesntCountSuccessfulLogins()
$result = $controller->login($request, $this->getResponse(), []);
$this->assertInstanceOf(\Psr\Http\Message\ResponseInterface::class, $result);
- // Can't assert the status code or data, as this can be overwrited by sprinkles
+ // Can't assert the status code or data, as this can be overwritten by sprinkles
// Test message
$ms = $this->ci->alerts;
diff --git a/app/sprinkles/account/tests/Integration/Database/Models/UserModelTest.php b/app/sprinkles/account/tests/Integration/Database/Models/UserModelTest.php
index 6364ca519..fdc6a2a62 100644
--- a/app/sprinkles/account/tests/Integration/Database/Models/UserModelTest.php
+++ b/app/sprinkles/account/tests/Integration/Database/Models/UserModelTest.php
@@ -43,8 +43,8 @@ public function setUp(): void
/**
* Test user hard deletion with user relations.
- * This is not a totaly acurate test, as each relations are added manually
- * and new relations might not be added automatically to accuratly test
+ * This is not a totally accurate test, as each relations are added manually
+ * and new relations might not be added automatically to accurately test
*/
public function testUserHardDeleteWithUserRelations()
{
diff --git a/app/sprinkles/account/tests/Integration/RegistrationTest.php b/app/sprinkles/account/tests/Integration/RegistrationTest.php
index 764ef1039..32be34100 100644
--- a/app/sprinkles/account/tests/Integration/RegistrationTest.php
+++ b/app/sprinkles/account/tests/Integration/RegistrationTest.php
@@ -89,7 +89,7 @@ public function testMissingFields()
]);
$this->expectException(HttpException::class);
- $this->expectExceptionMessage("Account can't be registrated as 'first_name' is required to create a new user.");
+ $this->expectExceptionMessage("Account can't be registered as 'first_name' is required to create a new user.");
$registration->validate();
}
@@ -135,7 +135,7 @@ public function testValidationWithDuplicateUsername()
$registration = new Registration($this->ci, $this->fakeUserData);
$this->expectException(HttpException::class);
- $this->expectExceptionMessage("Username is already in use.");
+ $this->expectExceptionMessage('Username is already in use.');
$registration->validate();
}
@@ -154,7 +154,7 @@ public function testValidationWithDuplicateEmail()
//Set expectations
$this->expectException(HttpException::class);
- $this->expectExceptionMessage("Email is already in use.");
+ $this->expectExceptionMessage('Email is already in use.');
// Act
$registration->validate();
diff --git a/app/sprinkles/account/tests/withTestUser.php b/app/sprinkles/account/tests/withTestUser.php
index 0a370237d..e98e394f0 100644
--- a/app/sprinkles/account/tests/withTestUser.php
+++ b/app/sprinkles/account/tests/withTestUser.php
@@ -74,7 +74,7 @@ protected function createTestUser($isMaster = false, $login = false, array $para
}
/**
- * Returns a random user id, exclusing th master id
+ * Returns a random user id, excluding the master id
* @param int $masterId
* @return int
*/
@@ -114,7 +114,7 @@ protected function giveUserTestPermission(UserInterface $user, $slug, $condition
* Add the test permission to a Role, then the role to the user
* @param UserInterface $user
* @param Permission $permission
- * @return Role The intermidiate role
+ * @return Role The intermediate role
*/
protected function giveUserPermission(UserInterface $user, Permission $permission)
{
diff --git a/app/sprinkles/admin/assets/userfrosting/js/handlebars-helpers.js b/app/sprinkles/admin/assets/userfrosting/js/handlebars-helpers.js
index 96f47bb81..ba0874caa 100644
--- a/app/sprinkles/admin/assets/userfrosting/js/handlebars-helpers.js
+++ b/app/sprinkles/admin/assets/userfrosting/js/handlebars-helpers.js
@@ -37,7 +37,7 @@ Handlebars.registerHelper('ifx', function (v1, operator, v2, options) {
/**
* Perform simple calculations.
- *
+ *
* usage: {{calc x '+' 2}}
*/
Handlebars.registerHelper('calc', function (v1, operator, v2, options) {
@@ -55,7 +55,7 @@ Handlebars.registerHelper('calc', function (v1, operator, v2, options) {
/**
* format an ISO date using Moment.js
- *
+ *
* moment syntax example: moment(Date("2011-07-18T15:50:52")).format("MMMM YYYY")
* usage: {{dateFormat creation_date format="MMMM YYYY"}}
* @requires momentjs http://momentjs.com/
@@ -103,17 +103,3 @@ Handlebars.registerHelper("currencyUsdFormat", function(amount) {
Handlebars.registerHelper('slug', function(text) {
return getSlug(text);
});
-
-/**
- * Equality helper for Handlebars
- * http://stackoverflow.com/questions/8853396/logical-operator-in-a-handlebars-js-if-conditional/21915381#21915381
- * @deprecated since 4.1 - use ifx instead
- * usage: {{ifCond apple orange}}
- */
-Handlebars.registerHelper('ifCond', function(v1, v2, options) {
- if(v1 == v2) {
- return options.fn(this);
- }
-
- return options.inverse(this);
-});
diff --git a/app/sprinkles/admin/composer.json b/app/sprinkles/admin/composer.json
index de8c4418a..f5691407d 100644
--- a/app/sprinkles/admin/composer.json
+++ b/app/sprinkles/admin/composer.json
@@ -17,7 +17,7 @@
{
"name": "Jordan Mele",
"email": "SiliconSoldier@outlook.com.au",
- "homepage": "https://blog.djmm.me"
+ "homepage": "https://djmm.me"
}
],
"autoload": {
diff --git a/app/sprinkles/admin/src/Controller/GroupController.php b/app/sprinkles/admin/src/Controller/GroupController.php
index 956143e37..59927ace0 100644
--- a/app/sprinkles/admin/src/Controller/GroupController.php
+++ b/app/sprinkles/admin/src/Controller/GroupController.php
@@ -47,7 +47,7 @@ class GroupController extends SimpleController
* @param Response $response
* @param array $args
*
- * @throws ForbiddenException If user is not authozied to access page
+ * @throws ForbiddenException If user is not authorized to access page
*/
public function create(Request $request, Response $response, $args)
{
@@ -144,7 +144,7 @@ public function create(Request $request, Response $response, $args)
* @param array $args
*
* @throws NotFoundException If group is not found
- * @throws ForbiddenException If user is not authozied to access page
+ * @throws ForbiddenException If user is not authorized to access page
* @throws BadRequestException
*/
public function delete(Request $request, Response $response, $args)
@@ -228,7 +228,7 @@ public function delete(Request $request, Response $response, $args)
* @param Response $response
* @param array $args
*
- * @throws ForbiddenException If user is not authozied to access page
+ * @throws ForbiddenException If user is not authorized to access page
* @throws NotFoundException If group is not found
*/
public function getInfo(Request $request, Response $response, $args)
@@ -276,7 +276,7 @@ public function getInfo(Request $request, Response $response, $args)
* @param Response $response
* @param array $args
*
- * @throws ForbiddenException If user is not authozied to access page
+ * @throws ForbiddenException If user is not authorized to access page
*/
public function getList(Request $request, Response $response, $args)
{
@@ -305,14 +305,14 @@ public function getList(Request $request, Response $response, $args)
}
/**
- * Get deletetion confirmation modal.
+ * Get deletion confirmation modal.
*
* @param Request $request
* @param Response $response
* @param array $args
*
* @throws NotFoundException If group is not found
- * @throws ForbiddenException If user is not authozied to access page
+ * @throws ForbiddenException If user is not authorized to access page
* @throws BadRequestException
*/
public function getModalConfirmDelete(Request $request, Response $response, $args)
@@ -372,7 +372,7 @@ public function getModalConfirmDelete(Request $request, Response $response, $arg
* @param Response $response
* @param array $args
*
- * @throws ForbiddenException If user is not authozied to access page
+ * @throws ForbiddenException If user is not authorized to access page
*/
public function getModalCreate(Request $request, Response $response, $args)
{
@@ -435,7 +435,7 @@ public function getModalCreate(Request $request, Response $response, $args)
* @param array $args
*
* @throws NotFoundException If group is not found
- * @throws ForbiddenException If user is not authozied to access page
+ * @throws ForbiddenException If user is not authorized to access page
*/
public function getModalEdit(Request $request, Response $response, $args)
{
@@ -502,7 +502,7 @@ public function getModalEdit(Request $request, Response $response, $args)
* @param array $args
*
* @throws NotFoundException If group is not found
- * @throws ForbiddenException If user is not authozied to access page
+ * @throws ForbiddenException If user is not authorized to access page
*/
public function getUsers(Request $request, Response $response, $args)
{
@@ -557,7 +557,7 @@ public function getUsers(Request $request, Response $response, $args)
* @param Response $response
* @param array $args
*
- * @throws ForbiddenException If user is not authozied to access page
+ * @throws ForbiddenException If user is not authorized to access page
*/
public function pageInfo(Request $request, Response $response, $args)
{
@@ -637,7 +637,7 @@ public function pageInfo(Request $request, Response $response, $args)
* @param Response $response
* @param array $args
*
- * @throws ForbiddenException If user is not authozied to access page
+ * @throws ForbiddenException If user is not authorized to access page
*/
public function pageList(Request $request, Response $response, $args)
{
@@ -673,7 +673,7 @@ public function pageList(Request $request, Response $response, $args)
* @param array $args
*
* @throws NotFoundException If group is not found
- * @throws ForbiddenException If user is not authozied to access page
+ * @throws ForbiddenException If user is not authorized to access page
*/
public function updateInfo(Request $request, Response $response, $args)
{
diff --git a/app/sprinkles/admin/src/Controller/PermissionController.php b/app/sprinkles/admin/src/Controller/PermissionController.php
index de0991666..6a6b2ffd6 100644
--- a/app/sprinkles/admin/src/Controller/PermissionController.php
+++ b/app/sprinkles/admin/src/Controller/PermissionController.php
@@ -34,7 +34,7 @@ class PermissionController extends SimpleController
* @param Response $response
* @param array $args
*
- * @throws ForbiddenException If user is not authozied to access page
+ * @throws ForbiddenException If user is not authorized to access page
* @throws NotFoundException If permission is not found
*/
public function getInfo(Request $request, Response $response, $args)
@@ -55,7 +55,7 @@ public function getInfo(Request $request, Response $response, $args)
/** @var \UserFrosting\Sprinkle\Core\Util\ClassMapper $classMapper */
$classMapper = $this->ci->classMapper;
- $permission = $classMapper->getClassMapping('permission')::find($permissionId);
+ $permission = $classMapper->getClassMapping('permission')::findInt($permissionId);
// If the permission doesn't exist, return 404
if (!$permission) {
@@ -82,7 +82,7 @@ public function getInfo(Request $request, Response $response, $args)
* @param Response $response
* @param array $args
*
- * @throws ForbiddenException If user is not authozied to access page
+ * @throws ForbiddenException If user is not authorized to access page
*/
public function getList(Request $request, Response $response, $args)
{
@@ -122,7 +122,7 @@ public function getList(Request $request, Response $response, $args)
* @param Response $response
* @param array $args
*
- * @throws ForbiddenException If user is not authozied to access page
+ * @throws ForbiddenException If user is not authorized to access page
*/
public function getUsers(Request $request, Response $response, $args)
{
@@ -157,7 +157,7 @@ public function getUsers(Request $request, Response $response, $args)
*
* This checks that the currently logged-in user has permission to view permissions.
* Note that permissions cannot be modified through the interface. This is because
- * permissions are tighly coupled to the code and should only be modified by developers.
+ * permissions are tightly coupled to the code and should only be modified by developers.
* This page requires authentication.
*
* Request type: GET
@@ -166,7 +166,7 @@ public function getUsers(Request $request, Response $response, $args)
* @param Response $response
* @param array $args
*
- * @throws ForbiddenException If user is not authozied to access page
+ * @throws ForbiddenException If user is not authorized to access page
* @throws NotFoundException If permission is not found
*/
public function pageInfo(Request $request, Response $response, $args)
@@ -187,7 +187,7 @@ public function pageInfo(Request $request, Response $response, $args)
/** @var \UserFrosting\Sprinkle\Core\Util\ClassMapper $classMapper */
$classMapper = $this->ci->classMapper;
- $permission = $classMapper->getClassMapping('permission')::find($permissionId);
+ $permission = $classMapper->getClassMapping('permission')::findInt($permissionId);
// If the permission doesn't exist, return 404
if (!$permission) {
@@ -212,7 +212,7 @@ public function pageInfo(Request $request, Response $response, $args)
* @param Response $response
* @param array $args
*
- * @throws ForbiddenException If user is not authozied to access page
+ * @throws ForbiddenException If user is not authorized to access page
*/
public function pageList(Request $request, Response $response, $args)
{
diff --git a/app/sprinkles/admin/src/Controller/RoleController.php b/app/sprinkles/admin/src/Controller/RoleController.php
index 9c53f1d57..602789ece 100644
--- a/app/sprinkles/admin/src/Controller/RoleController.php
+++ b/app/sprinkles/admin/src/Controller/RoleController.php
@@ -47,7 +47,7 @@ class RoleController extends SimpleController
* @param Response $response
* @param array $args
*
- * @throws ForbiddenException If user is not authozied to access page
+ * @throws ForbiddenException If user is not authorized to access page
*/
public function create(Request $request, Response $response, $args)
{
@@ -144,7 +144,7 @@ public function create(Request $request, Response $response, $args)
* @param array $args
*
* @throws NotFoundException If role is not found
- * @throws ForbiddenException If user is not authozied to access page
+ * @throws ForbiddenException If user is not authorized to access page
* @throws BadRequestException
*/
public function delete(Request $request, Response $response, $args)
@@ -227,7 +227,7 @@ public function delete(Request $request, Response $response, $args)
* @param Response $response
* @param array $args
*
- * @throws ForbiddenException If user is not authozied to access page
+ * @throws ForbiddenException If user is not authorized to access page
* @throws NotFoundException If role is not found
*/
public function getInfo(Request $request, Response $response, $args)
@@ -275,7 +275,7 @@ public function getInfo(Request $request, Response $response, $args)
* @param Response $response
* @param array $args
*
- * @throws ForbiddenException If user is not authozied to access page
+ * @throws ForbiddenException If user is not authorized to access page
*/
public function getList(Request $request, Response $response, $args)
{
@@ -311,7 +311,7 @@ public function getList(Request $request, Response $response, $args)
* @param array $args
*
* @throws NotFoundException If role is not found
- * @throws ForbiddenException If user is not authozied to access page
+ * @throws ForbiddenException If user is not authorized to access page
* @throws BadRequestException
*/
public function getModalConfirmDelete(Request $request, Response $response, $args)
@@ -382,7 +382,7 @@ public function getModalConfirmDelete(Request $request, Response $response, $arg
* @param Response $response
* @param array $args
*
- * @throws ForbiddenException If user is not authozied to access page
+ * @throws ForbiddenException If user is not authorized to access page
*/
public function getModalCreate(Request $request, Response $response, $args)
{
@@ -446,7 +446,7 @@ public function getModalCreate(Request $request, Response $response, $args)
* @param array $args
*
* @throws NotFoundException If role is not found
- * @throws ForbiddenException If user is not authozied to access page
+ * @throws ForbiddenException If user is not authorized to access page
*/
public function getModalEdit(Request $request, Response $response, $args)
{
@@ -518,7 +518,7 @@ public function getModalEdit(Request $request, Response $response, $args)
* @param array $args
*
* @throws NotFoundException If role is not found
- * @throws ForbiddenException If user is not authozied to access page
+ * @throws ForbiddenException If user is not authorized to access page
*/
public function getModalEditPermissions(Request $request, Response $response, $args)
{
@@ -564,7 +564,7 @@ public function getModalEditPermissions(Request $request, Response $response, $a
* @param array $args
*
* @throws NotFoundException If role is not found
- * @throws ForbiddenException If user is not authozied to access page
+ * @throws ForbiddenException If user is not authorized to access page
*/
public function getPermissions(Request $request, Response $response, $args)
{
@@ -617,7 +617,7 @@ public function getPermissions(Request $request, Response $response, $args)
* @param array $args
*
* @throws NotFoundException If role is not found
- * @throws ForbiddenException If user is not authozied to access page
+ * @throws ForbiddenException If user is not authorized to access page
*/
public function getUsers(Request $request, Response $response, $args)
{
@@ -672,7 +672,7 @@ public function getUsers(Request $request, Response $response, $args)
* @param Response $response
* @param array $args
*
- * @throws ForbiddenException If user is not authozied to access page
+ * @throws ForbiddenException If user is not authorized to access page
*/
public function pageInfo(Request $request, Response $response, $args)
{
@@ -752,7 +752,7 @@ public function pageInfo(Request $request, Response $response, $args)
* @param Response $response
* @param array $args
*
- * @throws ForbiddenException If user is not authozied to access page
+ * @throws ForbiddenException If user is not authorized to access page
*/
public function pageList(Request $request, Response $response, $args)
{
@@ -788,7 +788,7 @@ public function pageList(Request $request, Response $response, $args)
* @param array $args
*
* @throws NotFoundException If role is not found
- * @throws ForbiddenException If user is not authozied to access page
+ * @throws ForbiddenException If user is not authorized to access page
*/
public function updateInfo(Request $request, Response $response, $args)
{
@@ -910,7 +910,7 @@ public function updateInfo(Request $request, Response $response, $args)
* @param array $args
*
* @throws NotFoundException If role is not found
- * @throws ForbiddenException If user is not authozied to access page
+ * @throws ForbiddenException If user is not authorized to access page
* @throws BadRequestException
*/
public function updateField(Request $request, Response $response, $args)
diff --git a/app/sprinkles/admin/src/Controller/UserController.php b/app/sprinkles/admin/src/Controller/UserController.php
index 3604d6fbf..7f0be6c32 100644
--- a/app/sprinkles/admin/src/Controller/UserController.php
+++ b/app/sprinkles/admin/src/Controller/UserController.php
@@ -51,7 +51,7 @@ class UserController extends SimpleController
* @param Response $response
* @param string[] $args
*
- * @throws ForbiddenException If user is not authozied to access page
+ * @throws ForbiddenException If user is not authorized to access page
*/
public function create(Request $request, Response $response, array $args)
{
@@ -209,7 +209,7 @@ public function create(Request $request, Response $response, array $args)
* @param string[] $args
*
* @throws NotFoundException If user is not found
- * @throws ForbiddenException If user is not authozied to access page
+ * @throws ForbiddenException If user is not authorized to access page
*/
public function createPasswordReset(Request $request, Response $response, array $args)
{
@@ -283,7 +283,7 @@ public function createPasswordReset(Request $request, Response $response, array
* @param string[] $args
*
* @throws NotFoundException If user is not found
- * @throws ForbiddenException If user is not authozied to access page
+ * @throws ForbiddenException If user is not authorized to access page
* @throws BadRequestException
*/
public function delete(Request $request, Response $response, array $args)
@@ -355,7 +355,7 @@ public function delete(Request $request, Response $response, array $args)
* @param string[] $args
*
* @throws NotFoundException If user is not found
- * @throws ForbiddenException If user is not authozied to access page
+ * @throws ForbiddenException If user is not authorized to access page
*/
public function getActivities(Request $request, Response $response, array $args)
{
@@ -408,7 +408,7 @@ public function getActivities(Request $request, Response $response, array $args)
* @param string[] $args
*
* @throws NotFoundException If user is not found
- * @throws ForbiddenException If user is not authozied to access page
+ * @throws ForbiddenException If user is not authorized to access page
*/
public function getInfo(Request $request, Response $response, array $args)
{
@@ -460,7 +460,7 @@ public function getInfo(Request $request, Response $response, array $args)
* @param Response $response
* @param string[] $args
*
- * @throws ForbiddenException If user is not authozied to access page
+ * @throws ForbiddenException If user is not authorized to access page
*/
public function getList(Request $request, Response $response, array $args)
{
@@ -500,7 +500,7 @@ public function getList(Request $request, Response $response, array $args)
* @param string[] $args
*
* @throws NotFoundException If user is not found
- * @throws ForbiddenException If user is not authozied to access page
+ * @throws ForbiddenException If user is not authorized to access page
* @throws BadRequestException
*/
public function getModalConfirmDelete(Request $request, Response $response, array $args)
@@ -562,7 +562,7 @@ public function getModalConfirmDelete(Request $request, Response $response, arra
* @param Response $response
* @param string[] $args
*
- * @throws ForbiddenException If user is not authozied to access page
+ * @throws ForbiddenException If user is not authorized to access page
*/
public function getModalCreate(Request $request, Response $response, array $args)
{
@@ -660,7 +660,7 @@ public function getModalCreate(Request $request, Response $response, array $args
* @param string[] $args
*
* @throws NotFoundException If user is not found
- * @throws ForbiddenException If user is not authozied to access page
+ * @throws ForbiddenException If user is not authorized to access page
*/
public function getModalEdit(Request $request, Response $response, array $args)
{
@@ -761,7 +761,7 @@ public function getModalEdit(Request $request, Response $response, array $args)
* @param string[] $args
*
* @throws NotFoundException If user is not found
- * @throws ForbiddenException If user is not authozied to access page
+ * @throws ForbiddenException If user is not authorized to access page
*/
public function getModalEditPassword(Request $request, Response $response, array $args)
{
@@ -821,7 +821,7 @@ public function getModalEditPassword(Request $request, Response $response, array
* @param string[] $args
*
* @throws NotFoundException If user is not found
- * @throws ForbiddenException If user is not authozied to access page
+ * @throws ForbiddenException If user is not authorized to access page
*/
public function getModalEditRoles(Request $request, Response $response, array $args)
{
@@ -866,7 +866,7 @@ public function getModalEditRoles(Request $request, Response $response, array $a
* @param string[] $args
*
* @throws NotFoundException If user is not found
- * @throws ForbiddenException If user is not authozied to access page
+ * @throws ForbiddenException If user is not authorized to access page
*/
public function getPermissions(Request $request, Response $response, array $args)
{
@@ -916,7 +916,7 @@ public function getPermissions(Request $request, Response $response, array $args
* @param string[] $args
*
* @throws NotFoundException If user is not found
- * @throws ForbiddenException If user is not authozied to access page
+ * @throws ForbiddenException If user is not authorized to access page
*/
public function getRoles(Request $request, Response $response, array $args)
{
@@ -971,7 +971,7 @@ public function getRoles(Request $request, Response $response, array $args)
* @param Response $response
* @param string[] $args
*
- * @throws ForbiddenException If user is not authozied to access page
+ * @throws ForbiddenException If user is not authorized to access page
*/
public function pageInfo(Request $request, Response $response, array $args)
{
@@ -1113,7 +1113,7 @@ public function pageInfo(Request $request, Response $response, array $args)
* @param Response $response
* @param string[] $args
*
- * @throws ForbiddenException If user is not authozied to access page
+ * @throws ForbiddenException If user is not authorized to access page
*/
public function pageList(Request $request, Response $response, array $args)
{
@@ -1147,7 +1147,7 @@ public function pageList(Request $request, Response $response, array $args)
* @param string[] $args
*
* @throws NotFoundException If user is not found
- * @throws ForbiddenException If user is not authozied to access page
+ * @throws ForbiddenException If user is not authorized to access page
*/
public function updateInfo(Request $request, Response $response, array $args)
{
@@ -1280,7 +1280,7 @@ public function updateInfo(Request $request, Response $response, array $args)
* @param string[] $args
*
* @throws NotFoundException If user is not found
- * @throws ForbiddenException If user is not authozied to access page
+ * @throws ForbiddenException If user is not authorized to access page
* @throws BadRequestException
*/
public function updateField(Request $request, Response $response, array $args)
@@ -1326,9 +1326,6 @@ public function updateField(Request $request, Response $response, array $args)
// Make sure data is part of $_PUT data
if (isset($put[$fieldName])) {
$fieldData = $put[$fieldName];
- } elseif (isset($put['value'])) {
- /** @deprecated - Fieldname should be used instead of `value` */
- $fieldData = $put['value'];
} else {
throw new BadRequestException();
}
diff --git a/app/sprinkles/admin/src/ServicesProvider/ServicesProvider.php b/app/sprinkles/admin/src/ServicesProvider/ServicesProvider.php
index 334c417b9..b8d94fca7 100644
--- a/app/sprinkles/admin/src/ServicesProvider/ServicesProvider.php
+++ b/app/sprinkles/admin/src/ServicesProvider/ServicesProvider.php
@@ -65,13 +65,6 @@ public function register(ContainerInterface $container)
* @return \Psr\Http\Message\ResponseInterface
*/
return function (Request $request, Response $response, array $args) use ($c) {
- // Backwards compatibility for the deprecated determineRedirectOnLogin service
- if ($c->has('determineRedirectOnLogin')) {
- $determineRedirectOnLogin = $c->determineRedirectOnLogin;
-
- return $determineRedirectOnLogin($response)->withStatus(200);
- }
-
/** @var \UserFrosting\Sprinkle\Account\Authorize\AuthorizationManager */
$authorizer = $c->authorizer;
diff --git a/app/sprinkles/admin/src/Sprunje/PermissionUserSprunje.php b/app/sprinkles/admin/src/Sprunje/PermissionUserSprunje.php
index 6794d55d7..791cf9a1c 100644
--- a/app/sprinkles/admin/src/Sprunje/PermissionUserSprunje.php
+++ b/app/sprinkles/admin/src/Sprunje/PermissionUserSprunje.php
@@ -10,7 +10,6 @@
namespace UserFrosting\Sprinkle\Admin\Sprunje;
-use UserFrosting\Support\Exception\BadRequestException;
use UserFrosting\Support\Exception\NotFoundException;
/**
@@ -29,12 +28,7 @@ class PermissionUserSprunje extends UserSprunje
*/
protected function baseQuery()
{
- // Requires a permission id
- if (!isset($this->options['permission_id'])) {
- throw new BadRequestException();
- }
-
- $permission = $this->classMapper->getClassMapping('permission')::find($this->options['permission_id']);
+ $permission = $this->classMapper->getClassMapping('permission')::findInt($this->options['permission_id']);
// If the permission doesn't exist, return 404
if (!$permission) {
diff --git a/app/sprinkles/admin/src/Sprunje/UserPermissionSprunje.php b/app/sprinkles/admin/src/Sprunje/UserPermissionSprunje.php
index e0d2f898d..68670865b 100644
--- a/app/sprinkles/admin/src/Sprunje/UserPermissionSprunje.php
+++ b/app/sprinkles/admin/src/Sprunje/UserPermissionSprunje.php
@@ -10,7 +10,6 @@
namespace UserFrosting\Sprinkle\Admin\Sprunje;
-use UserFrosting\Support\Exception\BadRequestException;
use UserFrosting\Support\Exception\NotFoundException;
/**
@@ -29,12 +28,7 @@ class UserPermissionSprunje extends PermissionSprunje
*/
protected function baseQuery()
{
- // Requires a user id
- if (!isset($this->options['user_id'])) {
- throw new BadRequestException();
- }
-
- $user = $this->classMapper->getClassMapping('user')::find($this->options['user_id']);
+ $user = $this->classMapper->getClassMapping('user')::findInt($this->options['user_id']);
// If the user doesn't exist, return 404
if (!$user) {
diff --git a/app/sprinkles/admin/tests/Integration/Controller/ActivityControllerTest.php b/app/sprinkles/admin/tests/Integration/Controller/ActivityControllerTest.php
index 933d059d5..5549cb4a1 100644
--- a/app/sprinkles/admin/tests/Integration/Controller/ActivityControllerTest.php
+++ b/app/sprinkles/admin/tests/Integration/Controller/ActivityControllerTest.php
@@ -12,15 +12,31 @@
use UserFrosting\Sprinkle\Account\Tests\withTestUser;
use UserFrosting\Sprinkle\Admin\Controller\ActivityController;
-use UserFrosting\Sprinkle\Core\Tests\ControllerTestCase;
+use UserFrosting\Sprinkle\Core\Tests\RefreshDatabase;
+use UserFrosting\Sprinkle\Core\Tests\TestDatabase;
+use UserFrosting\Sprinkle\Core\Tests\withController;
use UserFrosting\Support\Exception\ForbiddenException;
+use UserFrosting\Tests\TestCase;
/**
* Tests ActivityController
*/
-class ActivityControllerTest extends ControllerTestCase
+class ActivityControllerTest extends TestCase
{
use withTestUser;
+ use TestDatabase;
+ use RefreshDatabase;
+ use withController;
+
+ /**
+ * Setup test database for controller tests
+ */
+ public function setUp(): void
+ {
+ parent::setUp();
+ $this->setupTestDatabase();
+ $this->refreshDatabase();
+ }
/**
* @return ActivityController
diff --git a/app/sprinkles/admin/tests/Integration/Controller/AdminControllerTest.php b/app/sprinkles/admin/tests/Integration/Controller/AdminControllerTest.php
index f681a1be5..cbe806974 100644
--- a/app/sprinkles/admin/tests/Integration/Controller/AdminControllerTest.php
+++ b/app/sprinkles/admin/tests/Integration/Controller/AdminControllerTest.php
@@ -12,15 +12,31 @@
use UserFrosting\Sprinkle\Account\Tests\withTestUser;
use UserFrosting\Sprinkle\Admin\Controller\AdminController;
-use UserFrosting\Sprinkle\Core\Tests\ControllerTestCase;
+use UserFrosting\Sprinkle\Core\Tests\RefreshDatabase;
+use UserFrosting\Sprinkle\Core\Tests\TestDatabase;
+use UserFrosting\Sprinkle\Core\Tests\withController;
use UserFrosting\Support\Exception\ForbiddenException;
+use UserFrosting\Tests\TestCase;
/**
* Tests CoreController
*/
-class AdminControllerTest extends ControllerTestCase
+class AdminControllerTest extends TestCase
{
use withTestUser;
+ use TestDatabase;
+ use RefreshDatabase;
+ use withController;
+
+ /**
+ * Setup test database for controller tests
+ */
+ public function setUp(): void
+ {
+ parent::setUp();
+ $this->setupTestDatabase();
+ $this->refreshDatabase();
+ }
/**
* @return AdminController
diff --git a/app/sprinkles/admin/tests/Integration/Controller/RoleControllerTest.php b/app/sprinkles/admin/tests/Integration/Controller/RoleControllerTest.php
index a9e455907..bef5eacd5 100644
--- a/app/sprinkles/admin/tests/Integration/Controller/RoleControllerTest.php
+++ b/app/sprinkles/admin/tests/Integration/Controller/RoleControllerTest.php
@@ -807,7 +807,7 @@ public function testupdateFieldNoValue(RoleController $controller)
*/
public function testupdateFieldWithFailedValidation(RoleController $controller)
{
- // Create a string wich will be too long for validation
+ // Create a string which will be too long for validation
$faker = Faker::getGenerator();
$value = $faker->text(500);
@@ -843,7 +843,7 @@ public function testupdateFieldWithPermissionField(RoleController $controller)
];
$request = $this->getRequest()->withParsedBody($data);
- // Check the default role has how many permisions
+ // Check the default role has how many permissions
$role = Role::where('slug', 'foo')->first();
$this->assertEmpty($role->permissions);
@@ -853,7 +853,7 @@ public function testupdateFieldWithPermissionField(RoleController $controller)
$this->assertJson((string) $result->getBody());
$this->assertSame('[]', (string) $result->getBody());
- // Make sure role permisions was updated
+ // Make sure role permissions was updated
$role = Role::where('slug', 'foo')->first();
$this->assertCount(1, $role->permissions);
diff --git a/app/sprinkles/admin/tests/Integration/Controller/UserControllerTest.php b/app/sprinkles/admin/tests/Integration/Controller/UserControllerTest.php
index d47573416..bd9edaa69 100644
--- a/app/sprinkles/admin/tests/Integration/Controller/UserControllerTest.php
+++ b/app/sprinkles/admin/tests/Integration/Controller/UserControllerTest.php
@@ -821,41 +821,6 @@ public function testUpdateField(UserController $controller)
$this->assertSame('success', end($messages)['type']);
}
- /**
- * @depends testControllerConstructorWithUser
- * @depends testUpdateField
- * @param UserController $controller
- */
- public function testUpdateFieldWithDeprecatedSupport(UserController $controller)
- {
- // Create a user
- $user = $this->createTestUser();
-
- // Set post data
- $data = [
- 'value' => 'deprecated', //<-- Use old `value`
- ];
- $request = $this->getRequest()->withParsedBody($data);
-
- // Get controller stuff
- $result = $controller->updateField($request, $this->getResponse(), ['user_name' => $user->user_name, 'field' => 'first_name']);
- $this->assertSame($result->getStatusCode(), 200);
- $this->assertJson((string) $result->getBody());
- $this->assertSame('[]', (string) $result->getBody());
-
- // Make sure user was update
- $editedUser = User::where('user_name', $user->user_name)->first();
- $this->assertSame('deprecated', $editedUser->first_name);
- $this->assertNotSame($user->first_name, $editedUser->first_name);
- $this->assertSame($user->last_name, $editedUser->last_name);
-
- // Test message
- /** @var \UserFrosting\Sprinkle\Core\Alert\AlertStream $ms */
- $ms = $this->ci->alerts;
- $messages = $ms->getAndClearMessages();
- $this->assertSame('success', end($messages)['type']);
- }
-
/**
* @depends testControllerConstructorWithUser
* @depends testUpdateField
diff --git a/app/sprinkles/core/assets/userfrosting/js/attrchange.js b/app/sprinkles/core/assets/userfrosting/js/attrchange.js
index 00878d30c..6cae77baa 100644
--- a/app/sprinkles/core/assets/userfrosting/js/attrchange.js
+++ b/app/sprinkles/core/assets/userfrosting/js/attrchange.js
@@ -4,7 +4,7 @@ http://meetselva.github.io/attrchange/
About License:
Copyright (C) 2013-2014 Selvakumar Arumugam
-You may use attrchange plugin under the terms of the MIT Licese.
+You may use attrchange plugin under the terms of the MIT License.
https://github.com/meetselva/attrchange/blob/master/MIT-License.txt
*/
(function($) {
diff --git a/app/sprinkles/core/assets/userfrosting/js/uf-alerts.js b/app/sprinkles/core/assets/userfrosting/js/uf-alerts.js
index 06a889c6a..b72931a9e 100644
--- a/app/sprinkles/core/assets/userfrosting/js/uf-alerts.js
+++ b/app/sprinkles/core/assets/userfrosting/js/uf-alerts.js
@@ -260,9 +260,9 @@
$.fn[pluginName] = function(methodOrOptions) {
// Grab plugin instance
var instance = $(this).data(pluginName);
- // If undefined or object, initalise plugin.
+ // If undefined or object, initialize plugin.
if (methodOrOptions === undefined || typeof methodOrOptions === 'object') {
- // Only initalise if not previously done.
+ // Only initialize if not previously done.
if (!instance) {
$(this).data(pluginName, new Plugin(this, methodOrOptions));
}
diff --git a/app/sprinkles/core/assets/userfrosting/js/uf-collection.js b/app/sprinkles/core/assets/userfrosting/js/uf-collection.js
index 94ea416b1..0bf1874ec 100644
--- a/app/sprinkles/core/assets/userfrosting/js/uf-collection.js
+++ b/app/sprinkles/core/assets/userfrosting/js/uf-collection.js
@@ -320,9 +320,9 @@
$.fn[pluginName] = function(methodOrOptions) {
// Grab plugin instance
var instance = $(this).data(pluginName);
- // If undefined or object, initalise plugin.
+ // If undefined or object, initialize plugin.
if (methodOrOptions === undefined || typeof methodOrOptions === 'object') {
- // Only initalise if not previously done.
+ // Only initialize if not previously done.
if (!instance) {
$(this).data(pluginName, new Plugin(this, methodOrOptions));
}
diff --git a/app/sprinkles/core/assets/userfrosting/js/uf-form.js b/app/sprinkles/core/assets/userfrosting/js/uf-form.js
index d77b02b37..e944fd371 100644
--- a/app/sprinkles/core/assets/userfrosting/js/uf-form.js
+++ b/app/sprinkles/core/assets/userfrosting/js/uf-form.js
@@ -406,9 +406,9 @@
$.fn[pluginName] = function (methodOrOptions) {
// Grab plugin instance
var instance = $(this).data(pluginName);
- // If undefined or object, initalise plugin.
+ // If undefined or object, initialize plugin.
if (methodOrOptions === undefined || typeof methodOrOptions === 'object') {
- // Only initalise if not previously done.
+ // Only initialize if not previously done.
if (!instance) {
$(this).data(pluginName, new Plugin(this, methodOrOptions));
}
diff --git a/app/sprinkles/core/assets/userfrosting/js/uf-modal.js b/app/sprinkles/core/assets/userfrosting/js/uf-modal.js
index b84a59a21..919864226 100644
--- a/app/sprinkles/core/assets/userfrosting/js/uf-modal.js
+++ b/app/sprinkles/core/assets/userfrosting/js/uf-modal.js
@@ -38,7 +38,7 @@
return this;
};
- /** #### INITIALISER #### */
+ /** #### INITIALIZER #### */
Plugin.prototype._init = function ( target )
{
var base = this;
@@ -171,7 +171,7 @@
return instance[ methodOrOptions ]( Array.prototype.slice.call( arguments, 1 ) );
- // CASE: argument is options object or empty = initialise
+ // CASE: argument is options object or empty = initialize
} else if ( typeof methodOrOptions === 'object' || ! methodOrOptions ) {
instance = new Plugin( $(this), methodOrOptions ); // ok to overwrite if this is a re-init
@@ -180,7 +180,7 @@
// CASE: method called before init
} else if ( !instance ) {
- console.warn( 'Plugin must be initialised before using method: ' + methodOrOptions );
+ console.warn( 'Plugin must be initialized before using method: ' + methodOrOptions );
// CASE: invalid method
} else if ( methodOrOptions.indexOf('_') == 0 ) {
diff --git a/app/sprinkles/core/assets/userfrosting/js/uf-table.js b/app/sprinkles/core/assets/userfrosting/js/uf-table.js
index 74af41e22..4c8ad46c9 100644
--- a/app/sprinkles/core/assets/userfrosting/js/uf-table.js
+++ b/app/sprinkles/core/assets/userfrosting/js/uf-table.js
@@ -122,7 +122,7 @@
'.filter-select' : function() { return null; }
},
- // apply disabled classname to the pager arrows when the rows at either extreme is visible
+ // apply disabled class name to the pager arrows when the rows at either extreme is visible
pager_updateArrows: true,
// starting page of the pager (zero based index)
@@ -690,9 +690,9 @@
$.fn[pluginName] = function(methodOrOptions) {
// Grab plugin instance
var instance = $(this).data(pluginName);
- // If undefined or object, initalise plugin.
+ // If undefined or object, initialize plugin.
if (methodOrOptions === undefined || typeof methodOrOptions === 'object') {
- // Only initalise if not previously done.
+ // Only initialize if not previously done.
if (!instance) {
$(this).data(pluginName, new Plugin(this, methodOrOptions));
}
diff --git a/app/sprinkles/core/composer.json b/app/sprinkles/core/composer.json
index 886617949..b8f821b55 100644
--- a/app/sprinkles/core/composer.json
+++ b/app/sprinkles/core/composer.json
@@ -17,7 +17,7 @@
{
"name": "Jordan Mele",
"email": "SiliconSoldier@outlook.com.au",
- "homepage": "https://blog.djmm.me"
+ "homepage": "https://djmm.me"
},
{
"name": "Mike Jacobs"
@@ -27,6 +27,7 @@
}
],
"require": {
+ "composer/semver": "^3.2.4",
"doctrine/dbal": "^2.5",
"filp/whoops": "^2.3.1",
"illuminate/cache": "5.8.*",
@@ -44,15 +45,18 @@
"slim/twig-view": "^2.5",
"symfony/http-foundation": "*",
"twig/twig": "^2.11",
- "userfrosting/assets": "^6.1.0",
- "userfrosting/config": "~4.4.0",
- "userfrosting/cache": "~4.4.0",
- "userfrosting/fortress": "~4.4.0",
- "userfrosting/i18n": "~4.4.0",
- "userfrosting/session": "~4.4.0",
- "userfrosting/support": "~4.4.0",
+ "userfrosting/assets": "^6.2.0",
+ "userfrosting/config": "~4.5.0",
+ "userfrosting/cache": "~4.5.0",
+ "userfrosting/fortress": "~4.5.0",
+ "userfrosting/i18n": "~4.5.0",
+ "userfrosting/session": "~4.5.0",
+ "userfrosting/support": "~4.5.0",
"vlucas/phpdotenv": "^3.4.0"
},
+ "require-dev": {
+ "php-mock/php-mock-phpunit": "^2.6"
+ },
"autoload": {
"files" : [
"defines.php"
diff --git a/app/sprinkles/core/config/default.php b/app/sprinkles/core/config/default.php
index adab1bb51..3dcb79835 100755
--- a/app/sprinkles/core/config/default.php
+++ b/app/sprinkles/core/config/default.php
@@ -25,7 +25,7 @@
*/
'address_book' => [
'admin' => [
- 'email' => getenv('SMTP_USER') ?: null,
+ 'email' => env('SMTP_USER'),
'name' => 'Site Administrator',
],
],
@@ -97,7 +97,7 @@
* Note : CSRF Middleware should only be disabled for dev or debug purposes.
*/
'csrf' => [
- 'enabled' => (getenv('CSRF_ENABLED') !== false) ? getenv('CSRF_ENABLED') : true,
+ 'enabled' => env('CSRF_ENABLED', true),
'name' => 'csrf',
'storage_limit' => 200,
'strength' => 16,
@@ -124,12 +124,12 @@
*/
'db' => [
'default' => [
- 'driver' => getenv('DB_DRIVER') ?: 'mysql',
- 'host' => getenv('DB_HOST') ?: 'localhost',
- 'port' => getenv('DB_PORT') ?: null,
- 'database' => getenv('DB_NAME') ?: null,
- 'username' => getenv('DB_USER') ?: null,
- 'password' => getenv('DB_PASSWORD') ?: null,
+ 'driver' => env('DB_DRIVER', 'mysql'),
+ 'host' => env('DB_HOST', 'localhost'),
+ 'port' => env('DB_PORT'),
+ 'database' => env('DB_NAME'),
+ 'username' => env('DB_USER'),
+ 'password' => env('DB_PASSWORD'),
'charset' => 'utf8',
'collation' => 'utf8_unicode_ci',
'prefix' => '',
@@ -160,8 +160,8 @@
* Supported Drivers for disk: "local", "ftp", "sftp", "s3", "rackspace"
*/
'filesystems' => [
- 'default' => getenv('FILESYSTEM_DRIVER') ?: 'local',
- 'cloud' => getenv('FILESYSTEM_CLOUD') ?: 's3',
+ 'default' => env('FILESYSTEM_DRIVER', 'local'),
+ 'cloud' => env('FILESYSTEM_CLOUD', 's3'),
'disks' => [
/*
@@ -196,11 +196,11 @@
*/
's3' => [
'driver' => 's3',
- 'key' => getenv('AWS_ACCESS_KEY_ID') ?: '',
- 'secret' => getenv('AWS_SECRET_ACCESS_KEY') ?: '',
- 'region' => getenv('AWS_DEFAULT_REGION') ?: '', // See : http://docs.aws.amazon.com/general/latest/gr/rande.html
- 'bucket' => getenv('AWS_BUCKET') ?: '',
- 'url' => getenv('AWS_URL') ?: '',
+ 'key' => env('AWS_ACCESS_KEY_ID', ''),
+ 'secret' => env('AWS_SECRET_ACCESS_KEY', ''),
+ 'region' => env('AWS_DEFAULT_REGION', ''), // See : http://docs.aws.amazon.com/general/latest/gr/rande.html
+ 'bucket' => env('AWS_BUCKET', ''),
+ 'url' => env('AWS_URL', ''),
],
/*
* Rackspace Config. Config should go in .env file. see :
@@ -213,12 +213,12 @@
*/
'rackspace' => [
'driver' => 'rackspace',
- 'username' => getenv('RACKSPACE_USERNAME') ?: '',
- 'key' => getenv('RACKSPACE_KEY') ?: '',
- 'container' => getenv('RACKSPACE_CONTAINER') ?: '',
- 'endpoint' => getenv('RACKSPACE_ENDPOINT') ?: '',
- 'region' => getenv('RACKSPACE_REGION') ?: '',
- 'url_type' => getenv('RACKSPACE_URL_TYPE') ?: '',
+ 'username' => env('RACKSPACE_USERNAME', ''),
+ 'key' => env('RACKSPACE_KEY', ''),
+ 'container' => env('RACKSPACE_CONTAINER', ''),
+ 'endpoint' => env('RACKSPACE_ENDPOINT', ''),
+ 'region' => env('RACKSPACE_REGION', ''),
+ 'url_type' => env('RACKSPACE_URL_TYPE', ''),
],
],
],
@@ -230,13 +230,13 @@
* See https://learn.userfrosting.com/mail/the-mailer-service
*/
'mail' => [
- 'mailer' => 'smtp', // Set to one of 'smtp', 'mail', 'qmail', 'sendmail'
- 'host' => getenv('SMTP_HOST') ?: null,
- 'port' => 587,
- 'auth' => true,
- 'secure' => 'tls', // Enable TLS encryption. Set to `tls`, `ssl` or `false` (to disabled)
- 'username' => getenv('SMTP_USER') ?: null,
- 'password' => getenv('SMTP_PASSWORD') ?: null,
+ 'mailer' => env('MAIL_MAILER', 'smtp'), // Set to one of 'smtp', 'mail', 'qmail', 'sendmail'
+ 'host' => env('SMTP_HOST'),
+ 'port' => env('SMTP_PORT', 587),
+ 'auth' => env('SMTP_AUTH', true),
+ 'secure' => env('SMTP_SECURE', 'tls'), // Enable TLS encryption. Set to `tls`, `ssl` or `false` (to disabled)
+ 'username' => env('SMTP_USER'),
+ 'password' => env('SMTP_PASSWORD'),
'smtp_debug' => 4,
'message_options' => [
'CharSet' => 'UTF-8',
diff --git a/app/sprinkles/core/config/testing.php b/app/sprinkles/core/config/testing.php
index 38a87253f..6d1231f88 100755
--- a/app/sprinkles/core/config/testing.php
+++ b/app/sprinkles/core/config/testing.php
@@ -61,12 +61,12 @@
* Disable native sessions in tests
*/
'session' => [
- 'handler' => getenv('TEST_SESSION_HANDLER') ?: 'array',
+ 'handler' => env('TEST_SESSION_HANDLER', 'array'),
],
/*
* Database to use when using the TestDatabase Trait
*/
'testing' => [
- 'dbConnection' => getenv('TEST_DB') ?: 'test_integration',
+ 'dbConnection' => env('TEST_DB', 'test_integration'),
],
];
diff --git a/app/sprinkles/core/src/Bakery/BakeCommand.php b/app/sprinkles/core/src/Bakery/BakeCommand.php
index e1c42c416..89242df65 100644
--- a/app/sprinkles/core/src/Bakery/BakeCommand.php
+++ b/app/sprinkles/core/src/Bakery/BakeCommand.php
@@ -42,7 +42,7 @@ protected function configure()
{
$this->setName('bake')
->setDescription('UserFrosting installation command')
- ->setHelp('This command combine the setup:db, setup:smtp, debug, migrate, create-admin and build-assets commands.');
+ ->setHelp('This command combine the setup:db, setup:mail, debug, migrate, create-admin and build-assets commands.');
}
/**
@@ -70,7 +70,7 @@ protected function executeSetup(InputInterface $input, OutputInterface $output)
$command = $this->getApplication()->find('setup:db');
$command->run($input, $output);
- $command = $this->getApplication()->find('setup:smtp');
+ $command = $this->getApplication()->find('setup:mail');
$command->run($input, $output);
}
diff --git a/app/sprinkles/core/src/Bakery/BuildAssets.php b/app/sprinkles/core/src/Bakery/BuildAssets.php
index 358de51cb..c12ce0c26 100644
--- a/app/sprinkles/core/src/Bakery/BuildAssets.php
+++ b/app/sprinkles/core/src/Bakery/BuildAssets.php
@@ -13,7 +13,8 @@
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Output\OutputInterface;
-use UserFrosting\Sprinkle\Core\Bakery\Helper\NodeVersionCheck;
+use UserFrosting\Sprinkle\Core\Exceptions\VersionCompareException;
+use UserFrosting\Sprinkle\Core\Util\VersionValidator;
use UserFrosting\System\Bakery\BaseCommand;
/**
@@ -24,8 +25,6 @@
*/
class BuildAssets extends BaseCommand
{
- use NodeVersionCheck;
-
/**
* @var string Path to the build/ directory
*/
@@ -52,10 +51,15 @@ protected function execute(InputInterface $input, OutputInterface $output)
$this->io->title("UserFrosting's Assets Builder");
// Validate Node and npm version
- $this->checkNodeVersion(false);
- $this->checkNpmVersion(false);
+ try {
+ VersionValidator::validateNodeVersion();
+ VersionValidator::validateNpmVersion();
+ } catch (VersionCompareException $e) {
+ $this->io->error($e->getMessage());
+ exit(1);
+ }
- // Set $buildPath. We'll use the aboslute path for this task
+ // Set $buildPath. We'll use the absolute path for this task
$this->buildPath = \UserFrosting\ROOT_DIR . \UserFrosting\DS . \UserFrosting\BUILD_DIR_NAME;
// Delete cached data is requested
diff --git a/app/sprinkles/core/src/Bakery/ClearCacheCommand.php b/app/sprinkles/core/src/Bakery/ClearCacheCommand.php
index 11221ae21..e695962fa 100644
--- a/app/sprinkles/core/src/Bakery/ClearCacheCommand.php
+++ b/app/sprinkles/core/src/Bakery/ClearCacheCommand.php
@@ -72,7 +72,7 @@ protected function clearIlluminateCache()
/**
* Clear the Twig cache using the Twig CacheHelper class.
*
- * @return bool true/false if operation is successfull
+ * @return bool true/false if operation is successful
*/
protected function clearTwigCache()
{
@@ -84,7 +84,7 @@ protected function clearTwigCache()
/**
* Clear the Router cache data file.
*
- * @return bool true/false if operation is successfull
+ * @return bool true/false if operation is successful
*/
protected function clearRouterCache()
{
diff --git a/app/sprinkles/core/src/Bakery/DebugCommand.php b/app/sprinkles/core/src/Bakery/DebugCommand.php
index 083db3ea2..394c8b74c 100644
--- a/app/sprinkles/core/src/Bakery/DebugCommand.php
+++ b/app/sprinkles/core/src/Bakery/DebugCommand.php
@@ -13,7 +13,8 @@
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use UserFrosting\Sprinkle\Core\Bakery\Helper\DatabaseTest;
-use UserFrosting\Sprinkle\Core\Bakery\Helper\NodeVersionCheck;
+use UserFrosting\Sprinkle\Core\Exceptions\VersionCompareException;
+use UserFrosting\Sprinkle\Core\Util\VersionValidator;
use UserFrosting\System\Bakery\BaseCommand;
/**
@@ -24,7 +25,6 @@
class DebugCommand extends BaseCommand
{
use DatabaseTest;
- use NodeVersionCheck;
/**
* {@inheritdoc}
@@ -45,17 +45,34 @@ protected function execute(InputInterface $input, OutputInterface $output)
$this->io->title('UserFrosting');
// Need to touch the config service first to load dotenv values
- $config = $this->ci->config;
+ $this->ci->config;
+
+ // Validate PHP, Node and npm version
+ try {
+ VersionValidator::validatePhpVersion();
+ VersionValidator::validateNodeVersion();
+ VersionValidator::validateNpmVersion();
+ } catch (VersionCompareException $e) {
+ $this->io->error($e->getMessage());
+ exit(1);
+ }
+
+ // Validate deprecated versions
+ try {
+ VersionValidator::validatePhpDeprecation();
+ } catch (VersionCompareException $e) {
+ $this->io->warning($e->getMessage());
+ }
// Perform tasks & display info
$this->io->definitionList(
- ['UserFrosing version' => \UserFrosting\VERSION],
+ ['UserFrosting version' => \UserFrosting\VERSION],
['OS Name' => php_uname('s')],
['Project Root' => \UserFrosting\ROOT_DIR],
- ['Environment mode' => getenv('UF_MODE')],
- ['PHP Version' => $this->checkPhpVersion()],
- ['Node Version' => $this->checkNodeVersion()],
- ['NPM Version' => $this->checkNpmVersion()]
+ ['Environment mode' => env('UF_MODE', 'default')],
+ ['PHP Version' => VersionValidator::getPhpVersion()],
+ ['Node Version' => VersionValidator::getNodeVersion()],
+ ['NPM Version' => VersionValidator::getNpmVersion()]
);
// Now we list Sprinkles
@@ -64,7 +81,7 @@ protected function execute(InputInterface $input, OutputInterface $output)
// Show the DB config
$this->showConfig();
- // Check database connexion
+ // Check database connection
$this->checkDatabase();
// If all went well and there's no fatal errors, we are ready to bake
@@ -74,29 +91,6 @@ protected function execute(InputInterface $input, OutputInterface $output)
return 0;
}
- /**
- * Check the minimum version of php.
- * This is done by composer itself, but we do it again for good mesure.
- *
- * @return string The current PHP Version
- */
- protected function checkPhpVersion(): string
- {
- $phpVersion = (string) phpversion();
-
- if (version_compare($phpVersion, \UserFrosting\PHP_MIN_VERSION, '<')) {
- $this->io->error('UserFrosting requires php version ' . \UserFrosting\PHP_MIN_VERSION . " or above. You'll need to update you PHP version before you can continue.");
- exit(1);
- }
-
- // Check for deprecated versions
- if (version_compare($phpVersion, \UserFrosting\PHP_RECOMMENDED_VERSION, '<')) {
- $this->io->warning('While your PHP version is still supported by UserFrosting, we recommend version ' . \UserFrosting\PHP_RECOMMENDED_VERSION . ' or above as ' . $phpVersion . ' will soon be unsupported. See http://php.net/supported-versions.php for more info.');
- }
-
- return $phpVersion;
- }
-
/**
* List all sprinkles defined in the Sprinkles schema file,
* making sure this file exist at the same time.
@@ -127,7 +121,7 @@ protected function listSprinkles(InputInterface $input, OutputInterface $output)
}
/**
- * Check the database connexion and setup the `.env` file if we can't
+ * Check the database connection and setup the `.env` file if we can't
* connect and there's no one found.
*/
protected function checkDatabase(): void
diff --git a/app/sprinkles/core/src/Bakery/Helper/DatabaseTest.php b/app/sprinkles/core/src/Bakery/Helper/DatabaseTest.php
index 6d5a73fe0..c5be6fa62 100644
--- a/app/sprinkles/core/src/Bakery/Helper/DatabaseTest.php
+++ b/app/sprinkles/core/src/Bakery/Helper/DatabaseTest.php
@@ -13,14 +13,14 @@
use Illuminate\Database\Capsule\Manager as Capsule;
/**
- * Database Test Trait. Include method to test the db connexion
+ * Database Test Trait. Include method to test the db connection
*
* @author Alex Weissman (https://alexanderweissman.com)
*/
trait DatabaseTest
{
/**
- * Function to test the db connexion.
+ * Function to test the db connection.
*
* @return bool True if success
*/
@@ -32,7 +32,7 @@ protected function testDB()
// Get config
$config = $this->ci->config;
- // Check params are valids
+ // Check params are valid
$dbParams = $config['db.default'];
if (!$dbParams) {
throw new \Exception("'default' database connection not found. Please double-check your configuration.");
diff --git a/app/sprinkles/core/src/Bakery/Helper/LocaleOption.php b/app/sprinkles/core/src/Bakery/Helper/LocaleOption.php
index fa74802ca..8c2a40ebe 100644
--- a/app/sprinkles/core/src/Bakery/Helper/LocaleOption.php
+++ b/app/sprinkles/core/src/Bakery/Helper/LocaleOption.php
@@ -24,7 +24,7 @@ trait LocaleOption
/**
* Display locale selection question.
*
- * @return string Selected locale indentifier
+ * @return string Selected locale identifier
*/
protected function askForLocale(string $name, bool $default = true): string
{
diff --git a/app/sprinkles/core/src/Bakery/Helper/NodeVersionCheck.php b/app/sprinkles/core/src/Bakery/Helper/NodeVersionCheck.php
deleted file mode 100644
index 07f0f860c..000000000
--- a/app/sprinkles/core/src/Bakery/Helper/NodeVersionCheck.php
+++ /dev/null
@@ -1,53 +0,0 @@
-io->error('UserFrosting requires Node version ' . \UserFrosting\NODE_MIN_VERSION . ' or above. Check the documentation for more details.');
- exit(1);
- }
-
- return $npmVersion;
- }
-
- /**
- * Check the minimum version requirement for Npm.
- *
- * @return string NPM version
- */
- protected function checkNpmVersion()
- {
- $npmVersion = trim(exec('npm -v'));
-
- if (version_compare($npmVersion, \UserFrosting\NPM_MIN_VERSION, '<')) {
- $this->io->error('UserFrosting requires npm version ' . \UserFrosting\NPM_MIN_VERSION . ' or above. Check the documentation for more details.');
- exit(1);
- }
-
- return $npmVersion;
- }
-}
diff --git a/app/sprinkles/core/src/Bakery/LocaleCompareCommand.php b/app/sprinkles/core/src/Bakery/LocaleCompareCommand.php
index 75289b79d..a721e4248 100644
--- a/app/sprinkles/core/src/Bakery/LocaleCompareCommand.php
+++ b/app/sprinkles/core/src/Bakery/LocaleCompareCommand.php
@@ -72,14 +72,14 @@ protected function execute(InputInterface $input, OutputInterface $output)
}
/**
- * Display dictionary comparaison table.
+ * Display dictionary comparison table.
*
* @param DictionaryInterface $leftDictionary
* @param DictionaryInterface $rightDictionary
*/
protected function compareDictionaries(DictionaryInterface $leftDictionary, DictionaryInterface $rightDictionary): void
{
- $this->io->section("Comparaison between {$rightDictionary->getLocale()->getName()} and {$leftDictionary->getLocale()->getName()}");
+ $this->io->section("Comparison between {$rightDictionary->getLocale()->getName()} and {$leftDictionary->getLocale()->getName()}");
$diff = Compare::dictionaries($leftDictionary, $rightDictionary);
@@ -104,7 +104,7 @@ protected function compareDictionaries(DictionaryInterface $leftDictionary, Dict
}
/**
- * Display dictionary keys comparaison table.
+ * Display dictionary keys comparison table.
*
* @param DictionaryInterface $leftDictionary
* @param DictionaryInterface $rightDictionary
@@ -135,7 +135,7 @@ protected function dictionariesKeys(DictionaryInterface $leftDictionary, Diction
}
/**
- * Display dictionary values comparaison table.
+ * Display dictionary values comparison table.
*
* @param DictionaryInterface $leftDictionary
* @param DictionaryInterface $rightDictionary
diff --git a/app/sprinkles/core/src/Bakery/LocaleDictionaryCommand.php b/app/sprinkles/core/src/Bakery/LocaleDictionaryCommand.php
index f0a9a5337..cf52f787d 100644
--- a/app/sprinkles/core/src/Bakery/LocaleDictionaryCommand.php
+++ b/app/sprinkles/core/src/Bakery/LocaleDictionaryCommand.php
@@ -34,7 +34,7 @@ class LocaleDictionaryCommand extends BaseCommand
protected function configure()
{
$this->setName('locale:dictionary')
- ->setHelp('This command shows the compiled dictionnary for the selected locale.')
+ ->setHelp('This command shows the compiled dictionary for the selected locale.')
->addOption('locale', 'l', InputOption::VALUE_REQUIRED, 'The selected locale.')
->addOption('width', 'w', InputOption::VALUE_REQUIRED, 'Set the length for preview column text.', 100)
->setDescription('Display locale dictionary');
diff --git a/app/sprinkles/core/src/Bakery/LocaleInfoCommand.php b/app/sprinkles/core/src/Bakery/LocaleInfoCommand.php
index c9991d493..de5c1c127 100644
--- a/app/sprinkles/core/src/Bakery/LocaleInfoCommand.php
+++ b/app/sprinkles/core/src/Bakery/LocaleInfoCommand.php
@@ -29,8 +29,8 @@ class LocaleInfoCommand extends BaseCommand
protected function configure()
{
$this->setName('locale:info')
- ->setHelp('This command list all available locale as well as the defaut locale.')
- ->setDescription('Informations about available locales');
+ ->setHelp('This command list all available locale as well as the default locale.')
+ ->setDescription('Information about available locales');
}
/**
diff --git a/app/sprinkles/core/src/Bakery/MigrateCleanCommand.php b/app/sprinkles/core/src/Bakery/MigrateCleanCommand.php
index 13b371612..b94fb50d4 100644
--- a/app/sprinkles/core/src/Bakery/MigrateCleanCommand.php
+++ b/app/sprinkles/core/src/Bakery/MigrateCleanCommand.php
@@ -81,7 +81,7 @@ protected function execute(InputInterface $input, OutputInterface $output)
/**
* Delete stale migrations from the database.
*
- * @param Collection $stale Collection of stale migartion classes.
+ * @param Collection $stale Collection of stale migration classes.
* @param Migrator $migrator Migrator object
*/
protected function cleanStaleRecords(Collection $stale, Migrator $migrator)
diff --git a/app/sprinkles/core/src/Bakery/MigrateResetCommand.php b/app/sprinkles/core/src/Bakery/MigrateResetCommand.php
index 5a52b5dfa..c83027199 100644
--- a/app/sprinkles/core/src/Bakery/MigrateResetCommand.php
+++ b/app/sprinkles/core/src/Bakery/MigrateResetCommand.php
@@ -104,7 +104,7 @@ protected function performReset(InputInterface $input)
// If all went well, there's no fatal errors and we have migrated
// something, show some success
if (empty($resetted)) {
- $this->io->warning('Nothing was reseted !');
+ $this->io->warning('Nothing was reset !');
} else {
$this->io->success('Reset successful !');
}
@@ -127,7 +127,7 @@ protected function performHardReset(InputInterface $input)
exit(1);
}
- // Get shema Builder
+ // Get schema Builder
$connection = $this->ci->db->connection($database);
$schema = $connection->getSchemaBuilder();
diff --git a/app/sprinkles/core/src/Bakery/MigrateRollbackCommand.php b/app/sprinkles/core/src/Bakery/MigrateRollbackCommand.php
index 4c1c64e77..ec5414073 100644
--- a/app/sprinkles/core/src/Bakery/MigrateRollbackCommand.php
+++ b/app/sprinkles/core/src/Bakery/MigrateRollbackCommand.php
@@ -91,7 +91,7 @@ protected function execute(InputInterface $input, OutputInterface $output)
// If all went well, there's no fatal errors and we have migrated
// something, show some success
if (empty($migrated)) {
- $this->io->warning('Nothing was rollbacked !');
+ $this->io->warning('Nothing was rolled back !');
} else {
$this->io->success('Rollback successful !');
}
diff --git a/app/sprinkles/core/src/Bakery/SeedCommand.php b/app/sprinkles/core/src/Bakery/SeedCommand.php
index dffe4df39..e8a861a06 100644
--- a/app/sprinkles/core/src/Bakery/SeedCommand.php
+++ b/app/sprinkles/core/src/Bakery/SeedCommand.php
@@ -61,7 +61,7 @@ protected function execute(InputInterface $input, OutputInterface $output)
// Seeds list
$seeds = [];
- // Start by gettings seeds
+ // Start by getting seeds
foreach ($classes as $className) {
// Get seed class and
diff --git a/app/sprinkles/core/src/Bakery/SetupCommand.php b/app/sprinkles/core/src/Bakery/SetupCommand.php
index 411e1bf7b..6d0ac9afe 100644
--- a/app/sprinkles/core/src/Bakery/SetupCommand.php
+++ b/app/sprinkles/core/src/Bakery/SetupCommand.php
@@ -29,7 +29,7 @@ protected function configure()
{
$this->setName('setup')
->setDescription('UserFrosting Configuration Wizard')
- ->setHelp('This command combine the setup:env, setup:db and setup:smtp commands.');
+ ->setHelp('This command combine the setup:env, setup:db and setup:mail commands.');
}
/**
@@ -40,7 +40,7 @@ protected function execute(InputInterface $input, OutputInterface $output)
$command = $this->getApplication()->find('setup:db');
$command->run($input, $output);
- $command = $this->getApplication()->find('setup:smtp');
+ $command = $this->getApplication()->find('setup:mail');
$command->run($input, $output);
$command = $this->getApplication()->find('setup:env');
diff --git a/app/sprinkles/core/src/Bakery/SetupDbCommand.php b/app/sprinkles/core/src/Bakery/SetupDbCommand.php
index b405e2e3d..c96364328 100644
--- a/app/sprinkles/core/src/Bakery/SetupDbCommand.php
+++ b/app/sprinkles/core/src/Bakery/SetupDbCommand.php
@@ -136,11 +136,11 @@ protected function execute(InputInterface $input, OutputInterface $output)
}
/**
- * Ask for database crendentials.
+ * Ask for database credentials.
*
* @param InputInterface $args Command arguments
*
- * @return array The databse credentials
+ * @return array The database credentials
*/
protected function askForDatabase(InputInterface $args)
{
@@ -201,7 +201,7 @@ protected function askForDatabase(InputInterface $args)
}
/**
- * Test new database connecion.
+ * Test new database connection.
*
* @param array $dbParams Database params
* @param bool $displayMessage Display io message
@@ -214,7 +214,7 @@ protected function testDatabase($dbParams, $displayMessage = true)
$capsule = new Capsule();
$capsule->addConnection($dbParams);
- // Test the db connexion.
+ // Test the db connection.
try {
$conn = $capsule->getConnection();
$conn->getPdo();
diff --git a/app/sprinkles/core/src/Bakery/SetupEnvCommand.php b/app/sprinkles/core/src/Bakery/SetupEnvCommand.php
index e7beb28d7..877c6fb45 100644
--- a/app/sprinkles/core/src/Bakery/SetupEnvCommand.php
+++ b/app/sprinkles/core/src/Bakery/SetupEnvCommand.php
@@ -41,7 +41,7 @@ protected function configure()
{
$this->setName('setup:env')
->setDescription('UserFrosting Environment Configuration Wizard')
- ->setHelp('Helper command to setup environement mode. This can also be done manually by editing the app/.env file or using global server environment variables.')
+ ->setHelp('Helper command to setup environment mode. This can also be done manually by editing the app/.env file or using global server environment variables.')
->addOption('mode', null, InputOption::VALUE_OPTIONAL, 'The environment to use');
}
@@ -53,7 +53,7 @@ protected function execute(InputInterface $input, OutputInterface $output)
// Display header,
$this->io->title("UserFrosting's Environment Setup Wizard");
$this->io->note("Environment mode will be saved in `{$this->envPath}`");
- $this->io->write('Select desired envrionement mode. Production should only be used when deploying a live app.');
+ $this->io->write('Select desired environment mode. Production should only be used when deploying a live app.');
// Get an instance of the DotenvEditor
$dotenvEditor = new DotenvEditor(\UserFrosting\APP_DIR, false);
diff --git a/app/sprinkles/core/src/Bakery/SetupSmtpCommand.php b/app/sprinkles/core/src/Bakery/SetupSmtpCommand.php
index 938c1b8ae..ef418a5b3 100644
--- a/app/sprinkles/core/src/Bakery/SetupSmtpCommand.php
+++ b/app/sprinkles/core/src/Bakery/SetupSmtpCommand.php
@@ -40,6 +40,11 @@ class SetupSmtpCommand extends BaseCommand
*/
const Setup_Gmail = 'Gmail';
+ /**
+ * @var string Native mail setup string
+ */
+ const Setup_Native = 'Native Mail';
+
/**
* @var string No email setup string
*/
@@ -50,13 +55,17 @@ class SetupSmtpCommand extends BaseCommand
*/
protected function configure()
{
- $this->setName('setup:smtp')
+ $this->setName('setup:mail')
+ ->setAliases(['setup:smtp'])
->setDescription('UserFrosting SMTP Configuration Wizard')
->setHelp('Helper command to setup outgoing email configuration. This can also be done manually by editing the app/.env file or using global server environment variables.')
->addOption('force', null, InputOption::VALUE_NONE, 'Force setup if SMTP appears to be already configured')
->addOption('smtp_host', null, InputOption::VALUE_OPTIONAL, 'The SMTP server hostname')
->addOption('smtp_user', null, InputOption::VALUE_OPTIONAL, 'The SMTP server user')
- ->addOption('smtp_password', null, InputOption::VALUE_OPTIONAL, 'The SMTP server password');
+ ->addOption('smtp_password', null, InputOption::VALUE_OPTIONAL, 'The SMTP server password')
+ ->addOption('smtp_port', null, InputOption::VALUE_OPTIONAL, 'The SMTP server port')
+ ->addOption('smtp_auth', null, InputOption::VALUE_OPTIONAL, 'The SMTP server authentication')
+ ->addOption('smtp_secure', null, InputOption::VALUE_OPTIONAL, 'The SMTP server security type');
}
/**
@@ -70,7 +79,7 @@ protected function execute(InputInterface $input, OutputInterface $output)
$config = $this->ci->config;
// Display header,
- $this->io->title("UserFrosting's SMTP Setup Wizard");
+ $this->io->title("UserFrosting's Mail Setup Wizard");
// Get an instance of the DotenvEditor
$dotenvEditor = new DotenvEditor(\UserFrosting\APP_DIR, false);
@@ -79,34 +88,43 @@ protected function execute(InputInterface $input, OutputInterface $output)
// Check if db is already setup
if (!$input->getOption('force') && $this->isSmtpConfigured($dotenvEditor)) {
- $this->io->note('SMTP already setup. Use the `php bakery setup:smtp --force` command to run SMTP setup again.');
+ $this->io->note('Mail is already setup. Use the `php bakery setup:mail --force` command to run setup again.');
return;
}
// Get keys
$keys = [
+ 'MAIL_MAILER' => ($dotenvEditor->keyExists('MAIL_MAILER')) ? $dotenvEditor->getValue('MAIL_MAILER') : '',
'SMTP_HOST' => ($dotenvEditor->keyExists('SMTP_HOST')) ? $dotenvEditor->getValue('SMTP_HOST') : '',
'SMTP_USER' => ($dotenvEditor->keyExists('SMTP_USER')) ? $dotenvEditor->getValue('SMTP_USER') : '',
'SMTP_PASSWORD' => ($dotenvEditor->keyExists('SMTP_PASSWORD')) ? $dotenvEditor->getValue('SMTP_PASSWORD') : '',
+ 'SMTP_PORT' => ($dotenvEditor->keyExists('SMTP_PORT')) ? $dotenvEditor->getValue('SMTP_PORT') : '',
+ 'SMTP_AUTH' => ($dotenvEditor->keyExists('SMTP_AUTH')) ? $dotenvEditor->getValue('SMTP_AUTH') : '',
+ 'SMTP_SECURE' => ($dotenvEditor->keyExists('SMTP_SECURE')) ? $dotenvEditor->getValue('SMTP_SECURE') : '',
];
// There may be some custom config or global env values defined on the server.
// We'll check for that and ask for confirmation in this case.
- if ($config['mail.host'] != $keys['SMTP_HOST'] ||
+ if ($config['mail.mailer'] != $keys['MAIL_MAILER'] ||
+ $config['mail.host'] != $keys['SMTP_HOST'] ||
$config['mail.username'] != $keys['SMTP_USER'] ||
- $config['mail.password'] != $keys['SMTP_PASSWORD']) {
- $this->io->warning("Current SMTP configuration differ from the configuration defined in `{$this->envPath}`. Global system environment variables might be defined.");
-
- if (!$this->io->confirm('Continue?', false)) {
+ $config['mail.password'] != $keys['SMTP_PASSWORD'] ||
+ $config['mail.port'] != $keys['SMTP_PORT'] ||
+ $config['mail.auth'] != $keys['SMTP_AUTH'] ||
+ $config['mail.secure'] != $keys['SMTP_SECURE']
+ ) {
+ $this->io->warning("Current mail configuration from config service differ from the configuration defined in `{$this->envPath}`. Global system environment variables might be defined, and it might not be required to setup mail again.");
+
+ if (!$this->io->confirm('Continue with mail setup?', false)) {
return;
}
}
- $this->io->note("SMTP credentials will be saved in `{$this->envPath}`");
+ $this->io->note("Mail configuration and SMTP credentials will be saved in `{$this->envPath}`");
// Ask for SMTP info
- $smtpParams = $this->askForSmtpMethod($input);
+ $smtpParams = $this->askForMailMethod($input);
// Time to save
$this->io->section('Saving data');
@@ -117,7 +135,7 @@ protected function execute(InputInterface $input, OutputInterface $output)
$dotenvEditor->save();
// Success
- $this->io->success("SMTP credentials saved to `{$this->envPath}`");
+ $this->io->success("Mail configuration saved to `{$this->envPath}`.\nYou can test outgoing mail using `test:mail` command.");
}
/**
@@ -127,17 +145,23 @@ protected function execute(InputInterface $input, OutputInterface $output)
*
* @return array The SMTP connection info
*/
- protected function askForSmtpMethod(InputInterface $input)
+ protected function askForMailMethod(InputInterface $input)
{
// If the user defined any of the command input argument, skip right to SMTP method
- if ($input->getOption('smtp_host') || $input->getOption('smtp_user') || $input->getOption('smtp_password')) {
+ if ($input->getOption('smtp_host') ||
+ $input->getOption('smtp_user') ||
+ $input->getOption('smtp_password') ||
+ $input->getOption('smtp_port') ||
+ $input->getOption('smtp_auth') ||
+ $input->getOption('smtp_secure')
+ ) {
return $this->askForSmtp($input);
}
- // Display nice explanation and ask wich method to use
- $this->io->write("In order to send registration emails, UserFrosting requires an outgoing mail server. When using UserFrosting in a production environment, a SMTP server should be used. A Gmail account can be used if you're only playing with UserFrosting or on a local dev environment. You can also choose to not setup an outgoing mail server at the moment, but account registration won't work. You can always re-run this setup or edit `{$this->envPath}` if you have problems sending email later.");
+ // Display nice explanation and ask which method to use
+ $this->io->write("In order to send registration emails, UserFrosting requires an outgoing mail server. When using UserFrosting in a production environment, a SMTP server should be used. A Gmail account or native mail command can be used if you're only playing with UserFrosting or on a local dev environment. You can also choose to not setup an outgoing mail server at the moment, but account registration won't work. You can always re-run this setup or edit `{$this->envPath}` if you have problems sending email later.");
- $choice = $this->io->choice('Select setup method', [self::Setup_SMTP, self::Setup_Gmail, self::Setup_None], self::Setup_SMTP);
+ $choice = $this->io->choice('Select setup method', [self::Setup_SMTP, self::Setup_Gmail, self::Setup_Native, self::Setup_None], self::Setup_SMTP);
switch ($choice) {
case self::Setup_SMTP:
@@ -146,6 +170,9 @@ protected function askForSmtpMethod(InputInterface $input)
case self::Setup_Gmail:
return $this->askForGmail($input);
break;
+ case self::Setup_Native:
+ return $this->askForNative($input);
+ break;
case self::Setup_None:
default:
return $this->askForNone($input);
@@ -169,11 +196,23 @@ protected function askForSmtp(InputInterface $input)
// Use custom validator to accept empty password
return $password;
});
+ $smtpPort = ($input->getOption('smtp_port')) ?: $this->io->ask('SMTP Server Port', 587);
+ $smtpAuth = ($input->getOption('smtp_auth')) ?: $this->io->confirm('SMTP Server Authentication', true);
+ $smtpSecure = ($input->getOption('smtp_secure')) ?: $this->io->choice('SMTP Server Security type', ['tls', 'ssl', 'Other...'], 'tls');
+
+ // Ask for custom input if 'other' was chosen
+ if ($smtpSecure == 'Other...') {
+ $smtpSecure = $this->io->ask('Enter custom SMTP Server Security type');
+ }
return [
+ 'MAIL_MAILER' => 'smtp',
'SMTP_HOST' => $smtpHost,
'SMTP_USER' => $smtpUser,
'SMTP_PASSWORD' => $smtpPassword,
+ 'SMTP_PORT' => $smtpPort,
+ 'SMTP_AUTH' => ($smtpAuth) ? 'true' : 'false',
+ 'SMTP_SECURE' => $smtpSecure,
];
}
@@ -193,12 +232,40 @@ protected function askForGmail(InputInterface $input)
});
return [
+ 'MAIL_MAILER' => 'smtp',
'SMTP_HOST' => 'smtp.gmail.com',
'SMTP_USER' => $smtpUser,
'SMTP_PASSWORD' => $smtpPassword,
];
}
+ /**
+ * Process the "native mail" setup option.
+ *
+ * @param InputInterface $input
+ *
+ * @return array The SMTP connection info
+ */
+ protected function askForNative(InputInterface $input)
+ {
+ // Display big warning and confirmation
+ $this->io->warning('Native mail function should only be used locally, inside containers or for development purposes.');
+
+ if ($this->io->confirm('Continue ?', false)) {
+ return [
+ 'MAIL_MAILER' => 'mail',
+ 'SMTP_HOST' => '',
+ 'SMTP_USER' => '',
+ 'SMTP_PASSWORD' => '',
+ 'SMTP_PORT' => '',
+ 'SMTP_AUTH' => '',
+ 'SMTP_SECURE' => '',
+ ];
+ } else {
+ $this->askForMailMethod($input);
+ }
+ }
+
/**
* Process the "no email support" setup option.
*
@@ -213,12 +280,16 @@ protected function askForNone(InputInterface $input)
if ($this->io->confirm('Continue ?', false)) {
return [
+ 'MAIL_MAILER' => 'smtp',
'SMTP_HOST' => '',
'SMTP_USER' => '',
'SMTP_PASSWORD' => '',
+ 'SMTP_PORT' => '',
+ 'SMTP_AUTH' => '',
+ 'SMTP_SECURE' => '',
];
} else {
- $this->askForSmtpMethod($input);
+ $this->askForMailMethod($input);
}
}
@@ -231,7 +302,14 @@ protected function askForNone(InputInterface $input)
*/
protected function isSmtpConfigured(DotenvEditor $dotenvEditor)
{
- if ($dotenvEditor->keyExists('SMTP_HOST') && $dotenvEditor->keyExists('SMTP_USER') && $dotenvEditor->keyExists('SMTP_PASSWORD')) {
+ if ($dotenvEditor->keyExists('MAIL_MAILER') || (
+ $dotenvEditor->keyExists('SMTP_HOST') &&
+ $dotenvEditor->keyExists('SMTP_USER') &&
+ $dotenvEditor->keyExists('SMTP_PASSWORD') &&
+ $dotenvEditor->keyExists('SMTP_PORT') &&
+ $dotenvEditor->keyExists('SMTP_AUTH') &&
+ $dotenvEditor->keyExists('SMTP_SECURE')
+ )) {
return true;
} else {
return false;
diff --git a/app/sprinkles/core/src/Bakery/Test.php b/app/sprinkles/core/src/Bakery/Test.php
index 211fccc84..21ea3ab8c 100644
--- a/app/sprinkles/core/src/Bakery/Test.php
+++ b/app/sprinkles/core/src/Bakery/Test.php
@@ -106,7 +106,7 @@ protected function execute(InputInterface $input, OutputInterface $output)
/**
* Return the sprinkle test class
*
- * @param string $testscope Testscope received from command line
+ * @param string $testscope Test scope received from command line
* @return string
*/
protected function parseSprinkleTestScope($testscope)
diff --git a/app/sprinkles/core/src/Core.php b/app/sprinkles/core/src/Core.php
index 93fcad518..8bd030f8e 100644
--- a/app/sprinkles/core/src/Core.php
+++ b/app/sprinkles/core/src/Core.php
@@ -10,7 +10,6 @@
namespace UserFrosting\Sprinkle\Core;
-use Psr\Container\ContainerInterface;
use RocketTheme\Toolbox\Event\Event;
use UserFrosting\Sprinkle\Core\Csrf\SlimCsrfProvider;
use UserFrosting\Sprinkle\Core\Database\Models\Model;
@@ -35,18 +34,6 @@ class Core extends Sprinkle
TranslatorServicesProvider::class,
];
- /**
- * Create a new Sprinkle object.
- *
- * @param ContainerInterface $ci The global container object, which holds all your services.
- */
- public function __construct(ContainerInterface $ci)
- {
- $this->ci = $ci;
-
- $this->registerStreams();
- }
-
/**
* Defines which events in the UF lifecycle our Sprinkle should hook into.
*/
@@ -70,6 +57,8 @@ public function onSprinklesInitialized()
// Set container for environment info class
EnvironmentInfo::$ci = $this->ci;
+
+ $this->registerStreams();
}
/**
diff --git a/app/sprinkles/core/src/Database/EloquentBuilder.php b/app/sprinkles/core/src/Database/EloquentBuilder.php
index 78676b2ff..11b839b1d 100644
--- a/app/sprinkles/core/src/Database/EloquentBuilder.php
+++ b/app/sprinkles/core/src/Database/EloquentBuilder.php
@@ -13,6 +13,7 @@
use Illuminate\Database\Eloquent\Builder as LaravelEloquentBuilder;
use Illuminate\Database\Query\Expression;
use Illuminate\Support\Str;
+use UserFrosting\Support\Exception\BadRequestException;
/**
* UserFrosting's custom Eloquent Builder Class.
@@ -21,6 +22,26 @@
*/
class EloquentBuilder extends LaravelEloquentBuilder
{
+ /**
+ * Find a model by its primary integer-valued key or throw an exception if
+ * something other than a nonnegative integer is provided.
+ *
+ * @param int $id
+ * @param array $columns
+ *
+ * @throws \UserFrosting\Support\Exception\BadRequestException
+ *
+ * @return \Illuminate\Database\Eloquent\Model|\Illuminate\Database\Eloquent\Collection|static[]|static|null
+ */
+ public function findInt($id, $columns = ['*'])
+ {
+ if (!isset($id) || (filter_var($id, FILTER_VALIDATE_INT) === false)) {
+ throw new BadRequestException();
+ }
+
+ return $this->find($id, $columns);
+ }
+
/**
* Add subselect queries to sum the relations.
*
diff --git a/app/sprinkles/core/src/Database/Migration.php b/app/sprinkles/core/src/Database/Migration.php
index cdadb67ed..94acc2bab 100644
--- a/app/sprinkles/core/src/Database/Migration.php
+++ b/app/sprinkles/core/src/Database/Migration.php
@@ -28,7 +28,7 @@ abstract class Migration implements MigrationInterface
* List of dependencies for this migration.
* Should return an array of class required to be run before this migration.
*
- * N.B.: Uncomment the next line when the static $dependencie deprecation is removed
+ * N.B.: Uncomment the next line when the static $dependencies deprecation is removed
*/
//public static $dependencies = [];
diff --git a/app/sprinkles/core/src/Database/Migrator/MigrationDependencyAnalyser.php b/app/sprinkles/core/src/Database/Migrator/MigrationDependencyAnalyser.php
index 3b30dd7d5..e91ce87a2 100644
--- a/app/sprinkles/core/src/Database/Migrator/MigrationDependencyAnalyser.php
+++ b/app/sprinkles/core/src/Database/Migrator/MigrationDependencyAnalyser.php
@@ -10,9 +10,6 @@
namespace UserFrosting\Sprinkle\Core\Database\Migrator;
-use ReflectionClass;
-use UserFrosting\Sprinkle\Core\Facades\Config;
-use UserFrosting\Sprinkle\Core\Facades\Debug;
use UserFrosting\Sprinkle\Core\Util\BadClassNameException;
/**
@@ -65,8 +62,6 @@ public function __construct(array $pending = [], array $installed = [])
/**
* Analyse the dependencies.
- *
- * @return void
*/
public function analyse(): void
{
@@ -89,10 +84,10 @@ public function analyse(): void
* dependencies. This is very important as the order the migrations needs
* to be run is defined by this recursion. By waiting for the dependency
* to be marked as fulfillable to mark the parent as fulfillable, the
- * parent class will be automatocally placed after it's dependencies
- * in the `fullfillable` property.
+ * parent class will be automatically placed after it's dependencies
+ * in the `fulfillable` property.
*
- * @param string $migrationName The migration classname
+ * @param string $migrationName The migration class name
*
* @return bool True/False if the migration is fulfillable
*/
@@ -128,7 +123,7 @@ protected function validateClassDependencies(string $migrationName): bool
}
// Check is the dependency is pending installation. If so, check for it's dependencies.
- // If the dependency is not fullfillable, then this one isn't either
+ // If the dependency is not fulfillable, then this one isn't either
if (!$this->pending->contains($dependency) || !$this->validateClassDependencies($dependency)) {
return $this->markAsUnfulfillable($migrationName, $dependency);
}
@@ -169,7 +164,7 @@ public function getUnfulfillable(): array
/**
* Mark a dependency as fulfillable. Removes it from the pending list and add it to the fulfillable list.
*
- * @param string $migration The migration classname
+ * @param string $migration The migration class name
*
* @return bool True, it's fulfillable
*/
@@ -183,10 +178,10 @@ protected function markAsFulfillable(string $migration): bool
/**
* Mark a dependency as unfulfillable. Removes it from the pending list and add it to the unfulfillable list.
*
- * @param string $migration The migration classname
- * @param string|array $dependency The problematic dependecy
+ * @param string $migration The migration class name
+ * @param string|array $dependency The problematic dependency
*
- * @return bool False, it's not fullfillable
+ * @return bool False, it's not fulfillable
*/
protected function markAsUnfulfillable(string $migration, $dependency): bool
{
@@ -200,8 +195,7 @@ protected function markAsUnfulfillable(string $migration, $dependency): bool
}
/**
- * Returns the migration dependency list
- * Also handles the old deprecated behaviour where dependencies where not in a static property.
+ * Returns the migration dependency list.
*
* @param string $migration The migration class
*
@@ -214,19 +208,9 @@ protected function getMigrationDependencies(string $migration): array
throw new BadClassNameException("Unable to find the migration class '$migration'. Run 'php bakery migrate:clean' to remove stale migrations.");
}
- // If the `dependencies` property exist and is static, use this one.
- // Otherwise, get a class instance and the non static property
- // We can remove this one the non static property is removed
- $reflectionClass = new ReflectionClass($migration);
- if ($reflectionClass->hasProperty('dependencies') && $reflectionClass->getProperty('dependencies')->isStatic()) {
+ // If the `dependencies` property exist, use it
+ if (property_exists($migration, 'dependencies')) {
return $this->normalizeClasses($migration::$dependencies);
- } elseif (property_exists($migration, 'dependencies')) {
- if (Config::get('debug.deprecation')) {
- Debug::warning("`$migration` uses a non static `dependencies` property. Please change the `dependencies` property to a static property.");
- }
- $instance = new $migration();
-
- return $this->normalizeClasses($instance->dependencies);
} else {
return [];
}
diff --git a/app/sprinkles/core/src/Database/Migrator/MigrationLocator.php b/app/sprinkles/core/src/Database/Migrator/MigrationLocator.php
index 7059be976..740218313 100644
--- a/app/sprinkles/core/src/Database/Migrator/MigrationLocator.php
+++ b/app/sprinkles/core/src/Database/Migrator/MigrationLocator.php
@@ -65,7 +65,7 @@ public function getMigrations()
}
/**
- * Return an array of migration details inclusing the classname and the sprinkle name.
+ * Return an array of migration details including the class name and the sprinkle name.
*
* @param ResourceInstance $file The migration file
*
@@ -77,7 +77,7 @@ protected function getMigrationDetails(ResourceInstance $file)
$sprinkleName = $file->getLocation()->getName();
$sprinkleName = Str::studly($sprinkleName);
- // Getting base path, name and classname
+ // Getting base path, name and class name
$basePath = str_replace($file->getBasename(), '', $file->getBasePath());
$name = $basePath . $file->getFilename();
$className = str_replace('/', '\\', $basePath) . $file->getFilename();
diff --git a/app/sprinkles/core/src/Database/Migrator/MigrationRollbackDependencyAnalyser.php b/app/sprinkles/core/src/Database/Migrator/MigrationRollbackDependencyAnalyser.php
index 6d5bd50ab..7503cb669 100644
--- a/app/sprinkles/core/src/Database/Migrator/MigrationRollbackDependencyAnalyser.php
+++ b/app/sprinkles/core/src/Database/Migrator/MigrationRollbackDependencyAnalyser.php
@@ -27,7 +27,7 @@ class MigrationRollbackDependencyAnalyser extends MigrationDependencyAnalyser
* represent the same thing as "up" dependencies. fulfillable can be
* rolledback, unfulfillable cannot.
*
- * @param string $migrationName The migration classname
+ * @param string $migrationName The migration class name
*
* @return bool True/False if the migration is fulfillable
*/
diff --git a/app/sprinkles/core/src/Database/Migrator/Migrator.php b/app/sprinkles/core/src/Database/Migrator/Migrator.php
index 2511dab6a..206cc4dd6 100644
--- a/app/sprinkles/core/src/Database/Migrator/Migrator.php
+++ b/app/sprinkles/core/src/Database/Migrator/Migrator.php
@@ -15,8 +15,6 @@
use UserFrosting\Sprinkle\Core\Database\MigrationInterface;
use UserFrosting\Sprinkle\Core\Database\Migrator\MigrationDependencyAnalyser as Analyser;
use UserFrosting\Sprinkle\Core\Database\Migrator\MigrationRollbackDependencyAnalyser as RollbackAnalyser;
-use UserFrosting\Sprinkle\Core\Facades\Config;
-use UserFrosting\Sprinkle\Core\Facades\Debug;
use UserFrosting\Sprinkle\Core\Util\BadClassNameException;
/**
@@ -158,7 +156,7 @@ protected function runPending(array $migrations, array $options = [])
* Run "up" a migration class.
*
* @param string $migrationClassName The migration class name
- * @param int $batch The current bacth number
+ * @param int $batch The current batch number
* @param bool $pretend If this operation should be pretended / faked
*/
protected function runUp($migrationClassName, $batch, $pretend)
@@ -173,7 +171,7 @@ protected function runUp($migrationClassName, $batch, $pretend)
return $this->pretendToRun($migration, 'up');
}
- // Run the actuall migration
+ // Run the actual migration
$this->runMigration($migration, 'up');
// Once we have run a migrations class, we will log that it was run in this
@@ -182,18 +180,6 @@ protected function runUp($migrationClassName, $batch, $pretend)
$this->repository->log($migrationClassName, $batch);
$this->note("Migrated: {$migrationClassName}");
-
- /*
- * If the migration has a `seed` method, run it
- * @deprecated Since 4.2.0. Use a seeder instead
- */
- if (method_exists($migration, 'seed')) {
- if (Config::get('debug.deprecation')) {
- Debug::warning('Migration `seed` method has been deprecated and will be removed in future versions. Please use a Seeder instead.');
- }
- $this->runMigration($migration, 'seed');
- $this->note("Seeded: {$migrationClassName}");
- }
}
/**
@@ -264,7 +250,7 @@ protected function getMigrationsForRollback(array $options)
/**
* Rollback the given migrations.
*
- * @param array $migrations An array of migrations to rollback formated as an eloquent collection
+ * @param array $migrations An array of migrations to rollback formatted as an eloquent collection
* @param array $options The options for the current operation
*
* @return array The list of rolledback migration classes
@@ -284,14 +270,14 @@ protected function rollbackMigrations(array $migrations, array $options)
// Next we will run through all of the migrations and call the "down" method
// which will reverse each migration in order. This getLast method on the
- // repository already returns these migration's classenames in reverse order.
+ // repository already returns these migration's class names in reverse order.
foreach ($migrations as $migration) {
// We have to make sure the class exist first
if (!$availableMigrations->contains($migration)) {
// NOTE This next was commented because if a class doesn't exist,
- // you'll get stuck and prevent futher classes to be rolledback
- // until this class is put back in the system. Might wan't to
+ // you'll get stuck and prevent further classes to be rolledback
+ // until this class is put back in the system. Might want to
// display a warning instead of silently skipping it. See related "todo" in "reset" method
//throw new \Exception("Can't rollback migrations `$migration`. The migration class doesn't exist");
$this->note("WARNING: Can't rollback migrations `$migration`. The migration class doesn't exist");
@@ -350,7 +336,7 @@ public function reset($pretend = false)
// this database. This will allow us to get the database back into its
// "empty" state and ready to be migrated "up" again.
//
- // !TODO :: Should compare to the install list to make sure no outstanding migration (ran, but with no migraiton class anymore) still exist in the db
+ // !TODO :: Should compare to the install list to make sure no outstanding migration (ran, but with no migration class anymore) still exist in the db
$migrations = array_reverse($this->getRanMigrations());
if (count($migrations) === 0) {
@@ -396,10 +382,7 @@ protected function runDown($migrationClassName, $pretend)
protected function runMigration(MigrationInterface $migration, $method)
{
$callback = function () use ($migration, $method) {
- // We keep this for seed...
- if (method_exists($migration, $method)) {
- $migration->{$method}();
- }
+ $migration->{$method}();
};
if ($this->getSchemaGrammar()->supportsSchemaTransactions()) {
diff --git a/app/sprinkles/core/src/Database/Models/Model.php b/app/sprinkles/core/src/Database/Models/Model.php
index 014ba60ee..987ae9139 100644
--- a/app/sprinkles/core/src/Database/Models/Model.php
+++ b/app/sprinkles/core/src/Database/Models/Model.php
@@ -141,32 +141,4 @@ protected function newBaseQueryBuilder()
$connection->getPostProcessor()
);
}
-
- /**
- * Get the properties of this object as an associative array. Alias for toArray().
- *
- * @deprecated since 4.1.8 There is no point in having this alias.
- *
- * @return array
- */
- public function export()
- {
- return $this->toArray();
- }
-
- /**
- * For raw array fetching. Must be static, otherwise PHP gets confused about where to find $table.
- *
- * @deprecated since 4.1.8 setFetchMode is no longer available as of Laravel 5.4.
- * @link https://github.com/laravel/framework/issues/17728
- *
- * @return Builder
- */
- public static function queryBuilder()
- {
- // Set query builder to fetch result sets as associative arrays (instead of creating stdClass objects)
- DB::connection()->setFetchMode(\PDO::FETCH_ASSOC);
-
- return DB::table(static::$table);
- }
}
diff --git a/app/sprinkles/core/src/Database/Relations/Concerns/Syncable.php b/app/sprinkles/core/src/Database/Relations/Concerns/Syncable.php
index f53917e93..757a72aed 100644
--- a/app/sprinkles/core/src/Database/Relations/Concerns/Syncable.php
+++ b/app/sprinkles/core/src/Database/Relations/Concerns/Syncable.php
@@ -46,7 +46,7 @@ public function sync($data, $deleting = true, $forceCreate = false, $relatedKeyN
$updateRows = [];
$newRows = [];
foreach ($data as $row) {
- // We determine "updateable" rows as those whose $relatedKeyName (usually 'id') is set, not empty, and
+ // We determine "updatable" rows as those whose $relatedKeyName (usually 'id') is set, not empty, and
// match a related row in the database.
if (isset($row[$relatedKeyName]) && !empty($row[$relatedKeyName]) && in_array($row[$relatedKeyName], $current)) {
$id = $row[$relatedKeyName];
diff --git a/app/sprinkles/core/src/Database/Relations/Concerns/Unique.php b/app/sprinkles/core/src/Database/Relations/Concerns/Unique.php
index ff8eee692..ed3b9acdb 100644
--- a/app/sprinkles/core/src/Database/Relations/Concerns/Unique.php
+++ b/app/sprinkles/core/src/Database/Relations/Concerns/Unique.php
@@ -126,34 +126,6 @@ public function limit($value)
return $this;
}
- /**
- * Set the limit on the number of intermediate models to load.
- *
- * @deprecated since 4.1.7
- *
- * @param int $value
- *
- * @return $this
- */
- public function withLimit($value)
- {
- return $this->limit($value);
- }
-
- /**
- * Set the offset when loading the intermediate models.
- *
- * @deprecated since 4.1.7
- *
- * @param int $value
- *
- * @return $this
- */
- public function withOffset($value)
- {
- return $this->offset($value);
- }
-
/**
* Add a query to load the nested tertiary models for this relationship.
*
diff --git a/app/sprinkles/core/src/Database/Seeder/BaseSeed.php b/app/sprinkles/core/src/Database/Seeder/BaseSeed.php
index 2feb03801..cb141cb8b 100644
--- a/app/sprinkles/core/src/Database/Seeder/BaseSeed.php
+++ b/app/sprinkles/core/src/Database/Seeder/BaseSeed.php
@@ -38,7 +38,7 @@ public function __construct(ContainerInterface $ci)
/**
* Validate if a specific set of migrations have been ran.
*
- * @param string|array $migrations List of migraiton or specific migration required
+ * @param string|array $migrations List of migration or specific migration required
*
* @throws \Exception If dependent migration is not available
*
diff --git a/app/sprinkles/core/src/Database/Seeder/Seeder.php b/app/sprinkles/core/src/Database/Seeder/Seeder.php
index b9edd8259..84f14f0b1 100644
--- a/app/sprinkles/core/src/Database/Seeder/Seeder.php
+++ b/app/sprinkles/core/src/Database/Seeder/Seeder.php
@@ -148,7 +148,7 @@ protected function loadSeeders(array $seedFiles)
}
/**
- * Return an array of seed details inclusing the classname and the sprinkle name.
+ * Return an array of seed details including the class name and the sprinkle name.
*
* @param ResourceInstance $file The seed file
*
@@ -160,7 +160,7 @@ protected function getSeedDetails(ResourceInstance $file)
$sprinkleName = $file->getLocation()->getName();
$sprinkleName = Str::studly($sprinkleName);
- // Getting base path, name and classname
+ // Getting base path, name and class name
$basePath = str_replace($file->getBasename(), '', $file->getBasePath());
$name = $basePath . $file->getFilename();
$className = str_replace('/', '\\', $basePath) . $file->getFilename();
diff --git a/app/sprinkles/core/src/Error/Renderer/WhoopsRenderer.php b/app/sprinkles/core/src/Error/Renderer/WhoopsRenderer.php
index 1a64198da..52294c15f 100644
--- a/app/sprinkles/core/src/Error/Renderer/WhoopsRenderer.php
+++ b/app/sprinkles/core/src/Error/Renderer/WhoopsRenderer.php
@@ -559,29 +559,6 @@ public function getResourcePaths()
return $this->searchPaths;
}
- /**
- * @deprecated
- *
- * @return string
- */
- public function getResourcesPath()
- {
- $allPaths = $this->getResourcePaths();
-
- // Compat: return only the first path added
- return end($allPaths) ?: null;
- }
-
- /**
- * @deprecated
- *
- * @param string $resourcesPath
- */
- public function setResourcesPath($resourcesPath)
- {
- $this->addResourcePath($resourcesPath);
- }
-
/**
* Return the application paths.
*
@@ -716,9 +693,9 @@ protected function getResource($resource)
/**
* Checks all values within the given superGlobal array.
- * Blacklisted values will be replaced by a equal length string cointaining only '*' characters.
+ * Blacklisted values will be replaced by a equal length string containing only '*' characters.
*
- * We intentionally dont rely on $GLOBALS as it depends on 'auto_globals_jit' php.ini setting.
+ * We intentionally don't rely on $GLOBALS as it depends on 'auto_globals_jit' php.ini setting.
*
* @param array $superGlobal One of the superglobal arrays
* @param string $superGlobalName the name of the superglobal array, e.g. '_GET'
diff --git a/app/sprinkles/core/src/Exceptions/VersionCompareException.php b/app/sprinkles/core/src/Exceptions/VersionCompareException.php
new file mode 100644
index 000000000..f81ca43b0
--- /dev/null
+++ b/app/sprinkles/core/src/Exceptions/VersionCompareException.php
@@ -0,0 +1,55 @@
+constraint = $constraint;
+
+ return $this;
+ }
+
+ public function getVersion(): string
+ {
+ return $this->version;
+ }
+
+ /**
+ * @return self
+ */
+ public function setVersion(string $version)
+ {
+ $this->version = $version;
+
+ return $this;
+ }
+
+ public function getConstraint(): string
+ {
+ return $this->constraint;
+ }
+}
diff --git a/app/sprinkles/core/src/I18n/SiteLocale.php b/app/sprinkles/core/src/I18n/SiteLocale.php
index 71c61f11f..508c7e671 100644
--- a/app/sprinkles/core/src/I18n/SiteLocale.php
+++ b/app/sprinkles/core/src/I18n/SiteLocale.php
@@ -22,6 +22,8 @@ class SiteLocale
{
/**
* @var ContainerInterface
+ *
+ * @todo Change this to only the config service
*/
protected $ci;
@@ -121,9 +123,11 @@ public function getDefaultLocale(): string
}
/**
- * Returns the locale intentifier (ie. en_US) to use.
+ * Returns the locale identifier (ie. en_US) to use.
+ *
+ * @return string Locale identifier
*
- * @return string Locale intentifier
+ * @todo This should accept the request service as argument, or null, in which case the `getBrowserLocale` method would be skipped
*/
public function getLocaleIndentifier(): string
{
@@ -142,6 +146,8 @@ public function getLocaleIndentifier(): string
* Return the browser locale.
*
* @return string|null Returns null if no valid locale can be found
+ *
+ * @todo This should accept the request service as argument.
*/
protected function getBrowserLocale(): ?string
{
diff --git a/app/sprinkles/core/src/Log/MixedFormatter.php b/app/sprinkles/core/src/Log/MixedFormatter.php
index 880705567..8867393ec 100644
--- a/app/sprinkles/core/src/Log/MixedFormatter.php
+++ b/app/sprinkles/core/src/Log/MixedFormatter.php
@@ -56,10 +56,6 @@ protected function toJson($data, $ignoreErrors = false)
*/
private function jsonEncodePretty($data)
{
- if (version_compare(PHP_VERSION, '5.4.0', '>=')) {
- return json_encode($data, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT);
- }
-
- return json_encode($data);
+ return json_encode($data, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT);
}
}
diff --git a/app/sprinkles/core/src/Model/UFModel.php b/app/sprinkles/core/src/Model/UFModel.php
deleted file mode 100644
index d85e62d4f..000000000
--- a/app/sprinkles/core/src/Model/UFModel.php
+++ /dev/null
@@ -1,31 +0,0 @@
-count();
}
-
- /**
- * Executes the sprunje query, applying all sorts, filters, and pagination.
- *
- * Returns an array containing `count` (the total number of rows, before filtering), `count_filtered` (the total number of rows after filtering),
- * and `rows` (the filtered result set).
- *
- * @deprecated since 4.1.7 Use getArray() instead.
- *
- * @return mixed[]
- */
- public function getResults()
- {
- return $this->getArray();
- }
}
diff --git a/app/sprinkles/core/src/Twig/CacheHelper.php b/app/sprinkles/core/src/Twig/CacheHelper.php
index 460248f14..0b1abe04d 100755
--- a/app/sprinkles/core/src/Twig/CacheHelper.php
+++ b/app/sprinkles/core/src/Twig/CacheHelper.php
@@ -22,6 +22,8 @@ class CacheHelper
{
/**
* @var ContainerInterface The global container object, which holds all your services.
+ *
+ * @todo Change this, only the locator service is required
*/
protected $ci;
@@ -38,7 +40,7 @@ public function __construct(ContainerInterface $ci)
/**
* Function that delete the Twig cache directory content.
*
- * @return bool true/false if operation is successfull
+ * @return bool true/false if operation is successful
*/
public function clearCache()
{
diff --git a/app/sprinkles/core/src/Util/CheckEnvironment.php b/app/sprinkles/core/src/Util/CheckEnvironment.php
index 055fe4ec8..40c8a73dc 100644
--- a/app/sprinkles/core/src/Util/CheckEnvironment.php
+++ b/app/sprinkles/core/src/Util/CheckEnvironment.php
@@ -14,6 +14,7 @@
use Psr\Http\Message\ResponseInterface as Response;
use Psr\Http\Message\ServerRequestInterface as Request;
use Slim\Views\Twig;
+use UserFrosting\Sprinkle\Core\Exceptions\VersionCompareException;
use UserFrosting\UniformResourceLocator\ResourceLocator;
/**
@@ -102,8 +103,10 @@ public function __invoke(Request $request, Response $response, $next)
/**
* Run through all pre-flight checks.
+ *
+ * @return bool True if problem(s) found.
*/
- public function checkAll()
+ public function checkAll(): bool
{
$problemsFound = false;
@@ -142,8 +145,10 @@ public function checkAll()
/**
* For Apache environments, check that required Apache modules are installed.
+ *
+ * @return bool True if problem(s) found.
*/
- public function checkApache()
+ public function checkApache(): bool
{
$problemsFound = false;
@@ -202,10 +207,11 @@ public function checkGd()
/**
* Check that all image* functions used by Captcha exist.
- *
* Some versions of GD are missing one or more of these functions, thus why we check for them explicitly.
+ *
+ * @return bool True if problem(s) found.
*/
- public function checkImageFunctions()
+ public function checkImageFunctions(): bool
{
$problemsFound = false;
@@ -242,8 +248,10 @@ public function checkImageFunctions()
/**
* Check that PDO is installed and enabled.
+ *
+ * @return bool True if problem(s) found.
*/
- public function checkPdo()
+ public function checkPdo(): bool
{
$problemsFound = false;
@@ -267,8 +275,10 @@ public function checkPdo()
/**
* Check that log, cache, and session directories exist.
+ *
+ * @return bool True if problem(s) found.
*/
- public function checkDirectories()
+ public function checkDirectories(): bool
{
$problemsFound = false;
@@ -299,9 +309,12 @@ public function checkDirectories()
}
/**
- * Check that log, cache, and session directories are writable, and that other directories are set appropriately for the environment.
+ * Check that log, cache, and session directories are writable,
+ * and that other directories are set appropriately for the environment.
+ *
+ * @return bool True if problem(s) found.
*/
- public function checkPermissions()
+ public function checkPermissions(): bool
{
$problemsFound = false;
@@ -351,28 +364,31 @@ public function checkPermissions()
/**
* Check that PHP meets the minimum required version.
+ *
+ * @return bool True if problem(s) found.
*/
- public function checkPhp()
+ public function checkPhp(): bool
{
- $problemsFound = false;
-
- // Check PHP version
- if (version_compare(phpversion(), \UserFrosting\PHP_MIN_VERSION, '<')) {
- $problemsFound = true;
+ try {
+ VersionValidator::validatePhpVersion();
+ } catch (VersionCompareException $e) {
$this->resultsFailed['phpVersion'] = [
- 'title' => " You need to upgrade your PHP installation.",
- 'message' => "I'm sorry, UserFrosting requires version " . \UserFrosting\PHP_MIN_VERSION . ' or greater. Please upgrade your version of PHP, or contact your web hosting service and ask them to upgrade it for you.',
+ 'title' => " Your PHP version does not satisfy UserFrosting required constraint.",
+ 'message' => $e->getMessage(),
'success' => false,
];
- } else {
- $this->resultsSuccess['phpVersion'] = [
- 'title' => " PHP version checks out!",
- 'message' => "You're using PHP " . \UserFrosting\PHP_MIN_VERSION . 'or higher. Great!',
- 'success' => true,
- ];
+
+ return true;
}
- return $problemsFound;
+ // No problem found !
+ $this->resultsSuccess['phpVersion'] = [
+ 'title' => " PHP version checks out!",
+ 'message' => 'Your PHP version satisfy UserFrosting required constraint. Great!',
+ 'success' => true,
+ ];
+
+ return false;
}
/**
@@ -380,9 +396,9 @@ public function checkPhp()
*
* @return bool
*/
- public function isProduction()
+ public function isProduction(): bool
{
- return getenv('UF_MODE') == 'production';
+ return env('UF_MODE') == 'production';
}
/**
@@ -390,8 +406,8 @@ public function isProduction()
*
* @return bool True if we should skip the check, false will proceed.
*/
- public function skipPermissionsCheck()
+ public function skipPermissionsCheck(): bool
{
- return getenv('SKIP_PERMISSION_CHECK') ? true : false;
+ return env('SKIP_PERMISSION_CHECK', false);
}
}
diff --git a/app/sprinkles/core/src/Util/ClassMapper.php b/app/sprinkles/core/src/Util/ClassMapper.php
index c20e3202e..a8eaeee43 100644
--- a/app/sprinkles/core/src/Util/ClassMapper.php
+++ b/app/sprinkles/core/src/Util/ClassMapper.php
@@ -13,7 +13,7 @@
/**
* UserFrosting class mapper.
*
- * This creates an abstraction layer for overrideable classes.
+ * This creates an abstraction layer for overridable classes.
* For example, if we want to replace usages of the User class with MyUser, this abstraction layer handles that.
*
* @author Alex Weissman (https://alexanderweissman.com)
diff --git a/app/sprinkles/core/src/Util/RawAssetBundles.php b/app/sprinkles/core/src/Util/RawAssetBundles.php
index 4d0277fed..7c3181a6f 100644
--- a/app/sprinkles/core/src/Util/RawAssetBundles.php
+++ b/app/sprinkles/core/src/Util/RawAssetBundles.php
@@ -88,18 +88,18 @@ public function extend($filePath)
*/
protected function addWithCollisionRule(&$bundle, $bundleName, $collisionRule, &$bundleStore)
{
- $standardisedBundle = $this->standardiseBundle($bundle);
+ $standardizedBundle = $this->standardiseBundle($bundle);
if (!array_key_exists($bundleName, $bundleStore)) {
- $bundleStore[$bundleName] = $standardisedBundle;
+ $bundleStore[$bundleName] = $standardizedBundle;
} else {
switch ($collisionRule) {
case 'replace':
// Replaces the existing bundle.
- $bundleStore[$bundleName] = $standardisedBundle;
+ $bundleStore[$bundleName] = $standardizedBundle;
break;
case 'merge':
// Merge with existing bundle.
- foreach ($standardisedBundle as $assetPath) {
+ foreach ($standardizedBundle as $assetPath) {
if (!in_array($assetPath, $bundleStore[$bundleName])) {
$bundleStore[$bundleName][] = $assetPath;
}
diff --git a/app/sprinkles/core/src/Util/VersionValidator.php b/app/sprinkles/core/src/Util/VersionValidator.php
new file mode 100644
index 000000000..eb4899acf
--- /dev/null
+++ b/app/sprinkles/core/src/Util/VersionValidator.php
@@ -0,0 +1,189 @@
+setConstraint($constraint)->setVersion($phpVersion);
+
+ throw $exception;
+ }
+
+ return true;
+ }
+
+ /**
+ * Check the minimum version of php.
+ * This should be done by composer itself, but we do it again for good measure.
+ *
+ * @throws VersionCompareException If constraint version is not matched.
+ *
+ * @return true Version is valid
+ */
+ public static function validatePhpDeprecation(): bool
+ {
+ $phpVersion = static::getPhpVersion();
+ $constraint = static::getPhpRecommended();
+
+ if (!Semver::satisfies($phpVersion, $constraint)) {
+ $message = 'UserFrosting recommend a PHP version that satisfies "' . $constraint . '". While your PHP version (' . $phpVersion . ') is still supported by UserFrosting, we recommend upgrading as your current version will soon be unsupported. See http://php.net/supported-versions.php for more info.';
+ $exception = new VersionCompareException($message);
+ $exception->setConstraint($constraint)->setVersion($phpVersion);
+
+ throw $exception;
+ }
+
+ return true;
+ }
+
+ /**
+ * Check the minimum version requirement of Node installed.
+ *
+ * @throws VersionCompareException If constraint version is not matched.
+ *
+ * @return true Version is valid
+ */
+ public static function validateNodeVersion(): bool
+ {
+ $nodeVersion = static::getNodeVersion();
+ $constraint = static::getNodeConstraint();
+
+ if (!Semver::satisfies($nodeVersion, $constraint)) {
+ $message = 'UserFrosting requires a Node version that satisfies "' . $constraint . '", but found ' . $nodeVersion . '. Check the documentation for more details.';
+ $exception = new VersionCompareException($message);
+ $exception->setConstraint($constraint)->setVersion($nodeVersion);
+
+ throw $exception;
+ }
+
+ return true;
+ }
+
+ /**
+ * Check the minimum version requirement for Npm.
+ *
+ * @throws VersionCompareException If constraint version is not matched.
+ *
+ * @return true Version is valid
+ */
+ public static function validateNpmVersion(): bool
+ {
+ $npmVersion = static::getNpmVersion();
+ $constraint = static::getNpmConstraint();
+
+ if (!Semver::satisfies($npmVersion, $constraint)) {
+ $message = 'UserFrosting requires a NPM version that satisfies "' . $constraint . '", but found ' . $npmVersion . '. Check the documentation for more details.';
+ $exception = new VersionCompareException($message);
+ $exception->setConstraint($constraint)->setVersion($npmVersion);
+
+ throw $exception;
+ }
+
+ return true;
+ }
+
+ /**
+ * Returns system php version.
+ * Handle non semver compliant version of PHP returned by some OS.
+ *
+ * @see https://github.com/composer/semver/issues/125
+ *
+ * @return string
+ */
+ public static function getPhpVersion(): string
+ {
+ $version = (string) phpversion();
+ $version = preg_replace('#^([^~+-]+).*$#', '$1', $version);
+
+ return $version;
+ }
+
+ /**
+ * Returns system Node version.
+ *
+ * @return string
+ */
+ public static function getNodeVersion(): string
+ {
+ return trim(exec('node -v'));
+ }
+
+ /**
+ * Returns system NPM version.
+ *
+ * @return string
+ */
+ public static function getNpmVersion(): string
+ {
+ return trim(exec('npm -v'));
+ }
+
+ /**
+ * Returns the required PHP semver range.
+ *
+ * @return string
+ */
+ public static function getPhpConstraint(): string
+ {
+ return \UserFrosting\PHP_MIN_VERSION;
+ }
+
+ /**
+ * Returns the recommended PHP semver range.
+ *
+ * @return string
+ */
+ public static function getPhpRecommended(): string
+ {
+ return \UserFrosting\PHP_RECOMMENDED_VERSION;
+ }
+
+ /**
+ * Returns the required Node semver range.
+ *
+ * @return string
+ */
+ public static function getNodeConstraint(): string
+ {
+ return \UserFrosting\NODE_MIN_VERSION;
+ }
+
+ /**
+ * Returns the required NPM semver range.
+ *
+ * @return string
+ */
+ public static function getNpmConstraint(): string
+ {
+ return \UserFrosting\NPM_MIN_VERSION;
+ }
+}
diff --git a/app/sprinkles/core/tests/ControllerTestCase.php b/app/sprinkles/core/tests/ControllerTestCase.php
deleted file mode 100644
index 2872935b5..000000000
--- a/app/sprinkles/core/tests/ControllerTestCase.php
+++ /dev/null
@@ -1,37 +0,0 @@
-setupTestDatabase();
- $this->refreshDatabase();
- }
-}
diff --git a/app/sprinkles/core/tests/Integration/Bakery/data/locale/en_US/messages.php b/app/sprinkles/core/tests/Integration/Bakery/data/locale/en_US/messages.php
index 0109fcb74..d9136dd5e 100644
--- a/app/sprinkles/core/tests/Integration/Bakery/data/locale/en_US/messages.php
+++ b/app/sprinkles/core/tests/Integration/Bakery/data/locale/en_US/messages.php
@@ -13,7 +13,7 @@
'test' => [
'@TRANSLATION' => 'Test',
'bbb' => 'BBB',
- 'ccc' => 'CCC', // Overwriten by ""
- 'ddd' => 'ddd', //Overwriten by "DDD"
+ 'ccc' => 'CCC', // Overwritten by ""
+ 'ddd' => 'ddd', // Overwritten by "DDD"
],
];
diff --git a/app/sprinkles/core/tests/Integration/Controllers/CoreControllerTest.php b/app/sprinkles/core/tests/Integration/Controllers/CoreControllerTest.php
index 33bd93a12..5032cfcf4 100644
--- a/app/sprinkles/core/tests/Integration/Controllers/CoreControllerTest.php
+++ b/app/sprinkles/core/tests/Integration/Controllers/CoreControllerTest.php
@@ -12,12 +12,15 @@
use UserFrosting\Sprinkle\Core\Controller\CoreController;
use UserFrosting\Support\Exception\NotFoundException;
+use UserFrosting\Tests\TestCase;
/**
* Tests CoreController
*/
-class CoreControllerTest extends ControllerTestCase
+class CoreControllerTest extends TestCase
{
+ use withController;
+
/**
* @return CoreController
*/
diff --git a/app/sprinkles/core/tests/Integration/Database/DatabaseTests.php b/app/sprinkles/core/tests/Integration/Database/DatabaseTests.php
index 9ef6a6b86..ec3753366 100644
--- a/app/sprinkles/core/tests/Integration/Database/DatabaseTests.php
+++ b/app/sprinkles/core/tests/Integration/Database/DatabaseTests.php
@@ -10,10 +10,11 @@
namespace UserFrosting\Sprinkle\Core\Tests\Integration\Database;
-use UserFrosting\Tests\TestCase;
use Illuminate\Database\Eloquent\Relations\Relation;
use Illuminate\Database\Schema\Blueprint;
use UserFrosting\Sprinkle\Core\Database\Models\Model;
+use UserFrosting\Support\Exception\BadRequestException;
+use UserFrosting\Tests\TestCase;
class DatabaseTests extends TestCase
{
@@ -886,6 +887,37 @@ public function testQueryExcludeWildcard()
], $job->toArray());
}
+ /**
+ * testFindInt
+ */
+ public function testFindInt()
+ {
+ $this->generateTasks();
+ $task = EloquentTestTask::findInt(1);
+
+ $this->assertEquals($task, EloquentTestTask::find(1));
+ }
+
+ /**
+ * testFindIntThrowsExceptionOnNull
+ */
+ public function testFindIntThrowsExceptionOnNull()
+ {
+ $this->generateTasks();
+ $this->expectException(BadRequestException::class);
+ EloquentTestTask::findInt(null);
+ }
+
+ /**
+ * testFindIntThrowsExceptionOnNonInteger
+ */
+ public function testFindIntThrowsExceptionOnNonInteger()
+ {
+ $this->generateTasks();
+ $this->expectException(BadRequestException::class);
+ EloquentTestTask::findInt('hi');
+ }
+
/**
* Helpers...
*/
diff --git a/app/sprinkles/core/tests/Integration/Database/Migrator/DatabaseMigratorIntegrationTest.php b/app/sprinkles/core/tests/Integration/Database/Migrator/DatabaseMigratorIntegrationTest.php
index db726c354..d58bc8f58 100644
--- a/app/sprinkles/core/tests/Integration/Database/Migrator/DatabaseMigratorIntegrationTest.php
+++ b/app/sprinkles/core/tests/Integration/Database/Migrator/DatabaseMigratorIntegrationTest.php
@@ -122,7 +122,7 @@ public function testMigrationsCanBeRolledBack()
// Make sure the data returned from migrator is accurate.
// N.B.: The order returned by the rollback method is ordered by which
- // migration was rollbacked first (reversed from the order they where ran up)
+ // migration was rolled back first (reversed from the order they where ran up)
$this->assertEquals(array_reverse($this->locator->getMigrations()), $rolledBack);
}
@@ -187,25 +187,6 @@ public function testPretendRollback()
$this->assertEquals(array_reverse($expected), $rolledBack);
}
- public function testChangeRepositoryAndDeprecatedClass()
- {
- // Change the repository so we can test with the DeprecatedMigrationLocatorStub
- $locator = new DeprecatedMigrationLocatorStub($this->ci->locator);
- $this->migrator->setLocator($locator);
-
- // Run up. Should also run the seeder
- $this->migrator->run();
- $this->assertTrue($this->schema->hasTable('deprecated_table'));
-
- // Make sure the seeder ran.
- // Easiest way to do so it asking the seeder to change the table structure
- $this->assertTrue($this->schema->hasColumn('deprecated_table', 'foo'));
-
- // Rollback
- $this->migrator->rollback();
- $this->assertFalse($this->schema->hasTable('deprecated_table'));
- }
-
public function testWithInvalidClass()
{
// Change the repository so we can test with the InvalidMigrationLocatorStub
@@ -234,7 +215,7 @@ public function testDependableMigrations()
// Note here the `two` migration has been placed at the bottom even if
// it was supposed to be migrated first from the order the locator
// returned them. This is because `two` migration depends on `one` migrations
- // We only check the last one, we don't care about the order the first two are since they are not dependendent on eachother
+ // We only check the last one, we don't care about the order the first two are since they are not dependent on each other
$this->assertEquals('\\UserFrosting\\Tests\\Integration\\Migrations\\two\\CreateFlightsTable', $migrated[2]);
}
@@ -261,7 +242,7 @@ public function testDependableMigrationsWithInstalled()
public function testUnfulfillableMigrations()
{
- // Change the repository so we can test with the DeprecatedStub
+ // Change the repository so we can test with the unfulfillable Stub
$locator = new UnfulfillableMigrationLocatorStub($this->ci->locator);
$this->migrator->setLocator($locator);
@@ -384,17 +365,3 @@ public function getMigrations()
];
}
}
-
-/**
- * This stub contain migration which order they need to be run is different
- * than the order the file are returned because of dependencies management
- */
-class DeprecatedMigrationLocatorStub extends MigrationLocator
-{
- public function getMigrations()
- {
- return [
- '\\UserFrosting\\Tests\\Integration\\Migrations\\DeprecatedClassTable',
- ];
- }
-}
diff --git a/app/sprinkles/core/tests/Integration/Database/Migrator/DatabaseMigratorTest.php b/app/sprinkles/core/tests/Integration/Database/Migrator/DatabaseMigratorTest.php
index ff7353aef..27886b059 100644
--- a/app/sprinkles/core/tests/Integration/Database/Migrator/DatabaseMigratorTest.php
+++ b/app/sprinkles/core/tests/Integration/Database/Migrator/DatabaseMigratorTest.php
@@ -24,7 +24,7 @@
* Tests for the Migrator Class
*
* Theses tests make sure the Migrator works correctly, without validating
- * agaist a simulated database. Those tests are performed by `DatabaseMigratorIntegrationTest`
+ * against a simulated database. Those tests are performed by `DatabaseMigratorIntegrationTest`
*
* @author Louis Charette
*/
@@ -76,7 +76,7 @@ public function setUp(): void
$capsule = m::mock(Capsule::class);
$this->connection = m::mock(Connection::class);
- // Set global expections for $capule and $connection
+ // Set global expectations for $capsule and $connection
$capsule->shouldReceive('getConnection')->andReturn($this->connection);
$this->connection->shouldReceive('getSchemaBuilder')->andReturn($this->schema);
@@ -85,11 +85,11 @@ public function setUp(): void
}
/**
- * Basic test to make sure the base method syntaxt is ok
+ * Basic test to make sure the base method syntax is ok
*/
public function testMigratorUpWithNoMigrations()
{
- // Locator will be asked to return the avaialble migrations
+ // Locator will be asked to return the available migrations
$this->locator->shouldReceive('getMigrations')->once()->andReturn([]);
// Repository will be asked to return the ran migrations
@@ -100,7 +100,7 @@ public function testMigratorUpWithNoMigrations()
}
/**
- * Basic test where all avaialble migrations are pending and fulfillable
+ * Basic test where all available migrations are pending and fulfillable
*/
public function testMigratorUpWithOnlyPendingMigrations()
{
@@ -135,7 +135,7 @@ public function testMigratorUpWithOnlyPendingMigrations()
}
/**
- * Test where one of the avaialble migrations is already installed
+ * Test where one of the available migrations is already installed
*/
public function testMigratorUpWithOneInstalledMigrations()
{
@@ -164,7 +164,7 @@ public function testMigratorUpWithOneInstalledMigrations()
// Run migrations up
$migrations = $this->migrator->run();
- // The migration already ran shoudn't be in the pending ones
+ // The migration already ran shouldn't be in the pending ones
$this->assertEquals([
'\\UserFrosting\\Tests\\Integration\\Migrations\\one\\CreatePasswordResetsTable',
'\\UserFrosting\\Tests\\Integration\\Migrations\\two\\CreateFlightsTable',
@@ -172,7 +172,7 @@ public function testMigratorUpWithOneInstalledMigrations()
}
/**
- * Test where all avaialble migrations have been ran
+ * Test where all available migrations have been ran
*/
public function testMigratorUpWithNoPendingMigrations()
{
@@ -197,7 +197,7 @@ public function testMigratorUpWithNoPendingMigrations()
// Run migrations up
$migrations = $this->migrator->run();
- // The migration already ran shoudn't be in the pending ones
+ // The migration already ran shouldn't be in the pending ones
$this->assertEquals([], $migrations);
}
@@ -217,7 +217,7 @@ public function testMigratorRollbackWithNoInstalledMigrations()
// Run migrations up
$migrations = $this->migrator->rollback();
- // The migration already ran shoudn't be in the pending ones
+ // The migration already ran shouldn't be in the pending ones
$this->assertEquals([], $migrations);
}
@@ -252,7 +252,7 @@ public function testMigratorRollbackAllInstalledMigrations()
// Run migrations up
$migrations = $this->migrator->rollback();
- // The migration already ran shoudn't be in the pending ones
+ // The migration already ran shouldn't be in the pending ones
$this->assertEquals($testMigrations, $migrations);
}
@@ -287,14 +287,14 @@ public function testMigratorRollbackAllInstalledMigrationsWithOneMissing()
// Rollback migrations
$migrations = $this->migrator->rollback();
- // The migration not available from the locator shouldn't have been run dowm
+ // The migration not available from the locator shouldn't have been run
$this->assertEquals([
'\\UserFrosting\\Tests\\Integration\\Migrations\\one\\CreatePasswordResetsTable',
], $migrations);
}
/**
- * Test a specific migration with no dependencies can be rollbacked
+ * Test a specific migration with no dependencies can be rolled back
*/
public function testMigratorRollbackSpecific()
{
@@ -330,12 +330,12 @@ public function testMigratorRollbackSpecific()
// Rollback only the Flights table. Should work as no other depends on it
$rolledback = $this->migrator->rollbackMigration($migration);
- // The migration already ran shoudn't be in the pending ones
+ // The migration already ran shouldn't be in the pending ones
$this->assertEquals([$migration], $rolledback);
}
/**
- * Test a specific migration with some dependencies can be rollbacked
+ * Test a specific migration with some dependencies can be rolled back
*/
public function testMigratorRollbackSpecificWithDependencies()
{
@@ -401,7 +401,7 @@ public function testMigratorResetAllInstalledMigrations()
$this->connection->shouldReceive('getSchemaGrammar')->andReturn($grammar);
$grammar->shouldReceive('supportsSchemaTransactions')->andReturn(false);
- // Reset mgirations
+ // Reset migrations
$migrations = $this->migrator->reset();
// All the migrations should have been rolledback
diff --git a/app/sprinkles/core/tests/Integration/Database/Migrator/MigrationLocatorTest.php b/app/sprinkles/core/tests/Integration/Database/Migrator/MigrationLocatorTest.php
index 144ce51a3..d9b3b248f 100644
--- a/app/sprinkles/core/tests/Integration/Database/Migrator/MigrationLocatorTest.php
+++ b/app/sprinkles/core/tests/Integration/Database/Migrator/MigrationLocatorTest.php
@@ -91,7 +91,7 @@ public function testGetMigrations()
new Resource($resourceStream, $resourceAccountLocation, 'two/CreateFlightsTable.php'),
new Resource($resourceStream, $resourceAccountLocation, 'CreateMainTable.php'),
- // Theses shoudn't be returned by the migrator
+ // Theses shouldn't be returned by the migrator
new Resource($resourceStream, $resourceAccountLocation, 'README.md'),
new Resource($resourceStream, $resourceAccountLocation, 'php.md'),
new Resource($resourceStream, $resourceAccountLocation, 'foo.foophp'),
@@ -122,7 +122,7 @@ public function testGetMigrations()
}
/**
- * Test MigratonLocator against the real thing, no Mockery
+ * Test MigrationLocator against the real thing, no Mockery
*/
public function testActualInstance()
{
diff --git a/app/sprinkles/core/tests/Integration/Database/Migrator/MigrationRepositoryTest.php b/app/sprinkles/core/tests/Integration/Database/Migrator/MigrationRepositoryTest.php
index 9f0e92cc6..d61ae25c8 100644
--- a/app/sprinkles/core/tests/Integration/Database/Migrator/MigrationRepositoryTest.php
+++ b/app/sprinkles/core/tests/Integration/Database/Migrator/MigrationRepositoryTest.php
@@ -17,7 +17,7 @@
use UserFrosting\Tests\TestCase;
/**
- * DatabaseMigrationRespository Test
+ * DatabaseMigrationRepository Test
*/
class MigrationRepositoryTest extends TestCase
{
@@ -44,7 +44,7 @@ public function setUp(): void
// Create repository instance
$this->repository = new DatabaseMigrationRepository($capsule, 'migrations');
- // Set global expections for $capule and $connection
+ // Set global expectations for $capsule and $connection
// Repository -> capsule -> connection -> Schema
// When repository call `getConnection`, it will receive the connection mock
// When repository call `getSchemaBuilder`, it will receive the schema builder mock
@@ -141,7 +141,7 @@ public function testGetNextBatchNumberReturnsLastBatchNumberPlusOne()
public function testCreateRepositoryCreatesProperDatabaseTable()
{
- // Setup expectations for SchemaBuilder. When asked to create the repository, the schema should reeceive the create command
+ // Setup expectations for SchemaBuilder. When asked to create the repository, the schema should receive the create command
$this->repository->getSchemaBuilder()->shouldReceive('create')->once()->with('migrations', m::type('Closure'));
$this->repository->createRepository();
}
diff --git a/app/sprinkles/core/tests/Integration/Migrations/DeprecatedClassTable.php b/app/sprinkles/core/tests/Integration/Migrations/DeprecatedClassTable.php
deleted file mode 100644
index 19055ed5f..000000000
--- a/app/sprinkles/core/tests/Integration/Migrations/DeprecatedClassTable.php
+++ /dev/null
@@ -1,47 +0,0 @@
-schema->create('deprecated_table', function (Blueprint $table) {
- $table->string('email')->index();
- $table->string('token')->index();
- $table->timestamp('created_at');
- });
- }
-
- /**
- * Reverse the migrations.
- */
- public function down()
- {
- $this->schema->dropIfExists('deprecated_table');
- }
-
- /**
- * Seed the database.
- */
- public function seed()
- {
- $this->schema->table('deprecated_table', function (Blueprint $table) {
- $table->string('foo')->nullable();
- });
- }
-}
diff --git a/app/sprinkles/core/tests/Integration/Migrations/UnfulfillableTable.php b/app/sprinkles/core/tests/Integration/Migrations/UnfulfillableTable.php
index cbaf5bb0d..91d88cf0a 100644
--- a/app/sprinkles/core/tests/Integration/Migrations/UnfulfillableTable.php
+++ b/app/sprinkles/core/tests/Integration/Migrations/UnfulfillableTable.php
@@ -14,7 +14,7 @@
use UserFrosting\Sprinkle\Core\Database\Migration;
/**
- * This migration is not fulfulable because it's dependencie are not met !
+ * This migration is not fulfillable because it's dependencies are not met !
*/
class UnfulfillableTable extends Migration
{
diff --git a/app/sprinkles/core/tests/Integration/Migrations/one/CreateUsersTable.php b/app/sprinkles/core/tests/Integration/Migrations/one/CreateUsersTable.php
index a5aed5a61..11445ce3b 100644
--- a/app/sprinkles/core/tests/Integration/Migrations/one/CreateUsersTable.php
+++ b/app/sprinkles/core/tests/Integration/Migrations/one/CreateUsersTable.php
@@ -17,10 +17,8 @@ class CreateUsersTable extends Migration
{
/**
* {@inheritdoc}
- *
- * N.B.: Not using static here to test old deprecated behavior
*/
- public $dependencies = [];
+ public static $dependencies = [];
/**
* Run the migrations.
diff --git a/app/sprinkles/core/tests/Integration/Session/SessionDatabaseHandlerTest.php b/app/sprinkles/core/tests/Integration/Session/SessionDatabaseHandlerTest.php
index 20f9e76e9..71137c1ef 100644
--- a/app/sprinkles/core/tests/Integration/Session/SessionDatabaseHandlerTest.php
+++ b/app/sprinkles/core/tests/Integration/Session/SessionDatabaseHandlerTest.php
@@ -36,7 +36,7 @@ public function setUp(): void
}
/**
- * Test session table connection & existance
+ * Test session table connection & existence
*/
public function testSessionTable()
{
@@ -44,7 +44,7 @@ public function testSessionTable()
$config = $this->ci->config;
$table = $config['session.database.table'];
- // Check connexion is ok and returns what's expected from DatabaseSessionHandler
+ // Check connection is ok and returns what's expected from DatabaseSessionHandler
$this->assertInstanceOf(\Illuminate\Database\ConnectionInterface::class, $connection);
$this->assertInstanceOf(\Illuminate\Database\Query\Builder::class, $connection->table($table));
diff --git a/app/sprinkles/core/tests/Integration/Twig/CoreExtensionTest.php b/app/sprinkles/core/tests/Integration/Twig/CoreExtensionTest.php
index 550b8cfb1..5d231a514 100644
--- a/app/sprinkles/core/tests/Integration/Twig/CoreExtensionTest.php
+++ b/app/sprinkles/core/tests/Integration/Twig/CoreExtensionTest.php
@@ -17,7 +17,7 @@
/**
* CoreExtensionTest class.
- * Tests Core twig extentions
+ * Tests Core twig extensions
*/
class CoreExtensionTest extends TestCase
{
@@ -67,16 +67,16 @@ public function testPhoneFilter(): void
public function testUnescapeFilter(): void
{
$string = "I'll \"walk\" the dog now";
- $this->assertNotSame($string, $this->ci->view->fetchFromString("{{ foo }}", ['foo' => htmlentities($string)]));
- $this->assertNotSame($string, $this->ci->view->fetchFromString("{{ foo|unescape }}", ['foo' => htmlentities($string)]));
- $this->assertNotSame($string, $this->ci->view->fetchFromString("{{ foo|raw }}", ['foo' => htmlentities($string)]));
- $this->assertSame($string, $this->ci->view->fetchFromString("{{ foo|unescape|raw }}", ['foo' => htmlentities($string)]));
+ $this->assertNotSame($string, $this->ci->view->fetchFromString('{{ foo }}', ['foo' => htmlentities($string)]));
+ $this->assertNotSame($string, $this->ci->view->fetchFromString('{{ foo|unescape }}', ['foo' => htmlentities($string)]));
+ $this->assertNotSame($string, $this->ci->view->fetchFromString('{{ foo|raw }}', ['foo' => htmlentities($string)]));
+ $this->assertSame($string, $this->ci->view->fetchFromString('{{ foo|unescape|raw }}', ['foo' => htmlentities($string)]));
}
public function testCurrentLocaleGlobal(): void
{
$this->ci->locale = Mockery::mock(SiteLocale::class)->shouldReceive('getLocaleIndentifier')->once()->andReturn('zz-ZZ')->getMock();
- $this->assertSame('zz-ZZ', $this->ci->view->fetchFromString("{{ currentLocale }}"));
+ $this->assertSame('zz-ZZ', $this->ci->view->fetchFromString('{{ currentLocale }}'));
}
}
diff --git a/app/sprinkles/core/tests/Integration/Util/CheckEnvironmentTest.php b/app/sprinkles/core/tests/Integration/Util/CheckEnvironmentTest.php
index 140dc2e93..272e2ed1f 100644
--- a/app/sprinkles/core/tests/Integration/Util/CheckEnvironmentTest.php
+++ b/app/sprinkles/core/tests/Integration/Util/CheckEnvironmentTest.php
@@ -14,7 +14,7 @@
use UserFrosting\Tests\TestCase;
/**
- * CheckEnvironement Test
+ * CheckEnvironment Test
*/
class CheckEnvironmentTest extends TestCase
{
diff --git a/app/sprinkles/core/tests/Unit/Util/VersionValidatorTest.php b/app/sprinkles/core/tests/Unit/Util/VersionValidatorTest.php
new file mode 100644
index 000000000..684faa211
--- /dev/null
+++ b/app/sprinkles/core/tests/Unit/Util/VersionValidatorTest.php
@@ -0,0 +1,200 @@
+getNamespaceName();
+ $mock = $this->getFunctionMock($namespace, 'phpversion');
+ $mock->expects($this->any())->willReturn($version);
+
+ // Assert GetPHPVersion
+ $this->assertSame($sanitized, VersionValidator::getPhpVersion());
+
+ // Assert validatePhpVersion
+ if ($valid) {
+ $this->assertTrue(VersionValidator::validatePhpVersion());
+ } else {
+ try {
+ VersionValidator::validatePhpVersion();
+ } catch (VersionCompareException $e) {
+ $this->assertSame(VersionValidator::getPhpConstraint(), $e->getConstraint());
+ $this->assertSame($sanitized, $e->getVersion());
+
+ return;
+ }
+
+ $this->fail();
+ }
+
+ // Assert validatePhpDeprecation
+ if (!$deprecated) {
+ $this->assertTrue(VersionValidator::validatePhpDeprecation());
+ } else {
+ try {
+ VersionValidator::validatePhpDeprecation();
+ } catch (VersionCompareException $e) {
+ $this->assertSame(VersionValidator::getPhpRecommended(), $e->getConstraint());
+ $this->assertSame($sanitized, $e->getVersion());
+
+ return;
+ }
+
+ $this->fail();
+ }
+ }
+
+ /**
+ * Assert Node related methods.
+ *
+ * @dataProvider nodeVersionProvider
+ * @runInSeparateProcess
+ *
+ * @param string $version
+ * @param string $sanitized
+ * @param bool $valid
+ */
+ public function testNode(string $version, string $sanitized, bool $valid): void
+ {
+ // Mock `exec` function
+ $class = new \ReflectionClass(VersionValidator::class);
+ $namespace = $class->getNamespaceName();
+ $mock = $this->getFunctionMock($namespace, 'exec');
+ $mock->expects($this->any())->willReturn($version);
+
+ // Assert getNodeVersion
+ $this->assertSame($sanitized, VersionValidator::getNodeVersion());
+
+ // Assert validateNodeVersion
+ if ($valid) {
+ $this->assertTrue(VersionValidator::validateNodeVersion());
+ } else {
+ try {
+ VersionValidator::validateNodeVersion();
+ } catch (VersionCompareException $e) {
+ $this->assertSame(VersionValidator::getNodeConstraint(), $e->getConstraint());
+ $this->assertSame($sanitized, $e->getVersion());
+
+ return;
+ }
+
+ $this->fail();
+ }
+ }
+
+ /**
+ * Assert Npm related methods.
+ *
+ * @dataProvider npmVersionProvider
+ * @runInSeparateProcess
+ *
+ * @param string $version
+ * @param string $sanitized
+ * @param bool $valid
+ */
+ public function testNpm(string $version, string $sanitized, bool $valid): void
+ {
+ // Mock `exec` function
+ $class = new \ReflectionClass(VersionValidator::class);
+ $namespace = $class->getNamespaceName();
+ $mock = $this->getFunctionMock($namespace, 'exec');
+ $mock->expects($this->any())->willReturn($version);
+
+ // Assert getNpmVersion
+ $this->assertSame($sanitized, VersionValidator::getNpmVersion());
+
+ // Assert validateNpmVersion
+ if ($valid) {
+ $this->assertTrue(VersionValidator::validateNpmVersion());
+ } else {
+ try {
+ VersionValidator::validateNpmVersion();
+ } catch (VersionCompareException $e) {
+ $this->assertSame(VersionValidator::getNpmConstraint(), $e->getConstraint());
+ $this->assertSame($sanitized, $e->getVersion());
+
+ return;
+ }
+
+ $this->fail();
+ }
+ }
+
+ /**
+ * PHP version provider.
+ *
+ * @return array [version, sanitized, valid, deprecated]
+ */
+ public function phpVersionProvider(): array
+ {
+ return [
+ ['7.1.4', '7.1.4', false, true],
+ ['7.2.1', '7.2.1', true, true],
+ ['7.2', '7.2', true, true],
+ ['7.3.14', '7.3.14', true, true],
+ ['7.4.13', '7.4.13', true, false],
+ ['7.2.34-18+ubuntu20.04.1+deb.sury.org+1', '7.2.34', true, true],
+ ];
+ }
+
+ /**
+ * Node version provider.
+ *
+ * @return array [version, sanitized, valid]
+ */
+ public function nodeVersionProvider(): array
+ {
+ return [
+ ['v12.18.1', 'v12.18.1', true],
+ ['v13.12.3', 'v13.12.3', false],
+ ['v14.0.0 ', 'v14.0.0', true], // Test trim here
+ ];
+ }
+
+ /**
+ * Node version provider.
+ *
+ * @return array [version, sanitized, valid]
+ */
+ public function npmVersionProvider(): array
+ {
+ return [
+ [' 6.14.10 ', '6.14.10', true], // Trim
+ ['6.14.4', '6.14.4', true],
+ ['5.12.14', '5.12.14', false],
+ ];
+ }
+}
diff --git a/app/sprinkles/core/tests/withDatabaseSessionHandler.php b/app/sprinkles/core/tests/withDatabaseSessionHandler.php
index d92e1053f..343f6461a 100644
--- a/app/sprinkles/core/tests/withDatabaseSessionHandler.php
+++ b/app/sprinkles/core/tests/withDatabaseSessionHandler.php
@@ -25,7 +25,7 @@ trait withDatabaseSessionHandler
public function useDatabaseSessionHandler()
{
// Skip test if using in-memory database.
- // However we tell UF to use database session handler and in-memroy
+ // However we tell UF to use database session handler and in-memory
// database, the session will always be created before the db can be
// migrate, causing "table not found" errors
if ($this->usingInMemoryDatabase()) {
diff --git a/app/system/Bakery/BaseCommand.php b/app/system/Bakery/BaseCommand.php
index e91fe136a..3ce30f816 100644
--- a/app/system/Bakery/BaseCommand.php
+++ b/app/system/Bakery/BaseCommand.php
@@ -62,7 +62,7 @@ protected function isProduction(): bool
{
// Need to touch the config service first to load dotenv values
$config = $this->ci->config;
- $mode = getenv('UF_MODE') ?: '';
+ $mode = env('UF_MODE', '');
return $mode === 'production';
}
diff --git a/app/system/Bakery/Migration.php b/app/system/Bakery/Migration.php
deleted file mode 100644
index 3eacdef35..000000000
--- a/app/system/Bakery/Migration.php
+++ /dev/null
@@ -1,42 +0,0 @@
-assertTrue(true);
- }
}
diff --git a/app/system/Sprinkle/SprinkleManager.php b/app/system/Sprinkle/SprinkleManager.php
index 3a77cc832..516b8ddc8 100644
--- a/app/system/Sprinkle/SprinkleManager.php
+++ b/app/system/Sprinkle/SprinkleManager.php
@@ -31,7 +31,7 @@ class SprinkleManager
protected $ci;
/**
- * @var Sprinkle[] An array of sprinkles.
+ * @var (Sprinkle|null)[] An array of sprinkles : array.
*/
protected $sprinkles = [];
@@ -54,7 +54,7 @@ public function __construct(ContainerInterface $ci)
* Register resource streams for all base sprinkles.
* For each sprinkle, register its resources and then run its initializer.
*/
- public function addResources()
+ public function addResources(): void
{
foreach ($this->sprinkles as $sprinkleName => $sprinkle) {
$this->addSprinkleResources($sprinkleName);
@@ -66,7 +66,7 @@ public function addResources()
*
* @param string $sprinkleName
*/
- public function addSprinkleResources($sprinkleName)
+ public function addSprinkleResources(string $sprinkleName): void
{
/** @var \UserFrosting\UniformResourceLocator\ResourceLocator $locator */
$locator = $this->ci->locator;
@@ -80,7 +80,7 @@ public function addSprinkleResources($sprinkleName)
*
* @return string
*/
- public function getSprinklePath($sprinkleName)
+ public function getSprinklePath(string $sprinkleName): string
{
// Get Sprinkle and make sure it exist
$sprinkle = $this->getSprinkle($sprinkleName);
@@ -104,7 +104,7 @@ public function getSprinklePath($sprinkleName)
*
* @return string
*/
- protected function getSprinkleClass($sprinkleName)
+ protected function getSprinkleClass(string $sprinkleName): string
{
$className = Str::studly($sprinkleName);
@@ -118,7 +118,7 @@ protected function getSprinkleClass($sprinkleName)
*
* @return string The Sprinkle Namespace
*/
- public function getSprinkleClassNamespace($sprinkleName)
+ public function getSprinkleClassNamespace(string $sprinkleName): string
{
$className = Str::studly($sprinkleName);
@@ -132,7 +132,7 @@ public function getSprinkleClassNamespace($sprinkleName)
*
* @return string
*/
- protected function getSprinkleDefaultServiceProvider($sprinkleName)
+ protected function getSprinkleDefaultServiceProvider(string $sprinkleName): string
{
return $this->getSprinkleClassNamespace($sprinkleName) . '\\ServicesProvider\\ServicesProvider';
}
@@ -145,9 +145,9 @@ protected function getSprinkleDefaultServiceProvider($sprinkleName)
*
* @param string $sprinkleName The name of the Sprinkle to initialize.
*
- * @return mixed Sprinkle class instance or null if no such class exist
+ * @return Sprinkle|null Sprinkle class instance or null if no such class exist
*/
- public function bootSprinkle($sprinkleName)
+ public function bootSprinkle(string $sprinkleName): ?Sprinkle
{
$fullClassName = $this->getSprinkleClass($sprinkleName);
@@ -155,9 +155,13 @@ public function bootSprinkle($sprinkleName)
if (class_exists($fullClassName)) {
$sprinkle = new $fullClassName($this->ci);
+ if (!$sprinkle instanceof Sprinkle) {
+ throw new SprinkleClassException("$fullClassName must be an instance of " . Sprinkle::class);
+ }
+
return $sprinkle;
} else {
- return;
+ return null;
}
}
@@ -166,7 +170,7 @@ public function bootSprinkle($sprinkleName)
*
* @return string[]
*/
- public function getSprinkleNames()
+ public function getSprinkleNames(): array
{
return array_keys($this->sprinkles);
}
@@ -174,9 +178,9 @@ public function getSprinkleNames()
/**
* Returns a list of available sprinkles.
*
- * @return Sprinkle[]
+ * @return (Sprinkle|null)[]
*/
- public function getSprinkles()
+ public function getSprinkles(): array
{
return $this->sprinkles;
}
@@ -187,7 +191,7 @@ public function getSprinkles()
*
* @param string[] $sprinkleNames
*/
- public function init(array $sprinkleNames)
+ public function init(array $sprinkleNames): void
{
foreach ($sprinkleNames as $sprinkleName) {
$sprinkle = $this->bootSprinkle($sprinkleName);
@@ -206,9 +210,9 @@ public function init(array $sprinkleNames)
*
* @param string $schemaPath
*/
- public function initFromSchema($schemaPath)
+ public function initFromSchema(string $schemaPath): void
{
- $baseSprinkleNames = $this->loadSchema($schemaPath)->base;
+ $baseSprinkleNames = $this->loadSchema($schemaPath);
$this->init($baseSprinkleNames);
}
@@ -220,7 +224,7 @@ public function initFromSchema($schemaPath)
*
* @return bool
*/
- public function isAvailable($sprinkleName)
+ public function isAvailable(string $sprinkleName): bool
{
return (bool) $this->getSprinkle($sprinkleName);
}
@@ -232,7 +236,7 @@ public function isAvailable($sprinkleName)
*
* @return string|false Return sprinkle name or false if sprinkle not found
*/
- public function getSprinkle($sprinkleName)
+ public function getSprinkle(string $sprinkleName)
{
$mathches = preg_grep("/^$sprinkleName$/i", $this->getSprinkleNames());
@@ -246,7 +250,7 @@ public function getSprinkle($sprinkleName)
/**
* Interate through the list of loaded Sprinkles, and invoke their ServiceProvider classes.
*/
- public function registerAllServices()
+ public function registerAllServices(): void
{
foreach ($this->getSprinkleNames() as $sprinkleName) {
$this->registerServices($sprinkleName);
@@ -258,7 +262,7 @@ public function registerAllServices()
*
* @param string $sprinkleName
*/
- public function registerServices($sprinkleName)
+ public function registerServices(string $sprinkleName): void
{
//Register the default services
$fullClassName = $this->getSprinkleDefaultServiceProvider($sprinkleName);
@@ -281,7 +285,7 @@ public function registerServices($sprinkleName)
*
* @return string
*/
- public function getSprinklesPath()
+ public function getSprinklesPath(): string
{
return $this->sprinklesPath;
}
@@ -293,7 +297,7 @@ public function getSprinklesPath()
*
* @return static
*/
- public function setSprinklesPath($sprinklesPath)
+ public function setSprinklesPath(string $sprinklesPath)
{
$this->sprinklesPath = $sprinklesPath;
@@ -307,7 +311,7 @@ public function setSprinklesPath($sprinklesPath)
*
* @return string[]
*/
- protected function loadSchema($schemaPath)
+ protected function loadSchema(string $schemaPath): array
{
$sprinklesFile = @file_get_contents($schemaPath);
@@ -324,6 +328,14 @@ protected function loadSchema($schemaPath)
throw new JsonException($errorMessage);
}
- return $data;
+ // Remove duplicates, keep the first one
+ // @see https://stackoverflow.com/a/2276400/445757
+ $sprinkles = $data->base;
+ $sprinkles = array_intersect_key(
+ $sprinkles,
+ array_unique(array_map('strtolower', $sprinkles))
+ );
+
+ return $sprinkles;
}
}
diff --git a/app/system/UserFrosting.php b/app/system/UserFrosting.php
index 20b378032..d16e96552 100644
--- a/app/system/UserFrosting.php
+++ b/app/system/UserFrosting.php
@@ -63,7 +63,7 @@ public function __construct(bool $cli = false)
*/
public function fireEvent($eventName, Event $event = null)
{
- /** @var EventDispatcher $events */
+ /** @var EventDispatcher */
$eventDispatcher = $this->ci->eventDispatcher;
return $eventDispatcher->dispatch($eventName, $event);
@@ -74,7 +74,7 @@ public function fireEvent($eventName, Event $event = null)
*
* @return App
*/
- public function getApp()
+ public function getApp(): App
{
return $this->app;
}
@@ -84,7 +84,7 @@ public function getApp()
*
* @return Container
*/
- public function getContainer()
+ public function getContainer(): Container
{
return $this->ci;
}
@@ -92,7 +92,7 @@ public function getContainer()
/**
* Initialize the application. Set up Sprinkles and the Slim app, define routes, register global middleware, and run Slim.
*/
- public function run()
+ public function run(): void
{
$this->app->run();
}
@@ -100,13 +100,14 @@ public function run()
/**
* Register system services, load all sprinkles, and add their resources and services.
*/
- protected function setupSprinkles()
+ protected function setupSprinkles(): void
{
// Register system services
$serviceProvider = new ServicesProvider();
$serviceProvider->register($this->ci);
// Boot the Sprinkle manager, which creates Sprinkle classes and subscribes them to the event dispatcher
+ /** @var \UserFrosting\System\Sprinkle\SprinkleManager */
$sprinkleManager = $this->ci->sprinkleManager;
try {
@@ -133,7 +134,7 @@ protected function setupSprinkles()
/**
* Setup UserFrosting App, load sprinkles, load routes, etc.
*/
- protected function setupApp()
+ protected function setupApp(): void
{
// Setup sprinkles
$this->setupSprinkles();
@@ -157,7 +158,7 @@ protected function setupApp()
*
* @param string $errorMessage Message to display [Default ""]
*/
- protected function renderSprinkleErrorPage($errorMessage = '')
+ protected function renderSprinkleErrorPage(string $errorMessage = '')
{
ob_clean();
$title = 'UserFrosting Application Error';
@@ -181,7 +182,7 @@ protected function renderSprinkleErrorPage($errorMessage = '')
*
* @param string $errorMessage Message to display [Default ""]
*/
- protected function renderSprinkleErrorCli($errorMessage = '')
+ protected function renderSprinkleErrorCli(string $errorMessage = '')
{
exit($errorMessage . PHP_EOL);
}
diff --git a/app/tests/DatabaseTransactions.php b/app/tests/DatabaseTransactions.php
deleted file mode 100644
index 5f914c186..000000000
--- a/app/tests/DatabaseTransactions.php
+++ /dev/null
@@ -1,49 +0,0 @@
-ci->db;
-
- foreach ($this->connectionsToTransact() as $name) {
- $database->connection($name)->beginTransaction();
- }
-
- $this->beforeApplicationDestroyed(function () use ($database) {
- foreach ($this->connectionsToTransact() as $name) {
- $database->connection($name)->rollBack();
- }
- });
- }
-
- /**
- * The database connections that should have transactions.
- *
- * @return array
- */
- protected function connectionsToTransact()
- {
- return property_exists($this, 'connectionsToTransact')
- ? $this->connectionsToTransact : [null];
- }
-}
diff --git a/app/tests/TestCase.php b/app/tests/TestCase.php
index c5b5ce077..c3fee8925 100644
--- a/app/tests/TestCase.php
+++ b/app/tests/TestCase.php
@@ -58,8 +58,6 @@ protected function setUp(): void
$this->refreshApplication();
}
- $this->setUpTraits();
-
foreach ($this->afterApplicationCreatedCallbacks as $callback) {
call_user_func($callback);
}
@@ -67,21 +65,6 @@ protected function setUp(): void
$this->setUpHasRun = true;
}
- /**
- * Boot the testing helper traits.
- *
- * @deprecated
- */
- protected function setUpTraits()
- {
- $uses = array_flip(class_uses_recursive(static::class));
-
- if (isset($uses[DatabaseTransactions::class])) {
- Debug::warning("`UserFrosting\Tests\DatabaseTransactions` has been deprecated and will be removed in future versions. Please use `UserFrosting\Sprinkle\Core\Tests\DatabaseTransactions` class instead.");
- $this->beginDatabaseTransaction();
- }
- }
-
/**
* Refresh the application instance.
*/
diff --git a/app/tests/Unit/SprinkleManagerTest.php b/app/tests/Unit/SprinkleManagerTest.php
index 6c74dc92b..efcd202bc 100644
--- a/app/tests/Unit/SprinkleManagerTest.php
+++ b/app/tests/Unit/SprinkleManagerTest.php
@@ -12,6 +12,10 @@
use Psr\Container\ContainerInterface;
use Mockery as m;
+use UserFrosting\Support\Exception\FileNotFoundException;
+use UserFrosting\Support\Exception\JsonException;
+use UserFrosting\System\Sprinkle\Sprinkle;
+use UserFrosting\System\Sprinkle\SprinkleClassException;
use UserFrosting\Tests\TestCase;
use UserFrosting\System\Sprinkle\SprinkleManager;
@@ -20,6 +24,9 @@ class SprinkleManagerTest extends TestCase
/** @var ContainerInterface $fakeCi Our mocked CI used for testing */
protected $fakeCi;
+ /** @var string */
+ protected $basePath = __DIR__ . '/data/';
+
public function setUp(): void
{
// We don't call parent function to cancel CI creation and get accurate test coverage
@@ -27,9 +34,6 @@ public function setUp(): void
$this->fakeCi = m::mock(ContainerInterface::class);
$this->fakeCi->eventDispatcher = new eventDispatcherStub();
$this->fakeCi->locator = new ResourceLocatorStub();
-
- // Setup test sprinkle mock class so it can be found by `class_exist`
- m::mock('UserFrosting\Sprinkle\Test\Test');
}
public function tearDown(): void
@@ -41,7 +45,7 @@ public function tearDown(): void
/**
* @return SprinkleManager
*/
- public function testConstructor()
+ public function testConstructor(): SprinkleManager
{
$sprinkleManager = new SprinkleManager($this->fakeCi);
$this->assertInstanceOf(SprinkleManager::class, $sprinkleManager);
@@ -53,7 +57,7 @@ public function testConstructor()
* @depends testConstructor
* @param SprinkleManager $sprinkleManager
*/
- public function testGetSetSprinklesPath(SprinkleManager $sprinkleManager)
+ public function testGetSetSprinklesPath(SprinkleManager $sprinkleManager): void
{
$sprinkleManager->setSprinklesPath('/foo');
$this->assertSame('/foo', $sprinkleManager->getSprinklesPath());
@@ -62,27 +66,48 @@ public function testGetSetSprinklesPath(SprinkleManager $sprinkleManager)
/**
* @depends testConstructor
*/
- public function testLoadSprinkleWithNonExistingFile()
+ public function testLoadSprinkleWithNonExistingFile(): void
{
$sprinkleManager = new SprinkleManager($this->fakeCi);
- $this->expectException(\UserFrosting\Support\Exception\FileNotFoundException::class);
+ $this->expectException(FileNotFoundException::class);
$sprinkleManager->initFromSchema('foo.json');
}
+ /**
+ * Will test the instanceof sprinkle check is done + that the right class
+ * is gnerated with the exception message assertion
+ *
+ * @depends testConstructor
+ * @param SprinkleManager $sprinkleManager
+ */
+ public function testGetSprinklesWihoutMockClass(SprinkleManager $sprinkleManager): void
+ {
+ // Setup test sprinkle mock class so it can be found by `class_exist`
+ class_alias(BlahSprinkleStub::class, 'UserFrosting\Sprinkle\Blah\Blah');
+
+ $this->expectException(SprinkleClassException::class);
+ $this->expectExceptionMessage("UserFrosting\Sprinkle\Blah\Blah must be an instance of UserFrosting\System\Sprinkle\Sprinkle");
+ $sprinkleManager->bootSprinkle('blah');
+ }
+
/**
* @depends testConstructor
* @param SprinkleManager $sprinkleManager
* @return SprinkleManager
*/
- public function testGetSprinkles(SprinkleManager $sprinkleManager)
+ public function testGetSprinkles(SprinkleManager $sprinkleManager): SprinkleManager
{
+ // Setup test sprinkle class alias so it can be found by `class_exist`
+ class_alias(TestSprinkleStub::class, 'UserFrosting\Sprinkle\Test\Test');
+
$sprinkleManager->initFromSchema(__DIR__ . '/data/sprinkles.json');
+
$sprinkles = $sprinkleManager->getSprinkles();
- $this->assertEquals([
- 'foo' => null,
- 'bar' => null,
- 'test' => new \UserFrosting\Sprinkle\Test\Test(),
- ], $sprinkles);
+ $this->assertIsArray($sprinkles);
+ $this->assertCount(3, $sprinkles);
+ $this->assertNull($sprinkles['foo']);
+ $this->assertNull($sprinkles['bar']);
+ $this->assertInstanceOf(Sprinkle::class, $sprinkles['test']);
return $sprinkleManager;
}
@@ -91,7 +116,7 @@ public function testGetSprinkles(SprinkleManager $sprinkleManager)
* @depends testGetSprinkles
* @param SprinkleManager $sprinkleManager
*/
- public function testGetSprinkleNames(SprinkleManager $sprinkleManager)
+ public function testGetSprinkleNames(SprinkleManager $sprinkleManager): void
{
$sprinkles = $sprinkleManager->getSprinkleNames();
$this->assertSame(['foo', 'bar', 'test'], $sprinkles);
@@ -119,7 +144,7 @@ public function testGetSprinkleNames(SprinkleManager $sprinkleManager)
* ["barfoo", false]
* ["blah", false]
*/
- public function testIsAvailable($sprinkleName, $isAvailable, SprinkleManager $sprinkleManager)
+ public function testIsAvailable($sprinkleName, $isAvailable, SprinkleManager $sprinkleManager): void
{
$this->assertSame($isAvailable, $sprinkleManager->isAvailable($sprinkleName));
}
@@ -132,11 +157,10 @@ public function testIsAvailable($sprinkleName, $isAvailable, SprinkleManager $sp
* ["bar"]
* ["test"]
*/
- public function testGetSprinklePath($sprinkleName, SprinkleManager $sprinkleManager)
+ public function testGetSprinklePath($sprinkleName, SprinkleManager $sprinkleManager): void
{
- $basePath = 'app/tests/Unit/data/';
- $sprinkleManager->setSprinklesPath($basePath);
- $this->assertSame($basePath . $sprinkleName, $sprinkleManager->getSprinklePath($sprinkleName));
+ $sprinkleManager->setSprinklesPath($this->basePath);
+ $this->assertSame($this->basePath . $sprinkleName, $sprinkleManager->getSprinklePath($sprinkleName));
}
/**
@@ -144,12 +168,11 @@ public function testGetSprinklePath($sprinkleName, SprinkleManager $sprinkleMana
* @depends testGetSprinklePath
* @param SprinkleManager $sprinkleManager
*/
- public function testGetSprinklePathWherePathDoesntExist(SprinkleManager $sprinkleManager)
+ public function testGetSprinklePathWherePathDoesntExist(SprinkleManager $sprinkleManager): void
{
- $basePath = 'app/tests/Unit/foo/';
- $sprinkleManager->setSprinklesPath($basePath);
+ $sprinkleManager->setSprinklesPath(__DIR__ . '/foo/');
- $this->expectException(\UserFrosting\Support\Exception\FileNotFoundException::class);
+ $this->expectException(FileNotFoundException::class);
$sprinkleManager->getSprinklePath('foo');
}
@@ -158,9 +181,9 @@ public function testGetSprinklePathWherePathDoesntExist(SprinkleManager $sprinkl
* @depends testGetSprinklePath
* @param SprinkleManager $sprinkleManager
*/
- public function testGetSprinklePathWhereSprinkleDoesntExist(SprinkleManager $sprinkleManager)
+ public function testGetSprinklePathWhereSprinkleDoesntExist(SprinkleManager $sprinkleManager): void
{
- $this->expectException(\UserFrosting\Support\Exception\FileNotFoundException::class);
+ $this->expectException(FileNotFoundException::class);
$sprinkleManager->getSprinklePath('blah');
}
@@ -168,15 +191,15 @@ public function testGetSprinklePathWhereSprinkleDoesntExist(SprinkleManager $spr
* @depends testGetSprinkles
* @param SprinkleManager $sprinkleManager
*/
- public function testRegisterAllServices(SprinkleManager $sprinkleManager)
+ public function testRegisterAllServices(SprinkleManager $sprinkleManager): void
{
// Set Expectations for test sprinkle ServiceProvider
// @see https://stackoverflow.com/a/13390001/445757
$this->getMockBuilder('nonexistant')
- ->setMockClassName('foo')
+ ->setMockClassName('FooService') // MockClassName doesn't accept namespace
->setMethods(['register'])
->getMock();
- class_alias('foo', 'UserFrosting\Sprinkle\Test\ServicesProvider\ServicesProvider');
+ class_alias('FooService', 'UserFrosting\Sprinkle\Test\ServicesProvider\ServicesProvider');
$this->assertNull($sprinkleManager->registerAllServices());
}
@@ -186,10 +209,9 @@ class_alias('foo', 'UserFrosting\Sprinkle\Test\ServicesProvider\ServicesProvider
* @depends testGetSprinklePath
* @param SprinkleManager $sprinkleManager
*/
- public function testAddResources(SprinkleManager $sprinkleManager)
+ public function testAddResources(SprinkleManager $sprinkleManager): void
{
- $basePath = 'app/tests/Unit/data/';
- $sprinkleManager->setSprinklesPath($basePath);
+ $sprinkleManager->setSprinklesPath($this->basePath);
$this->assertNull($sprinkleManager->addResources());
}
@@ -200,7 +222,7 @@ public function testAddResources(SprinkleManager $sprinkleManager)
* @depends testConstructor
* @depends testGetSprinkles
*/
- public function testLoadSprinkleWithTxtFile()
+ public function testLoadSprinkleWithTxtFile(): void
{
$sprinkleManager = new SprinkleManager($this->fakeCi);
$sprinkleManager->initFromSchema(__DIR__ . '/data/sprinkles.txt');
@@ -210,10 +232,10 @@ public function testLoadSprinkleWithTxtFile()
/**
* @depends testConstructor
*/
- public function testLoadSprinkleWithBadJson()
+ public function testLoadSprinkleWithBadJson(): void
{
$sprinkleManager = new SprinkleManager($this->fakeCi);
- $this->expectException(\UserFrosting\Support\Exception\JsonException::class);
+ $this->expectException(JsonException::class);
$sprinkleManager->initFromSchema(__DIR__ . '/data/sprinkles-bad.json');
}
@@ -221,17 +243,31 @@ public function testLoadSprinkleWithBadJson()
* @depends testConstructor
* @depends testIsAvailable
*/
- public function testLoadSprinkleWithDuplicateSprinkles()
+ public function testLoadSprinkleWithDuplicateSprinkles(): void
{
- $sprinkleManager = new SprinkleManager($this->fakeCi);
+ $sprinkleManager = m::mock(SprinkleManager::class, [$this->fakeCi])->makePartial();
+
+ // Make sure the sprinkles are not booted twice
+ $sprinkleManager->shouldReceive('bootSprinkle')->with('foo')->once();
+ $sprinkleManager->shouldReceive('bootSprinkle')->with('bar')->once();
+
+ $sprinkleManager->setSprinklesPath($this->basePath);
$sprinkleManager->initFromSchema(__DIR__ . '/data/sprinkles-duplicate.json');
+ $sprinkles = $sprinkleManager->getSprinkles();
+
$this->assertEquals([
'foo' => null,
- 'FOO' => null,
'bar' => null,
- ], $sprinkleManager->getSprinkles());
+ ], $sprinkles);
+ // Test isAvailable work with only the correct case.
+ $this->assertTrue($sprinkleManager->isAvailable('foo'));
$this->assertTrue($sprinkleManager->isAvailable('Foo'));
+ $this->assertTrue($sprinkleManager->isAvailable('FOO'));
+
+ // Test getSprinklePath get the right case
+ $this->assertsame(__DIR__ . '/data/bar', $sprinkleManager->getSprinklePath('bar'));
+ $this->assertsame(__DIR__ . '/data/foo', $sprinkleManager->getSprinklePath('foo'));
}
}
@@ -248,3 +284,11 @@ public function registerLocation()
{
}
}
+
+class TestSprinkleStub extends Sprinkle
+{
+}
+
+class BlahSprinkleStub
+{
+}
\ No newline at end of file
diff --git a/build/package.json b/build/package.json
index c2215a0bc..4bdfec1d6 100755
--- a/build/package.json
+++ b/build/package.json
@@ -5,31 +5,32 @@
"@userfrosting/gulp-bundle-assets": "^4.0.1",
"@userfrosting/merge-package-dependencies": "^2.1.0",
"@userfrosting/vinyl-fs-vpath": "^2.0.0",
- "bower": "^1.8.8",
+ "@yarnpkg/shell": "^2.4.1",
+ "bower": "^1.8.12",
"del": "^6.0.0",
"dotenv": "^8.2.0",
"esm": "^3.2.25",
"gulp": "^4.0.2",
- "gulp-clean-css": "^4.2.0",
+ "gulp-clean-css": "^4.3.0",
"gulp-concat": "^2.6.1",
"gulp-concat-css": "^3.1.0",
"gulp-if": "^3.0.0",
"gulp-prune": "^0.2.0",
"gulp-rev": "^9.0.0",
- "gulp-sourcemaps": "^2.6.5",
- "gulp-terser": "^1.2.0",
+ "gulp-sourcemaps": "^3.0.0",
+ "gulp-terser": "^2.0.1",
"gulplog": "^1.0.0",
"strip-ansi": "^6.0.0"
},
"scripts": {
- "uf-bundle": "./node_modules/.bin/gulp build",
- "uf-assets-install": "./node_modules/.bin/gulp assetsInstall",
- "uf-frontend": "./node_modules/.bin/gulp frontend",
- "uf-clean": "./node_modules/.bin/gulp clean"
+ "uf-bundle": "shell './node_modules/.bin/gulp build'",
+ "uf-assets-install": "shell './node_modules/.bin/gulp assetsInstall'",
+ "uf-frontend": "shell './node_modules/.bin/gulp frontend'",
+ "uf-clean": "shell './node_modules/.bin/gulp clean'"
},
"engines": {
- "node": ">=10.12.0",
- "npm": ">=6.0.0"
+ "node": "^12.17.0 || >=14.0.0",
+ "npm": ">=6.14.4"
},
"engineStrict": true
}
diff --git a/composer.json b/composer.json
index 47d3b9d16..34b3c18e8 100755
--- a/composer.json
+++ b/composer.json
@@ -17,19 +17,19 @@
{
"name": "Jordan Mele",
"email": "SiliconSoldier@outlook.com.au",
- "homepage": "https://blog.djmm.me"
+ "homepage": "https://djmm.me"
}
],
"config": {
"vendor-dir": "app/vendor"
},
"require": {
- "php": ">=7.1",
+ "php": ">=7.2",
"ext-gd": "*",
"composer/installers": "^1.4.0",
- "userfrosting/uniformresourcelocator": "~4.4.0",
+ "userfrosting/uniformresourcelocator": "~4.5.0",
"symfony/console": "^4.3",
- "wikimedia/composer-merge-plugin": "^1.4.0"
+ "wikimedia/composer-merge-plugin": "^2.1.0"
},
"require-dev": {
"friendsofphp/php-cs-fixer": "^2.13",
diff --git a/phpunit.xml b/phpunit.xml.dist
similarity index 97%
rename from phpunit.xml
rename to phpunit.xml.dist
index 044b4fe72..161175b00 100644
--- a/phpunit.xml
+++ b/phpunit.xml.dist
@@ -8,7 +8,7 @@
convertWarningsToExceptions="true"
processIsolation="false"
stderr="true"
- stopOnFailure="false">
+ stopOnFailure="true">
app/tests/Unit